diff --git a/packages/base/any/fit/loader/builds/Makefile b/packages/base/any/fit/loader/builds/Makefile index f257e3b8..840f6fa7 100644 --- a/packages/base/any/fit/loader/builds/Makefile +++ b/packages/base/any/fit/loader/builds/Makefile @@ -4,7 +4,7 @@ endif .PHONY: onl-loader-fit.itb onl-loader-fit.its -onl-loader-fit.itb: +onl-loader-fit.itb: its $(ONL)/tools/flat-image-tree.py --initrd onl-loader-initrd:$(ARCH),onl-loader-initrd-$(ARCH).cpio.gz --arch $(ARCH) --add-platform initrd --itb $@ $(ONLPM) --copy-file onl-loader-initrd:$(ARCH) manifest.json . diff --git a/packages/base/any/kernels/4.14-lts/configs/arm-iproc-all/.gitignore b/packages/base/any/kernels/4.14-lts/configs/arm-iproc-all/.gitignore new file mode 100644 index 00000000..3898a1cf --- /dev/null +++ b/packages/base/any/kernels/4.14-lts/configs/arm-iproc-all/.gitignore @@ -0,0 +1,2 @@ +linux-3.2* +kernel-3.2* diff --git a/packages/base/any/kernels/4.14-lts/configs/arm-iproc-all/Makefile b/packages/base/any/kernels/4.14-lts/configs/arm-iproc-all/Makefile new file mode 100644 index 00000000..26b39526 --- /dev/null +++ b/packages/base/any/kernels/4.14-lts/configs/arm-iproc-all/Makefile @@ -0,0 +1,42 @@ +############################################################ +# +# +# Copyright 2015 Big Switch Networks, Inc. +# +# Licensed under the Eclipse Public License, Version 1.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.eclipse.org/legal/epl-v10.html +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, +# either express or implied. See the License for the specific +# language governing permissions and limitations under the +# License. +# +# +############################################################ + +THIS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) +include $(ONL)/make/config.mk + +ifndef K_TARGET_DIR +K_TARGET_DIR := $(THIS_DIR) +endif + +K_PATCH_DIR := $(THIS_DIR)/patches + +include ../../kconfig.mk +K_CONFIG := arm-iproc-all.config +K_BUILD_TARGET := Image +K_COPY_SRC := arch/arm/boot/Image +K_COPY_GZIP := 1 +ifndef K_COPY_DST +K_COPY_DST := kernel-4.14-lts-arm-iproc-all.bin.gz +endif + +export ARCH=arm + +include $(ONL)/make/kbuild.mk diff --git a/packages/base/any/kernels/4.14-lts/configs/arm-iproc-all/arm-iproc-all.config b/packages/base/any/kernels/4.14-lts/configs/arm-iproc-all/arm-iproc-all.config new file mode 100644 index 00000000..4f574567 --- /dev/null +++ b/packages/base/any/kernels/4.14-lts/configs/arm-iproc-all/arm-iproc-all.config @@ -0,0 +1,3294 @@ +# +# Automatically generated file; DO NOT EDIT. +# Linux/arm 4.14.49 Kernel Configuration +# +CONFIG_ARM=y +CONFIG_ARM_HAS_SG_CHAIN=y +CONFIG_MIGHT_HAVE_PCI=y +CONFIG_SYS_SUPPORTS_APM_EMULATION=y +CONFIG_HAVE_PROC_CPU=y +CONFIG_STACKTRACE_SUPPORT=y +CONFIG_LOCKDEP_SUPPORT=y +CONFIG_TRACE_IRQFLAGS_SUPPORT=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_FIX_EARLYCON_MEM=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_NEED_DMA_MAP_STATE=y +CONFIG_ARCH_SUPPORTS_UPROBES=y +CONFIG_VECTORS_BASE=0xffff0000 +CONFIG_ARM_PATCH_PHYS_VIRT=y +CONFIG_GENERIC_BUG=y +CONFIG_PGTABLE_LEVELS=2 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" +CONFIG_IRQ_WORK=y +CONFIG_BUILDTIME_EXTABLE_SORT=y + +# +# General setup +# +CONFIG_INIT_ENV_ARG_LIMIT=32 +CONFIG_CROSS_COMPILE="arm-linux-gnueabi-" +# CONFIG_COMPILE_TEST is not set +CONFIG_LOCALVERSION="" +# CONFIG_LOCALVERSION_AUTO is not set +CONFIG_HAVE_KERNEL_GZIP=y +CONFIG_HAVE_KERNEL_LZMA=y +CONFIG_HAVE_KERNEL_XZ=y +CONFIG_HAVE_KERNEL_LZO=y +CONFIG_HAVE_KERNEL_LZ4=y +CONFIG_KERNEL_GZIP=y +# CONFIG_KERNEL_LZMA is not set +# CONFIG_KERNEL_XZ is not set +# CONFIG_KERNEL_LZO is not set +# CONFIG_KERNEL_LZ4 is not set +CONFIG_DEFAULT_HOSTNAME="(none)" +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +CONFIG_SYSVIPC_SYSCTL=y +# CONFIG_POSIX_MQUEUE is not set +CONFIG_CROSS_MEMORY_ATTACH=y +CONFIG_FHANDLE=y +CONFIG_USELIB=y +# CONFIG_AUDIT is not set +CONFIG_HAVE_ARCH_AUDITSYSCALL=y + +# +# IRQ subsystem +# +CONFIG_GENERIC_IRQ_PROBE=y +CONFIG_GENERIC_IRQ_SHOW=y +CONFIG_GENERIC_IRQ_SHOW_LEVEL=y +CONFIG_GENERIC_IRQ_EFFECTIVE_AFF_MASK=y +CONFIG_HARDIRQS_SW_RESEND=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=y +CONFIG_IRQ_FORCED_THREADING=y +CONFIG_SPARSE_IRQ=y +# CONFIG_GENERIC_IRQ_DEBUGFS is not set +CONFIG_ARCH_CLOCKSOURCE_DATA=y +CONFIG_GENERIC_CLOCKEVENTS=y +CONFIG_ARCH_HAS_TICK_BROADCAST=y +CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y + +# +# Timers subsystem +# +CONFIG_TICK_ONESHOT=y +CONFIG_NO_HZ_COMMON=y +# CONFIG_HZ_PERIODIC is not set +CONFIG_NO_HZ_IDLE=y +# CONFIG_NO_HZ_FULL is not set +CONFIG_NO_HZ=y +# CONFIG_HIGH_RES_TIMERS is not set + +# +# CPU/Task time and stats accounting +# +CONFIG_TICK_CPU_ACCOUNTING=y +# CONFIG_VIRT_CPU_ACCOUNTING_GEN is not set +# CONFIG_IRQ_TIME_ACCOUNTING is not set +# CONFIG_BSD_PROCESS_ACCT is not set +# CONFIG_TASKSTATS is not set + +# +# 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_CGROUPS is not set +# CONFIG_CHECKPOINT_RESTORE is not set +# CONFIG_NAMESPACES is not set +# CONFIG_SCHED_AUTOGROUP is not set +# 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_BPF=y +CONFIG_EXPERT=y +CONFIG_UID16=y +CONFIG_MULTIUSER=y +# CONFIG_SGETMASK_SYSCALL is not set +CONFIG_SYSFS_SYSCALL=y +CONFIG_SYSCTL_SYSCALL=y +CONFIG_POSIX_TIMERS=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_ALL is not set +# CONFIG_KALLSYMS_ABSOLUTE_PERCPU is not set +CONFIG_KALLSYMS_BASE_RELATIVE=y +CONFIG_PRINTK=y +CONFIG_PRINTK_NMI=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_FUTEX_PI=y +CONFIG_EPOLL=y +CONFIG_SIGNALFD=y +CONFIG_TIMERFD=y +CONFIG_EVENTFD=y +# CONFIG_BPF_SYSCALL is not set +# CONFIG_SHMEM is not set +CONFIG_AIO=y +CONFIG_ADVISE_SYSCALLS=y +# CONFIG_USERFAULTFD is not set +CONFIG_PCI_QUIRKS=y +CONFIG_MEMBARRIER=y +CONFIG_EMBEDDED=y +CONFIG_HAVE_PERF_EVENTS=y +CONFIG_PERF_USE_VMALLOC=y +# CONFIG_PC104 is not set + +# +# Kernel Performance Events And Counters +# +# CONFIG_PERF_EVENTS is not set +CONFIG_VM_EVENT_COUNTERS=y +# CONFIG_SLUB_DEBUG is not set +# CONFIG_COMPAT_BRK is not set +# CONFIG_SLAB is not set +CONFIG_SLUB=y +# CONFIG_SLOB is not set +CONFIG_SLAB_MERGE_DEFAULT=y +# CONFIG_SLAB_FREELIST_RANDOM is not set +# CONFIG_SLAB_FREELIST_HARDENED is not set +CONFIG_SLUB_CPU_PARTIAL=y +# CONFIG_SYSTEM_DATA_VERIFICATION is not set +# CONFIG_PROFILING is not set +CONFIG_HAVE_OPROFILE=y +# CONFIG_KPROBES is not set +# CONFIG_JUMP_LABEL is not set +# CONFIG_UPROBES is not set +# CONFIG_HAVE_64BIT_ALIGNED_ACCESS is not set +CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y +CONFIG_ARCH_USE_BUILTIN_BSWAP=y +CONFIG_HAVE_KPROBES=y +CONFIG_HAVE_KRETPROBES=y +CONFIG_HAVE_OPTPROBES=y +CONFIG_HAVE_NMI=y +CONFIG_HAVE_ARCH_TRACEHOOK=y +CONFIG_HAVE_DMA_CONTIGUOUS=y +CONFIG_GENERIC_SMP_IDLE_THREAD=y +CONFIG_GENERIC_IDLE_POLL_SETUP=y +CONFIG_ARCH_HAS_SET_MEMORY=y +CONFIG_HAVE_REGS_AND_STACK_ACCESS_API=y +CONFIG_HAVE_CLK=y +CONFIG_HAVE_DMA_API_DEBUG=y +CONFIG_HAVE_PERF_REGS=y +CONFIG_HAVE_PERF_USER_STACK_DUMP=y +CONFIG_HAVE_ARCH_JUMP_LABEL=y +CONFIG_ARCH_WANT_IPC_PARSE_VERSION=y +CONFIG_HAVE_ARCH_SECCOMP_FILTER=y +CONFIG_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_MOD_ARCH_SPECIFIC=y +CONFIG_MODULES_USE_ELF_REL=y +CONFIG_ARCH_HAS_ELF_RANDOMIZE=y +CONFIG_HAVE_ARCH_MMAP_RND_BITS=y +CONFIG_HAVE_EXIT_THREAD=y +CONFIG_ARCH_MMAP_RND_BITS_MIN=8 +CONFIG_ARCH_MMAP_RND_BITS_MAX=16 +CONFIG_ARCH_MMAP_RND_BITS=8 +# CONFIG_HAVE_ARCH_HASH is not set +# CONFIG_ISA_BUS_API is not set +CONFIG_CLONE_BACKWARDS=y +CONFIG_OLD_SIGSUSPEND3=y +CONFIG_OLD_SIGACTION=y +# CONFIG_CPU_NO_EFFICIENT_FFS is not set +# CONFIG_HAVE_ARCH_VMAP_STACK is not set +CONFIG_ARCH_OPTIONAL_KERNEL_RWX=y +CONFIG_ARCH_OPTIONAL_KERNEL_RWX_DEFAULT=y +CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y +CONFIG_STRICT_KERNEL_RWX=y +CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y +CONFIG_STRICT_MODULE_RWX=y +# CONFIG_REFCOUNT_FULL is not set + +# +# GCOV-based kernel profiling +# +# CONFIG_GCOV_KERNEL is not set +CONFIG_ARCH_HAS_GCOV_PROFILE_ALL=y +CONFIG_HAVE_GENERIC_DMA_COHERENT=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_BLOCK=y +CONFIG_LBDAF=y +CONFIG_BLK_SCSI_REQUEST=y +CONFIG_BLK_DEV_BSG=y +# CONFIG_BLK_DEV_BSGLIB is not set +# CONFIG_BLK_DEV_INTEGRITY is not set +# CONFIG_BLK_DEV_ZONED is not set +# CONFIG_BLK_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=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_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +CONFIG_EFI_PARTITION=y +# CONFIG_SYSV68_PARTITION is not set +# CONFIG_CMDLINE_PARTITION is not set +CONFIG_BLK_MQ_PCI=y + +# +# IO Schedulers +# +CONFIG_IOSCHED_NOOP=y +CONFIG_IOSCHED_DEADLINE=y +CONFIG_IOSCHED_CFQ=y +# CONFIG_DEFAULT_DEADLINE 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 + +# +# System Type +# +CONFIG_MMU=y +CONFIG_ARCH_MULTIPLATFORM=y +# CONFIG_ARCH_EBSA110 is not set +# CONFIG_ARCH_EP93XX is not set +# CONFIG_ARCH_FOOTBRIDGE is not set +# CONFIG_ARCH_NETX is not set +# CONFIG_ARCH_IOP13XX is not set +# CONFIG_ARCH_IOP32X is not set +# CONFIG_ARCH_IOP33X is not set +# CONFIG_ARCH_IXP4XX is not set +# CONFIG_ARCH_DOVE is not set +# CONFIG_ARCH_KS8695 is not set +# CONFIG_ARCH_W90X900 is not set +# CONFIG_ARCH_LPC32XX is not set +# CONFIG_ARCH_PXA is not set +# CONFIG_ARCH_RPC is not set +# CONFIG_ARCH_SA1100 is not set +# CONFIG_ARCH_S3C24XX is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_ARCH_OMAP1 is not set + +# +# Multiple platform selection +# + +# +# CPU Core family selection +# +# CONFIG_ARCH_MULTI_V6 is not set +CONFIG_ARCH_MULTI_V7=y +CONFIG_ARCH_MULTI_V6_V7=y +# CONFIG_ARCH_MULTI_CPU_AUTO is not set +# CONFIG_ARCH_VIRT is not set +# CONFIG_ARCH_MVEBU is not set +# CONFIG_ARCH_ACTIONS is not set +# CONFIG_ARCH_ALPINE is not set +# CONFIG_ARCH_ARTPEC is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_ARCH_BCM is not set +# CONFIG_ARCH_BERLIN is not set +# CONFIG_ARCH_DIGICOLOR is not set +# CONFIG_ARCH_HIGHBANK is not set +# CONFIG_ARCH_HISI is not set +CONFIG_ARCH_XGS_IPROC=y + +# +# XGS iProc SoC based Machine types +# +CONFIG_XGS_IPROC_ARM32_PLATFORM=y +# CONFIG_MACH_HX4 is not set +# CONFIG_MACH_HR2 is not set +# CONFIG_MACH_KT2 is not set +# CONFIG_MACH_GH is not set +# CONFIG_MACH_SB2 is not set +# CONFIG_MACH_HR3 is not set +# CONFIG_MACH_GH2 is not set +# CONFIG_MACH_WH2 is not set +# CONFIG_MACH_IPROC_EMULATION is not set +# CONFIG_ARCH_KEYSTONE is not set +# CONFIG_ARCH_MESON is not set +# CONFIG_ARCH_MXC is not set +# CONFIG_ARCH_MEDIATEK is not set + +# +# TI OMAP/AM/DM/DRA Family +# +# CONFIG_ARCH_OMAP3 is not set +# CONFIG_ARCH_OMAP4 is not set +# CONFIG_SOC_OMAP5 is not set +# CONFIG_SOC_AM33XX is not set +# CONFIG_SOC_AM43XX is not set +# CONFIG_SOC_DRA7XX is not set +# CONFIG_ARCH_MMP is not set +# CONFIG_ARCH_QCOM is not set +# CONFIG_ARCH_REALVIEW is not set +# CONFIG_ARCH_ROCKCHIP is not set +# CONFIG_ARCH_SOCFPGA is not set +# CONFIG_PLAT_SPEAR is not set +# CONFIG_ARCH_STI is not set +# CONFIG_ARCH_S5PV210 is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_RENESAS is not set +# CONFIG_ARCH_SUNXI is not set +# CONFIG_ARCH_SIRF is not set +# CONFIG_ARCH_TANGO is not set +# CONFIG_ARCH_TEGRA is not set +# CONFIG_ARCH_UNIPHIER is not set +# CONFIG_ARCH_U8500 is not set +# CONFIG_ARCH_VEXPRESS is not set +# CONFIG_ARCH_WM8850 is not set +# CONFIG_ARCH_ZX is not set +# CONFIG_ARCH_ZYNQ is not set + +# +# Processor Type +# +CONFIG_CPU_V7=y +CONFIG_CPU_THUMB_CAPABLE=y +CONFIG_CPU_32v6K=y +CONFIG_CPU_32v7=y +CONFIG_CPU_ABRT_EV7=y +CONFIG_CPU_PABRT_V7=y +CONFIG_CPU_CACHE_V7=y +CONFIG_CPU_CACHE_VIPT=y +CONFIG_CPU_COPY_V6=y +CONFIG_CPU_TLB_V7=y +CONFIG_CPU_HAS_ASID=y +CONFIG_CPU_CP15=y +CONFIG_CPU_CP15_MMU=y + +# +# Processor Features +# +# CONFIG_ARM_LPAE is not set +# CONFIG_ARCH_PHYS_ADDR_T_64BIT is not set +CONFIG_ARM_THUMB=y +# CONFIG_ARM_THUMBEE is not set +CONFIG_ARM_VIRT_EXT=y +CONFIG_SWP_EMULATE=y +# CONFIG_CPU_BIG_ENDIAN is not set +# CONFIG_CPU_ICACHE_DISABLE is not set +# CONFIG_CPU_BPREDICT_DISABLE is not set +CONFIG_KUSER_HELPERS=y +# CONFIG_VDSO is not set +CONFIG_OUTER_CACHE=y +CONFIG_OUTER_CACHE_SYNC=y +CONFIG_MIGHT_HAVE_CACHE_L2X0=y +CONFIG_CACHE_L2X0=y +# CONFIG_PL310_ERRATA_588369 is not set +# CONFIG_PL310_ERRATA_727915 is not set +# CONFIG_PL310_ERRATA_753970 is not set +# CONFIG_PL310_ERRATA_769419 is not set +CONFIG_ARM_L1_CACHE_SHIFT_6=y +CONFIG_ARM_L1_CACHE_SHIFT=6 +CONFIG_ARM_DMA_MEM_BUFFERABLE=y +CONFIG_ARM_HEAVY_MB=y +CONFIG_ARCH_SUPPORTS_BIG_ENDIAN=y +CONFIG_DEBUG_ALIGN_RODATA=y +CONFIG_MULTI_IRQ_HANDLER=y +# CONFIG_ARM_ERRATA_430973 is not set +# CONFIG_ARM_ERRATA_643719 is not set +# CONFIG_ARM_ERRATA_720789 is not set +CONFIG_ARM_ERRATA_754322=y +# CONFIG_ARM_ERRATA_754327 is not set +CONFIG_ARM_ERRATA_764369=y +CONFIG_ARM_ERRATA_775420=y +# CONFIG_ARM_ERRATA_798181 is not set +# CONFIG_ARM_ERRATA_773022 is not set +# CONFIG_ARM_ERRATA_818325_852422 is not set +# CONFIG_ARM_ERRATA_821420 is not set +# CONFIG_ARM_ERRATA_825619 is not set +# CONFIG_ARM_ERRATA_852421 is not set +# CONFIG_ARM_ERRATA_852423 is not set + +# +# Bus support +# +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y +CONFIG_PCI_DOMAINS_GENERIC=y +CONFIG_PCI_SYSCALL=y +# CONFIG_PCIEPORTBUS is not set +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_IOV is not set +# CONFIG_PCI_PRI is not set +# CONFIG_PCI_PASID is not set +# CONFIG_HOTPLUG_PCI is not set + +# +# DesignWare PCI Core Support +# +# CONFIG_PCIE_DW_PLAT is not set +# CONFIG_PCI_LAYERSCAPE is not set + +# +# PCI host controller drivers +# +# CONFIG_PCI_FTPCI100 is not set +# CONFIG_PCI_HOST_GENERIC is not set +CONFIG_PCIE_XGS_IPROC=y +CONFIG_PCIE_IPROC_MSI=y +# CONFIG_PCIE_ALTERA is not set + +# +# PCI Endpoint +# +# CONFIG_PCI_ENDPOINT is not set + +# +# PCI switch controller drivers +# +# CONFIG_PCI_SW_SWITCHTEC is not set +# CONFIG_PCCARD is not set + +# +# Kernel Features +# +CONFIG_HAVE_SMP=y +CONFIG_SMP=y +CONFIG_SMP_ON_UP=y +CONFIG_ARM_CPU_TOPOLOGY=y +# CONFIG_SCHED_MC is not set +# CONFIG_SCHED_SMT is not set +CONFIG_HAVE_ARM_SCU=y +# CONFIG_HAVE_ARM_ARCH_TIMER is not set +CONFIG_HAVE_ARM_TWD=y +# CONFIG_MCPM is not set +# CONFIG_BIG_LITTLE is not set +CONFIG_VMSPLIT_3G=y +# CONFIG_VMSPLIT_3G_OPT is not set +# CONFIG_VMSPLIT_2G is not set +# CONFIG_VMSPLIT_1G is not set +CONFIG_PAGE_OFFSET=0xC0000000 +CONFIG_NR_CPUS=4 +CONFIG_HOTPLUG_CPU=y +# CONFIG_ARM_PSCI is not set +CONFIG_ARCH_NR_GPIO=0 +# CONFIG_PREEMPT_NONE is not set +# CONFIG_PREEMPT_VOLUNTARY is not set +CONFIG_PREEMPT=y +CONFIG_PREEMPT_COUNT=y +CONFIG_HZ_FIXED=0 +CONFIG_HZ_100=y +# CONFIG_HZ_200 is not set +# CONFIG_HZ_250 is not set +# CONFIG_HZ_300 is not set +# CONFIG_HZ_500 is not set +# CONFIG_HZ_1000 is not set +CONFIG_HZ=100 +# CONFIG_SCHED_HRTICK is not set +# CONFIG_THUMB2_KERNEL is not set +CONFIG_ARM_PATCH_IDIV=y +CONFIG_AEABI=y +# CONFIG_OABI_COMPAT is not set +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set +CONFIG_HAVE_ARCH_PFN_VALID=y +# CONFIG_HIGHMEM is not set +CONFIG_CPU_SW_DOMAIN_PAN=y +CONFIG_ARCH_WANT_GENERAL_HUGETLB=y +CONFIG_ARM_MODULE_PLTS=y +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +CONFIG_HAVE_MEMBLOCK=y +CONFIG_NO_BOOTMEM=y +CONFIG_MEMORY_ISOLATION=y +# CONFIG_HAVE_BOOTMEM_INFO_NODE is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_COMPACTION=y +CONFIG_MIGRATION=y +# CONFIG_PHYS_ADDR_T_64BIT is not set +# CONFIG_KSM is not set +CONFIG_DEFAULT_MMAP_MIN_ADDR=4096 +# CONFIG_ARCH_WANTS_THP_SWAP is not set +# CONFIG_CLEANCACHE is not set +# CONFIG_FRONTSWAP is not set +CONFIG_CMA=y +CONFIG_CMA_DEBUG=y +# 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_FORCE_MAX_ZONEORDER=11 +CONFIG_ALIGNMENT_TRAP=y +# CONFIG_UACCESS_WITH_MEMCPY is not set +# CONFIG_SECCOMP is not set +CONFIG_SWIOTLB=y +CONFIG_IOMMU_HELPER=y +# CONFIG_PARAVIRT is not set +# CONFIG_PARAVIRT_TIME_ACCOUNTING is not set +# CONFIG_XEN is not set + +# +# Boot options +# +CONFIG_USE_OF=y +CONFIG_ATAGS=y +# CONFIG_DEPRECATED_PARAM_STRUCT is not set +CONFIG_ZBOOT_ROM_TEXT=0x0 +CONFIG_ZBOOT_ROM_BSS=0x0 +# CONFIG_ARM_APPENDED_DTB is not set +CONFIG_CMDLINE="console=ttyS0,115200n8 maxcpus=1 mem=240M" +CONFIG_CMDLINE_FROM_BOOTLOADER=y +# CONFIG_CMDLINE_EXTEND is not set +# CONFIG_CMDLINE_FORCE is not set +# CONFIG_KEXEC is not set +# CONFIG_CRASH_DUMP is not set +CONFIG_AUTO_ZRELADDR=y +# CONFIG_EFI is not set + +# +# CPU Power Management +# + +# +# CPU Frequency scaling +# +# CONFIG_CPU_FREQ is not set + +# +# CPU Idle +# +# CONFIG_CPU_IDLE is not set +# CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED is not set + +# +# Floating point emulation +# + +# +# At least one emulation must be selected +# +# CONFIG_VFP is not set + +# +# Userspace binary formats +# +CONFIG_BINFMT_ELF=y +CONFIG_ELFCORE=y +CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS=y +CONFIG_BINFMT_SCRIPT=y +# CONFIG_BINFMT_FLAT is not set +# CONFIG_HAVE_AOUT is not set +# CONFIG_BINFMT_MISC is not set +CONFIG_COREDUMP=y + +# +# Power management options +# +CONFIG_SUSPEND=y +CONFIG_SUSPEND_FREEZER=y +# CONFIG_SUSPEND_SKIP_SYNC is not set +# CONFIG_HIBERNATION is not set +CONFIG_PM_SLEEP=y +CONFIG_PM_SLEEP_SMP=y +# CONFIG_PM_AUTOSLEEP is not set +# CONFIG_PM_WAKELOCKS is not set +CONFIG_PM=y +# CONFIG_PM_DEBUG is not set +# CONFIG_APM_EMULATION is not set +CONFIG_PM_CLK=y +# CONFIG_WQ_POWER_EFFICIENT_DEFAULT is not set +CONFIG_CPU_PM=y +CONFIG_ARCH_SUSPEND_POSSIBLE=y +CONFIG_ARM_CPU_SUSPEND=y +CONFIG_ARCH_HIBERNATION_POSSIBLE=y +CONFIG_NET=y +CONFIG_NET_INGRESS=y + +# +# Networking options +# +CONFIG_PACKET=y +# CONFIG_PACKET_DIAG is not set +CONFIG_UNIX=y +# CONFIG_UNIX_DIAG is not set +# CONFIG_TLS is not set +# CONFIG_XFRM_USER is not set +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_ADVANCED_ROUTER=y +# CONFIG_IP_FIB_TRIE_STATS is not set +CONFIG_IP_MULTIPLE_TABLES=y +# CONFIG_IP_ROUTE_MULTIPATH is not set +# CONFIG_IP_ROUTE_VERBOSE is not set +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE_DEMUX is not set +CONFIG_NET_IP_TUNNEL=y +# 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_INET_TUNNEL=y +# 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 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_IPV6=y +# 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=y +# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set +# CONFIG_INET6_XFRM_MODE_TUNNEL is not set +# CONFIG_INET6_XFRM_MODE_BEET is not set +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set +CONFIG_IPV6_SIT=y +# CONFIG_IPV6_SIT_6RD is not set +CONFIG_IPV6_NDISC_NODETYPE=y +CONFIG_IPV6_TUNNEL=y +# CONFIG_IPV6_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_NETWORK_SECMARK is not set +CONFIG_NET_PTP_CLASSIFY=y +# CONFIG_NETWORK_PHY_TIMESTAMPING is not set +CONFIG_NETFILTER=y +CONFIG_NETFILTER_ADVANCED=y +CONFIG_BRIDGE_NETFILTER=y + +# +# Core Netfilter Configuration +# +CONFIG_NETFILTER_INGRESS=y +CONFIG_NETFILTER_NETLINK=y +# CONFIG_NETFILTER_NETLINK_ACCT is not set +CONFIG_NETFILTER_NETLINK_QUEUE=y +CONFIG_NETFILTER_NETLINK_LOG=y +CONFIG_NF_CONNTRACK=y +# CONFIG_NF_LOG_NETDEV is not set +CONFIG_NF_CONNTRACK_MARK=y +# CONFIG_NF_CONNTRACK_ZONES is not set +CONFIG_NF_CONNTRACK_PROCFS=y +# CONFIG_NF_CONNTRACK_EVENTS is not set +# CONFIG_NF_CONNTRACK_TIMEOUT is not set +# CONFIG_NF_CONNTRACK_TIMESTAMP is not set +# CONFIG_NF_CT_PROTO_DCCP is not set +# CONFIG_NF_CT_PROTO_SCTP is not set +# CONFIG_NF_CT_PROTO_UDPLITE is not set +# CONFIG_NF_CONNTRACK_AMANDA is not set +CONFIG_NF_CONNTRACK_FTP=y +# 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=y +# CONFIG_NF_CT_NETLINK is not set +# CONFIG_NF_CT_NETLINK_TIMEOUT is not set +# CONFIG_NF_TABLES is not set +CONFIG_NETFILTER_XTABLES=y + +# +# Xtables combined modules +# +CONFIG_NETFILTER_XT_MARK=y +CONFIG_NETFILTER_XT_CONNMARK=y + +# +# Xtables targets +# +# CONFIG_NETFILTER_XT_TARGET_CHECKSUM is not set +# CONFIG_NETFILTER_XT_TARGET_CLASSIFY is not set +# CONFIG_NETFILTER_XT_TARGET_CONNMARK is not set +CONFIG_NETFILTER_XT_TARGET_CT=y +# CONFIG_NETFILTER_XT_TARGET_DSCP is not set +CONFIG_NETFILTER_XT_TARGET_HL=y +# CONFIG_NETFILTER_XT_TARGET_HMARK is not set +# CONFIG_NETFILTER_XT_TARGET_IDLETIMER is not set +# CONFIG_NETFILTER_XT_TARGET_LOG is not set +# CONFIG_NETFILTER_XT_TARGET_MARK is not set +# CONFIG_NETFILTER_XT_TARGET_NFLOG is not set +# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set +# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set +# CONFIG_NETFILTER_XT_TARGET_RATEEST is not set +# CONFIG_NETFILTER_XT_TARGET_TEE is not set +# CONFIG_NETFILTER_XT_TARGET_TPROXY is not set +# CONFIG_NETFILTER_XT_TARGET_TRACE is not set +CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +# CONFIG_NETFILTER_XT_TARGET_TCPOPTSTRIP is not set + +# +# Xtables matches +# +# CONFIG_NETFILTER_XT_MATCH_ADDRTYPE is not set +# CONFIG_NETFILTER_XT_MATCH_BPF 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=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +# 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=y +# CONFIG_NETFILTER_XT_MATCH_ESP is not set +# CONFIG_NETFILTER_XT_MATCH_HASHLIMIT is not set +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_HL=y +# 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_OSF is not set +# CONFIG_NETFILTER_XT_MATCH_OWNER is not set +# CONFIG_NETFILTER_XT_MATCH_PHYSDEV 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=y +# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set +# CONFIG_NETFILTER_XT_MATCH_STRING is not set +CONFIG_NETFILTER_XT_MATCH_TCPMSS=y +# 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 + +# +# IP: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV4=y +CONFIG_NF_CONNTRACK_IPV4=y +# 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 is not set +CONFIG_NF_REJECT_IPV4=y +# CONFIG_NF_NAT_IPV4 is not set +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +# CONFIG_IP_NF_MATCH_RPFILTER is not set +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_TARGET_REJECT=y +# CONFIG_IP_NF_TARGET_SYNPROXY is not set +# CONFIG_IP_NF_NAT is not set +CONFIG_IP_NF_MANGLE=y +# CONFIG_IP_NF_TARGET_CLUSTERIP is not set +CONFIG_IP_NF_TARGET_ECN=y +CONFIG_IP_NF_TARGET_TTL=y +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARP_MANGLE=y + +# +# IPv6: Netfilter Configuration +# +CONFIG_NF_DEFRAG_IPV6=y +CONFIG_NF_CONNTRACK_IPV6=y +# CONFIG_NF_SOCKET_IPV6 is not set +# CONFIG_NF_DUP_IPV6 is not set +CONFIG_NF_REJECT_IPV6=y +# CONFIG_NF_LOG_IPV6 is not set +# CONFIG_NF_NAT_IPV6 is not set +CONFIG_IP6_NF_IPTABLES=y +# 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=y +CONFIG_IP6_NF_MATCH_RT=y +# CONFIG_IP6_NF_TARGET_HL is not set +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_TARGET_REJECT=y +# CONFIG_IP6_NF_TARGET_SYNPROXY is not set +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +# CONFIG_IP6_NF_NAT is not set +# CONFIG_BRIDGE_NF_EBTABLES 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_STP=y +CONFIG_GARP=y +CONFIG_BRIDGE=y +CONFIG_BRIDGE_IGMP_SNOOPING=y +# CONFIG_BRIDGE_VLAN_FILTERING is not set +CONFIG_HAVE_NET_DSA=y +# CONFIG_NET_DSA is not set +CONFIG_VLAN_8021Q=y +CONFIG_VLAN_8021Q_GVRP=y +# CONFIG_VLAN_8021Q_MVRP is not set +# CONFIG_DECNET is not set +CONFIG_LLC=y +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_PHONET is not set +# CONFIG_6LOWPAN is not set +# CONFIG_IEEE802154 is not set +# CONFIG_NET_SCHED 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_NET_RX_BUSY_POLL=y +CONFIG_BQL=y +# CONFIG_BPF_JIT is not set +CONFIG_NET_FLOW_LIMIT=y + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_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_FIB_RULES=y +# CONFIG_WIRELESS is not set +# CONFIG_WIMAX is not set +# CONFIG_RFKILL 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 + +# +# Device Drivers +# +CONFIG_ARM_AMBA=y + +# +# Generic Driver Options +# +CONFIG_UEVENT_HELPER=y +CONFIG_UEVENT_HELPER_PATH="/sbin/mdev" +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 is not set +# CONFIG_GENERIC_CPU_DEVICES is not set +CONFIG_GENERIC_CPU_AUTOPROBE=y +CONFIG_REGMAP=y +CONFIG_REGMAP_I2C=y +# CONFIG_DMA_SHARED_BUFFER is not set +CONFIG_DMA_CMA=y + +# +# Default contiguous memory area size: +# +CONFIG_CMA_SIZE_MBYTES=32 +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_BRCMSTB_GISB_ARB is not set +# CONFIG_SIMPLE_PM_BUS is not set +# CONFIG_VEXPRESS_CONFIG is not set +# CONFIG_CONNECTOR is not set +CONFIG_MTD=y +CONFIG_MTD_TESTS=m +# CONFIG_MTD_REDBOOT_PARTS is not set +CONFIG_MTD_CMDLINE_PARTS=y +# CONFIG_MTD_AFS_PARTS is not set +CONFIG_MTD_OF_PARTS=y +# CONFIG_MTD_AR7_PARTS is not set + +# +# Partition parsers +# + +# +# User Modules And Translation Layers +# +CONFIG_MTD_BLKDEVS=y +CONFIG_MTD_BLOCK=y +# 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 + +# +# RAM/ROM/Flash chip drivers +# +CONFIG_MTD_CFI=y +CONFIG_MTD_JEDECPROBE=y +CONFIG_MTD_GEN_PROBE=y +# CONFIG_MTD_CFI_ADV_OPTIONS is not set +CONFIG_MTD_MAP_BANK_WIDTH_1=y +CONFIG_MTD_MAP_BANK_WIDTH_2=y +CONFIG_MTD_MAP_BANK_WIDTH_4=y +# CONFIG_MTD_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_CFI_INTELEXT=y +CONFIG_MTD_CFI_AMDSTD=y +CONFIG_MTD_CFI_STAA=y +CONFIG_MTD_CFI_UTIL=y +# 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_PHYSMAP=y +# CONFIG_MTD_PHYSMAP_COMPAT is not set +CONFIG_MTD_PHYSMAP_OF=y +# CONFIG_MTD_IMPA7 is not set +# CONFIG_MTD_INTEL_VR_NOR is not set +# CONFIG_MTD_PLATRAM is not set +CONFIG_MTD_NOR_XGS_IPROC=y + +# +# 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_ECC=y +# CONFIG_MTD_NAND_ECC_SMC is not set +CONFIG_MTD_NAND=y +# CONFIG_MTD_NAND_ECC_BCH is not set +# CONFIG_MTD_SM_COMMON is not set +# CONFIG_MTD_NAND_DENALI_PCI is not set +# CONFIG_MTD_NAND_DENALI_DT is not set +# CONFIG_MTD_NAND_GPIO is not set +# CONFIG_MTD_NAND_OMAP_BCH_BUILD is not set +# CONFIG_MTD_NAND_RICOH is not set +# CONFIG_MTD_NAND_DISKONCHIP is not set +# CONFIG_MTD_NAND_DOCG4 is not set +# CONFIG_MTD_NAND_CAFE is not set +# CONFIG_MTD_NAND_NANDSIM is not set +CONFIG_MTD_NAND_BRCMNAND=y +# CONFIG_MTD_NAND_PLATFORM is not set +# CONFIG_MTD_ONENAND is not set + +# +# LPDDR & LPDDR2 PCM memory drivers +# +# CONFIG_MTD_LPDDR is not set +# CONFIG_MTD_LPDDR2_NVM is not set +CONFIG_MTD_SPI_NOR=y +# CONFIG_MTD_MT81xx_NOR is not set +# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set +# CONFIG_SPI_CADENCE_QUADSPI is not set +CONFIG_MTD_UBI=y +CONFIG_MTD_UBI_WL_THRESHOLD=4096 +CONFIG_MTD_UBI_BEB_LIMIT=20 +# CONFIG_MTD_UBI_FASTMAP is not set +# CONFIG_MTD_UBI_GLUEBI is not set +# CONFIG_MTD_UBI_BLOCK is not set +CONFIG_DTC=y +CONFIG_OF=y +# CONFIG_OF_UNITTEST is not set +CONFIG_OF_FLATTREE=y +CONFIG_OF_EARLY_FLATTREE=y +CONFIG_OF_DYNAMIC=y +CONFIG_OF_ADDRESS=y +CONFIG_OF_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_RESOLVE=y +CONFIG_OF_OVERLAY=y +CONFIG_ARCH_MIGHT_HAVE_PC_PARPORT=y +# CONFIG_PARPORT is not set +CONFIG_BLK_DEV=y +# CONFIG_BLK_DEV_NULL_BLK is not set +# CONFIG_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_BLK_DEV_LOOP=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=8 +CONFIG_BLK_DEV_CRYPTOLOOP=y +# CONFIG_BLK_DEV_DRBD is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=32768 +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH 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 + +# +# Misc devices +# +# 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 is not set +# CONFIG_PCI_ENDPOINT_TEST is not set +# CONFIG_C2PORT is not set + +# +# EEPROM support +# +CONFIG_EEPROM_AT24=y +# CONFIG_EEPROM_AT25 is not set +# CONFIG_EEPROM_LEGACY is not set +# CONFIG_EEPROM_MAX6875 is not set +# CONFIG_EEPROM_93CX6 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 + +# +# Altera FPGA firmware download module +# +# CONFIG_ALTERA_STAPL is not set + +# +# Intel MIC Bus Driver +# + +# +# SCIF Bus Driver +# + +# +# VOP Bus Driver +# + +# +# Intel MIC Host Driver +# + +# +# Intel MIC Card Driver +# + +# +# SCIF Driver +# + +# +# Intel MIC Coprocessor State Management (COSM) Drivers +# + +# +# VOP Driver +# +# 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 +CONFIG_HAVE_IDE=y +# CONFIG_IDE is not set + +# +# SCSI device support +# +CONFIG_SCSI_MOD=y +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_DMA=y +# CONFIG_SCSI_NETLINK is not set +# CONFIG_SCSI_MQ_DEFAULT is not set +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +CONFIG_CHR_DEV_ST=y +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +CONFIG_CHR_DEV_SG=y +# CONFIG_CHR_DEV_SCH is not set +CONFIG_SCSI_CONSTANTS=y +CONFIG_SCSI_LOGGING=y +# CONFIG_SCSI_SCAN_ASYNC is not set + +# +# SCSI Transports +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set +# CONFIG_SCSI_SAS_LIBSAS is not set +# CONFIG_SCSI_SRP_ATTRS is not set +CONFIG_SCSI_LOWLEVEL=y +# CONFIG_ISCSI_TCP is not set +# CONFIG_ISCSI_BOOT_SYSFS is not set +# CONFIG_SCSI_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_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_NSP32 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_DH is not set +# CONFIG_SCSI_OSD_INITIATOR is not set +# CONFIG_ATA is not set +# CONFIG_MD is not set +# CONFIG_TARGET_CORE is not set +# CONFIG_FUSION is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_FIREWIRE is not set +# CONFIG_FIREWIRE_NOSY is not set +CONFIG_NETDEVICES=y +CONFIG_NET_CORE=y +CONFIG_BONDING=y +# 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_NLMON is not set +# CONFIG_ARCNET is not set + +# +# CAIF transport drivers +# + +# +# Distributed Switch Architecture drivers +# +CONFIG_ETHERNET=y +CONFIG_NET_VENDOR_3COM=y +# CONFIG_VORTEX is not set +# CONFIG_TYPHOON is not set +CONFIG_NET_VENDOR_ADAPTEC=y +# CONFIG_ADAPTEC_STARFIRE is not set +CONFIG_NET_VENDOR_AGERE=y +# CONFIG_ET131X is not set +CONFIG_NET_VENDOR_ALACRITECH=y +# CONFIG_SLICOSS is not set +CONFIG_NET_VENDOR_ALTEON=y +# CONFIG_ACENIC is not set +# CONFIG_ALTERA_TSE is not set +CONFIG_NET_VENDOR_AMAZON=y +CONFIG_NET_VENDOR_AMD=y +# CONFIG_AMD8111_ETH is not set +# CONFIG_PCNET32 is not set +# CONFIG_AMD_XGBE_HAVE_ECC is not set +CONFIG_NET_VENDOR_AQUANTIA=y +CONFIG_NET_VENDOR_ARC=y +CONFIG_NET_VENDOR_ATHEROS=y +# CONFIG_ATL2 is not set +# CONFIG_ATL1 is not set +# CONFIG_ATL1E is not set +# CONFIG_ATL1C is not set +# CONFIG_ALX is not set +# CONFIG_NET_VENDOR_AURORA is not set +CONFIG_NET_CADENCE=y +# CONFIG_MACB is not set +CONFIG_NET_VENDOR_BROADCOM=y +# CONFIG_B44 is not set +# CONFIG_BCMGENET is not set +# CONFIG_BNX2 is not set +# CONFIG_CNIC is not set +CONFIG_TIGON3=y +CONFIG_TIGON3_HWMON=y +# CONFIG_BNX2X is not set +CONFIG_BGMAC=y +CONFIG_BGMAC_PLATFORM=y +# CONFIG_APM is not set +# CONFIG_SYSTEMPORT is not set +# CONFIG_BNXT is not set +CONFIG_NET_VENDOR_BROCADE=y +# CONFIG_BNA is not set +CONFIG_NET_VENDOR_CAVIUM=y +CONFIG_NET_VENDOR_CHELSIO=y +# CONFIG_CHELSIO_T1 is not set +# CONFIG_CHELSIO_T3 is not set +# CONFIG_CHELSIO_T4 is not set +# CONFIG_CHELSIO_T4VF is not set +CONFIG_NET_VENDOR_CIRRUS=y +# CONFIG_CS89x0 is not set +CONFIG_NET_VENDOR_CISCO=y +# CONFIG_ENIC is not set +# CONFIG_DM9000 is not set +# CONFIG_DNET is not set +CONFIG_NET_VENDOR_DEC=y +# CONFIG_NET_TULIP is not set +CONFIG_NET_VENDOR_DLINK=y +# CONFIG_DL2K is not set +# CONFIG_SUNDANCE is not set +CONFIG_NET_VENDOR_EMULEX=y +# CONFIG_BE2NET is not set +CONFIG_NET_VENDOR_EZCHIP=y +# CONFIG_EZCHIP_NPS_MANAGEMENT_ENET is not set +CONFIG_NET_VENDOR_EXAR=y +# CONFIG_S2IO is not set +# CONFIG_VXGE is not set +CONFIG_NET_VENDOR_FARADAY=y +# CONFIG_FTMAC100 is not set +# CONFIG_FTGMAC100 is not set +CONFIG_NET_VENDOR_HISILICON=y +# CONFIG_HIX5HD2_GMAC is not set +# CONFIG_HISI_FEMAC is not set +# CONFIG_HIP04_ETH is not set +# CONFIG_HNS is not set +# CONFIG_HNS_DSAF is not set +# CONFIG_HNS_ENET is not set +# CONFIG_HNS3 is not set +CONFIG_NET_VENDOR_HP=y +# CONFIG_HP100 is not set +CONFIG_NET_VENDOR_HUAWEI=y +CONFIG_NET_VENDOR_INTEL=y +# CONFIG_E100 is not set +# CONFIG_E1000 is not set +# CONFIG_E1000E is not set +# CONFIG_IGB is not set +# CONFIG_IGBVF is not set +# CONFIG_IXGB is not set +# CONFIG_IXGBE is not set +# CONFIG_IXGBEVF is not set +# CONFIG_I40E is not set +# CONFIG_I40EVF is not set +# CONFIG_FM10K is not set +CONFIG_NET_VENDOR_I825XX=y +# CONFIG_JME is not set +CONFIG_NET_VENDOR_MARVELL=y +# CONFIG_MVMDIO is not set +# CONFIG_MVNETA_BM is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +CONFIG_NET_VENDOR_MELLANOX=y +# CONFIG_MLX4_EN is not set +# CONFIG_MLX4_CORE is not set +# CONFIG_MLX5_CORE is not set +# CONFIG_MLXSW_CORE is not set +# CONFIG_MLXFW is not set +CONFIG_NET_VENDOR_MICREL=y +# CONFIG_KS8842 is not set +# CONFIG_KS8851 is not set +# CONFIG_KS8851_MLL is not set +# CONFIG_KSZ884X_PCI is not set +CONFIG_NET_VENDOR_MICROCHIP=y +# CONFIG_ENC28J60 is not set +# CONFIG_ENCX24J600 is not set +CONFIG_NET_VENDOR_MYRI=y +# CONFIG_MYRI10GE is not set +# CONFIG_FEALNX is not set +CONFIG_NET_VENDOR_NATSEMI=y +# CONFIG_NATSEMI is not set +# CONFIG_NS83820 is not set +CONFIG_NET_VENDOR_NETRONOME=y +# CONFIG_NFP is not set +CONFIG_NET_VENDOR_8390=y +# CONFIG_AX88796 is not set +# CONFIG_NE2K_PCI is not set +CONFIG_NET_VENDOR_NVIDIA=y +# CONFIG_FORCEDETH is not set +CONFIG_NET_VENDOR_OKI=y +# CONFIG_ETHOC is not set +CONFIG_NET_PACKET_ENGINE=y +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +CONFIG_NET_VENDOR_QLOGIC=y +# CONFIG_QLA3XXX is not set +# CONFIG_QLCNIC is not set +# CONFIG_QLGE is not set +# CONFIG_NETXEN_NIC is not set +# CONFIG_QED is not set +CONFIG_NET_VENDOR_QUALCOMM=y +# CONFIG_QCA7000_SPI is not set +# CONFIG_QCOM_EMAC is not set +# CONFIG_RMNET is not set +CONFIG_NET_VENDOR_REALTEK=y +# CONFIG_8139CP is not set +# CONFIG_8139TOO is not set +# CONFIG_R8169 is not set +CONFIG_NET_VENDOR_RENESAS=y +CONFIG_NET_VENDOR_RDC=y +# CONFIG_R6040 is not set +CONFIG_NET_VENDOR_ROCKER=y +CONFIG_NET_VENDOR_SAMSUNG=y +# CONFIG_SXGBE_ETH is not set +CONFIG_NET_VENDOR_SEEQ=y +CONFIG_NET_VENDOR_SILAN=y +# CONFIG_SC92031 is not set +CONFIG_NET_VENDOR_SIS=y +# CONFIG_SIS900 is not set +# CONFIG_SIS190 is not set +CONFIG_NET_VENDOR_SOLARFLARE=y +# CONFIG_SFC is not set +# CONFIG_SFC_FALCON is not set +CONFIG_NET_VENDOR_SMSC=y +# CONFIG_SMC91X is not set +# CONFIG_EPIC100 is not set +# CONFIG_SMC911X is not set +# CONFIG_SMSC911X is not set +# CONFIG_SMSC9420 is not set +CONFIG_NET_VENDOR_STMICRO=y +# CONFIG_STMMAC_ETH is not set +CONFIG_NET_VENDOR_SUN=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NIU is not set +CONFIG_NET_VENDOR_TEHUTI=y +# CONFIG_TEHUTI is not set +CONFIG_NET_VENDOR_TI=y +# CONFIG_TI_CPSW_ALE is not set +# CONFIG_TLAN is not set +CONFIG_NET_VENDOR_VIA=y +# CONFIG_VIA_RHINE is not set +# CONFIG_VIA_VELOCITY is not set +CONFIG_NET_VENDOR_WIZNET=y +# CONFIG_WIZNET_W5100 is not set +# CONFIG_WIZNET_W5300 is not set +CONFIG_NET_VENDOR_SYNOPSYS=y +# CONFIG_DWC_XLGMAC is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI 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_PHYLIB=y +CONFIG_SWPHY=y +CONFIG_MDIO_XGS_IPROC=y + +# +# 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_BCM_NET_PHYLIB=y +CONFIG_BROADCOM_PHY=y +CONFIG_XGS_IPROC_SERDES=y +# 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_MICREL_PHY is not set +# 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 is not set +# 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=y +# CONFIG_USB_CATC is not set +# CONFIG_USB_KAWETH is not set +# CONFIG_USB_PEGASUS is not set +# CONFIG_USB_RTL8150 is not set +# CONFIG_USB_RTL8152 is not set +# CONFIG_USB_LAN78XX is not set +# CONFIG_USB_USBNET is not set +# CONFIG_USB_IPHETH is not set +# CONFIG_WLAN is not set + +# +# Enable WiMAX (Networking options) to see the WiMAX drivers +# +# CONFIG_WAN is not set +# CONFIG_VMXNET3 is not set +# CONFIG_ISDN is not set +# CONFIG_NVM is not set + +# +# Input device support +# +# CONFIG_INPUT is not set + +# +# Hardware I/O ports +# +CONFIG_SERIO=y +CONFIG_SERIO_SERPORT=y +# CONFIG_SERIO_AMBAKMI is not set +# 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 + +# +# Character devices +# +CONFIG_TTY=y +# CONFIG_VT is not set +CONFIG_UNIX98_PTYS=y +# CONFIG_LEGACY_PTYS is not set +# 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 +CONFIG_DEVKMEM=y + +# +# Serial drivers +# +CONFIG_SERIAL_EARLYCON=y +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_DEPRECATED_OPTIONS=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=2 +CONFIG_SERIAL_8250_RUNTIME_UARTS=2 +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=y +CONFIG_SERIAL_8250_RSA=y +CONFIG_SERIAL_8250_FSL=y +CONFIG_SERIAL_8250_DW=y +# CONFIG_SERIAL_8250_EM is not set +# CONFIG_SERIAL_8250_RT288X is not set +# CONFIG_SERIAL_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 is not set +# CONFIG_SERIAL_EARLYCON_ARM_SEMIHOST is not set +# CONFIG_SERIAL_MAX3100 is not set +# CONFIG_SERIAL_MAX310X is not set +# CONFIG_SERIAL_UARTLITE is not set +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +# CONFIG_SERIAL_SCCNXP is not set +# CONFIG_SERIAL_SC16IS7XX is not set +# CONFIG_SERIAL_BCM63XX is not set +# CONFIG_SERIAL_ALTERA_JTAGUART is not set +# CONFIG_SERIAL_ALTERA_UART is not set +# CONFIG_SERIAL_IFX6X60 is not set +# CONFIG_SERIAL_XILINX_PS_UART is not set +# CONFIG_SERIAL_ARC is not set +# CONFIG_SERIAL_RP2 is not set +# CONFIG_SERIAL_FSL_LPUART is not set +# CONFIG_SERIAL_CONEXANT_DIGICOLOR is not set +# CONFIG_SERIAL_ST_ASC is not set +# CONFIG_SERIAL_DEV_BUS is not set +# CONFIG_TTY_PRINTK is not set +# CONFIG_HVC_DCC is not set +# CONFIG_IPMI_HANDLER is not set +CONFIG_HW_RANDOM=y +# CONFIG_HW_RANDOM_TIMERIOMEM is not set +CONFIG_HW_RANDOM_XGS_IPROC_RNG=y +# CONFIG_R3964 is not set +# CONFIG_APPLICOM is not set +# CONFIG_RAW_DRIVER is not set +# CONFIG_TCG_TPM is not set +CONFIG_DEVPORT=y +# CONFIG_XILLYBUS is not set + +# +# I2C support +# +CONFIG_I2C=y +CONFIG_I2C_BOARDINFO=y +CONFIG_I2C_COMPAT=y +CONFIG_I2C_CHARDEV=y +CONFIG_I2C_MUX=y + +# +# Multiplexer I2C Chip support +# +# CONFIG_I2C_ARB_GPIO_CHALLENGE is not set +CONFIG_I2C_MUX_GPIO=y +# CONFIG_I2C_MUX_GPMUX is not set +# CONFIG_I2C_MUX_LTC4306 is not set +CONFIG_I2C_MUX_PCA9541=y +CONFIG_I2C_MUX_PCA954x=y +CONFIG_I2C_MUX_PCA954X_DESELECT_ON_EXIT=y +CONFIG_I2C_MUX_REG=y +# CONFIG_I2C_MUX_MLXCPLD is not set +CONFIG_I2C_HELPER_AUTO=y +CONFIG_I2C_SMBUS=y + +# +# I2C Algorithms +# +# CONFIG_I2C_ALGOBIT is not set +# CONFIG_I2C_ALGOPCF is not set +# CONFIG_I2C_ALGOPCA is not set + +# +# I2C Hardware Bus support +# + +# +# PC SMBus host controller drivers +# +# CONFIG_I2C_ALI1535 is not set +# CONFIG_I2C_ALI1563 is not set +# CONFIG_I2C_ALI15X3 is not set +# CONFIG_I2C_AMD756 is not set +# CONFIG_I2C_AMD8111 is not set +# CONFIG_I2C_I801 is not set +# CONFIG_I2C_ISCH is not set +# CONFIG_I2C_PIIX4 is not set +# CONFIG_I2C_NFORCE2 is not set +# CONFIG_I2C_SIS5595 is not set +# CONFIG_I2C_SIS630 is not set +# CONFIG_I2C_SIS96X is not set +# CONFIG_I2C_VIA is not set +# CONFIG_I2C_VIAPRO is not set + +# +# I2C system bus drivers (mostly embedded / system-on-chip) +# +# CONFIG_I2C_XGS_IPROC is not set +CONFIG_SMBUS_XGS_IPROC=y +# CONFIG_I2C_CBUS_GPIO is not set +# CONFIG_I2C_DESIGNWARE_PLATFORM is not set +# CONFIG_I2C_DESIGNWARE_PCI is not set +# CONFIG_I2C_EMEV2 is not set +# CONFIG_I2C_GPIO is not set +# CONFIG_I2C_NOMADIK is not set +# CONFIG_I2C_OCORES is not set +# CONFIG_I2C_PCA_PLATFORM is not set +# CONFIG_I2C_PXA_PCI is not set +# CONFIG_I2C_RK3X is not set +# CONFIG_I2C_SIMTEC is not set +# CONFIG_I2C_XILINX is not set + +# +# External I2C/SMBus adapter drivers +# +# CONFIG_I2C_DIOLAN_U2C is not set +# CONFIG_I2C_PARPORT_LIGHT is not set +# CONFIG_I2C_ROBOTFUZZ_OSIF is not set +# CONFIG_I2C_TAOS_EVM is not set +# CONFIG_I2C_TINY_USB is not set + +# +# Other I2C/SMBus bus drivers +# +# CONFIG_I2C_STUB is not set +# CONFIG_I2C_SLAVE is not set +# CONFIG_I2C_DEBUG_CORE is not set +# CONFIG_I2C_DEBUG_ALGO is not set +# CONFIG_I2C_DEBUG_BUS is not set +CONFIG_SPI=y +# CONFIG_SPI_DEBUG is not set +CONFIG_SPI_MASTER=y + +# +# SPI Master Controller Drivers +# +# CONFIG_SPI_ALTERA is not set +# CONFIG_SPI_AXI_SPI_ENGINE is not set +CONFIG_SPI_BCM_QSPI=y +# 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_OC_TINY is not set +# CONFIG_SPI_PL022 is not set +# 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_XCOMM is not set +# CONFIG_SPI_XILINX is not set +# CONFIG_SPI_ZYNQMP_GQSPI is not set + +# +# SPI Protocol Masters +# +# CONFIG_SPI_SPIDEV is not set +# CONFIG_SPI_LOOPBACK_TEST is not set +# CONFIG_SPI_TLE62X0 is not set +# CONFIG_SPI_SLAVE is not set +# CONFIG_SPMI is not set +# CONFIG_HSI is not set +CONFIG_PPS=y +# CONFIG_PPS_DEBUG is not set + +# +# PPS clients support +# +# CONFIG_PPS_CLIENT_KTIMER is not set +# CONFIG_PPS_CLIENT_LDISC is not set +# CONFIG_PPS_CLIENT_GPIO is not set + +# +# PPS generators support +# + +# +# PTP clock support +# +CONFIG_PTP_1588_CLOCK=y + +# +# Enable PHYLIB and NETWORK_PHY_TIMESTAMPING to see the additional clocks. +# +CONFIG_ARCH_HAVE_CUSTOM_GPIO_H=y +CONFIG_GPIOLIB=y +CONFIG_OF_GPIO=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_XGS_IPROC=y +# CONFIG_GPIO_DWAPB is not set +# CONFIG_GPIO_EXAR is not set +# CONFIG_GPIO_FTGPIO010 is not set +# CONFIG_GPIO_GENERIC_PLATFORM is not set +# CONFIG_GPIO_GRGPIO is not set +# CONFIG_GPIO_MOCKUP is not set +# CONFIG_GPIO_MPC8XXX is not set +# CONFIG_GPIO_PL061 is not set +# CONFIG_GPIO_XILINX is not set +# CONFIG_GPIO_ZEVIO is not set + +# +# I2C GPIO expanders +# +# CONFIG_GPIO_ADP5588 is not set +# CONFIG_GPIO_ADNP is not set +# CONFIG_GPIO_MAX7300 is not set +# CONFIG_GPIO_MAX732X is not set +# CONFIG_GPIO_PCA953X is not set +# CONFIG_GPIO_PCF857X is not set +# CONFIG_GPIO_TPIC2810 is not set + +# +# MFD GPIO expanders +# +# CONFIG_HTC_EGPIO is not set + +# +# 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 is not set +# CONFIG_POWER_SUPPLY is not set +CONFIG_HWMON=y +CONFIG_HWMON_VID=y +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Native drivers +# +# CONFIG_SENSORS_AD7314 is not set +# CONFIG_SENSORS_AD7414 is not set +# CONFIG_SENSORS_AD7418 is not set +# CONFIG_SENSORS_ADM1021 is not set +# CONFIG_SENSORS_ADM1025 is not set +# CONFIG_SENSORS_ADM1026 is not set +# CONFIG_SENSORS_ADM1029 is not set +# CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_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_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_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=y +CONFIG_SENSORS_LM73=y +CONFIG_SENSORS_LM75=y +CONFIG_SENSORS_LM77=y +CONFIG_SENSORS_LM78=y +CONFIG_SENSORS_LM80=y +CONFIG_SENSORS_LM83=y +CONFIG_SENSORS_LM85=y +CONFIG_SENSORS_LM87=y +CONFIG_SENSORS_LM90=y +CONFIG_SENSORS_LM92=y +CONFIG_SENSORS_LM93=y +# 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_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 is not set +# CONFIG_SENSORS_INA3221 is not set +# CONFIG_SENSORS_TC74 is not set +# CONFIG_SENSORS_THMC50 is not set +# CONFIG_SENSORS_TMP102 is not set +# CONFIG_SENSORS_TMP103 is not set +# CONFIG_SENSORS_TMP108 is not set +# CONFIG_SENSORS_TMP401 is not set +# CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_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 +# CONFIG_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_XILINX_WATCHDOG is not set +# CONFIG_ZIIRAVE_WATCHDOG is not set +CONFIG_ARM_SP805_WATCHDOG=y +# CONFIG_CADENCE_WATCHDOG is not set +# CONFIG_DW_WATCHDOG is not set +# CONFIG_MAX63XX_WATCHDOG is not set +# CONFIG_ALIM7101_WDT is not set +# CONFIG_I6300ESB_WDT is not set +# CONFIG_MEN_A21_WDT is not set + +# +# 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 is not set +# 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_MFD_ASIC3 is not set +# CONFIG_PMIC_DA903X is not set +# CONFIG_MFD_DA9052_SPI is not set +# CONFIG_MFD_DA9052_I2C is not set +# CONFIG_MFD_DA9055 is not set +# CONFIG_MFD_DA9062 is not set +# CONFIG_MFD_DA9063 is not set +# CONFIG_MFD_DA9150 is not set +# CONFIG_MFD_DLN2 is not set +# CONFIG_MFD_MC13XXX_SPI is not set +# CONFIG_MFD_MC13XXX_I2C is not set +# CONFIG_MFD_HI6421_PMIC is not set +# CONFIG_HTC_PASIC3 is not set +# CONFIG_HTC_I2CPLD is not set +# CONFIG_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_MAX77620 is not set +# CONFIG_MFD_MAX77686 is not set +# CONFIG_MFD_MAX77693 is not set +# CONFIG_MFD_MAX77843 is not set +# CONFIG_MFD_MAX8907 is not set +# CONFIG_MFD_MAX8925 is not set +# CONFIG_MFD_MAX8997 is not set +# CONFIG_MFD_MAX8998 is not set +# CONFIG_MFD_MT6397 is not set +# CONFIG_MFD_MENF21BMC is not set +# CONFIG_EZX_PCAP is not set +# CONFIG_MFD_CPCAP is not set +# CONFIG_MFD_VIPERBOARD is not set +# CONFIG_MFD_RETU is not set +# CONFIG_MFD_PCF50633 is not set +# CONFIG_MFD_PM8XXX is not set +# CONFIG_MFD_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 is not set +# CONFIG_MFD_RN5T618 is not set +# CONFIG_MFD_SEC_CORE is not set +# CONFIG_MFD_SI476X_CORE is not set +# CONFIG_MFD_SM501 is not set +# CONFIG_MFD_SKY81452 is not set +# CONFIG_MFD_SMSC is not set +# CONFIG_ABX500_CORE is not set +# CONFIG_MFD_STMPE is not set +# CONFIG_MFD_SYSCON is not set +# CONFIG_MFD_TI_AM335X_TSCADC is not set +# CONFIG_MFD_LP3943 is not set +# CONFIG_MFD_LP8788 is not set +# CONFIG_MFD_TI_LMU is not set +# CONFIG_MFD_PALMAS is not set +# CONFIG_TPS6105X is not set +# CONFIG_TPS65010 is not set +# CONFIG_TPS6507X is not set +# CONFIG_MFD_TPS65086 is not set +# CONFIG_MFD_TPS65090 is not set +# CONFIG_MFD_TPS65217 is not set +# CONFIG_MFD_TI_LP873X is not set +# CONFIG_MFD_TI_LP87565 is not set +# CONFIG_MFD_TPS65218 is not set +# CONFIG_MFD_TPS6586X is not set +# CONFIG_MFD_TPS65910 is not set +# CONFIG_MFD_TPS65912_I2C is not set +# CONFIG_MFD_TPS65912_SPI is not set +# CONFIG_MFD_TPS80031 is not set +# CONFIG_TWL4030_CORE is not set +# CONFIG_TWL6040_CORE is not set +# CONFIG_MFD_WL1273_CORE is not set +# CONFIG_MFD_LM3533 is not set +# CONFIG_MFD_TC3589X is not set +# CONFIG_MFD_TMIO is not set +# CONFIG_MFD_T7L66XB is not set +# CONFIG_MFD_TC6387XB is not set +# CONFIG_MFD_TC6393XB is not set +# CONFIG_MFD_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_REGULATOR is not set +# CONFIG_MEDIA_SUPPORT is not set + +# +# Graphics support +# +# CONFIG_VGA_ARB is not set +# CONFIG_IMX_IPUV3_CORE is not set +# CONFIG_DRM is not set + +# +# ACP (Audio CoProcessor) Configuration +# +# CONFIG_DRM_LIB_RANDOM is not set + +# +# Frame buffer Devices +# +# CONFIG_FB is not set +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set +# CONFIG_VGASTATE is not set +# CONFIG_SOUND 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=y + +# +# Miscellaneous USB options +# +CONFIG_USB_DEFAULT_PERSIST=y +CONFIG_USB_DYNAMIC_MINORS=y +# CONFIG_USB_OTG is not set +# CONFIG_USB_OTG_WHITELIST is not set +# CONFIG_USB_OTG_BLACKLIST_HUB is not set +# CONFIG_USB_MON is not set +# CONFIG_USB_WUSB_CBAF is not set + +# +# USB Host Controller Drivers +# +# CONFIG_USB_C67X00_HCD is not set +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI_ROOT_HUB_TT=y +CONFIG_USB_EHCI_TT_NEWSCHED=y +CONFIG_USB_EHCI_PCI=y +CONFIG_USB_EHCI_XGS_IPROC=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_OHCI_XGS_IPROC=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 + +# +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may +# + +# +# also be needed; see USB_STORAGE Help for more info +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_STORAGE_DEBUG is not set +# CONFIG_USB_STORAGE_REALTEK is not set +# CONFIG_USB_STORAGE_DATAFAB is not set +# CONFIG_USB_STORAGE_FREECOM is not set +# CONFIG_USB_STORAGE_ISD200 is not set +# CONFIG_USB_STORAGE_USBAT is not set +# CONFIG_USB_STORAGE_SDDR09 is not set +# CONFIG_USB_STORAGE_SDDR55 is not set +# CONFIG_USB_STORAGE_JUMPSHOT is not set +# CONFIG_USB_STORAGE_ALAUDA is not set +# CONFIG_USB_STORAGE_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 + +# +# USB Imaging devices +# +# CONFIG_USB_MDC800 is not set +# CONFIG_USB_MICROTEK is not set +# CONFIG_USBIP_CORE is not set +# CONFIG_USB_MUSB_HDRC is not set +# CONFIG_USB_DWC3 is not set +# CONFIG_USB_DWC2 is not set +# CONFIG_USB_CHIPIDEA is not set +# CONFIG_USB_ISP1760 is not set + +# +# USB port drivers +# +# CONFIG_USB_SERIAL 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_HSIC_USB3503 is not set +# CONFIG_USB_HSIC_USB4604 is not set +# CONFIG_USB_LINK_LAYER_TEST is not set +# CONFIG_USB_CHAOSKEY is not set + +# +# USB Physical Layer drivers +# +CONFIG_USB_PHY=y +# CONFIG_NOP_USB_XCEIV is not set +# CONFIG_USB_GPIO_VBUS is not set +# CONFIG_USB_ISP1301 is not set +# CONFIG_USB_ULPI is not set +CONFIG_USBPHY_XGS_IPROC=y +# CONFIG_USB_XGS_IPROC_DRD is not set +CONFIG_USB_GADGET=y +# CONFIG_USB_GADGET_DEBUG is not set +# CONFIG_USB_GADGET_DEBUG_FILES is not set +# CONFIG_USB_GADGET_DEBUG_FS is not set +CONFIG_USB_GADGET_VBUS_DRAW=2 +CONFIG_USB_GADGET_STORAGE_NUM_BUFFERS=2 +# CONFIG_U_SERIAL_CONSOLE is not set + +# +# USB Peripheral Controller +# +# CONFIG_USB_FUSB300 is not set +# CONFIG_USB_FOTG210_UDC is not set +# CONFIG_USB_GR_UDC is not set +# CONFIG_USB_R8A66597 is not set +# CONFIG_USB_PXA27X is not set +# CONFIG_USB_MV_UDC is not set +# CONFIG_USB_MV_U3D is not set +# CONFIG_USB_SNP_UDC_PLAT is not set +# CONFIG_USB_M66592 is not set +# CONFIG_USB_BDC_UDC is not set +# CONFIG_USB_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_XGS_IPROC_UDC=y +# CONFIG_USB_DUMMY_HCD is not set +CONFIG_USB_LIBCOMPOSITE=m +CONFIG_USB_F_ACM=m +CONFIG_USB_U_SERIAL=m +CONFIG_USB_F_SERIAL=m +CONFIG_USB_F_OBEX=m +# CONFIG_USB_CONFIGFS is not set +# CONFIG_USB_ZERO is not set +# CONFIG_USB_ETH is not set +# CONFIG_USB_G_NCM is not set +# CONFIG_USB_GADGETFS is not set +# CONFIG_USB_FUNCTIONFS is not set +# CONFIG_USB_MASS_STORAGE is not set +CONFIG_USB_G_SERIAL=m +# CONFIG_USB_G_PRINTER is not set +# CONFIG_USB_CDC_COMPOSITE is not set +# CONFIG_USB_G_ACM_MS is not set +# CONFIG_USB_G_MULTI is not set +# CONFIG_USB_G_HID is not set +# CONFIG_USB_G_DBGP is not set + +# +# USB Power Delivery and Type-C drivers +# +# CONFIG_TYPEC_UCSI is not set +# CONFIG_USB_ULPI_BUS is not set +# CONFIG_UWB is not set +CONFIG_MMC=y +CONFIG_PWRSEQ_EMMC=y +CONFIG_PWRSEQ_SIMPLE=y +CONFIG_MMC_BLOCK=y +CONFIG_MMC_BLOCK_MINORS=8 +# 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 is not set +CONFIG_MMC_SDHCI=y +CONFIG_MMC_SDHCI_IO_ACCESSORS=y +# CONFIG_MMC_SDHCI_PCI is not set +CONFIG_MMC_SDHCI_PLTFM=y +# CONFIG_MMC_SDHCI_OF_ARASAN is not set +# 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_TIFM_SD is not set +# CONFIG_MMC_SPI is not set +# CONFIG_MMC_CB710 is not set +# CONFIG_MMC_VIA_SDMMC is not set +# CONFIG_MMC_DW 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_XGS_IPROC=y +# CONFIG_MMC_SDHCI_XENON is not set +# CONFIG_MEMSTICK is not set +# CONFIG_NEW_LEDS is not set +# CONFIG_ACCESSIBILITY is not set +# CONFIG_INFINIBAND is not set +CONFIG_EDAC_ATOMIC_SCRUB=y +CONFIG_EDAC_SUPPORT=y +CONFIG_RTC_LIB=y +# CONFIG_RTC_CLASS is not set +CONFIG_DMADEVICES=y +CONFIG_DMADEVICES_DEBUG=y +CONFIG_DMADEVICES_VDEBUG=y + +# +# DMA Devices +# +CONFIG_DMA_ENGINE=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_NBPFAXI_DMA is not set +CONFIG_PL330_DMA=y +# CONFIG_QCOM_HIDMA_MGMT is not set +# CONFIG_QCOM_HIDMA is not set +# CONFIG_DW_DMAC 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 is not set +# CONFIG_AUXDISPLAY is not set +# CONFIG_UIO is not set +# CONFIG_VIRT_DRIVERS is not set + +# +# Virtio drivers +# +# CONFIG_VIRTIO_PCI is not set +# CONFIG_VIRTIO_MMIO is not set + +# +# Microsoft Hyper-V guest support +# +# CONFIG_HYPERV_TSCPAGE is not set +# CONFIG_STAGING 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 +# +# CONFIG_CLK_HSDK is not set +# 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 is not set +# CONFIG_CLK_QORIQ is not set +# CONFIG_COMMON_CLK_NXP is not set +# CONFIG_COMMON_CLK_PXA is not set +# CONFIG_COMMON_CLK_PIC32 is not set +# CONFIG_COMMON_CLK_VC5 is not set +CONFIG_COMMON_CLK_IPROC=y +CONFIG_CLK_XGS_IPROC=y +# CONFIG_HWSPINLOCK is not set + +# +# Clock Source drivers +# +CONFIG_TIMER_OF=y +CONFIG_TIMER_PROBE=y +CONFIG_ARM_GLOBAL_TIMER=y +# CONFIG_ARM_TIMER_SP804 is not set +CONFIG_CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK=y +# CONFIG_ATMEL_PIT is not set +# CONFIG_SH_TIMER_CMT is not set +# CONFIG_SH_TIMER_MTU2 is not set +# CONFIG_SH_TIMER_TMU is not set +# CONFIG_EM_TIMER_STI is not set +# CONFIG_MAILBOX is not set +CONFIG_IOMMU_SUPPORT=y + +# +# Generic IOMMU Pagetable Support +# +# CONFIG_IOMMU_IO_PGTABLE_LPAE is not set +# CONFIG_IOMMU_IO_PGTABLE_ARMV7S is not set +# CONFIG_ARM_SMMU is not set + +# +# Remoteproc drivers +# +# CONFIG_REMOTEPROC is not set + +# +# Rpmsg drivers +# + +# +# SOC (System On Chip) specific Drivers +# + +# +# Amlogic SoC drivers +# + +# +# Broadcom SoC drivers +# +# CONFIG_SOC_BRCMSTB is not set + +# +# i.MX SoC drivers +# + +# +# Qualcomm SoC drivers +# +# CONFIG_SUNXI_SRAM is not set +# CONFIG_SOC_TI is not set +# CONFIG_PM_DEVFREQ is not set +CONFIG_EXTCON=y + +# +# Extcon Device Drivers +# +# 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 is not set +# CONFIG_MEMORY is not set +# CONFIG_IIO is not set +# CONFIG_NTB is not set +# CONFIG_VME_BUS is not set +# CONFIG_PWM is not set +CONFIG_IRQCHIP=y +CONFIG_ARM_GIC=y +CONFIG_ARM_GIC_MAX_NR=1 +# CONFIG_IPACK_BUS is not set +# CONFIG_RESET_CONTROLLER is not set +# CONFIG_FMC is not set + +# +# PHY Subsystem +# +CONFIG_GENERIC_PHY=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_POWERCAP is not set +# CONFIG_MCB is not set +# CONFIG_RAS is not set + +# +# Android +# +# CONFIG_ANDROID is not set +# CONFIG_DAX is not set +CONFIG_NVMEM=y +# CONFIG_STM is not set +# CONFIG_INTEL_TH is not set +# CONFIG_FPGA is not set + +# +# FSI support +# +# CONFIG_FSI is not set +# CONFIG_TEE is not set + +# +# Firmware Drivers +# +# CONFIG_FIRMWARE_MEMMAP is not set +# CONFIG_FW_CFG_SYSFS is not set +CONFIG_HAVE_ARM_SMCCC=y +# CONFIG_GOOGLE_FIRMWARE is not set + +# +# Tegra firmware driver +# + +# +# File systems +# +CONFIG_DCACHE_WORD_ACCESS=y +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +CONFIG_EXT3_FS=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_EXT4_FS=y +# CONFIG_EXT4_FS_POSIX_ACL is not set +# 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_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 is not set +CONFIG_INOTIFY_USER=y +# CONFIG_FANOTIFY is not set +# CONFIG_QUOTA is not set +# CONFIG_QUOTACTL is not set +CONFIG_AUTOFS4_FS=y +# CONFIG_FUSE_FS is not set +CONFIG_OVERLAY_FS=y +# CONFIG_OVERLAY_FS_REDIRECT_DIR is not set +# CONFIG_OVERLAY_FS_INDEX is not set + +# +# Caches +# +# CONFIG_FSCACHE is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y +CONFIG_VFAT_FS=y +CONFIG_FAT_DEFAULT_CODEPAGE=437 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" +# CONFIG_FAT_DEFAULT_UTF8 is not set +CONFIG_NTFS_FS=y +# CONFIG_NTFS_DEBUG is not set +# CONFIG_NTFS_RW is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_SYSCTL=y +CONFIG_PROC_PAGE_MONITOR=y +# CONFIG_PROC_CHILDREN is not set +CONFIG_KERNFS=y +CONFIG_SYSFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_CONFIGFS_FS=m +CONFIG_MISC_FILESYSTEMS=y +# CONFIG_ORANGEFS_FS is not set +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_ECRYPT_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +CONFIG_JFFS2_FS=y +CONFIG_JFFS2_FS_DEBUG=0 +CONFIG_JFFS2_FS_WRITEBUFFER=y +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set +# CONFIG_JFFS2_SUMMARY is not set +# CONFIG_JFFS2_FS_XATTR is not set +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set +CONFIG_JFFS2_ZLIB=y +# CONFIG_JFFS2_LZO is not set +CONFIG_JFFS2_RTIME=y +# CONFIG_JFFS2_RUBIN is not set +CONFIG_UBIFS_FS=y +# CONFIG_UBIFS_FS_ADVANCED_COMPR is not set +CONFIG_UBIFS_FS_LZO=y +CONFIG_UBIFS_FS_ZLIB=y +# CONFIG_UBIFS_ATIME_SUPPORT is not set +# CONFIG_UBIFS_FS_ENCRYPTION is not set +CONFIG_UBIFS_FS_SECURITY=y +# CONFIG_CRAMFS is not set +CONFIG_SQUASHFS=y +# CONFIG_SQUASHFS_FILE_CACHE is not set +CONFIG_SQUASHFS_FILE_DIRECT=y +# CONFIG_SQUASHFS_DECOMP_SINGLE is not set +CONFIG_SQUASHFS_DECOMP_MULTI=y +# CONFIG_SQUASHFS_DECOMP_MULTI_PERCPU is not set +CONFIG_SQUASHFS_XATTR=y +CONFIG_SQUASHFS_ZLIB=y +CONFIG_SQUASHFS_LZ4=y +CONFIG_SQUASHFS_LZO=y +CONFIG_SQUASHFS_XZ=y +CONFIG_SQUASHFS_ZSTD=y +CONFIG_SQUASHFS_4K_DEVBLK_SIZE=y +# CONFIG_SQUASHFS_EMBEDDED is not set +CONFIG_SQUASHFS_FRAGMENT_CACHE_SIZE=3 +# CONFIG_VXFS_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_OMFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_QNX6FS_FS is not set +# CONFIG_ROMFS_FS is not set +# CONFIG_PSTORE is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set +CONFIG_NETWORK_FILESYSTEMS=y +CONFIG_NFS_FS=y +CONFIG_NFS_V2=y +CONFIG_NFS_V3=y +CONFIG_NFS_V3_ACL=y +CONFIG_NFS_V4=y +CONFIG_NFS_SWAP=y +# CONFIG_NFS_V4_1 is not set +CONFIG_ROOT_NFS=y +# CONFIG_NFS_USE_LEGACY_DNS is not set +CONFIG_NFS_USE_KERNEL_DNS=y +CONFIG_NFSD=y +# CONFIG_NFSD_V3 is not set +# CONFIG_NFSD_V4 is not set +CONFIG_GRACE_PERIOD=y +CONFIG_LOCKD=y +CONFIG_LOCKD_V4=y +CONFIG_NFS_ACL_SUPPORT=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +CONFIG_SUNRPC_GSS=y +CONFIG_SUNRPC_SWAP=y +# CONFIG_SUNRPC_DEBUG is not set +# CONFIG_CEPH_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +CONFIG_NLS=y +CONFIG_NLS_DEFAULT="iso8859-1" +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=y +CONFIG_NLS_ISO8859_1=y +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_ISO8859_13 is not set +# CONFIG_NLS_ISO8859_14 is not set +# CONFIG_NLS_ISO8859_15 is not set +# CONFIG_NLS_KOI8_R is not set +# CONFIG_NLS_KOI8_U is not set +# CONFIG_NLS_MAC_ROMAN is not set +# CONFIG_NLS_MAC_CELTIC is not set +# CONFIG_NLS_MAC_CENTEURO is not set +# CONFIG_NLS_MAC_CROATIAN is not set +# CONFIG_NLS_MAC_CYRILLIC is not set +# CONFIG_NLS_MAC_GAELIC is not set +# CONFIG_NLS_MAC_GREEK is not set +# CONFIG_NLS_MAC_ICELAND is not set +# CONFIG_NLS_MAC_INUIT is not set +# CONFIG_NLS_MAC_ROMANIAN is not set +# CONFIG_NLS_MAC_TURKISH is not set +# CONFIG_NLS_UTF8 is not set +# CONFIG_DLM is not set + +# +# Kernel hacking +# + +# +# printk and dmesg options +# +# CONFIG_PRINTK_TIME is not set +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=1024 +# CONFIG_STRIP_ASM_SYMS is not set +# CONFIG_READABLE_ASM is not set +# CONFIG_UNUSED_SYMBOLS is not set +# CONFIG_PAGE_OWNER is not set +CONFIG_DEBUG_FS=y +# CONFIG_HEADERS_CHECK is not set +# CONFIG_DEBUG_SECTION_MISMATCH is not set +CONFIG_SECTION_MISMATCH_WARN_ONLY=y +# CONFIG_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_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 is not set +# CONFIG_DEBUG_PER_CPU_MAPS is not set +# CONFIG_DEBUG_SHIRQ is not set + +# +# Debug Lockups and Hangs +# +# CONFIG_SOFTLOCKUP_DETECTOR is not set +# CONFIG_DETECT_HUNG_TASK is not set +# 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 is not set +# CONFIG_SCHEDSTATS is not set +# CONFIG_SCHED_STACK_END_CHECK is not set +# CONFIG_DEBUG_TIMEKEEPING is not set +CONFIG_DEBUG_PREEMPT=y + +# +# 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_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 + +# +# 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_DYNAMIC_FTRACE_WITH_REGS=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_MEMTEST is not set +# CONFIG_BUG_ON_DATA_CORRUPTION is not set +# CONFIG_SAMPLES is not set +CONFIG_HAVE_ARCH_KGDB=y +# CONFIG_KGDB is not set +# CONFIG_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_ARM_PTDUMP is not set +CONFIG_ARM_UNWIND=y +CONFIG_DEBUG_USER=y +# CONFIG_DEBUG_LL is not set +CONFIG_DEBUG_LL_INCLUDE="mach/debug-macro.S" +# CONFIG_DEBUG_UART_8250 is not set +CONFIG_UNCOMPRESS_INCLUDE="debug/uncompress.h" +# CONFIG_PID_IN_CONTEXTIDR is not set +# CONFIG_CORESIGHT is not set + +# +# Security options +# +CONFIG_KEYS=y +# CONFIG_PERSISTENT_KEYRINGS 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 is not set +# CONFIG_SECURITYFS is not set +CONFIG_HAVE_HARDENED_USERCOPY_ALLOCATOR=y +# CONFIG_HARDENED_USERCOPY is not set +# CONFIG_STATIC_USERMODEHELPER is not set +CONFIG_DEFAULT_SECURITY_DAC=y +CONFIG_DEFAULT_SECURITY="" +CONFIG_CRYPTO=y + +# +# Crypto core or helper +# +CONFIG_CRYPTO_ALGAPI=y +CONFIG_CRYPTO_ALGAPI2=y +CONFIG_CRYPTO_AEAD=m +CONFIG_CRYPTO_AEAD2=y +CONFIG_CRYPTO_BLKCIPHER=y +CONFIG_CRYPTO_BLKCIPHER2=y +CONFIG_CRYPTO_HASH=y +CONFIG_CRYPTO_HASH2=y +CONFIG_CRYPTO_RNG=m +CONFIG_CRYPTO_RNG2=y +CONFIG_CRYPTO_RNG_DEFAULT=m +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 is not set +CONFIG_CRYPTO_MANAGER=y +CONFIG_CRYPTO_MANAGER2=y +# CONFIG_CRYPTO_USER is not set +CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y +# CONFIG_CRYPTO_GF128MUL is not set +CONFIG_CRYPTO_NULL=m +CONFIG_CRYPTO_NULL2=y +# CONFIG_CRYPTO_PCRYPT is not set +CONFIG_CRYPTO_WORKQUEUE=y +# CONFIG_CRYPTO_CRYPTD is not set +# CONFIG_CRYPTO_MCRYPTD is not set +# CONFIG_CRYPTO_AUTHENC is not set +# CONFIG_CRYPTO_TEST is not set + +# +# Authenticated Encryption with Associated Data +# +# CONFIG_CRYPTO_CCM is not set +# CONFIG_CRYPTO_GCM is not set +# CONFIG_CRYPTO_CHACHA20POLY1305 is not set +# CONFIG_CRYPTO_SEQIV is not set +CONFIG_CRYPTO_ECHAINIV=m + +# +# Block modes +# +CONFIG_CRYPTO_CBC=y +# CONFIG_CRYPTO_CTR is not set +# CONFIG_CRYPTO_CTS is not set +# CONFIG_CRYPTO_ECB is not set +# CONFIG_CRYPTO_LRW is not set +# CONFIG_CRYPTO_PCBC is not set +# CONFIG_CRYPTO_XTS is not set +# CONFIG_CRYPTO_KEYWRAP is not set + +# +# Hash modes +# +# CONFIG_CRYPTO_CMAC is not set +CONFIG_CRYPTO_HMAC=m +# CONFIG_CRYPTO_XCBC is not set +# CONFIG_CRYPTO_VMAC is not set + +# +# Digest +# +CONFIG_CRYPTO_CRC32C=y +# CONFIG_CRYPTO_CRC32 is not set +# CONFIG_CRYPTO_CRCT10DIF is not set +# CONFIG_CRYPTO_GHASH is not set +# CONFIG_CRYPTO_POLY1305 is not set +# CONFIG_CRYPTO_MD4 is not set +CONFIG_CRYPTO_MD5=y +# 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 is not set +CONFIG_CRYPTO_SHA256=m +# CONFIG_CRYPTO_SHA512 is not set +# 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 is not set +# CONFIG_CRYPTO_BLOWFISH is not set +# CONFIG_CRYPTO_CAMELLIA is not set +# CONFIG_CRYPTO_CAST5 is not set +# CONFIG_CRYPTO_CAST6 is not set +CONFIG_CRYPTO_DES=y +# CONFIG_CRYPTO_FCRYPT is not set +# CONFIG_CRYPTO_KHAZAD is not set +# CONFIG_CRYPTO_SALSA20 is not set +# CONFIG_CRYPTO_CHACHA20 is not set +# CONFIG_CRYPTO_SEED is not set +# CONFIG_CRYPTO_SERPENT is not set +# CONFIG_CRYPTO_TEA is not set +# CONFIG_CRYPTO_TWOFISH is not set + +# +# Compression +# +CONFIG_CRYPTO_DEFLATE=y +CONFIG_CRYPTO_LZO=y +# CONFIG_CRYPTO_842 is not set +# CONFIG_CRYPTO_LZ4 is not set +# CONFIG_CRYPTO_LZ4HC is not set + +# +# Random Number Generation +# +CONFIG_CRYPTO_ANSI_CPRNG=m +CONFIG_CRYPTO_DRBG_MENU=m +CONFIG_CRYPTO_DRBG_HMAC=y +# CONFIG_CRYPTO_DRBG_HASH is not set +CONFIG_CRYPTO_DRBG=m +CONFIG_CRYPTO_JITTERENTROPY=m +# 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_HIFN_795X is not set +# CONFIG_CRYPTO_DEV_FSL_CAAM_CRYPTO_API_DESC is not set +# CONFIG_ASYMMETRIC_KEY_TYPE is not set + +# +# Certificates for signature checking +# +# CONFIG_SYSTEM_BLACKLIST_KEYRING is not set +# CONFIG_ARM_CRYPTO is not set +# CONFIG_BINARY_PRINTF is not set + +# +# 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_T10DIF is not set +# CONFIG_CRC_ITU_T is not set +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 is not set +# CONFIG_LIBCRC32C is not set +# CONFIG_CRC8 is not set +CONFIG_XXHASH=y +# CONFIG_AUDIT_ARCH_COMPAT_GENERIC is not set +# CONFIG_RANDOM32_SELFTEST is not set +CONFIG_ZLIB_INFLATE=y +CONFIG_ZLIB_DEFLATE=y +CONFIG_LZO_COMPRESS=y +CONFIG_LZO_DECOMPRESS=y +CONFIG_LZ4_DECOMPRESS=y +CONFIG_ZSTD_DECOMPRESS=y +CONFIG_XZ_DEC=y +CONFIG_XZ_DEC_X86=y +CONFIG_XZ_DEC_POWERPC=y +CONFIG_XZ_DEC_IA64=y +CONFIG_XZ_DEC_ARM=y +CONFIG_XZ_DEC_ARMTHUMB=y +CONFIG_XZ_DEC_SPARC=y +CONFIG_XZ_DEC_BCJ=y +# CONFIG_XZ_DEC_TEST is not set +CONFIG_DECOMPRESS_GZIP=y +CONFIG_DECOMPRESS_BZIP2=y +CONFIG_DECOMPRESS_LZMA=y +CONFIG_DECOMPRESS_XZ=y +CONFIG_DECOMPRESS_LZO=y +CONFIG_DECOMPRESS_LZ4=y +CONFIG_GENERIC_ALLOCATOR=y +CONFIG_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_NLATTR=y +# CONFIG_CORDIC is not set +# CONFIG_DDR is not set +# CONFIG_IRQ_POLL is not set +CONFIG_LIBFDT=y +CONFIG_OID_REGISTRY=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_VIRTUALIZATION is not set diff --git a/packages/base/any/kernels/4.14-lts/patches/brcm-iproc-4.14.patch b/packages/base/any/kernels/4.14-lts/patches/brcm-iproc-4.14.patch new file mode 100644 index 00000000..d2023acb --- /dev/null +++ b/packages/base/any/kernels/4.14-lts/patches/brcm-iproc-4.14.patch @@ -0,0 +1,32416 @@ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/Kconfig b/arch/arm/Kconfig +--- a/arch/arm/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/arch/arm/Kconfig 2018-05-10 11:31:28.281398222 +0800 +@@ -759,6 +759,8 @@ source "arch/arm/mach-iop33x/Kconfig" + + source "arch/arm/mach-iop13xx/Kconfig" + ++source "arch/arm/mach-iproc/Kconfig" ++ + source "arch/arm/mach-ixp4xx/Kconfig" + + source "arch/arm/mach-keystone/Kconfig" +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/Makefile b/arch/arm/Makefile +--- a/arch/arm/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/arch/arm/Makefile 2018-05-10 11:31:28.281398222 +0800 +@@ -177,6 +177,7 @@ machine-$(CONFIG_ARCH_INTEGRATOR) += int + machine-$(CONFIG_ARCH_IOP13XX) += iop13xx + machine-$(CONFIG_ARCH_IOP32X) += iop32x + machine-$(CONFIG_ARCH_IOP33X) += iop33x ++machine-$(CONFIG_ARCH_XGS_IPROC) += iproc + machine-$(CONFIG_ARCH_IXP4XX) += ixp4xx + machine-$(CONFIG_ARCH_KEYSTONE) += keystone + machine-$(CONFIG_ARCH_KS8695) += ks8695 +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/compressed/ashldi3.S b/arch/arm/boot/compressed/ashldi3.S +--- a/arch/arm/boot/compressed/ashldi3.S 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/compressed/ashldi3.S 2018-02-27 17:12:26.660706150 +0800 +@@ -0,0 +1,54 @@ ++/* Copyright 1995, 1996, 1998, 1999, 2000, 2003, 2004, 2005 ++ Free Software Foundation, Inc. ++ ++This file is free software; you can redistribute it and/or modify it ++under the terms of the GNU General Public License as published by the ++Free Software Foundation; either version 2, or (at your option) any ++later version. ++ ++In addition to the permissions in the GNU General Public License, the ++Free Software Foundation gives you unlimited permission to link the ++compiled version of this file into combinations with other programs, ++and to distribute those combinations without any restriction coming ++from the use of this file. (The General Public License restrictions ++do apply in other respects; for example, they cover modification of ++the file, and distribution when not linked into a combine ++executable.) ++ ++This file is distributed in the hope that it will be useful, but ++WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program; see the file COPYING. If not, write to ++the Free Software Foundation, 51 Franklin Street, Fifth Floor, ++Boston, MA 02110-1301, USA. */ ++ ++ ++#include ++#include ++ ++#ifdef __ARMEB__ ++#define al r1 ++#define ah r0 ++#else ++#define al r0 ++#define ah r1 ++#endif ++ ++ENTRY(__ashldi3) ++ENTRY(__aeabi_llsl) ++ ++ subs r3, r2, #32 ++ rsb ip, r2, #32 ++ movmi ah, ah, lsl r2 ++ movpl ah, al, lsl r3 ++ ARM( orrmi ah, ah, al, lsr ip ) ++ THUMB( lsrmi r3, al, ip ) ++ THUMB( orrmi ah, ah, r3 ) ++ mov al, al, lsl r2 ++ ret lr ++ ++ENDPROC(__ashldi3) ++ENDPROC(__aeabi_llsl) +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/compressed/bswapsdi2.S b/arch/arm/boot/compressed/bswapsdi2.S +--- a/arch/arm/boot/compressed/bswapsdi2.S 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/compressed/bswapsdi2.S 2018-02-27 17:12:26.688706343 +0800 +@@ -0,0 +1,38 @@ ++/* SPDX-License-Identifier: GPL-2.0 */ ++#include ++#include ++ ++#if __LINUX_ARM_ARCH__ >= 6 ++ENTRY(__bswapsi2) ++ rev r0, r0 ++ bx lr ++ENDPROC(__bswapsi2) ++ ++ENTRY(__bswapdi2) ++ rev r3, r0 ++ rev r0, r1 ++ mov r1, r3 ++ bx lr ++ENDPROC(__bswapdi2) ++#else ++ENTRY(__bswapsi2) ++ eor r3, r0, r0, ror #16 ++ mov r3, r3, lsr #8 ++ bic r3, r3, #0xff00 ++ eor r0, r3, r0, ror #8 ++ ret lr ++ENDPROC(__bswapsi2) ++ ++ENTRY(__bswapdi2) ++ mov ip, r1 ++ eor r3, ip, ip, ror #16 ++ eor r1, r0, r0, ror #16 ++ mov r1, r1, lsr #8 ++ mov r3, r3, lsr #8 ++ bic r3, r3, #0xff00 ++ bic r1, r1, #0xff00 ++ eor r1, r1, r0, ror #8 ++ eor r0, r3, ip, ror #8 ++ ret lr ++ENDPROC(__bswapdi2) ++#endif +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/compressed/hyp-stub.S b/arch/arm/boot/compressed/hyp-stub.S +--- a/arch/arm/boot/compressed/hyp-stub.S 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/compressed/hyp-stub.S 2018-02-27 17:12:26.604705764 +0800 +@@ -0,0 +1,285 @@ ++/* ++ * Copyright (c) 2012 Linaro Limited. ++ * ++ * 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., ++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef ZIMAGE ++/* ++ * For the kernel proper, we need to find out the CPU boot mode long after ++ * boot, so we need to store it in a writable variable. ++ * ++ * This is not in .bss, because we set it sufficiently early that the boot-time ++ * zeroing of .bss would clobber it. ++ */ ++.data ++ .align 2 ++ENTRY(__boot_cpu_mode) ++ .long 0 ++.text ++ ++ /* ++ * Save the primary CPU boot mode. Requires 3 scratch registers. ++ */ ++ .macro store_primary_cpu_mode reg1, reg2, reg3 ++ mrs \reg1, cpsr ++ and \reg1, \reg1, #MODE_MASK ++ adr \reg2, .L__boot_cpu_mode_offset ++ ldr \reg3, [\reg2] ++ str \reg1, [\reg2, \reg3] ++ .endm ++ ++ /* ++ * Compare the current mode with the one saved on the primary CPU. ++ * If they don't match, record that fact. The Z bit indicates ++ * if there's a match or not. ++ * Requires 3 additionnal scratch registers. ++ */ ++ .macro compare_cpu_mode_with_primary mode, reg1, reg2, reg3 ++ adr \reg2, .L__boot_cpu_mode_offset ++ ldr \reg3, [\reg2] ++ ldr \reg1, [\reg2, \reg3] ++ cmp \mode, \reg1 @ matches primary CPU boot mode? ++ orrne \reg1, \reg1, #BOOT_CPU_MODE_MISMATCH ++ strne \reg1, [\reg2, \reg3] @ record what happened and give up ++ .endm ++ ++#else /* ZIMAGE */ ++ ++ .macro store_primary_cpu_mode reg1:req, reg2:req, reg3:req ++ .endm ++ ++/* ++ * The zImage loader only runs on one CPU, so we don't bother with mult-CPU ++ * consistency checking: ++ */ ++ .macro compare_cpu_mode_with_primary mode, reg1, reg2, reg3 ++ cmp \mode, \mode ++ .endm ++ ++#endif /* ZIMAGE */ ++ ++/* ++ * Hypervisor stub installation functions. ++ * ++ * These must be called with the MMU and D-cache off. ++ * They are not ABI compliant and are only intended to be called from the kernel ++ * entry points in head.S. ++ */ ++@ Call this from the primary CPU ++ENTRY(__hyp_stub_install) ++ store_primary_cpu_mode r4, r5, r6 ++ENDPROC(__hyp_stub_install) ++ ++ @ fall through... ++ ++@ Secondary CPUs should call here ++ENTRY(__hyp_stub_install_secondary) ++ mrs r4, cpsr ++ and r4, r4, #MODE_MASK ++ ++ /* ++ * If the secondary has booted with a different mode, give up ++ * immediately. ++ */ ++ compare_cpu_mode_with_primary r4, r5, r6, r7 ++ retne lr ++ ++ /* ++ * Once we have given up on one CPU, we do not try to install the ++ * stub hypervisor on the remaining ones: because the saved boot mode ++ * is modified, it can't compare equal to the CPSR mode field any ++ * more. ++ * ++ * Otherwise... ++ */ ++ ++ cmp r4, #HYP_MODE ++ retne lr @ give up if the CPU is not in HYP mode ++ ++/* ++ * Configure HSCTLR to set correct exception endianness/instruction set ++ * state etc. ++ * Turn off all traps ++ * Eventually, CPU-specific code might be needed -- assume not for now ++ * ++ * This code relies on the "eret" instruction to synchronize the ++ * various coprocessor accesses. This is done when we switch to SVC ++ * (see safe_svcmode_maskall). ++ */ ++ @ Now install the hypervisor stub: ++ W(adr) r7, __hyp_stub_vectors ++ mcr p15, 4, r7, c12, c0, 0 @ set hypervisor vector base (HVBAR) ++ ++ @ Disable all traps, so we don't get any nasty surprise ++ mov r7, #0 ++ mcr p15, 4, r7, c1, c1, 0 @ HCR ++ mcr p15, 4, r7, c1, c1, 2 @ HCPTR ++ mcr p15, 4, r7, c1, c1, 3 @ HSTR ++ ++THUMB( orr r7, #(1 << 30) ) @ HSCTLR.TE ++ARM_BE8(orr r7, r7, #(1 << 25)) @ HSCTLR.EE ++ mcr p15, 4, r7, c1, c0, 0 @ HSCTLR ++ ++ mrc p15, 4, r7, c1, c1, 1 @ HDCR ++ and r7, #0x1f @ Preserve HPMN ++ mcr p15, 4, r7, c1, c1, 1 @ HDCR ++ ++ @ Make sure NS-SVC is initialised appropriately ++ mrc p15, 0, r7, c1, c0, 0 @ SCTLR ++ orr r7, #(1 << 5) @ CP15 barriers enabled ++ bic r7, #(3 << 7) @ Clear SED/ITD for v8 (RES0 for v7) ++ bic r7, #(3 << 19) @ WXN and UWXN disabled ++ mcr p15, 0, r7, c1, c0, 0 @ SCTLR ++ ++ mrc p15, 0, r7, c0, c0, 0 @ MIDR ++ mcr p15, 4, r7, c0, c0, 0 @ VPIDR ++ ++ mrc p15, 0, r7, c0, c0, 5 @ MPIDR ++ mcr p15, 4, r7, c0, c0, 5 @ VMPIDR ++ ++#if !defined(ZIMAGE) && defined(CONFIG_ARM_ARCH_TIMER) ++ @ make CNTP_* and CNTPCT accessible from PL1 ++ mrc p15, 0, r7, c0, c1, 1 @ ID_PFR1 ++ lsr r7, #16 ++ and r7, #0xf ++ cmp r7, #1 ++ bne 1f ++ mrc p15, 4, r7, c14, c1, 0 @ CNTHCTL ++ orr r7, r7, #3 @ PL1PCEN | PL1PCTEN ++ mcr p15, 4, r7, c14, c1, 0 @ CNTHCTL ++ mov r7, #0 ++ mcrr p15, 4, r7, r7, c14 @ CNTVOFF ++ ++ @ Disable virtual timer in case it was counting ++ mrc p15, 0, r7, c14, c3, 1 @ CNTV_CTL ++ bic r7, #1 @ Clear ENABLE ++ mcr p15, 0, r7, c14, c3, 1 @ CNTV_CTL ++1: ++#endif ++ ++#ifdef CONFIG_ARM_GIC_V3 ++ @ Check whether GICv3 system registers are available ++ mrc p15, 0, r7, c0, c1, 1 @ ID_PFR1 ++ ubfx r7, r7, #28, #4 ++ cmp r7, #1 ++ bne 2f ++ ++ @ Enable system register accesses ++ mrc p15, 4, r7, c12, c9, 5 @ ICC_HSRE ++ orr r7, r7, #(ICC_SRE_EL2_ENABLE | ICC_SRE_EL2_SRE) ++ mcr p15, 4, r7, c12, c9, 5 @ ICC_HSRE ++ isb ++ ++ @ SRE bit could be forced to 0 by firmware. ++ @ Check whether it sticks before accessing any other sysreg ++ mrc p15, 4, r7, c12, c9, 5 @ ICC_HSRE ++ tst r7, #ICC_SRE_EL2_SRE ++ beq 2f ++ mov r7, #0 ++ mcr p15, 4, r7, c12, c11, 0 @ ICH_HCR ++2: ++#endif ++ ++ bx lr @ The boot CPU mode is left in r4. ++ENDPROC(__hyp_stub_install_secondary) ++ ++__hyp_stub_do_trap: ++ teq r0, #HVC_SET_VECTORS ++ bne 1f ++ mcr p15, 4, r1, c12, c0, 0 @ set HVBAR ++ b __hyp_stub_exit ++ ++1: teq r0, #HVC_SOFT_RESTART ++ bne 1f ++ bx r1 ++ ++1: teq r0, #HVC_RESET_VECTORS ++ beq __hyp_stub_exit ++ ++ ldr r0, =HVC_STUB_ERR ++ __ERET ++ ++__hyp_stub_exit: ++ mov r0, #0 ++ __ERET ++ENDPROC(__hyp_stub_do_trap) ++ ++/* ++ * __hyp_set_vectors: Call this after boot to set the initial hypervisor ++ * vectors as part of hypervisor installation. On an SMP system, this should ++ * be called on each CPU. ++ * ++ * r0 must be the physical address of the new vector table (which must lie in ++ * the bottom 4GB of physical address space. ++ * ++ * r0 must be 32-byte aligned. ++ * ++ * Before calling this, you must check that the stub hypervisor is installed ++ * everywhere, by waiting for any secondary CPUs to be brought up and then ++ * checking that BOOT_CPU_MODE_HAVE_HYP(__boot_cpu_mode) is true. ++ * ++ * If not, there is a pre-existing hypervisor, some CPUs failed to boot, or ++ * something else went wrong... in such cases, trying to install a new ++ * hypervisor is unlikely to work as desired. ++ * ++ * When you call into your shiny new hypervisor, sp_hyp will contain junk, ++ * so you will need to set that to something sensible at the new hypervisor's ++ * initialisation entry point. ++ */ ++ENTRY(__hyp_set_vectors) ++ mov r1, r0 ++ mov r0, #HVC_SET_VECTORS ++ __HVC(0) ++ ret lr ++ENDPROC(__hyp_set_vectors) ++ ++ENTRY(__hyp_soft_restart) ++ mov r1, r0 ++ mov r0, #HVC_SOFT_RESTART ++ __HVC(0) ++ ret lr ++ENDPROC(__hyp_soft_restart) ++ ++ENTRY(__hyp_reset_vectors) ++ mov r0, #HVC_RESET_VECTORS ++ __HVC(0) ++ ret lr ++ENDPROC(__hyp_reset_vectors) ++ ++#ifndef ZIMAGE ++.align 2 ++.L__boot_cpu_mode_offset: ++ .long __boot_cpu_mode - . ++#endif ++ ++.align 5 ++ENTRY(__hyp_stub_vectors) ++__hyp_stub_reset: W(b) . ++__hyp_stub_und: W(b) . ++__hyp_stub_svc: W(b) . ++__hyp_stub_pabort: W(b) . ++__hyp_stub_dabort: W(b) . ++__hyp_stub_trap: W(b) __hyp_stub_do_trap ++__hyp_stub_irq: W(b) . ++__hyp_stub_fiq: W(b) . ++ENDPROC(__hyp_stub_vectors) ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/compressed/lib1funcs.S b/arch/arm/boot/compressed/lib1funcs.S +--- a/arch/arm/boot/compressed/lib1funcs.S 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/compressed/lib1funcs.S 2018-02-27 17:12:26.632705957 +0800 +@@ -0,0 +1,371 @@ ++/* ++ * linux/arch/arm/lib/lib1funcs.S: Optimized ARM division routines ++ * ++ * Author: Nicolas Pitre ++ * - contributed to gcc-3.4 on Sep 30, 2003 ++ * - adapted for the Linux kernel on Oct 2, 2003 ++ */ ++ ++/* Copyright 1995, 1996, 1998, 1999, 2000, 2003 Free Software Foundation, Inc. ++ ++This file is free software; you can redistribute it and/or modify it ++under the terms of the GNU General Public License as published by the ++Free Software Foundation; either version 2, or (at your option) any ++later version. ++ ++In addition to the permissions in the GNU General Public License, the ++Free Software Foundation gives you unlimited permission to link the ++compiled version of this file into combinations with other programs, ++and to distribute those combinations without any restriction coming ++from the use of this file. (The General Public License restrictions ++do apply in other respects; for example, they cover modification of ++the file, and distribution when not linked into a combine ++executable.) ++ ++This file is distributed in the hope that it will be useful, but ++WITHOUT ANY WARRANTY; without even the implied warranty of ++MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++General Public License for more details. ++ ++You should have received a copy of the GNU General Public License ++along with this program; see the file COPYING. If not, write to ++the Free Software Foundation, 59 Temple Place - Suite 330, ++Boston, MA 02111-1307, USA. */ ++ ++ ++#include ++#include ++#include ++ ++.macro ARM_DIV_BODY dividend, divisor, result, curbit ++ ++#if __LINUX_ARM_ARCH__ >= 5 ++ ++ clz \curbit, \divisor ++ clz \result, \dividend ++ sub \result, \curbit, \result ++ mov \curbit, #1 ++ mov \divisor, \divisor, lsl \result ++ mov \curbit, \curbit, lsl \result ++ mov \result, #0 ++ ++#else ++ ++ @ Initially shift the divisor left 3 bits if possible, ++ @ set curbit accordingly. This allows for curbit to be located ++ @ at the left end of each 4 bit nibbles in the division loop ++ @ to save one loop in most cases. ++ tst \divisor, #0xe0000000 ++ moveq \divisor, \divisor, lsl #3 ++ moveq \curbit, #8 ++ movne \curbit, #1 ++ ++ @ Unless the divisor is very big, shift it up in multiples of ++ @ four bits, since this is the amount of unwinding in the main ++ @ division loop. Continue shifting until the divisor is ++ @ larger than the dividend. ++1: cmp \divisor, #0x10000000 ++ cmplo \divisor, \dividend ++ movlo \divisor, \divisor, lsl #4 ++ movlo \curbit, \curbit, lsl #4 ++ blo 1b ++ ++ @ For very big divisors, we must shift it a bit at a time, or ++ @ we will be in danger of overflowing. ++1: cmp \divisor, #0x80000000 ++ cmplo \divisor, \dividend ++ movlo \divisor, \divisor, lsl #1 ++ movlo \curbit, \curbit, lsl #1 ++ blo 1b ++ ++ mov \result, #0 ++ ++#endif ++ ++ @ Division loop ++1: cmp \dividend, \divisor ++ subhs \dividend, \dividend, \divisor ++ orrhs \result, \result, \curbit ++ cmp \dividend, \divisor, lsr #1 ++ subhs \dividend, \dividend, \divisor, lsr #1 ++ orrhs \result, \result, \curbit, lsr #1 ++ cmp \dividend, \divisor, lsr #2 ++ subhs \dividend, \dividend, \divisor, lsr #2 ++ orrhs \result, \result, \curbit, lsr #2 ++ cmp \dividend, \divisor, lsr #3 ++ subhs \dividend, \dividend, \divisor, lsr #3 ++ orrhs \result, \result, \curbit, lsr #3 ++ cmp \dividend, #0 @ Early termination? ++ movnes \curbit, \curbit, lsr #4 @ No, any more bits to do? ++ movne \divisor, \divisor, lsr #4 ++ bne 1b ++ ++.endm ++ ++ ++.macro ARM_DIV2_ORDER divisor, order ++ ++#if __LINUX_ARM_ARCH__ >= 5 ++ ++ clz \order, \divisor ++ rsb \order, \order, #31 ++ ++#else ++ ++ cmp \divisor, #(1 << 16) ++ movhs \divisor, \divisor, lsr #16 ++ movhs \order, #16 ++ movlo \order, #0 ++ ++ cmp \divisor, #(1 << 8) ++ movhs \divisor, \divisor, lsr #8 ++ addhs \order, \order, #8 ++ ++ cmp \divisor, #(1 << 4) ++ movhs \divisor, \divisor, lsr #4 ++ addhs \order, \order, #4 ++ ++ cmp \divisor, #(1 << 2) ++ addhi \order, \order, #3 ++ addls \order, \order, \divisor, lsr #1 ++ ++#endif ++ ++.endm ++ ++ ++.macro ARM_MOD_BODY dividend, divisor, order, spare ++ ++#if __LINUX_ARM_ARCH__ >= 5 ++ ++ clz \order, \divisor ++ clz \spare, \dividend ++ sub \order, \order, \spare ++ mov \divisor, \divisor, lsl \order ++ ++#else ++ ++ mov \order, #0 ++ ++ @ Unless the divisor is very big, shift it up in multiples of ++ @ four bits, since this is the amount of unwinding in the main ++ @ division loop. Continue shifting until the divisor is ++ @ larger than the dividend. ++1: cmp \divisor, #0x10000000 ++ cmplo \divisor, \dividend ++ movlo \divisor, \divisor, lsl #4 ++ addlo \order, \order, #4 ++ blo 1b ++ ++ @ For very big divisors, we must shift it a bit at a time, or ++ @ we will be in danger of overflowing. ++1: cmp \divisor, #0x80000000 ++ cmplo \divisor, \dividend ++ movlo \divisor, \divisor, lsl #1 ++ addlo \order, \order, #1 ++ blo 1b ++ ++#endif ++ ++ @ Perform all needed subtractions to keep only the reminder. ++ @ Do comparisons in batch of 4 first. ++ subs \order, \order, #3 @ yes, 3 is intended here ++ blt 2f ++ ++1: cmp \dividend, \divisor ++ subhs \dividend, \dividend, \divisor ++ cmp \dividend, \divisor, lsr #1 ++ subhs \dividend, \dividend, \divisor, lsr #1 ++ cmp \dividend, \divisor, lsr #2 ++ subhs \dividend, \dividend, \divisor, lsr #2 ++ cmp \dividend, \divisor, lsr #3 ++ subhs \dividend, \dividend, \divisor, lsr #3 ++ cmp \dividend, #1 ++ mov \divisor, \divisor, lsr #4 ++ subges \order, \order, #4 ++ bge 1b ++ ++ tst \order, #3 ++ teqne \dividend, #0 ++ beq 5f ++ ++ @ Either 1, 2 or 3 comparison/subtractions are left. ++2: cmn \order, #2 ++ blt 4f ++ beq 3f ++ cmp \dividend, \divisor ++ subhs \dividend, \dividend, \divisor ++ mov \divisor, \divisor, lsr #1 ++3: cmp \dividend, \divisor ++ subhs \dividend, \dividend, \divisor ++ mov \divisor, \divisor, lsr #1 ++4: cmp \dividend, \divisor ++ subhs \dividend, \dividend, \divisor ++5: ++.endm ++ ++ ++#ifdef CONFIG_ARM_PATCH_IDIV ++ .align 3 ++#endif ++ ++ENTRY(__udivsi3) ++ENTRY(__aeabi_uidiv) ++UNWIND(.fnstart) ++ ++ subs r2, r1, #1 ++ reteq lr ++ bcc Ldiv0 ++ cmp r0, r1 ++ bls 11f ++ tst r1, r2 ++ beq 12f ++ ++ ARM_DIV_BODY r0, r1, r2, r3 ++ ++ mov r0, r2 ++ ret lr ++ ++11: moveq r0, #1 ++ movne r0, #0 ++ ret lr ++ ++12: ARM_DIV2_ORDER r1, r2 ++ ++ mov r0, r0, lsr r2 ++ ret lr ++ ++UNWIND(.fnend) ++ENDPROC(__udivsi3) ++ENDPROC(__aeabi_uidiv) ++ ++ENTRY(__umodsi3) ++UNWIND(.fnstart) ++ ++ subs r2, r1, #1 @ compare divisor with 1 ++ bcc Ldiv0 ++ cmpne r0, r1 @ compare dividend with divisor ++ moveq r0, #0 ++ tsthi r1, r2 @ see if divisor is power of 2 ++ andeq r0, r0, r2 ++ retls lr ++ ++ ARM_MOD_BODY r0, r1, r2, r3 ++ ++ ret lr ++ ++UNWIND(.fnend) ++ENDPROC(__umodsi3) ++ ++#ifdef CONFIG_ARM_PATCH_IDIV ++ .align 3 ++#endif ++ ++ENTRY(__divsi3) ++ENTRY(__aeabi_idiv) ++UNWIND(.fnstart) ++ ++ cmp r1, #0 ++ eor ip, r0, r1 @ save the sign of the result. ++ beq Ldiv0 ++ rsbmi r1, r1, #0 @ loops below use unsigned. ++ subs r2, r1, #1 @ division by 1 or -1 ? ++ beq 10f ++ movs r3, r0 ++ rsbmi r3, r0, #0 @ positive dividend value ++ cmp r3, r1 ++ bls 11f ++ tst r1, r2 @ divisor is power of 2 ? ++ beq 12f ++ ++ ARM_DIV_BODY r3, r1, r0, r2 ++ ++ cmp ip, #0 ++ rsbmi r0, r0, #0 ++ ret lr ++ ++10: teq ip, r0 @ same sign ? ++ rsbmi r0, r0, #0 ++ ret lr ++ ++11: movlo r0, #0 ++ moveq r0, ip, asr #31 ++ orreq r0, r0, #1 ++ ret lr ++ ++12: ARM_DIV2_ORDER r1, r2 ++ ++ cmp ip, #0 ++ mov r0, r3, lsr r2 ++ rsbmi r0, r0, #0 ++ ret lr ++ ++UNWIND(.fnend) ++ENDPROC(__divsi3) ++ENDPROC(__aeabi_idiv) ++ ++ENTRY(__modsi3) ++UNWIND(.fnstart) ++ ++ cmp r1, #0 ++ beq Ldiv0 ++ rsbmi r1, r1, #0 @ loops below use unsigned. ++ movs ip, r0 @ preserve sign of dividend ++ rsbmi r0, r0, #0 @ if negative make positive ++ subs r2, r1, #1 @ compare divisor with 1 ++ cmpne r0, r1 @ compare dividend with divisor ++ moveq r0, #0 ++ tsthi r1, r2 @ see if divisor is power of 2 ++ andeq r0, r0, r2 ++ bls 10f ++ ++ ARM_MOD_BODY r0, r1, r2, r3 ++ ++10: cmp ip, #0 ++ rsbmi r0, r0, #0 ++ ret lr ++ ++UNWIND(.fnend) ++ENDPROC(__modsi3) ++ ++#ifdef CONFIG_AEABI ++ ++ENTRY(__aeabi_uidivmod) ++UNWIND(.fnstart) ++UNWIND(.save {r0, r1, ip, lr} ) ++ ++ stmfd sp!, {r0, r1, ip, lr} ++ bl __aeabi_uidiv ++ ldmfd sp!, {r1, r2, ip, lr} ++ mul r3, r0, r2 ++ sub r1, r1, r3 ++ ret lr ++ ++UNWIND(.fnend) ++ENDPROC(__aeabi_uidivmod) ++ ++ENTRY(__aeabi_idivmod) ++UNWIND(.fnstart) ++UNWIND(.save {r0, r1, ip, lr} ) ++ stmfd sp!, {r0, r1, ip, lr} ++ bl __aeabi_idiv ++ ldmfd sp!, {r1, r2, ip, lr} ++ mul r3, r0, r2 ++ sub r1, r1, r3 ++ ret lr ++ ++UNWIND(.fnend) ++ENDPROC(__aeabi_idivmod) ++ ++#endif ++ ++Ldiv0: ++UNWIND(.fnstart) ++UNWIND(.pad #4) ++UNWIND(.save {lr}) ++ str lr, [sp, #-8]! ++ bl __div0 ++ mov r0, #0 @ About as wrong as it could be. ++ ldr pc, [sp], #8 ++UNWIND(.fnend) ++ENDPROC(Ldiv0) +Binary files a/arch/arm/boot/compressed/piggy_data and b/arch/arm/boot/compressed/piggy_data differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile +--- a/arch/arm/boot/dts/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/arch/arm/boot/dts/Makefile 2018-05-10 11:31:28.285398226 +0800 +@@ -1069,6 +1069,24 @@ dtb-$(CONFIG_ARCH_ZX) += zx296702-ad1.dt + dtb-$(CONFIG_ARCH_ASPEED) += aspeed-bmc-opp-palmetto.dtb \ + aspeed-bmc-opp-romulus.dtb \ + aspeed-ast2500-evb.dtb ++dtb-$(CONFIG_MACH_HX4) += bcm956340.dtb ++dtb-$(CONFIG_MACH_KT2) += bcm956450.dtb ++dtb-$(CONFIG_MACH_GH) += bcm95341x.dtb ++dtb-$(CONFIG_MACH_GH2) += bcm956170.dtb ++dtb-$(CONFIG_MACH_SB2) += bcm956260.dtb ++dtb-$(CONFIG_MACH_HR3) += \ ++ bcm956160.dtb \ ++ bcm953444.dtb ++dtb-$(CONFIG_MACH_WH2) += bcm953547.dtb ++dtb-$(CONFIG_XGS_IPROC_ARM32_PLATFORM) += \ ++ bcm956340.dtb \ ++ bcm956450.dtb \ ++ bcm95341x.dtb \ ++ bcm956260.dtb \ ++ bcm956160.dtb \ ++ bcm953444.dtb \ ++ bcm956170.dtb \ ++ bcm953547.dtb + endif + + dtstree := $(srctree)/$(src) +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-greyhound.dtsi b/arch/arm/boot/dts/bcm-greyhound.dtsi +--- a/arch/arm/boot/dts/bcm-greyhound.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-greyhound.dtsi 2018-05-10 11:31:28.309398252 +0800 +@@ -0,0 +1,408 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom GH iProc"; ++ compatible = "brcm,greyhound"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ /*clocks = <&osc_50M>;*/ /* 50MHZ crystal/oscillator */ ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ /* 50MHZ crystal/oscillator clock source */ ++ /* ++ osc_50M: oscillator_50M { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <50000000>; ++ }; ++ */ ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@0x1800fc00 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk"; ++ clocks = <&osc>; ++ reg = <0x1800fc00 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18020000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18020000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18021000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18021000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18042000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x18042000 0x1000>, ++ <0x18110000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@1800a000 { ++ compatible = "brcm,iproc-gpio-ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x1800a000 0x50>; ++ ngpios = <12>; ++ pin-reg-bit-shift = <4>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy-gh"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18111000 0x1000>; ++ vbus-gpio = <&gpio_ccg 6 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@18048000 { ++ compatible = "generic-ehci"; ++ reg = <0x18048000 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ ohci0: usb@18048800 { ++ compatible = "generic-ohci"; ++ reg = <0x18048800 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ /* Over Current Protect Mode fix */ ++ iproc-ocpm-fix; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@1804c000 { ++ compatible = "brcm,usbd-xgs-iproc"; ++ reg = <0x1804c000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18046000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18046000 0x600>, ++ <0xf8105408 0x10>, ++ <0x18046f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,spi-bcm-qspi", "brcm,spi-xgs-iproc-qspi"; ++ reg = <0x18047200 0x188>, ++ <0x18047000 0x124>, ++ <0xf8106408 0x004>, ++ <0x180473a0 0x01c>, ++ <0x1800e000 0x004>; ++ reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg", "cru_ctrl"; ++ interrupts = ; ++ num-cs = <2>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18008000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18008000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_ext: mdio_ext@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <2>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ pnor_flash: pnor_flash@18045000 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "brcm,iproc-nor"; ++ reg = nor_regs: <0x18045000 0x1000>, ++ nor_mem: <0xE8000000 0x8000000>, ++ nor_strap: <0x18000a5c 0x4>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18032000 { ++ compatible = "brcm,iproc-rng200"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18032000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18009000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18009000 0x1000>, ++ iproc_reset_reg: <0x1800f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18040000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = pl330_base: <0x18040000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@03200000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x03200000 0x100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x20000000, ++ * cpu addr 0x20000000, size 0x0 0x20000000 ++ */ ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; ++ wa-list = "pcie_rc", "pcie_perst"; ++ status = "disabled"; ++ ++ msi-parent = <&msi0>; ++ msi0: msi@18012000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ }; ++ }; ++ ++ dmu_pcu: dmu_pcu@1800f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0x1800f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0x1800fc00 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ reg = idm0: <0x18100000 0x100000>, ++ idm1: <0xf8100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-greyhound2.dtsi b/arch/arm/boot/dts/bcm-greyhound2.dtsi +--- a/arch/arm/boot/dts/bcm-greyhound2.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-greyhound2.dtsi 2018-05-10 11:31:28.309398252 +0800 +@@ -0,0 +1,429 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom GH2 iProc"; ++ compatible = "brcm,greyhound2"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@0x1800fc00 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk"; ++ clocks = <&osc>; ++ reg = <0x1800fc00 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18020000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18020000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18021000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18021000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18042000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x18042000 0x1000>, ++ <0x18110000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac1: ethernet@1804a000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x1804a000 0x1000>, ++ <0x1811f000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@1800a000 { ++ compatible = "brcm,iproc-gpio-ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x1800a000 0x50>; ++ ngpios = <12>; ++ pin-reg-bit-shift = <4>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy-gh2"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18111000 0x1000>, ++ idm_utmih: <0x18049500 0x100>; ++ vbus-gpio = <&gpio_ccg 6 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@18048000 { ++ compatible = "generic-ehci"; ++ reg = <0x18048000 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ ohci0: usb@18048800 { ++ compatible = "generic-ohci"; ++ reg = <0x18048800 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ /* Over Current Protect Mode fix */ ++ iproc-ocpm-fix; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@1804c000 { ++ compatible = "brcm,usbd-xgs-iproc"; ++ reg = <0x1804c000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18046000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18046000 0x600>, ++ <0xf8105408 0x10>, ++ <0x18046f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,spi-bcm-qspi", "brcm,spi-xgs-iproc-qspi"; ++ reg = <0x18047200 0x188>, ++ <0x18047000 0x124>, ++ <0xf8106408 0x004>, ++ <0x180473a0 0x01c>, ++ <0x1800e000 0x004>; ++ reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg", "cru_ctrl"; ++ interrupts = ; ++ num-cs = <2>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18008000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18008000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ ccg_mdio_int: ccg_mdio_int@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_int: mdio_int@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_ext: mdio_ext@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <2>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ pnor_flash: pnor_flash@18045000 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "brcm,iproc-nor"; ++ reg = nor_regs: <0x18045000 0x1000>, ++ nor_mem: <0xE8000000 0x8000000>, ++ nor_strap: <0x18000a5c 0x4>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18032000 { ++ compatible = "brcm,iproc-rng200"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18032000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18009000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18009000 0x1000>, ++ iproc_reset_reg: <0x1800f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18018000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = pl330_base: <0x18018000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ crypto: crypto@03100000 { ++ compatible = "brcm,iproc-crypto"; ++ reg = axi: <0x03100000 0x100>, /* SPUM AXI registers */ ++ apb: <0x18037000 0x100>, /* SPUM control registers */ ++ idm: <0x1811a000 0x1000>; /* Crypto control registers */ ++ brcm,max-pkt-size = <65536>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@03200000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x03200000 0x100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x20000000, ++ * cpu addr 0x20000000, size 0x0 0x20000000 ++ */ ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; ++ wa-list = "pcie_rc", "pcie_perst"; ++ status = "disabled"; ++ ++ msi-parent = <&msi0>; ++ msi0: msi@18012000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ }; ++ }; ++ ++ dmu_pcu: dmu_pcu@1800f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0x1800f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0x1800fc00 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ reg = idm0: <0x18100000 0x100000>, ++ idm1: <0xf8100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-helix4.dtsi b/arch/arm/boot/dts/bcm-helix4.dtsi +--- a/arch/arm/boot/dts/bcm-helix4.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-helix4.dtsi 2018-05-10 11:31:28.309398252 +0800 +@@ -0,0 +1,483 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom HX4 iProc"; ++ compatible = "brcm,helix4"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ ++ cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ enable-method = "brcm,bcm-nsp-smp"; ++ secondary-boot-reg = <0xffff042c>; ++ reg = <0x1>; ++ }; ++ }; ++ ++ mpcore { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ /*arm,parity-enable; ++ interrupts = ;*/ ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@0x1803fc00 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk", "axi-clk-hx4"; ++ clocks = <&osc>; ++ reg = <0x1803fc00 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18000300 { ++ compatible = "ns16550a"; ++ reg = <0x18000300 0x100>; ++ interrupts = ; ++ clock-frequency = <62500000>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18000400 { ++ compatible = "ns16550a"; ++ reg = <0x18000400 0x100>; ++ interrupts = ; ++ clock-frequency = <62500000>; ++ status = "disabled"; ++ }; ++ ++ uart2: serial@18037000 { ++ compatible = "ns16550a"; ++ reg = <0x18037000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_cca: gpio@18000060 { ++ compatible = "brcm,iproc-gpio-cca"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x18000060 0x50>, ++ intr: <0x18000000 0x50>; ++ ngpios = <8>; ++ pin-reg-bit-shift = <0>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18022000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x18022000 0x1000>, ++ <0x18110000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac1: ethernet@18023000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x18023000 0x1000>, ++ <0x18111000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18026000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18026000 0x600>, ++ <0x1811b408 0x10>, ++ <0x18026f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ }; ++ ++ qspi: spi@18027000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,spi-bcm-qspi", "brcm,spi-xgs-iproc-qspi"; ++ reg = <0x18027200 0x188>, ++ <0x18027000 0x124>, ++ <0x1811c408 0x004>, ++ <0x180273a0 0x01c>, ++ <0x1803e000 0x004>; ++ reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg", "cru_ctrl"; ++ interrupts = ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ interrupt-names = ++ "spi_lr_fullness_reached", ++ "spi_lr_session_aborted", ++ "spi_lr_impatient", ++ "spi_lr_session_done", ++ "spi_lr_overread", ++ "mspi_done", ++ "mspi_halted"; ++ num-cs = <2>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy-hx4"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18116000 0x1000>; ++ vbus-gpio = <&gpio_cca 1 GPIO_ACTIVE_LOW>; ++ usbdev-gpio = <&gpio_cca 0 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@1802a000 { ++ compatible = "generic-ehci"; ++ reg = <0x1802a000 0x1000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@18042000 { ++ compatible = "brcm,usbd-xgs-hx4"; ++ reg = <0x18042000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18038000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18038000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@1803b000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x1803b000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@18032000 { ++ compatible = "brcm,iproc-ccb-mdio"; ++ reg = <0x18032000 0x1000>, ++ <0x1803fc3c 0x4>; ++ reg-names = "mdio-base", "iproc-mdio-enable"; ++ iproc-mdio-sel-bit = <4>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ mdio_ext: mdio_ext@18032000 { ++ compatible = "brcm,iproc-ccb-mdio"; ++ reg = <0x18032000 0x1000>, ++ <0x1803fc3c 0x4>; ++ reg-names = "mdio-base", "iproc-mdio-enable"; ++ iproc-mdio-sel-bit = <4>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18033000 { ++ compatible = "brcm,iproc-rng100"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18033000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@0x18039000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18039000 0x1000>, ++ iproc_reset_reg: <0x1803f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18020000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = pl330_base: <0x18020000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ /*arm,primecell-periphid = <0x00041330>;*/ ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@48000000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x48000000 0x40000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x08000000, ++ * cpu addr 0x08000000, size 0x0 0x08000000 ++ */ ++ ranges = <0x82000000 0 0x08000000 0x08000000 0 0x08000000>; ++ wa-list = "pcie_wrong_gen2"; ++ status = "disabled"; ++ ++ msi-parent = <&msi0>; ++ msi0: msi@18012000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ brcm,pcie-msi-inten; ++ }; ++ }; ++ ++ pcie1: pcie@18013000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18013000 0x1000>; ++ linux,pci-domain = <1>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x40000000, ++ * cpu addr 0x40000000, size 0x0 0x08000000 ++ */ ++ ranges = <0x82000000 0 0x40000000 0x40000000 0 0x08000000>; ++ wa-list = "pcie_wrong_gen2"; ++ status = "disabled"; ++ ++ msi-parent = <&msi1>; ++ msi1: msi@18013000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ brcm,pcie-msi-inten; ++ }; ++ }; ++ ++ dmu_pcu: dmu_pcu@1803f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x1803f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1803fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x1803fc00 0x100>; ++ /* offset to 0x1803fc00, ctrl bit, mdio bit */ ++ amac-serdes-mdio-ctrl-sel = <0x3c>, <0x2>, <0x3>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-hurricane3.dtsi b/arch/arm/boot/dts/bcm-hurricane3.dtsi +--- a/arch/arm/boot/dts/bcm-hurricane3.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-hurricane3.dtsi 2018-05-10 11:31:28.309398252 +0800 +@@ -0,0 +1,416 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom HR3 iProc"; ++ compatible = "brcm,hurricane3"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ /*clocks = <&osc_50M>;*/ /* 50MHZ crystal/oscillator */ ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ /* 50MHZ crystal/oscillator clock source */ ++ /* ++ osc_50M: oscillator_50M { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <50000000>; ++ }; ++ */ ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@1800fc00 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk"; ++ clocks = <&osc>; ++ reg = <0x1800fc00 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18020000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18020000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18021000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18021000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18042000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x18042000 0x1000>, ++ <0x18110000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@1800a000 { ++ compatible = "brcm,iproc-gpio-ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x1800a000 0x50>; ++ ngpios = <12>; ++ pin-reg-bit-shift = <4>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy@1800fc40 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy-gh"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18111000 0x1000>; ++ vbus-gpio = <&gpio_ccg 3 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@18048000 { ++ compatible = "generic-ehci"; ++ reg = <0x18048000 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ ohci0: usb@18048800 { ++ compatible = "generic-ohci"; ++ reg = <0x18048800 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ /* Over Current Protect Mode fix */ ++ iproc-ocpm-fix; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@1804c000 { ++ compatible = "brcm,usbd-xgs-iproc"; ++ reg = <0x1804c000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ sdio: sdio@18041000 { ++ compatible = "brcm,iproc-hr3-sdio"; ++ reg = <0x18041000 0x1000>, ++ <0x18116408 0x1000>; ++ reg-names = "sdio", "iproc-idm"; ++ interrupts = ; ++ bus-width = <8>; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18046000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18046000 0x600>, ++ <0x1811d408 0x10>, ++ <0x18046f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,spi-bcm-qspi", "brcm,spi-xgs-iproc-qspi"; ++ reg = <0x18047200 0x188>, ++ <0x18047000 0x124>, ++ <0x1811f408 0x004>, ++ <0x180473a0 0x01c>, ++ <0x1800e000 0x004>; ++ reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg", "cru_ctrl"; ++ interrupts = ; ++ num-cs = <2>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18008000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18008000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_ext: mdio_ext { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <2>; ++ bus-type = "external"; ++ /* Currently clocks is not used by driver */ ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ pnor_flash: pnor_flash@18045000 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "brcm,iproc-nor"; ++ reg = nor_regs: <0x18045000 0x1000>, ++ nor_mem: <0xE8000000 0x8000000>, ++ nor_strap: <0x18000a5c 0x4>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18032000 { ++ compatible = "brcm,iproc-rng200"; ++ reg = <0x18032000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18009000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18009000 0x1000>, ++ iproc_reset_reg: <0x1800f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18018000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = pl330_base: <0x18018000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ /*arm,primecell-periphid = <0x00041330>;*/ ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@03200000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x03200000 0x100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x20000000, ++ * cpu addr 0x20000000, size 0x0 0x20000000 ++ */ ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; ++ wa-list = "pcie_rc", "pcie_perst"; ++ status = "disabled"; ++ ++ msi-parent = <&msi0>; ++ msi0: msi@18012000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ }; ++ }; ++ ++ dmu_pcu: dmu_pcu@1800f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0x1800f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0x1800fc00 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ reg = <0x18100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-katana2.dtsi b/arch/arm/boot/dts/bcm-katana2.dtsi +--- a/arch/arm/boot/dts/bcm-katana2.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-katana2.dtsi 2018-05-10 11:31:28.309398252 +0800 +@@ -0,0 +1,480 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom KT2 iProc"; ++ compatible = "brcm,katana2"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu0: cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ ++ cpu1: cpu@1 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ enable-method = "brcm,bcm-nsp-smp"; ++ secondary-boot-reg = <0xffff042c>; ++ reg = <0x1>; ++ }; ++ }; ++ ++ mpcore { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: axi_clk_fixed_495M { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <495000000>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18000300 { ++ compatible = "ns16550a"; ++ reg = <0x18000300 0x100>; ++ interrupts = ; ++ clock-frequency = <61875000>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18000400 { ++ compatible = "ns16550a"; ++ reg = <0x18000400 0x100>; ++ interrupts = ; ++ clock-frequency = <61875000>; ++ status = "disabled"; ++ }; ++ ++ uart2: serial@18037000 { ++ compatible = "ns16550a"; ++ reg = <0x18037000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gpio_cca: gpio@18000060 { ++ compatible = "brcm,iproc-gpio-cca"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x18000060 0x50>, ++ intr: <0x18000000 0x50>; ++ ngpios = <8>; ++ pin-reg-bit-shift = <0>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18022000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x18022000 0x1000>, ++ <0x18110000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gmac1: ethernet@18023000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x18023000 0x1000>, ++ <0x18111000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18026000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18026000 0x600>, ++ <0x1811b408 0x10>, ++ <0x18026f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ }; ++ ++ qspi: spi@18027000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,spi-bcm-qspi", "brcm,spi-xgs-iproc-qspi"; ++ reg = <0x18027200 0x188>, ++ <0x18027000 0x124>, ++ <0x1811c408 0x004>, ++ <0x180273a0 0x01c>, ++ <0x1803e000 0x004>; ++ reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg", "cru_ctrl"; ++ interrupts = ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ interrupt-names = ++ "spi_lr_fullness_reached", ++ "spi_lr_session_aborted", ++ "spi_lr_impatient", ++ "spi_lr_session_done", ++ "spi_lr_overread", ++ "mspi_done", ++ "mspi_halted"; ++ num-cs = <2>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy-kt2"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18116000 0x1000>; ++ vbus-gpio = <&gpio_cca 1 GPIO_ACTIVE_LOW>; ++ usbdev-gpio = <&gpio_cca 0 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@1802a000 { ++ compatible = "generic-ehci"; ++ reg = <0x1802a000 0x1000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@18042000 { ++ compatible = "brcm,usbd-xgs-hx4"; ++ reg = <0x18042000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@0x18038000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18038000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@1803b000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x1803b000 0x100>; ++ interrupts = ; ++ #bus-id = <1>; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@18032000 { ++ compatible = "brcm,iproc-ccb-mdio"; ++ reg = <0x18032000 0x1000>, ++ <0x1803fc24 0x4>; ++ reg-names = "mdio-base", "iproc-mdio-enable"; ++ iproc-mdio-sel-bit = <3>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ mdio_ext: mdio_ext@18032000 { ++ compatible = "brcm,iproc-ccb-mdio"; ++ reg = <0x18032000 0x1000>, ++ <0x1803fc24 0x4>; ++ reg-names = "mdio-base", "iproc-mdio-enable"; ++ iproc-mdio-sel-bit = <3>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18033000 { ++ compatible = "brcm,iproc-rng100"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18033000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18039000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18039000 0x1000>, ++ iproc_reset_reg: <0x1803f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18020000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = pl330_base: <0x18020000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ /*arm,primecell-periphid = <0x00041330>;*/ ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@48000000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x48000000 0x40000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 186 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x08000000, ++ * cpu addr 0x08000000, size 0x0 0x08000000 ++ */ ++ ranges = <0x82000000 0 0x08000000 0x08000000 0 0x08000000>; ++ wa-list = "pcie_wrong_gen2"; ++ status = "disabled"; ++ ++ msi-parent = <&msi0>; ++ msi0: msi@18012000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ brcm,pcie-msi-inten; ++ }; ++ }; ++ ++ pcie1: pcie@18013000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18013000 0x1000>; ++ linux,pci-domain = <1>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x40000000, ++ * cpu addr 0x40000000, size 0x0 0x08000000 ++ */ ++ ranges = <0x82000000 0 0x40000000 0x40000000 0 0x08000000>; ++ wa-list = "pcie_wrong_gen2"; ++ status = "disabled"; ++ ++ msi-parent = <&msi1>; ++ msi1: msi@18013000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ brcm,pcie-msi-inten; ++ }; ++ }; ++ ++ dmu_pcu: dmu_pcu@1803f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x1803f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1803fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x1803fc00 0x100>; ++ /* offset to 0x1803fc00, ctrl bit, mdio bit */ ++ amac-serdes-mdio-ctrl-sel = <0x24>, <0x1>, <0x2>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-saber2.dtsi b/arch/arm/boot/dts/bcm-saber2.dtsi +--- a/arch/arm/boot/dts/bcm-saber2.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-saber2.dtsi 2018-05-10 11:31:28.309398252 +0800 +@@ -0,0 +1,396 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++/ { ++ model = "Broadcom SB2 iProc"; ++ compatible = "brcm,saber2"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator_25M { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ osc_1: oscillator_50M { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <50000000>; ++ }; ++ ++ periph_clk: periph_clk@19000000 { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@1800fc50 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk", "axi-clk-sb2"; ++ clocks = <&osc_1>; ++ reg = <0x1800fc50 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18020000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18020000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18021000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18021000 0x1000>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,spi-bcm-qspi", "brcm,spi-xgs-iproc-qspi"; ++ reg = <0x18047200 0x188>, ++ <0x18047000 0x124>, ++ <0xf8106408 0x004>, ++ <0x180473a0 0x01c>, ++ <0x1800e000 0x004>; ++ reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg", "cru_ctrl"; ++ interrupts = ; ++ num-cs = <2>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18042000 { ++ compatible = "brcm,xgs-iproc-amac"; ++ reg = <0x18042000 0x1000>, ++ <0x18110000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy0 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy-sb2"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18111000 0x1000>; ++ vbus-gpio = <&gpio_ccg 1 GPIO_ACTIVE_LOW>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@18048000 { ++ compatible = "generic-ehci"; ++ reg = <0x18048000 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ ohci0: usb@18048800 { ++ compatible = "generic-ohci"; ++ reg = <0x18048800 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@1804c000 { ++ compatible = "brcm,usbd-xgs-iproc"; ++ reg = usb2d: <0x1804c000 0x2000>, ++ idm_usb: <0x18111000 0x1000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@1800a000 { ++ compatible = "brcm,iproc-gpio-ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x1800a000 0x50>; ++ ngpios = <16>; ++ pin-reg-bit-shift = <0>; ++ pin-base = <0>; ++ gpio-controller; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18046000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x18046000 0x600>, ++ <0xf8105408 0x10>, ++ <0x18046f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18008000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18008000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>, ++ <0x1800fc40 0x4>; ++ reg-names = "mdio-base", "ipoc-mdio-enable"; ++ iproc-mdio-sel-bit = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ mdio_ext: mdio_ext@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>, ++ <0x1800fc40 0x4>; ++ reg-names = "mdio-base", "iproc-mdio-enable"; ++ iproc-mdio-sel-bit = <1>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "external"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18032000 { ++ compatible = "brcm,iproc-rng200"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x18032000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18009000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18009000 0x1000>, ++ iproc_reset_reg: <0x1800f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18018000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = pl330_base: <0x18018000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@03200000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x03200000 0x100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x20000000, ++ * cpu addr 0x20000000, size 0x0 0x20000000 ++ */ ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; ++ wa-list = "pcie_rc"; ++ status = "disabled"; ++ ++ msi-parent = <&msi0>; ++ msi0: msi@18012000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ }; ++ }; ++ ++ dmu_pcu: dmu_pcu@1800f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0x1800f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0x1800fc00 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ reg = idm0: <0x18100000 0x100000>, ++ idm1: <0xf8100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm-wolfhound2.dtsi b/arch/arm/boot/dts/bcm-wolfhound2.dtsi +--- a/arch/arm/boot/dts/bcm-wolfhound2.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm-wolfhound2.dtsi 2018-05-10 11:31:28.309398252 +0800 +@@ -0,0 +1,385 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++#include "skeleton.dtsi" ++ ++ ++/ { ++ model = "Broadcom HR3 iProc"; ++ compatible = "brcm,hurricane3"; ++ interrupt-parent = <&gic>; ++ ++ cpus { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a9"; ++ next-level-cache = <&L2>; ++ reg = <0x0>; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ ranges = <0x00000000 0x19000000 0x00023000>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ a9pll: arm_clk@00000 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-armpll"; ++ clocks = <&osc>; ++ reg = <0x0 0x1000>; ++ }; ++ ++ gic: interrupt-controller@21000 { ++ compatible = "arm,cortex-a9-gic"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x21000 0x1000>, <0x20100 0x100>; ++ }; ++ ++ twd-timer@20600 { ++ compatible = "arm,cortex-a9-twd-timer"; ++ reg = <0x20600 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ timer@20200 { ++ compatible = "arm,cortex-a9-global-timer"; ++ reg = <0x20200 0x100>; ++ interrupts = ; ++ clocks = <&periph_clk>; ++ }; ++ ++ L2: l2-cache { ++ compatible = "arm,pl310-cache"; ++ reg = <0x22000 0x1000>; ++ cache-unified; ++ cache-level = <2>; ++ arm,filter-ranges = <0x60000000 0x80000000>; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ osc: oscillator { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <25000000>; ++ }; ++ ++ periph_clk: periph_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&a9pll>; ++ clock-div = <2>; ++ clock-mult = <1>; ++ }; ++ ++ iproc_axi_clk: iproc_axi_clk@1800fc00 { ++ #clock-cells = <0>; ++ compatible = "brcm,xgs-iproc-axi-clk"; ++ clocks = <&osc>; ++ reg = <0x1800fc00 0x1c>; ++ }; ++ ++ iproc_apb_clk: iproc_apb_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&iproc_axi_clk>; ++ clock-div = <4>; ++ clock-mult = <1>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@18020000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18020000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@18021000 { ++ compatible = "snps,dw-apb-uart"; ++ reg = <0x18021000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_apb_clk>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@18042000 { ++ compatible = "brcm,xgs-wh2-amac"; ++ reg = <0x18042000 0x1000>, ++ <0x18110000 0x1000>; ++ reg-names = "amac_base", "idm_base"; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@1800a000 { ++ compatible = "brcm,iproc-gpio-ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x1800a000 0x50>; ++ ngpios = <12>; ++ pin-reg-bit-shift = <4>; ++ pin-base = <4>; ++ gpio-controller; ++ interrupt-controller; ++ #interrupt-cells = <2>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ usbphy0: usbphy@1800fc40 { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy-gh"; ++ reg = idm_usb2h: <0x18115000 0x1000>, ++ idm_usb2d: <0x18111000 0x1000>; ++ vbus-gpio = <&gpio_ccg 3 GPIO_ACTIVE_HIGH>; ++ status = "disabled"; ++ }; ++ ++ ehci0: usb@18048000 { ++ compatible = "generic-ehci"; ++ reg = <0x18048000 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ ohci0: usb@18048800 { ++ compatible = "generic-ohci"; ++ reg = <0x18048800 0x800>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ /* Over Current Protect Mode fix */ ++ iproc-ocpm-fix; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@1804c000 { ++ compatible = "brcm,usbd-xgs-iproc"; ++ reg = <0x1804c000 0x2000>; ++ interrupts = ; ++ usb-phy = <&usbphy0>; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,spi-bcm-qspi", "brcm,spi-xgs-iproc-qspi"; ++ reg = <0x18047200 0x188>, ++ <0x18047000 0x124>, ++ <0x1811f408 0x004>, ++ <0x180473a0 0x01c>, ++ <0x1800e000 0x004>; ++ reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg", "cru_ctrl"; ++ interrupts = ; ++ num-cs = <2>; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@18008000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x18008000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_int0: mdio_int0@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd cmic_common mdio */ ++ mdio_int1: mdio_int1@03210000 { ++ compatible = "brcm,iproc-cmicd-mdio"; ++ reg = <0x03210000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <1>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ /* CCG mdio */ ++ mdio_int2: mdio_int2@18002000 { ++ compatible = "brcm,iproc-ccg-mdio"; ++ reg = <0x18002000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ bus-type = "internal"; ++ clocks = <&iproc_apb_clk>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@18032000 { ++ compatible = "brcm,iproc-rng200"; ++ reg = <0x18032000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@18009000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x18009000 0x1000>, ++ iproc_reset_reg: <0x1800f014 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@18018000 { ++ compatible = "arm,pl330", "arm,primecell"; ++ reg = pl330_base: <0x18018000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ /*arm,primecell-periphid = <0x00041330>;*/ ++ clocks = <&iproc_apb_clk>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ /* cmicd */ ++ iproc_cmicd: iproc_cmicd@03200000 { ++ compatible = "brcm,iproc-cmicd"; ++ reg = <0x03200000 0x100000>; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ }; ++ ++ pcie0: pcie@18012000 { ++ compatible = "brcm,iproc-pcie"; ++ reg = <0x18012000 0x1000>; ++ linux,pci-domain = <0>; ++ ++ #interrupt-cells = <1>; ++ interrupt-map-mask = <0 0 0 0>; ++ interrupt-map = <0 0 0 0 &gic GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; ++ ++ #address-cells = <3>; ++ #size-cells = <2>; ++ device_type = "pci"; ++ ++ /* ++ * non-prefetchable mem space, pcie addr 0x0 0x20000000, ++ * cpu addr 0x20000000, size 0x0 0x20000000 ++ */ ++ ranges = <0x82000000 0 0x20000000 0x20000000 0 0x20000000>; ++ wa-list = "pcie_rc", "pcie_perst"; ++ status = "disabled"; ++ ++ msi-parent = <&msi0>; ++ msi0: msi@18012000 { ++ compatible = "brcm,iproc-msi"; ++ msi-controller; ++ interrupt-parent = <&gic>; ++ interrupts = , ++ , ++ , ++ ; ++ }; ++ }; ++ ++ dmu_pcu: dmu_pcu@1800f000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0x1800f000 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@1800fc00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0x1800fc00 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@18100000 { ++ compatible = "brcm,iproc-idm"; ++ reg = <0x18100000 0x100000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ }; ++}; +Binary files a/arch/arm/boot/dts/bcm95341x.dtb and b/arch/arm/boot/dts/bcm95341x.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm95341x.dts b/arch/arm/boot/dts/bcm95341x.dts +--- a/arch/arm/boot/dts/bcm95341x.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm95341x.dts 2018-05-10 11:31:28.313398255 +0800 +@@ -0,0 +1,220 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-greyhound.dtsi" ++ ++/ { ++ model = "Broadcom GH SVK (BCM95341x)"; ++ compatible = "brcm,bcm95341x", "brcm,greyhound"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&amac_phy0>; ++ phy-mode = "gmii"; /* "gmii-id", "gmii-rxid" */ ++}; ++ ++&usbphy0 { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy0>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x30000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&pnor_flash { ++ status = "okay"; ++ ++ partition@0 { ++ label = "pboot"; ++ reg = <0x0 0xc0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "penv"; ++ reg = <0xc0000 0x40000>; ++ }; ++ partition@2 { ++ label = "psystem"; ++ reg = <0x100000 0xf00000>; ++ }; ++ partition@3 { ++ label = "prootfs"; ++ reg = <0x1000000 0x1000000>; ++ }; ++ partition@4 { ++ label = "pcustfs"; ++ reg = <0x2000000 0x2000000>; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++ pcie_phy0: pcie_phy@0 { ++ reg = <2>; ++ }; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <24>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; +Binary files a/arch/arm/boot/dts/bcm953444.dtb and b/arch/arm/boot/dts/bcm953444.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm953444.dts b/arch/arm/boot/dts/bcm953444.dts +--- a/arch/arm/boot/dts/bcm953444.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm953444.dts 2018-05-10 11:31:28.313398255 +0800 +@@ -0,0 +1,135 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-hurricane3.dtsi" ++ ++/ { ++ model = "Broadcom HR3 SVK (BCM953444K)"; ++ compatible = "brcm,bcm953444k", "brcm,hurricane3"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&amac_phy0>; ++ phy-mode = "gmii"; /* "gmii-id", "gmii-rxid" */ ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy0>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++ pcie_phy0: pcie_phy@0 { ++ reg = <2>; ++ }; ++}; ++ ++&mdio_ext { ++ #bus-id = <1>; ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <24>; ++ }; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; ++ +Binary files a/arch/arm/boot/dts/bcm953547.dtb and b/arch/arm/boot/dts/bcm953547.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm953547.dts b/arch/arm/boot/dts/bcm953547.dts +--- a/arch/arm/boot/dts/bcm953547.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm953547.dts 2018-05-10 11:31:28.313398255 +0800 +@@ -0,0 +1,167 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-wolfhound2.dtsi" ++ ++/ { ++ model = "Broadcom WH2 SVK (BCM953547K)"; ++ compatible = "brcm,bcm953547k", "brcm,wolfhound2"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&amac_phy0>; ++ phy-mode = "gmii"; /* "gmii-id", "gmii-rxid" */ ++ serdes-phy-handle = <&amac_serdes0>; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy0>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&mdio_int0 { ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <24>; ++ }; ++}; ++ ++&mdio_int1 { ++ status = "okay"; ++ amac_serdes0: amac_serdes@0 { ++ reg = <20>; ++ lane-num = <3>; ++ }; ++}; ++ ++&mdio_int2 { ++ status = "okay"; ++ pcie_phy0: pcie_phy@0 { ++ reg = <2>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; ++ +Binary files a/arch/arm/boot/dts/bcm956160.dtb and b/arch/arm/boot/dts/bcm956160.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956160.dts b/arch/arm/boot/dts/bcm956160.dts +--- a/arch/arm/boot/dts/bcm956160.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm956160.dts 2018-05-10 11:31:28.313398255 +0800 +@@ -0,0 +1,225 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-hurricane3.dtsi" ++ ++/ { ++ model = "Broadcom HR3 SVK (BCM956160K)"; ++ compatible = "brcm,bcm956160k", "brcm,hurricane3"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&amac_phy0>; ++ phy-mode = "gmii"; /* "gmii-id", "gmii-rxid" */ ++}; ++ ++&usbphy0 { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&sdio { ++ status = "okay"; ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy0>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x30000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&pnor_flash { ++ status = "okay"; ++ ++ partition@0 { ++ label = "pboot"; ++ reg = <0x0 0xc0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "penv"; ++ reg = <0xc0000 0x40000>; ++ }; ++ partition@2 { ++ label = "psystem"; ++ reg = <0x100000 0xf00000>; ++ }; ++ partition@3 { ++ label = "prootfs"; ++ reg = <0x1000000 0x1000000>; ++ }; ++ partition@4 { ++ label = "pcustfs"; ++ reg = <0x2000000 0x2000000>; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++ pcie_phy0: pcie_phy@0 { ++ reg = <2>; ++ }; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <24>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; ++ +Binary files a/arch/arm/boot/dts/bcm956170.dtb and b/arch/arm/boot/dts/bcm956170.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956170.dts b/arch/arm/boot/dts/bcm956170.dts +--- a/arch/arm/boot/dts/bcm956170.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm956170.dts 2018-05-10 17:50:42.895946853 +0800 +@@ -0,0 +1,248 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-greyhound2.dtsi" ++ ++/ { ++ model = "Broadcom GH2 SVK (BCM956170)"; ++ compatible = "brcm,bcm956170", "brcm,greyhound2"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&amac_phy0>; ++ phy-mode = "sgmii"; ++ serdes-handle = <&amac_serdes0>; ++}; ++ ++&gmac1 { ++ status = "okay"; ++ phy-handle = <&amac_phy1>; ++ phy-mode = "sgmii"; ++ serdes-handle = <&amac_serdes1>; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy0>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x30000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&pnor_flash { ++ status = "okay"; ++ ++ partition@0 { ++ label = "pboot"; ++ reg = <0x0 0xc0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "penv"; ++ reg = <0xc0000 0x40000>; ++ }; ++ partition@2 { ++ label = "psystem"; ++ reg = <0x100000 0xf00000>; ++ }; ++ partition@3 { ++ label = "prootfs"; ++ reg = <0x1000000 0x1000000>; ++ }; ++ partition@4 { ++ label = "pcustfs"; ++ reg = <0x2000000 0x2000000>; ++ }; ++}; ++ ++&ccg_mdio_int { ++ status = "okay"; ++ pcie_phy0: pcie_phy@0 { ++ reg = <2>; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++ amac_serdes0: amac_serdes@0 { ++ reg = <25>; ++ lane-num = <0>; ++ }; ++ amac_serdes1: amac_serdes@1 { ++ reg = <26>; ++ lane-num = <1>; ++ }; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <16>; ++ }; ++ amac_phy1: amac_phy@1 { ++ reg = <17>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&crypto { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; +Binary files a/arch/arm/boot/dts/bcm956260.dtb and b/arch/arm/boot/dts/bcm956260.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956260.dts b/arch/arm/boot/dts/bcm956260.dts +--- a/arch/arm/boot/dts/bcm956260.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm956260.dts 2018-05-10 11:31:28.317398259 +0800 +@@ -0,0 +1,203 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-saber2.dtsi" ++ ++/ { ++ model = "Broadcom SB2 SVK (BCM956260K)"; ++ compatible = "brcm,bcm956260k", "brcm,saber2"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&amac_phy0>; ++ phy-mode = "sgmii"; ++ serdes-handle = <&amac_serdes0>; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++ mdio-phy-handle = <&usb_phy>; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&ohci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy0>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c64"; ++ reg = <0x50>; ++ pagesize = <32>; ++ }; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x70000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x01000000>; ++ }; ++ }; ++}; ++ ++ ++&mdio_int { ++ status = "okay"; ++ amac_serdes0: amac_serdes@0 { ++ reg = <1>; ++ }; ++ pcie_phy0: pcie_phy@0 { ++ reg = <2>; ++ }; ++ usb_phy: usb_phy@0 { ++ reg = <3>; ++ }; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <1>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; +Binary files a/arch/arm/boot/dts/bcm956340.dtb and b/arch/arm/boot/dts/bcm956340.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956340.dts b/arch/arm/boot/dts/bcm956340.dts +--- a/arch/arm/boot/dts/bcm956340.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm956340.dts 2018-05-10 11:31:28.317398259 +0800 +@@ -0,0 +1,230 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-helix4.dtsi" ++ ++/ { ++ model = "Broadcom HX4 SVK (BCM956340K)"; ++ compatible = "brcm,bcm956340k", "brcm,helix4"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ sdk-serdes-lane2 = &amac_serdes2; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=2 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&amac_phy0>; ++ phy-mode = "sgmii"; /* "gmii-id", "gmii-rxid", "sgmii" */ ++ serdes-handle = <&amac_serdes0>; ++}; ++ ++&gmac1 { ++ status = "okay"; ++ phy-handle = <&amac_phy1>; ++ phy-mode = "sgmii"; /* "gmii-id", "gmii-rxid", "sgmii" */ ++ serdes-handle = <&amac_serdes1>; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++ mdio-phy-handle = <&usb_phy>; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_cca { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy0>; ++}; ++ ++&pcie1 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy1>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&i2c1 { ++ status = "okay"; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x70000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x01000000>; ++ }; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++ /* 3 AMAC serdes, amac_serdes2 is for switch front port */ ++ amac_serdes0: amac_serdes@0 { ++ reg = <1>; ++ }; ++ amac_serdes1: amac_serdes@1 { ++ reg = <2>; ++ }; ++ amac_serdes2: amac_serdes@2 { ++ reg = <3>; ++ }; ++ usb_phy: usb_phy@0 { ++ reg = <6>; ++ }; ++ pcie_phy0: pcie_phy@0 { ++ reg = <7>; ++ }; ++ pcie_phy1: pcie_phy@1 { ++ reg = <8>; ++ }; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <1>; ++ }; ++ amac_phy1: amac_phy@1 { ++ reg = <2>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; ++ +Binary files a/arch/arm/boot/dts/bcm956450.dtb and b/arch/arm/boot/dts/bcm956450.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/bcm956450.dts b/arch/arm/boot/dts/bcm956450.dts +--- a/arch/arm/boot/dts/bcm956450.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/bcm956450.dts 2018-05-10 11:31:28.317398259 +0800 +@@ -0,0 +1,229 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-katana2.dtsi" ++ ++/ { ++ model = "Broadcom KT2 SVK (BCM956450K)"; ++ compatible = "brcm,bcm956450k", "brcm,katana2"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ sdk-serdes-lane2 = &amac_serdes2; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=2 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&amac_phy0>; ++ phy-mode = "sgmii"; /* "gmii-id", "gmii-rxid", "sgmii" */ ++ serdes-handle = <&amac_serdes0>; ++}; ++ ++&gmac1 { ++ status = "okay"; ++ phy-handle = <&amac_phy1>; ++ phy-mode = "sgmii"; /* "gmii-id", "gmii-rxid", "sgmii" */ ++ serdes-handle = <&amac_serdes1>; ++}; ++ ++&usbphy0 { ++ status = "okay"; ++ mdio-phy-handle = <&usb_phy>; ++}; ++ ++&ehci0 { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++ ++&gpio_cca { ++ status = "okay"; ++}; ++ ++&pcie0 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy0>; ++}; ++ ++&pcie1 { ++ status = "okay"; ++ mdio-phy-handle = <&pcie_phy1>; ++}; ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c01"; ++ reg = <0x50>; ++ pagesize = <8>; ++ }; ++}; ++ ++&i2c1 { ++ status = "okay"; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ /*nand-bus-width = <8>;*/ ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x0 0x200000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x200000 0x400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x600000 0xa00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x1000000 0xf000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x70000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ /*read-only;*/ ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x01000000>; ++ }; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++ /* 3 AMAC serdes, amac_serdes2 is for switch front port */ ++ amac_serdes0: amac_serdes@0 { ++ reg = <1>; ++ }; ++ amac_serdes1: amac_serdes@1 { ++ reg = <2>; ++ }; ++ amac_serdes2: amac_serdes@2 { ++ reg = <3>; ++ }; ++ usb_phy: usb_phy@0 { ++ reg = <6>; ++ }; ++ pcie_phy0: pcie_phy@0 { ++ reg = <7>; ++ }; ++ pcie_phy1: pcie_phy@1 { ++ reg = <8>; ++ }; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++ amac_phy0: amac_phy@0 { ++ reg = <1>; ++ }; ++ amac_phy1: amac_phy@1 { ++ reg = <2>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&iproc_cmicd { ++ status = "okay"; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/greyhound.its b/arch/arm/boot/dts/greyhound.its +--- a/arch/arm/boot/dts/greyhound.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/greyhound.its 2018-05-10 11:31:28.333398276 +0800 +@@ -0,0 +1,62 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm95341x.dtb"; ++ data = /incbin/("./bcm95341x.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++/* ++ fdt@2 { ++ description = "Flattened Device Tree blob - bcm95606x.dtb"; ++ data = /incbin/("./bcm95606x.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "md5"; ++ }; ++ }; ++*/ ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++/* ++ conf@2 { ++ description = "Boot Linux kernel with FDT blob"; ++ kernel = "kernel@1"; ++ fdt = "fdt@2"; ++ }; ++*/ ++ }; ++}; ++ +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/greyhound2.its b/arch/arm/boot/dts/greyhound2.its +--- a/arch/arm/boot/dts/greyhound2.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/greyhound2.its 2018-05-10 11:31:28.333398276 +0800 +@@ -0,0 +1,62 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm956170.dtb"; ++ data = /incbin/("./bcm956170.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ /*fdt@2 { ++ description = "Flattened Device Tree blob - bcm95357x.dtb"; ++ data = /incbin/("./bcm95357x.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ };*/ ++ ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++/* ++ conf@2 { ++ description = "Boot Linux kernel with FDT blob"; ++ kernel = "kernel@1"; ++ fdt = "fdt@2"; ++ }; ++*/ ++ }; ++}; ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/helix4.its b/arch/arm/boot/dts/helix4.its +--- a/arch/arm/boot/dts/helix4.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/helix4.its 2018-05-10 11:31:28.333398276 +0800 +@@ -0,0 +1,42 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm956340.dtb"; ++ data = /incbin/("./bcm956340.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/hurricane3.its b/arch/arm/boot/dts/hurricane3.its +--- a/arch/arm/boot/dts/hurricane3.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/hurricane3.its 2018-05-10 11:31:28.333398276 +0800 +@@ -0,0 +1,59 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm956160.dtb"; ++ data = /incbin/("./bcm956160.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@2 { ++ description = "Flattened Device Tree blob - bcm953444.dtb"; ++ data = /incbin/("./bcm953444.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob 1"; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++ ++ conf@2 { ++ description = "Boot Linux kernel with FDT blob 2"; ++ kernel = "kernel@1"; ++ fdt = "fdt@2"; ++ }; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/katana2.its b/arch/arm/boot/dts/katana2.its +--- a/arch/arm/boot/dts/katana2.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/katana2.its 2018-05-10 11:31:28.361398305 +0800 +@@ -0,0 +1,43 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm956450.dtb"; ++ data = /incbin/("./bcm956450.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++ }; ++}; ++ +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/saber2.its b/arch/arm/boot/dts/saber2.its +--- a/arch/arm/boot/dts/saber2.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/saber2.its 2018-05-10 11:31:28.397398343 +0800 +@@ -0,0 +1,42 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm956260.dtb"; ++ data = /incbin/("./bcm956260.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/wolfhound2.its b/arch/arm/boot/dts/wolfhound2.its +--- a/arch/arm/boot/dts/wolfhound2.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/wolfhound2.its 2018-05-10 11:31:28.421398368 +0800 +@@ -0,0 +1,60 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel@1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt@1 { ++ description = "Flattened Device Tree blob - bcm953547.dtb"; ++ data = /incbin/("./bcm953547.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ /* fdt@2 { ++ description = "Flattened Device Tree blob - bcm953444.dtb"; ++ data = /incbin/("./bcm953444.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; */ ++ }; ++ ++ configurations { ++ default = "conf@1"; ++ conf@1 { ++ description = "Boot Linux kernel with FDT blob 1"; ++ kernel = "kernel@1"; ++ fdt = "fdt@1"; ++ }; ++ ++ /* conf@2 { ++ description = "Boot Linux kernel with FDT blob 2"; ++ kernel = "kernel@1"; ++ fdt = "fdt@2"; ++ }; */ ++ }; ++}; ++ +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/boot/dts/xgs-iproc-arm32.its b/arch/arm/boot/dts/xgs-iproc-arm32.its +--- a/arch/arm/boot/dts/xgs-iproc-arm32.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/boot/dts/xgs-iproc-arm32.its 2018-05-10 11:31:28.421398368 +0800 +@@ -0,0 +1,163 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel_iproc { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../zImage"); ++ type = "kernel"; ++ arch = "arm"; ++ os = "linux"; ++ compression = "none"; ++ load = <0x61008000>; ++ entry = <0x61008000>; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_hx4 { ++ description = "Helix4 Device Tree blob - bcm956340.dtb"; ++ data = /incbin/("./bcm956340.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_kt2 { ++ description = "Katana2 Device Tree blob - bcm956450.dtb"; ++ data = /incbin/("./bcm956450.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_sb2 { ++ description = "Saber2 Device Tree blob - bcm956260.dtb"; ++ data = /incbin/("./bcm956260.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_gh { ++ description = "Greyhound Device Tree blob - bcm95341x.dtb"; ++ data = /incbin/("./bcm95341x.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_hr3 { ++ description = "Hurricane3 Device Tree blob - bcm956160.dtb"; ++ data = /incbin/("./bcm956160.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_hr3_lite { ++ description = "Hurricane3 Lite Device Tree blob - bcm953444.dtb"; ++ data = /incbin/("./bcm953444.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_gh2 { ++ description = "Greyhound2 Device Tree blob - bcm956170.dtb"; ++ data = /incbin/("./bcm956170.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_wh2 { ++ description = "Wolfhound2 Device Tree blob - bcm953547.dtb"; ++ data = /incbin/("./bcm953547.dtb"); ++ type = "flat_dt"; ++ arch = "arm"; ++ compression = "none"; ++ hash@1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "hx4"; ++ /* use "bootm 0x64000000#katana2" for booting Katana2 */ ++ hx4 { ++ description = "Boot Linux kernel with Helix4 FDT blob "; ++ kernel = "kernel_iproc"; ++ fdt = "fdt_hx4"; ++ }; ++ ++ kt2 { ++ description = "Boot Linux kernel with Katana2 FDT blob "; ++ kernel = "kernel_iproc"; ++ fdt = "fdt_kt2"; ++ }; ++ ++ sb2 { ++ description = "Boot Linux kernel with Saber2 FDT blob "; ++ kernel = "kernel_iproc"; ++ fdt = "fdt_sb2"; ++ }; ++ ++ gh { ++ description = "Boot Linux kernel with Greyhound FDT blob "; ++ kernel = "kernel_iproc"; ++ fdt = "fdt_gh"; ++ }; ++ ++ hr3 { ++ description = "Boot Linux kernel with Hurricane3 FDT blob "; ++ kernel = "kernel_iproc"; ++ fdt = "fdt_hr3"; ++ }; ++ ++ hr3_lite { ++ description = "Boot Linux kernel with Hurricane3 Lite FDT blob "; ++ kernel = "kernel_iproc"; ++ fdt = "fdt_hr3_lite"; ++ }; ++ ++ gh2 { ++ description = "Boot Linux kernel with Greyhound2 FDT blob "; ++ kernel = "kernel_iproc"; ++ fdt = "fdt_gh2"; ++ }; ++ ++ wh2 { ++ description = "Boot Linux kernel with Wolfhound2 FDT blob "; ++ kernel = "kernel_iproc"; ++ fdt = "fdt_wh2"; ++ }; ++ ++ }; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/configs/iproc_arm32_be_defconfig b/arch/arm/configs/iproc_arm32_be_defconfig +--- a/arch/arm/configs/iproc_arm32_be_defconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/configs/iproc_arm32_be_defconfig 2018-05-10 11:31:28.429398377 +0800 +@@ -0,0 +1,210 @@ ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_USELIB=y ++CONFIG_IRQ_DOMAIN_DEBUG=y ++CONFIG_NO_HZ=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_SYSCTL_SYSCALL=y ++# CONFIG_SHMEM is not set ++CONFIG_EMBEDDED=y ++# CONFIG_SLUB_DEBUG is not set ++# CONFIG_COMPAT_BRK is not set ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_ARCH_XGS_IPROC=y ++CONFIG_CPU_BIG_ENDIAN=y ++# CONFIG_ARM_ERRATA_643719 is not set ++CONFIG_PCI=y ++CONFIG_PCI_MSI=y ++CONFIG_PCIE_XGS_IPROC=y ++CONFIG_PCIE_IPROC_MSI=y ++CONFIG_SMP=y ++CONFIG_PREEMPT=y ++CONFIG_ARM_MODULE_PLTS=y ++CONFIG_CMA=y ++CONFIG_CMA_DEBUG=y ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 ++CONFIG_CMDLINE="console=ttyS0,115200n8 maxcpus=1 mem=240M" ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++# 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 is not set ++# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET6_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET6_XFRM_MODE_BEET is not set ++CONFIG_IPV6_TUNNEL=y ++CONFIG_NETFILTER=y ++CONFIG_BRIDGE_NETFILTER=y ++CONFIG_NETFILTER_NETLINK_QUEUE=y ++CONFIG_NETFILTER_NETLINK_LOG=y ++CONFIG_NF_CONNTRACK=y ++# CONFIG_NF_CT_PROTO_DCCP is not set ++# CONFIG_NF_CT_PROTO_SCTP is not set ++# CONFIG_NF_CT_PROTO_UDPLITE is not set ++CONFIG_NF_CONNTRACK_FTP=y ++CONFIG_NF_CONNTRACK_TFTP=y ++CONFIG_NETFILTER_XT_MARK=y ++CONFIG_NETFILTER_XT_TARGET_CT=y ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=y ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y ++CONFIG_NETFILTER_XT_MATCH_HELPER=y ++CONFIG_NETFILTER_XT_MATCH_STATE=y ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=y ++CONFIG_NF_CONNTRACK_IPV4=y ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_AH=y ++CONFIG_IP_NF_MATCH_ECN=y ++CONFIG_IP_NF_MATCH_TTL=y ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=y ++CONFIG_IP_NF_MANGLE=y ++CONFIG_IP_NF_TARGET_ECN=y ++CONFIG_IP_NF_TARGET_TTL=y ++CONFIG_IP_NF_RAW=y ++CONFIG_IP_NF_ARPTABLES=y ++CONFIG_IP_NF_ARPFILTER=y ++CONFIG_IP_NF_ARP_MANGLE=y ++CONFIG_NF_CONNTRACK_IPV6=y ++CONFIG_IP6_NF_IPTABLES=y ++CONFIG_IP6_NF_MATCH_RPFILTER=y ++CONFIG_IP6_NF_MATCH_RT=y ++CONFIG_IP6_NF_FILTER=y ++CONFIG_IP6_NF_TARGET_REJECT=y ++CONFIG_IP6_NF_MANGLE=y ++CONFIG_IP6_NF_RAW=y ++CONFIG_BRIDGE=y ++CONFIG_VLAN_8021Q=y ++CONFIG_VLAN_8021Q_GVRP=y ++# CONFIG_WIRELESS is not set ++CONFIG_UEVENT_HELPER_PATH="/sbin/mdev" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=32 ++CONFIG_MTD=y ++CONFIG_MTD_TESTS=m ++CONFIG_MTD_CMDLINE_PARTS=y ++CONFIG_MTD_BLOCK=y ++CONFIG_MTD_CFI=y ++CONFIG_MTD_JEDECPROBE=y ++CONFIG_MTD_CFI_ADV_OPTIONS=y ++CONFIG_MTD_CFI_LE_BYTE_SWAP=y ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_CFI_AMDSTD=y ++CONFIG_MTD_CFI_STAA=y ++CONFIG_MTD_NOR_XGS_IPROC=y ++CONFIG_MTD_M25P80=y ++CONFIG_MTD_NAND=y ++CONFIG_MTD_NAND_BRCMNAND=y ++CONFIG_MTD_SPI_NOR=y ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++CONFIG_MTD_UBI=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_EEPROM_AT24=y ++CONFIG_SCSI=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_CHR_DEV_ST=y ++CONFIG_CHR_DEV_SG=y ++CONFIG_SCSI_CONSTANTS=y ++CONFIG_SCSI_LOGGING=y ++CONFIG_NETDEVICES=y ++CONFIG_BONDING=y ++CONFIG_TIGON3=y ++CONFIG_MDIO_XGS_IPROC=y ++CONFIG_BROADCOM_PHY=y ++CONFIG_XGS_IPROC_SERDES=y ++# CONFIG_WLAN is not set ++# CONFIG_INPUT is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_VT is not set ++# CONFIG_LEGACY_PTYS is not set ++CONFIG_DEVKMEM=y ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=2 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=2 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_8250_DETECT_IRQ=y ++CONFIG_SERIAL_8250_RSA=y ++CONFIG_SERIAL_8250_DW=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_XGS_IPROC_RNG=y ++CONFIG_I2C=y ++# CONFIG_I2C_COMPAT is not set ++CONFIG_I2C_CHARDEV=y ++# CONFIG_I2C_HELPER_AUTO is not set ++CONFIG_SPI=y ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_WATCHDOG=y ++CONFIG_ARM_SP805_WATCHDOG=y ++# CONFIG_VGA_ARB is not set ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_DYNAMIC_MINORS=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_ROOT_HUB_TT=y ++CONFIG_USB_EHCI_XGS_IPROC=y ++CONFIG_USB_EHCI_HCD_PLATFORM=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_HCD_PLATFORM=y ++CONFIG_USB_OHCI_XGS_IPROC=y ++CONFIG_USB_STORAGE=y ++CONFIG_USBPHY_XGS_IPROC=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_XGS_IPROC_UDC=m ++CONFIG_USB_G_SERIAL=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_XGS_IPROC=y ++CONFIG_DMADEVICES=y ++CONFIG_DMADEVICES_DEBUG=y ++CONFIG_DMADEVICES_VDEBUG=y ++CONFIG_PL330_DMA=y ++CONFIG_GENERIC_PHY=y ++CONFIG_EXT2_FS=y ++CONFIG_EXT3_FS=y ++# CONFIG_DNOTIFY is not set ++CONFIG_AUTOFS4_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_NTFS_FS=y ++CONFIG_JFFS2_FS=y ++CONFIG_UBIFS_FS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFSD=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_DEBUG_INFO=y ++CONFIG_DEBUG_FS=y ++CONFIG_MAGIC_SYSRQ=y ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_FTRACE is not set ++CONFIG_DEBUG_USER=y ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_ANSI_CPRNG=m ++CONFIG_XZ_DEC=y +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/configs/iproc_arm32_defconfig b/arch/arm/configs/iproc_arm32_defconfig +--- a/arch/arm/configs/iproc_arm32_defconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/configs/iproc_arm32_defconfig 2018-05-10 11:31:28.429398377 +0800 +@@ -0,0 +1,207 @@ ++# CONFIG_LOCALVERSION_AUTO is not set ++CONFIG_SYSVIPC=y ++CONFIG_USELIB=y ++CONFIG_IRQ_DOMAIN_DEBUG=y ++CONFIG_NO_HZ=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_SYSCTL_SYSCALL=y ++# CONFIG_SHMEM is not set ++CONFIG_EMBEDDED=y ++# CONFIG_SLUB_DEBUG is not set ++# CONFIG_COMPAT_BRK is not set ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_ARCH_XGS_IPROC=y ++# CONFIG_ARM_ERRATA_643719 is not set ++CONFIG_PCI=y ++CONFIG_PCI_MSI=y ++CONFIG_PCIE_XGS_IPROC=y ++CONFIG_PCIE_IPROC_MSI=y ++CONFIG_SMP=y ++CONFIG_PREEMPT=y ++CONFIG_ARM_MODULE_PLTS=y ++CONFIG_CMA=y ++CONFIG_CMA_DEBUG=y ++CONFIG_ZBOOT_ROM_TEXT=0x0 ++CONFIG_ZBOOT_ROM_BSS=0x0 ++CONFIG_CMDLINE="console=ttyS0,115200n8 maxcpus=1 mem=240M" ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++# 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 is not set ++# CONFIG_INET6_XFRM_MODE_TRANSPORT is not set ++# CONFIG_INET6_XFRM_MODE_TUNNEL is not set ++# CONFIG_INET6_XFRM_MODE_BEET is not set ++CONFIG_IPV6_TUNNEL=y ++CONFIG_NETFILTER=y ++CONFIG_BRIDGE_NETFILTER=y ++CONFIG_NETFILTER_NETLINK_QUEUE=y ++CONFIG_NETFILTER_NETLINK_LOG=y ++CONFIG_NF_CONNTRACK=y ++# CONFIG_NF_CT_PROTO_DCCP is not set ++# CONFIG_NF_CT_PROTO_SCTP is not set ++# CONFIG_NF_CT_PROTO_UDPLITE is not set ++CONFIG_NF_CONNTRACK_FTP=y ++CONFIG_NF_CONNTRACK_TFTP=y ++CONFIG_NETFILTER_XT_MARK=y ++CONFIG_NETFILTER_XT_TARGET_CT=y ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=y ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y ++CONFIG_NETFILTER_XT_MATCH_HELPER=y ++CONFIG_NETFILTER_XT_MATCH_STATE=y ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=y ++CONFIG_NF_CONNTRACK_IPV4=y ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_AH=y ++CONFIG_IP_NF_MATCH_ECN=y ++CONFIG_IP_NF_MATCH_TTL=y ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=y ++CONFIG_IP_NF_MANGLE=y ++CONFIG_IP_NF_TARGET_ECN=y ++CONFIG_IP_NF_TARGET_TTL=y ++CONFIG_IP_NF_RAW=y ++CONFIG_IP_NF_ARPTABLES=y ++CONFIG_IP_NF_ARPFILTER=y ++CONFIG_IP_NF_ARP_MANGLE=y ++CONFIG_NF_CONNTRACK_IPV6=y ++CONFIG_IP6_NF_IPTABLES=y ++CONFIG_IP6_NF_MATCH_RPFILTER=y ++CONFIG_IP6_NF_MATCH_RT=y ++CONFIG_IP6_NF_FILTER=y ++CONFIG_IP6_NF_TARGET_REJECT=y ++CONFIG_IP6_NF_MANGLE=y ++CONFIG_IP6_NF_RAW=y ++CONFIG_BRIDGE=y ++CONFIG_VLAN_8021Q=y ++CONFIG_VLAN_8021Q_GVRP=y ++# CONFIG_WIRELESS is not set ++CONFIG_UEVENT_HELPER_PATH="/sbin/mdev" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=32 ++CONFIG_MTD=y ++CONFIG_MTD_TESTS=m ++CONFIG_MTD_CMDLINE_PARTS=y ++CONFIG_MTD_BLOCK=y ++CONFIG_MTD_CFI=y ++CONFIG_MTD_JEDECPROBE=y ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_CFI_AMDSTD=y ++CONFIG_MTD_CFI_STAA=y ++CONFIG_MTD_NOR_XGS_IPROC=y ++CONFIG_MTD_M25P80=y ++CONFIG_MTD_NAND=y ++CONFIG_MTD_NAND_BRCMNAND=y ++CONFIG_MTD_SPI_NOR=y ++# CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set ++CONFIG_MTD_UBI=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_EEPROM_AT24=y ++CONFIG_SCSI=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_CHR_DEV_ST=y ++CONFIG_CHR_DEV_SG=y ++CONFIG_SCSI_CONSTANTS=y ++CONFIG_SCSI_LOGGING=y ++CONFIG_NETDEVICES=y ++CONFIG_BONDING=y ++CONFIG_TIGON3=y ++CONFIG_MDIO_XGS_IPROC=y ++CONFIG_BROADCOM_PHY=y ++CONFIG_XGS_IPROC_SERDES=y ++# CONFIG_WLAN is not set ++# CONFIG_INPUT is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_VT is not set ++# CONFIG_LEGACY_PTYS is not set ++CONFIG_DEVKMEM=y ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=2 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=2 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_8250_DETECT_IRQ=y ++CONFIG_SERIAL_8250_RSA=y ++CONFIG_SERIAL_8250_DW=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_XGS_IPROC_RNG=y ++CONFIG_I2C=y ++# CONFIG_I2C_COMPAT is not set ++CONFIG_I2C_CHARDEV=y ++# CONFIG_I2C_HELPER_AUTO is not set ++CONFIG_SPI=y ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_WATCHDOG=y ++CONFIG_ARM_SP805_WATCHDOG=y ++# CONFIG_VGA_ARB is not set ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_DYNAMIC_MINORS=y ++CONFIG_USB_EHCI_HCD=y ++CONFIG_USB_EHCI_ROOT_HUB_TT=y ++CONFIG_USB_EHCI_XGS_IPROC=y ++CONFIG_USB_EHCI_HCD_PLATFORM=y ++CONFIG_USB_OHCI_HCD=y ++CONFIG_USB_OHCI_HCD_PLATFORM=y ++CONFIG_USB_OHCI_XGS_IPROC=y ++CONFIG_USB_STORAGE=y ++CONFIG_USBPHY_XGS_IPROC=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_XGS_IPROC_UDC=m ++CONFIG_USB_G_SERIAL=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_MMC_SDHCI_PLTFM=y ++CONFIG_MMC_SDHCI_XGS_IPROC=y ++CONFIG_DMADEVICES=y ++CONFIG_DMADEVICES_DEBUG=y ++CONFIG_DMADEVICES_VDEBUG=y ++CONFIG_PL330_DMA=y ++CONFIG_GENERIC_PHY=y ++CONFIG_EXT2_FS=y ++CONFIG_EXT3_FS=y ++# CONFIG_DNOTIFY is not set ++CONFIG_AUTOFS4_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_NTFS_FS=y ++CONFIG_JFFS2_FS=y ++CONFIG_UBIFS_FS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFSD=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_DEBUG_INFO=y ++CONFIG_DEBUG_FS=y ++CONFIG_MAGIC_SYSRQ=y ++# CONFIG_SCHED_DEBUG is not set ++# CONFIG_FTRACE is not set ++CONFIG_DEBUG_USER=y ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_ANSI_CPRNG=m ++CONFIG_XZ_DEC=y +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/Kconfig b/arch/arm/mach-iproc/Kconfig +--- a/arch/arm/mach-iproc/Kconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/Kconfig 2018-05-10 11:31:28.505398457 +0800 +@@ -0,0 +1,77 @@ ++menuconfig ARCH_XGS_IPROC ++ bool "Broadcom XGS iProc Support" if ARCH_MULTI_V7 ++ select HAVE_ARM_TWD if SMP ++ select HAVE_ARM_SCU if SMP ++ select ARM_GLOBAL_TIMER ++ select ARM_GIC ++ select ARCH_REQUIRE_GPIOLIB ++ select CACHE_L2X0 ++ select ARM_AMBA ++ select ARCH_SUPPORTS_BIG_ENDIAN ++ select CPU_ENDIAN_BE8 if CPU_BIG_ENDIAN ++ select ARM_ERRATA_754322 ++ select ARM_ERRATA_764369 if SMP ++ select ARM_ERRATA_775420 ++ help ++ This enables support for Broadcom XGS iProc based SoC chips ++ ++if ARCH_XGS_IPROC ++ ++comment "XGS iProc SoC based Machine types" ++ ++choice ++ prompt "XGS iProc SoC based Machine types" ++ default XGS_IPROC_ARM32_PLATFORM ++ ++config XGS_IPROC_ARM32_PLATFORM ++ bool "Support all XGS iProc ARM32 platforms" ++ help ++ Support for all XGS iProc ARM32 platforms. ++ ++config MACH_HX4 ++ bool "Support Broadcom Helix4 bring-up board" ++ help ++ Support for the Broadcom Helix4 bring-up board. ++ ++config MACH_HR2 ++ bool "Support Broadcom Hurricane2 bring-up board" ++ help ++ Support for the Broadcom Hurricane2 bring-up board. ++ ++config MACH_KT2 ++ bool "Support Broadcom Katana2 bring-up board" ++ help ++ Support for the Broadcom Katana2 bring-up board. ++ ++config MACH_GH ++ bool "Support Broadcom Greyhound bring-up board" ++ help ++ Support for the Broadcom Greyhound bring-up board. ++ ++config MACH_SB2 ++ bool "Support Broadcom Saber2 bring-up board" ++ help ++ Support for the Broadcom Saber2 bring-up board. ++ ++config MACH_HR3 ++ bool "Support Broadcom Hurricane3 bring-up board" ++ help ++ Support for the Broadcom Hurricane3 bring-up board. ++ ++config MACH_GH2 ++ bool "Support Broadcom Greyhound2 bring-up board" ++ help ++ Support for the Broadcom Greyhound2 bring-up board. ++ ++config MACH_WH2 ++ bool "Support Broadcom wolfhound2 bring-up board" ++ help ++ Support for the Broadcom Wolfhound2 bring-up board. ++endchoice ++ ++config MACH_IPROC_EMULATION ++ bool "Support iProc emulation" ++ help ++ Support for the iProc emulation. ++ ++endif +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/Makefile b/arch/arm/mach-iproc/Makefile +--- a/arch/arm/mach-iproc/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/Makefile 2018-05-10 11:31:28.505398457 +0800 +@@ -0,0 +1,3 @@ ++obj-y := board_bu.o ++obj-y += shm.o ++obj-$(CONFIG_SMP) += platsmp.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/board_bu.c b/arch/arm/mach-iproc/board_bu.c +--- a/arch/arm/mach-iproc/board_bu.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/board_bu.c 2018-05-10 11:31:28.505398457 +0800 +@@ -0,0 +1,108 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define DMU_CRU_RESET_BASE 0x200 ++ ++enum xgs_iproc_dev_id { ++ XGS_IPROC_HX4=0, ++ XGS_IPROC_KT2, ++ XGS_IPROC_HR2, ++ XGS_IPROC_GH, ++ XGS_IPROC_SB2, ++ XGS_IPROC_HR3, ++ XGS_IPROC_GH2, ++ XGS_IPROC_WH2, ++ XGS_IPROC_GENERIC, ++}; ++ ++const char *const xgs_iproc_dt_compat[] = { ++ "brcm,helix4", ++ "brcm,katana2", ++ "brcm,hurricane2", ++ "brcm,greyhound", ++ "brcm,saber2", ++ "brcm,hurricane3", ++ "brcm,greyhound2", ++ "brcm,wolfhound2", ++ "brcm,xgs-iproc", ++ NULL, ++}; ++ ++void __init xgs_iproc_init_early(void) ++{ ++ /* ++ * SDK allocates coherent buffers from atomic context. ++ * Increase size of atomic coherent pool to make sure such ++ * allocations won't fail. ++ */ ++ /* can be overrided by "coherent_pool" in kernel boot argument */ ++ if (IS_ENABLED(CONFIG_DMA_CMA)) ++ init_dma_coherent_pool_size(SZ_1M * 16); ++} ++ ++static void __init xgs_iproc_init(void) ++{ ++ int ret; ++ ++ ret = xgs_iproc_misc_setup(); ++ if (ret < 0) ++ return; ++ ++ /* Init idm and setup idm timeout handler for debug purpose */ ++ /* xgs_iproc_idm_init should be init before reset dmac */ ++ ret = xgs_iproc_idm_init(); ++ if (ret < 0) ++ return; ++ ++ xgs_iproc_idm_dmac_reset(); ++ ++ /* Populate platform devices */ ++ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); ++} ++ ++ ++static void xgs_iproc_restart(enum reboot_mode mode, const char *cmd) ++{ ++ void * __iomem reg_addr; ++ u32 reg; ++ ++ /* CRU_RESET register */ ++ reg_addr = (void * __iomem)(get_iproc_dmu_pcu_base() + ++ DMU_CRU_RESET_BASE); ++ /* set iproc_reset_n to 0 */ ++ reg = readl(reg_addr); ++ reg &= ~((u32) 1 << 1); ++ ++ writel(reg, reg_addr); ++ ++ /* Wait for reset */ ++ while (1) ++ cpu_do_idle(); ++} ++ ++DT_MACHINE_START(XGS_iProc_DT, "BRCM XGS iProc") ++ .init_early = xgs_iproc_init_early, ++ .init_machine = xgs_iproc_init, ++ .dt_compat = xgs_iproc_dt_compat, ++ .restart = xgs_iproc_restart, ++ .l2c_aux_val = 0, ++ .l2c_aux_mask = ~0, ++MACHINE_END +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/include/plat/shm.h b/arch/arm/mach-iproc/include/plat/shm.h +--- a/arch/arm/mach-iproc/include/plat/shm.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/include/plat/shm.h 2018-05-10 11:31:28.505398457 +0800 +@@ -0,0 +1,72 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++/* ++ * Header for declaring shim layer exports. ++ */ ++ ++#ifndef __SHM_DOT_H_INCLUDED__ ++#define __SHM_DOT_H_INCLUDED__ ++ ++#include ++#include ++#include ++ ++ ++#define iproc_class_create(owner, name) \ ++({ \ ++ static struct lock_class_key __key; \ ++ iproc__class_create(owner, name, &__key); \ ++}) ++ ++extern int iproc_platform_get_irq(struct platform_device *dev, unsigned int num); ++extern struct resource * ++iproc_platform_get_resource_byname(struct platform_device *dev, unsigned int type, const char *name); ++extern struct resource * ++iproc_platform_get_resource(struct platform_device *dev, unsigned int type, ++ unsigned int num); ++extern int iproc_platform_device_add_resources(struct platform_device *pdev, const struct resource *res, unsigned int num); ++ ++extern int iproc_platform_device_register(struct platform_device * pdev); ++extern void iproc_platform_device_unregister(struct platform_device * pdev); ++extern int iproc_platform_driver_register(struct platform_driver *drv); ++extern void iproc_platform_driver_unregister(struct platform_driver *drv); ++ ++extern struct platform_device *iproc_platform_device_alloc(const char *name, int id); ++ ++extern int iproc_platform_device_add(struct platform_device *pdev); ++extern void iproc_platform_device_put(struct platform_device *pdev); ++ ++extern void iproc_platform_device_put(struct platform_device *pdev); ++extern int iproc_platform_device_add(struct platform_device *pdev); ++extern void iproc_platform_device_del(struct platform_device *pdev); ++extern int iproc_sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp); ++extern void iproc_sysfs_remove_group(struct kobject *kobj, const struct attribute_group *grp); ++ ++ ++extern struct class *iproc__class_create(struct module *owner, const char *name, ++ struct lock_class_key *key); ++extern void iproc_class_destroy(struct class *cls); ++extern int iproc_device_create_file(struct device *dev, ++ const struct device_attribute *attr); ++extern struct device *iproc_device_create(struct class *class, ++ struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...); ++extern void iproc_device_destroy(struct class *class, dev_t devt); ++extern void iproc_device_remove_file(struct device *dev, ++ const struct device_attribute *attr); ++extern int iproc_platform_get_irq_byname(struct platform_device *, const char *); ++ ++extern int iproc_gpio_to_irq(unsigned gpio); ++#endif /*#ifndef __SHM_DOT_H_INCLUDED__*/ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/platsmp.c b/arch/arm/mach-iproc/platsmp.c +--- a/arch/arm/mach-iproc/platsmp.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/platsmp.c 2018-05-10 11:31:28.505398457 +0800 +@@ -0,0 +1,309 @@ ++/* ++ * Copyright (C) 2014-2015 Broadcom Corporation ++ * Copyright 2014 Linaro Limited ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++#include "../mach-bcm/platsmp.c" ++ ++#if 0 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++ ++/* Size of mapped Cortex A9 SCU address space */ ++#define CORTEX_A9_SCU_SIZE 0x58 ++ ++#define SECONDARY_TIMEOUT_NS NSEC_PER_MSEC /* 1 msec (in nanoseconds) */ ++#define BOOT_ADDR_CPUID_MASK 0x3 ++ ++/* Name of device node property defining secondary boot register location */ ++#define OF_SECONDARY_BOOT "secondary-boot-reg" ++#define MPIDR_CPUID_BITMASK 0x3 ++ ++/* ++ * Enable the Cortex A9 Snoop Control Unit ++ * ++ * By the time this is called we already know there are multiple ++ * cores present. We assume we're running on a Cortex A9 processor, ++ * so any trouble getting the base address register or getting the ++ * SCU base is a problem. ++ * ++ * Return 0 if successful or an error code otherwise. ++ */ ++static int __init scu_a9_enable(void) ++{ ++ unsigned long config_base; ++ void __iomem *scu_base; ++ ++ if (!scu_a9_has_base()) { ++ pr_err("no configuration base address register!\n"); ++ return -ENXIO; ++ } ++ ++ /* Config base address register value is zero for uniprocessor */ ++ config_base = scu_a9_get_base(); ++ if (!config_base) { ++ pr_err("hardware reports only one core\n"); ++ return -ENOENT; ++ } ++ ++ scu_base = ioremap((phys_addr_t)config_base, CORTEX_A9_SCU_SIZE); ++ if (!scu_base) { ++ pr_err("failed to remap config base (%lu/%u) for SCU\n", ++ config_base, CORTEX_A9_SCU_SIZE); ++ return -ENOMEM; ++ } ++ ++ scu_enable(scu_base); ++ ++ iounmap(scu_base); /* That's the last we'll need of this */ ++ ++ return 0; ++} ++ ++static u32 secondary_boot_addr_for(unsigned int cpu) ++{ ++ u32 secondary_boot_addr = 0; ++ struct device_node *cpu_node = of_get_cpu_node(cpu, NULL); ++ ++ if (!cpu_node) { ++ pr_err("Failed to find device tree node for CPU%u\n", cpu); ++ return 0; ++ } ++ ++ if (of_property_read_u32(cpu_node, ++ OF_SECONDARY_BOOT, ++ &secondary_boot_addr)) ++ pr_err("required secondary boot register not specified for CPU%u\n", ++ cpu); ++ ++ of_node_put(cpu_node); ++ ++ return secondary_boot_addr; ++} ++ ++static int nsp_write_lut(unsigned int cpu) ++{ ++ void __iomem *sku_rom_lut; ++ phys_addr_t secondary_startup_phy; ++ const u32 secondary_boot_addr = secondary_boot_addr_for(cpu); ++ ++ if (!secondary_boot_addr) ++ return -EINVAL; ++ ++ sku_rom_lut = ioremap_nocache((phys_addr_t)secondary_boot_addr, ++ sizeof(phys_addr_t)); ++ if (!sku_rom_lut) { ++ pr_warn("unable to ioremap SKU-ROM LUT register for cpu %u\n", cpu); ++ return -ENOMEM; ++ } ++ ++ secondary_startup_phy = virt_to_phys(secondary_startup); ++ BUG_ON(secondary_startup_phy > (phys_addr_t)U32_MAX); ++ ++ writel_relaxed(secondary_startup_phy, sku_rom_lut); ++ ++ /* Ensure the write is visible to the secondary core */ ++ smp_wmb(); ++ ++ iounmap(sku_rom_lut); ++ ++ return 0; ++} ++ ++static void __init bcm_smp_prepare_cpus(unsigned int max_cpus) ++{ ++ const cpumask_t only_cpu_0 = { CPU_BITS_CPU0 }; ++ ++ /* Enable the SCU on Cortex A9 based SoCs */ ++ if (scu_a9_enable()) { ++ /* Update the CPU present map to reflect uniprocessor mode */ ++ pr_warn("failed to enable A9 SCU - disabling SMP\n"); ++ init_cpu_present(&only_cpu_0); ++ } ++} ++ ++/* ++ * The ROM code has the secondary cores looping, waiting for an event. ++ * When an event occurs each core examines the bottom two bits of the ++ * secondary boot register. When a core finds those bits contain its ++ * own core id, it performs initialization, including computing its boot ++ * address by clearing the boot register value's bottom two bits. The ++ * core signals that it is beginning its execution by writing its boot ++ * address back to the secondary boot register, and finally jumps to ++ * that address. ++ * ++ * So to start a core executing we need to: ++ * - Encode the (hardware) CPU id with the bottom bits of the secondary ++ * start address. ++ * - Write that value into the secondary boot register. ++ * - Generate an event to wake up the secondary CPU(s). ++ * - Wait for the secondary boot register to be re-written, which ++ * indicates the secondary core has started. ++ */ ++static int kona_boot_secondary(unsigned int cpu, struct task_struct *idle) ++{ ++ void __iomem *boot_reg; ++ phys_addr_t boot_func; ++ u64 start_clock; ++ u32 cpu_id; ++ u32 boot_val; ++ bool timeout = false; ++ const u32 secondary_boot_addr = secondary_boot_addr_for(cpu); ++ ++ cpu_id = cpu_logical_map(cpu); ++ if (cpu_id & ~BOOT_ADDR_CPUID_MASK) { ++ pr_err("bad cpu id (%u > %u)\n", cpu_id, BOOT_ADDR_CPUID_MASK); ++ return -EINVAL; ++ } ++ ++ if (!secondary_boot_addr) ++ return -EINVAL; ++ ++ boot_reg = ioremap_nocache((phys_addr_t)secondary_boot_addr, ++ sizeof(phys_addr_t)); ++ if (!boot_reg) { ++ pr_err("unable to map boot register for cpu %u\n", cpu_id); ++ return -ENOMEM; ++ } ++ ++ /* ++ * Secondary cores will start in secondary_startup(), ++ * defined in "arch/arm/kernel/head.S" ++ */ ++ boot_func = virt_to_phys(secondary_startup); ++ BUG_ON(boot_func & BOOT_ADDR_CPUID_MASK); ++ BUG_ON(boot_func > (phys_addr_t)U32_MAX); ++ ++ /* The core to start is encoded in the low bits */ ++ boot_val = (u32)boot_func | cpu_id; ++ writel_relaxed(boot_val, boot_reg); ++ ++ sev(); ++ ++ /* The low bits will be cleared once the core has started */ ++ start_clock = local_clock(); ++ while (!timeout && readl_relaxed(boot_reg) == boot_val) ++ timeout = local_clock() - start_clock > SECONDARY_TIMEOUT_NS; ++ ++ iounmap(boot_reg); ++ ++ if (!timeout) ++ return 0; ++ ++ pr_err("timeout waiting for cpu %u to start\n", cpu_id); ++ ++ return -ENXIO; ++} ++ ++/* Cluster Dormant Control command to bring CPU into a running state */ ++#define CDC_CMD 6 ++#define CDC_CMD_OFFSET 0 ++#define CDC_CMD_REG(cpu) (CDC_CMD_OFFSET + 4*(cpu)) ++ ++/* ++ * BCM23550 has a Cluster Dormant Control block that keeps the core in ++ * idle state. A command needs to be sent to the block to bring the CPU ++ * into running state. ++ */ ++static int bcm23550_boot_secondary(unsigned int cpu, struct task_struct *idle) ++{ ++ void __iomem *cdc_base; ++ struct device_node *dn; ++ char *name; ++ int ret; ++ ++ /* Make sure a CDC node exists before booting the ++ * secondary core. ++ */ ++ name = "brcm,bcm23550-cdc"; ++ dn = of_find_compatible_node(NULL, NULL, name); ++ if (!dn) { ++ pr_err("unable to find cdc node\n"); ++ return -ENODEV; ++ } ++ ++ cdc_base = of_iomap(dn, 0); ++ of_node_put(dn); ++ ++ if (!cdc_base) { ++ pr_err("unable to remap cdc base register\n"); ++ return -ENOMEM; ++ } ++ ++ /* Boot the secondary core */ ++ ret = kona_boot_secondary(cpu, idle); ++ if (ret) ++ goto out; ++ ++ /* Bring this CPU to RUN state so that nIRQ nFIQ ++ * signals are unblocked. ++ */ ++ writel_relaxed(CDC_CMD, cdc_base + CDC_CMD_REG(cpu)); ++ ++out: ++ iounmap(cdc_base); ++ ++ return ret; ++} ++ ++static int nsp_boot_secondary(unsigned int cpu, struct task_struct *idle) ++{ ++ int ret; ++ ++ /* ++ * After wake up, secondary core branches to the startup ++ * address programmed at SKU ROM LUT location. ++ */ ++ ret = nsp_write_lut(cpu); ++ if (ret) { ++ pr_err("unable to write startup addr to SKU ROM LUT\n"); ++ goto out; ++ } ++ ++ /* Send a CPU wakeup interrupt to the secondary core */ ++ arch_send_wakeup_ipi_mask(cpumask_of(cpu)); ++ ++out: ++ return ret; ++} ++ ++static const struct smp_operations kona_smp_ops __initconst = { ++ .smp_prepare_cpus = bcm_smp_prepare_cpus, ++ .smp_boot_secondary = kona_boot_secondary, ++}; ++CPU_METHOD_OF_DECLARE(bcm_smp_bcm281xx, "brcm,bcm11351-cpu-method", ++ &kona_smp_ops); ++ ++static const struct smp_operations bcm23550_smp_ops __initconst = { ++ .smp_boot_secondary = bcm23550_boot_secondary, ++}; ++CPU_METHOD_OF_DECLARE(bcm_smp_bcm23550, "brcm,bcm23550", ++ &bcm23550_smp_ops); ++ ++static const struct smp_operations nsp_smp_ops __initconst = { ++ .smp_prepare_cpus = bcm_smp_prepare_cpus, ++ .smp_boot_secondary = nsp_boot_secondary, ++}; ++CPU_METHOD_OF_DECLARE(bcm_smp_nsp, "brcm,bcm-nsp-smp", &nsp_smp_ops); ++#endif +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/mach-iproc/shm.c b/arch/arm/mach-iproc/shm.c +--- a/arch/arm/mach-iproc/shm.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm/mach-iproc/shm.c 2018-05-10 11:31:28.505398457 +0800 +@@ -0,0 +1,309 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ */ ++ ++#include "include/plat/shm.h" ++/** ++ * iproc_platform_get_irq - get an IRQ for a device ++ * wrapper function for platform_get_irq ++ * @dev: platform device ++ * @num: IRQ number index ++ */ ++int iproc_platform_get_irq(struct platform_device *dev, unsigned int num) ++{ ++ return platform_get_irq(dev, num); ++} ++EXPORT_SYMBOL(iproc_platform_get_irq); ++ ++ ++/** ++ * iproc_platform_get_resource_byname - ++ * wrapper function for platform_get_resource_byname ++ * @dev: platform device ++ * @type: resource type ++ * @name: resource name ++ */ ++struct resource * ++iproc_platform_get_resource_byname(struct platform_device *dev, ++ unsigned int type, ++ const char *name) ++{ ++ return platform_get_resource_byname(dev, type, name); ++} ++EXPORT_SYMBOL(iproc_platform_get_resource_byname); ++ ++ ++/** ++ * iproc_platform_get_resource - ++ * wrapper function for platform_get_resource ++ * @dev: platform device ++ * @type: resource type ++ * @num: resource index ++ */ ++struct resource * ++iproc_platform_get_resource(struct platform_device *dev, unsigned int type, ++ unsigned int num) ++{ ++ return platform_get_resource(dev, type, num); ++} ++EXPORT_SYMBOL(iproc_platform_get_resource); ++ ++ ++/** ++ * iproc_platform_driver_register - ++ * wrapper function for platform_driver_register ++ * @drv: platform driver structure ++ */ ++int iproc_platform_driver_register(struct platform_driver *drv) ++{ ++ return platform_driver_register(drv); ++} ++EXPORT_SYMBOL(iproc_platform_driver_register); ++ ++ ++/** ++ * iproc_platform_driver_unregister ++ * wrapper function for platform_driver_unregister ++ * @drv: platform driver structure ++ */ ++void iproc_platform_driver_unregister(struct platform_driver *drv) ++{ ++ return platform_driver_unregister(drv); ++} ++EXPORT_SYMBOL(iproc_platform_driver_unregister); ++ ++ ++/** ++ * iproc_platform_device_register - add a platform-level device ++ * wrapper function for platform_device_register ++ * @pdev: platform device we're adding ++ * ++ */ ++int iproc_platform_device_register(struct platform_device * pdev) ++{ ++ return platform_device_register(pdev); ++} ++EXPORT_SYMBOL(iproc_platform_device_register); ++ ++ ++/** ++ * iproc_platform_device_unregister - ++ * wrapper function for platform_device_unregister ++ * @pdev: platform device we're unregistering ++ */ ++void iproc_platform_device_unregister(struct platform_device * pdev) ++{ ++ return platform_device_unregister(pdev); ++} ++EXPORT_SYMBOL(iproc_platform_device_unregister); ++ ++ ++/** ++ * iproc_platform_device_alloc - ++ * wrapper function for platform_device_alloc ++ * @name: base name of the device we're adding ++ * @id: instance id ++ */ ++struct platform_device *iproc_platform_device_alloc(const char *name, int id) ++{ ++ return platform_device_alloc(name, id); ++} ++EXPORT_SYMBOL(iproc_platform_device_alloc); ++ ++/** ++ * iproc_platform_device_add - ++ * wrapper function for platform_device_add ++ * @pdev: platform device we're adding ++ */ ++int iproc_platform_device_add(struct platform_device *pdev) ++{ ++ return platform_device_add(pdev); ++} ++EXPORT_SYMBOL(iproc_platform_device_add); ++ ++/** ++ * iproc_platform_device_del - ++ * wrapper function for platform_device_del ++ * @pdev: platform device we're removing ++ */ ++void iproc_platform_device_del(struct platform_device *pdev) ++{ ++ platform_device_del(pdev); ++} ++EXPORT_SYMBOL(iproc_platform_device_del); ++ ++ ++/** ++ * iproc_platform_device_put - ++ * wrapper function for platform_device_put ++ * @pdev: platform device to free ++ */ ++void iproc_platform_device_put(struct platform_device *pdev) ++{ ++ platform_device_put(pdev); ++} ++EXPORT_SYMBOL(iproc_platform_device_put); ++ ++ ++/** ++ * iproc_platform_device_add_resources - ++ * wrapper function for platform_device_add_resources ++ * @pdev: platform device allocated by platform_device_alloc to add resources to ++ * @res: set of resources that needs to be allocated for the device ++ * @num: number of resources ++ */ ++int iproc_platform_device_add_resources(struct platform_device *pdev, ++ const struct resource *res, unsigned int num) ++{ ++ return platform_device_add_resources(pdev, res, num); ++} ++EXPORT_SYMBOL(iproc_platform_device_add_resources); ++ ++ ++/** ++ * iproc_platform_device_put - ++ * wrapper function for sysfs_create_group ++ * @kobj: The kobject to create the group on ++ * @grp: The attribute group to create ++ */ ++int iproc_sysfs_create_group(struct kobject *kobj, const struct attribute_group *grp) ++{ ++ return sysfs_create_group(kobj, grp); ++} ++EXPORT_SYMBOL(iproc_sysfs_create_group); ++ ++ ++/** ++ * iproc_sysfs_remove_group - ++ * wrapper function for sysfs_remove_group ++ * @kobj: The kobject which the group is on ++ * @grp: The attribute group to remove ++ */ ++void iproc_sysfs_remove_group(struct kobject * kobj, const struct attribute_group * grp) ++{ ++ sysfs_remove_group(kobj, grp); ++} ++EXPORT_SYMBOL(iproc_sysfs_remove_group); ++ ++/** ++ * iproc__class_create - ++ * wrapper function for __class_create ++ * @ower: pointer to the module that is to "own" this struct class ++ * @name: pointer to a string for the name of this class. ++ * @key: the lock_class_key for this class; used by mutex lock debugging ++ */ ++struct class *iproc__class_create(struct module *owner, const char *name, ++ struct lock_class_key *key) ++{ ++ return __class_create(owner, name, key); ++} ++EXPORT_SYMBOL(iproc__class_create); ++ ++/** ++ * iproc_class_destroy - ++ * wrapper function for class_destroy ++ * @cls: pointer to the struct class that is to be destroyed ++ */ ++void iproc_class_destroy(struct class *cls) ++{ ++ class_destroy(cls); ++} ++EXPORT_SYMBOL(iproc_class_destroy); ++ ++/** ++ * iproc_device_create_file - ++ * wrapper function for device_create_file ++ * @dev: device. ++ * @attr: device attribute descriptor. ++ */ ++int iproc_device_create_file(struct device *dev, ++ const struct device_attribute *attr) ++{ ++ return device_create_file(dev, attr); ++} ++EXPORT_SYMBOL(iproc_device_create_file); ++ ++/** ++ * iproc_device_create - ++ * wrapper function for device_create ++ * ++ * @class: pointer to the struct class that this device should be ++ * registered to ++ * @parent: pointer to the parent struct device of this new device, if any ++ * @devt: the dev_t for the char device to be added ++ * @drvdata: the data to be added to the device for callbacks ++ * @fmt: string for the device's name ++ */ ++struct device *iproc_device_create(struct class *class, ++ struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...) ++{ ++ va_list args; ++ struct device *r; ++ ++ va_start(args, fmt); ++ r = device_create_vargs(class, parent, devt, drvdata, fmt, args); ++ va_end(args); ++ ++ return r; ++} ++EXPORT_SYMBOL(iproc_device_create); ++ ++/** ++ * iproc_device_destroy - ++ * wrapper function for device_destroy ++ * @class: pointer to the struct class that this device was registered with ++ * @devt: the dev_t of the device that was previously registered ++ */ ++void iproc_device_destroy(struct class *class, dev_t devt) ++{ ++ return device_destroy(class, devt); ++} ++EXPORT_SYMBOL(iproc_device_destroy); ++ ++/** ++ * proc_device_remove_file - ++ * wrapper function for device_remove_file ++ * @dev: device. ++ * @attr: device attribute descriptor. ++ */ ++void iproc_device_remove_file(struct device *dev, ++ const struct device_attribute *attr) ++{ ++ return device_remove_file(dev, attr); ++} ++EXPORT_SYMBOL(iproc_device_remove_file); ++ ++/** ++ * iproc_platform_get_irq_byname - ++ * wrapper function for platform_get_irq_byname ++ * @dev: platform device ++ * @name: IRQ name ++ */ ++int iproc_platform_get_irq_byname(struct platform_device *dev, const char *n) ++{ ++ return platform_get_irq_byname(dev,n); ++} ++EXPORT_SYMBOL(iproc_platform_get_irq_byname); ++ ++/** ++ * iproc_gpio_to_irq - ++ * wrapper function for gpio_to_irq ++ * @gpio: gpio whose IRQ will be returned (already requested) ++ */ ++int iproc_gpio_to_irq(unsigned gpio) ++{ ++ return gpio_to_irq(gpio); ++} ++EXPORT_SYMBOL(iproc_gpio_to_irq); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm/mm/init.c b/arch/arm/mm/init.c +--- a/arch/arm/mm/init.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/arch/arm/mm/init.c 2018-05-10 11:31:28.609398566 +0800 +@@ -721,6 +721,16 @@ static void update_sections_early(struct + for_each_process(t) { + if (t->flags & PF_KTHREAD) + continue; ++ ++ /* ++ * A process in getting shut down state (PF_EXITING), with its ++ * task mmu pointer (mm) being NULL, causes hang in ++ * set_section_perms(). ++ * NOTE: update_sections_early() runs if CONFIG_DEBUG_RODATA=y ++ */ ++ if (t->flags & PF_EXITING) ++ continue; ++ + for_each_thread(t, s) + set_section_perms(perms, n, true, s->mm); + } +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms +--- a/arch/arm64/Kconfig.platforms 2017-11-13 02:46:13.000000000 +0800 ++++ b/arch/arm64/Kconfig.platforms 2018-05-10 11:31:28.629398587 +0800 +@@ -254,6 +254,14 @@ config ARCH_XGENE + help + This enables support for AppliedMicro X-Gene SOC Family + ++config ARCH_XGS_IPROC ++ bool "Broadcom iProc XGS SoC Family" ++ select ARCH_REQUIRE_GPIOLIB ++ select ARM_ARCH_TIMER ++ select ARM_GIC ++ help ++ This enables support for Broadcom XGS iProcbased SoC chips ++ + config ARCH_ZX + bool "ZTE ZX SoC Family" + select PINCTRL +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/boot/dts/broadcom/Makefile b/arch/arm64/boot/dts/broadcom/Makefile +--- a/arch/arm64/boot/dts/broadcom/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/arch/arm64/boot/dts/broadcom/Makefile 2018-05-10 11:31:28.637398596 +0800 +@@ -3,6 +3,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rp + + dts-dirs += northstar2 + dts-dirs += stingray ++dts-dirs += helix5 + always := $(dtb-y) + subdir-y := $(dts-dirs) + clean-files := *.dtb +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/boot/dts/broadcom/helix5/Makefile b/arch/arm64/boot/dts/broadcom/helix5/Makefile +--- a/arch/arm64/boot/dts/broadcom/helix5/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm64/boot/dts/broadcom/helix5/Makefile 2018-05-10 11:31:28.637398596 +0800 +@@ -0,0 +1,5 @@ ++dtb-$(CONFIG_ARCH_XGS_IPROC) += bcm956370.dtb ++ ++always := $(dtb-y) ++subdir-y := $(dts-dirs) ++clean-files := *.dtb +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/boot/dts/broadcom/helix5/bcm-helix5.dtsi b/arch/arm64/boot/dts/broadcom/helix5/bcm-helix5.dtsi +--- a/arch/arm64/boot/dts/broadcom/helix5/bcm-helix5.dtsi 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm64/boot/dts/broadcom/helix5/bcm-helix5.dtsi 2018-05-31 15:24:26.192724756 +0800 +@@ -0,0 +1,377 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGdLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include ++#include ++ ++/ { ++ model = "Broadcom HX5 iProc"; ++ compatible = "brcm,helix5"; ++ interrupt-parent = <&gic>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ cpus { ++ #address-cells = <2>; ++ #size-cells = <0>; ++ ++ cpu@0 { ++ device_type = "cpu"; ++ compatible = "arm,cortex-a72", "arm,armv8"; ++ next-level-cache = <&L2>; ++ reg = <0 0>; ++ }; ++ ++ L2: l2-cache@000 { ++ compatible = "cache"; ++ }; ++ }; ++ ++ core { ++ compatible = "simple-bus"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ranges; ++ ++ gic: interrupt-controller@10781000 { ++ compatible = "arm,gic-400"; ++ #interrupt-cells = <3>; ++ interrupt-controller; ++ reg = <0x10781000 0x1000>, ++ <0x10782000 0x2000>, ++ <0x10784000 0x2000>, ++ <0x10786000 0x2000>; ++ interrupts = ; ++ }; ++ ++ timer { ++ compatible = "arm,armv8-timer"; ++ interrupts = , ++ , ++ , ++ ; ++ }; ++ }; ++ ++ clocks { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ osc: oscillator_50M { ++ #clock-cells = <0>; ++ compatible = "fixed-clock"; ++ clock-frequency = <50000000>; ++ // clock-frequency = <35029>; ++ }; ++ ++ iproc_clk: iproc_clk { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&osc>; ++ clock-div = <7>; ++ clock-mult = <120>; ++ }; ++ ++ iproc_clk250: iproc_clk250 { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&osc>; ++ clock-div = <24>; ++ clock-mult = <120>; ++// compatible = "fixed-clock"; ++// clock-frequency = <153600>; ++ }; ++ ++ iproc_clk200: iproc_clk200 { ++ #clock-cells = <0>; ++ compatible = "fixed-factor-clock"; ++ clocks = <&osc>; ++ clock-div = <1>; ++ clock-mult = <4>; ++ }; ++ }; ++ ++ axi { ++ compatible = "simple-bus"; ++ ranges; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ uart0: serial@10200000 { ++ compatible = "ns16550a"; ++ reg = <0x10200000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_clk250>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ uart1: serial@10201000 { ++ compatible = "ns16550a"; ++ reg = <0x10201000 0x100>; ++ interrupts = ; ++ clocks = <&iproc_clk250>; ++ reg-io-width = <4>; ++ reg-shift = <2>; ++ status = "disabled"; ++ }; ++ ++ qspi: spi@18047000 { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ compatible = "brcm,spi-bcm-qspi", "brcm,spi-xgs-iproc-qspi"; ++ reg = <0x15000200 0x188>, ++ <0x15000000 0x050>, ++ <0x10236460 0x004>, ++ <0x150003a0 0x01c>, ++ <0x10241000 0x004>; ++ reg-names = "mspi", "bspi", "intr_regs", "intr_status_reg", "cru_ctrl"; ++ interrupts = ; ++ #chip-select = <0>; ++ clocks = <&iproc_clk250>; ++ status = "disabled"; ++ }; ++ ++ nand: nand@18046000 { ++ compatible = "brcm,nand-iproc", "brcm,brcmnand-v6.1"; ++ reg = <0x15001000 0x600>, ++ <0x1023787c 0x10>, ++ <0x15001f00 0x20>; ++ reg-names = "nand", "iproc-idm", "iproc-ext"; ++ interrupts = ; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ brcm,nand-has-wp; ++ status = "disabled"; ++ }; ++ ++ gmac0: ethernet@10239000 { ++ compatible = "brcm,xgs-iproc-apm,hx5"; ++ reg = <0x10239000 0x1000>, ++ <0x1025e000 0x1000>; ++ reg-names = "apm_base", "idm_base"; ++ pm-type = "pm4x10"; ++ land-idx = <0>; ++ tx-channels = <1>; ++ strict-mode = <1>; ++ interrupts = , ++ , ++ ; ++ status = "disabled"; ++ }; ++ ++ gmac1: ethernet@1023a000 { ++ compatible = "brcm,xgs-iproc-apm,hx5"; ++ reg = <0x1023a000 0x1000>, ++ <0x1025f000 0x1000>; ++ reg-names = "apm_base", "idm_base"; ++ pm-type = "pm4x10"; ++ land-idx = <2>; ++ tx-channels = <1>; ++ strict-mode = <1>; ++ interrupts = , ++ , ++ ; ++ status = "disabled"; ++ }; ++ ++ usbphy: usbphy { ++ #phy-cells = <0>; ++ compatible = "brcm,usb-phy,hx5"; ++ reg = icfg_usb: <0x102378c0 0x50>; ++ status = "disabled"; ++ }; ++ ++ xhci: usb@10243000 { ++ compatible = "generic-xhci"; ++ reg = <0x10243000 0x1000>; ++ interrupts = ; ++ usb-phy = <&usbphy>; ++ status = "disabled"; ++ }; ++ ++ usbd: usbd@10242000 { ++ compatible = "brcm,bdc,hx5"; ++ reg = <0x10242000 0x1000>; ++ interrupts = ; ++ usb-phy = <&usbphy>; ++ status = "disabled"; ++ }; ++ ++ gpio_ccg: gpio@10207000 { ++ compatible = "brcm,iproc-gpio,ccg"; ++ #gpio-cells = <2>; ++ reg = gpio: <0x10207000 0x50>; ++ ngpios = <10>; ++ pin-reg-bit-shift = <0>; ++ pin-base = <0>; ++ gpio-controller; ++ interrupt-controller; ++ interrupts = ; ++ status = "disabled"; ++ }; ++ ++ i2c0: i2c@10202000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x10202000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ i2c1: i2c@10203000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x10203000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ i2c2: i2c@10204000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x10204000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ i2c3: i2c@10205000 { ++ compatible = "brcm,iproc-i2c"; ++ reg = <0x10205000 0x100>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ interrupts = ; ++ clock-frequency = <100000>; ++ status = "disabled"; ++ }; ++ ++ mdio_int: mdio_int@10019000 { ++ compatible = "brcm,iproc-cmicx-mdio"; ++ reg = <0x10019000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <3>; ++ bus-type = "internal"; ++ clocks = <&iproc_clk250>; ++ status = "disabled"; ++ }; ++ ++ mdio_ext: mdio_ext@10019000 { ++ compatible = "brcm,iproc-cmicx-mdio"; ++ reg = <0x10019000 0x1000>; ++ #address-cells = <1>; ++ #size-cells = <0>; ++ #bus-id = <3>; ++ bus-type = "external"; ++ clocks = <&iproc_clk250>; ++ status = "disabled"; ++ }; ++ ++ hwrng: hwrng@1021e000 { ++ compatible = "brcm,iproc-rng200"; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ reg = <0x1021e000 0x1000>; ++ status = "disabled"; ++ }; ++ ++ iproc_wdt: iproc_wdt@10211000 { ++ compatible = "arm,sp805", "arm,primecell"; ++ reg = iproc_wdt_base: <0x10211000 0x1000>, ++ iproc_reset_reg: <0x10220020 0x4>; ++ wdt_boot_status_bit = <0x0>; ++ interrupts = ; ++ clocks = <&iproc_clk250>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ ++ dmac0: dma@10234000 { ++ compatible = "brcm,dma330", "arm,primecell"; ++ reg = dma330_base: <0x10234000 0x1000>; ++ interrupts = , ++ , ++ , ++ , ++ , ++ , ++ , ++ ; ++ clocks = <&iproc_clk250>; ++ clock-names = "apb_pclk"; ++ #dma-cells = <1>; ++ #dma-channels = <8>; ++ #dma-requests = <16>; ++ status = "disabled"; ++ }; ++ ++ pl022: dma@10206000 { ++ compatible = "arm,pl022", "arm,primecell"; ++ reg = pl022_base: <0x10206000 0x1000>; ++ interrupts = ; ++ clocks = <&iproc_clk250>; ++ clock-names = "apb_pclk"; ++ status = "disabled"; ++ }; ++ }; ++ ++ dmu_pcu: dmu_pcu@10220000 { ++ compatible = "brcm,iproc-dmu-pcu"; ++ reg = <0 0x10220000 0 0xc00>; ++ }; ++ ++ iproc_wrap_ctrl: iproc_wrap_ctrl@10220c00 { ++ compatible = "brcm,iproc-wrap-ctrl"; ++ reg = <0 0x10220c00 0 0x100>; ++ }; ++ ++ iproc_idm: iproc_idm@10250000 { ++ compatible = "brcm,iproc-idm"; ++ reg = idm0: <0x10250000 0x100000>; ++ interrupts = ; ++ }; ++ ++ iproc_cmicx: iproc_cmicx@10100000 { ++ compatible = "brcm,iproc-cmicx"; ++ reg = cmicx: <0x10100000 0x200000>; ++ top-blkid = <7>; ++ amac-blkid = <38>; ++ interrupts = ; ++ }; ++}; +Binary files a/arch/arm64/boot/dts/broadcom/helix5/bcm956370.dtb and b/arch/arm64/boot/dts/broadcom/helix5/bcm956370.dtb differ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/boot/dts/broadcom/helix5/bcm956370.dts b/arch/arm64/boot/dts/broadcom/helix5/bcm956370.dts +--- a/arch/arm64/boot/dts/broadcom/helix5/bcm956370.dts 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm64/boot/dts/broadcom/helix5/bcm956370.dts 2018-05-31 15:24:26.196724803 +0800 +@@ -0,0 +1,216 @@ ++/* ++ * BSD LICENSE ++ * ++ * Copyright(c) 2016 Broadcom Corporation. All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * ++ * * Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * * Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in ++ * the documentation and/or other materials provided with the ++ * distribution. ++ * * Neither the name of Broadcom Corporation nor the names of its ++ * contributors may be used to endorse or promote products derived ++ * from this software without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/dts-v1/; ++ ++#include "bcm-helix5.dtsi" ++ ++/ { ++ model = "Broadcom HX5 SVK (BCM956370K)"; ++ compatible = "brcm,bcm956370k", "brcm,helix5"; ++ ++ aliases { ++ serial0 = &uart0; ++ serial1 = &uart1; ++ ethernet0 = &gmac0; ++ ethernet1 = &gmac1; ++ }; ++ ++ chosen { ++ bootargs = "console=ttyS0,115200n8 maxcpus=1 mem=496M"; ++ }; ++}; ++ ++&uart0 { ++ status = "okay"; ++}; ++ ++&uart1 { ++ status = "okay"; ++}; ++ ++&gmac0 { ++ status = "okay"; ++ phy-handle = <&apm_phy0>; ++ phy-mode = "sgmii"; ++}; ++ ++&gmac1 { ++ status = "okay"; ++ phy-handle = <&apm_phy1>; ++ phy-mode = "sgmii"; ++}; ++/* ++&usbphy { ++ status = "okay"; ++}; ++ ++&xhci { ++ status = "okay"; ++}; ++ ++&usbd { ++ status = "okay"; ++}; ++*/ ++&gpio_ccg { ++ status = "okay"; ++}; ++ ++/* ++&pcie0 { ++ status = "okay"; ++}; ++*/ ++ ++&i2c0 { ++ status = "okay"; ++ eeprom@0x50 { ++ compatible = "atmel,24c64"; ++ reg = <0x50>; ++ pagesize = <32>; ++ }; ++}; ++ ++&i2c1 { ++ status = "okay"; ++}; ++ ++&i2c2 { ++ status = "okay"; ++}; ++ ++&i2c3 { ++ status = "okay"; ++}; ++ ++&nand { ++ status = "okay"; ++ nandcs@1 { ++ compatible = "brcm,nandcs"; ++ reg = <0>; ++ nand-on-flash-bbt; ++ //nand-bus-width = <8>; ++ nand-ecc-strength = <24>; ++ nand-ecc-step-size = <1024>; ++ brcm,nand-oob-sector-size = <27>; ++ #address-cells = <1>; ++ #size-cells = <1>; ++ ++ partition@0 { ++ label = "nboot"; ++ reg = <0x00000000 0x00200000>; ++ /* read-only; */ ++ }; ++ partition@1 { ++ label = "nenv"; ++ reg = <0x00200000 0x00400000>; ++ }; ++ partition@2 { ++ label = "nsystem"; ++ reg = <0x00600000 0x00a00000>; ++ }; ++ partition@3 { ++ label = "nrootfs"; ++ reg = <0x01000000 0x00f000000>; ++ }; ++ partition@4 { ++ label = "ncustfs"; ++ reg = <0x10000000 0x070000000>; ++ }; ++ }; ++}; ++ ++&qspi { ++ status = "okay"; ++ flash: m25p80@0 { ++ #address-cells = <1>; ++ #size-cells = <1>; ++ compatible = "m25p80"; ++ m25p,fast-read = <1>; ++ spi-max-frequency = <62500000>; ++ reg = <0x0>; ++ partition@0 { ++ label = "boot"; ++ reg = <0x00000000 0x000c0000>; ++ //read-only; ++ }; ++ partition@1 { ++ label = "env"; ++ reg = <0x000c0000 0x00040000>; ++ }; ++ partition@2 { ++ label = "system"; ++ reg = <0x00100000 0x00f00000>; ++ }; ++ partition@3 { ++ label = "rootfs"; ++ reg = <0x01000000 0x03000000>; ++ }; ++ }; ++}; ++ ++&mdio_int { ++ status = "okay"; ++ apm_serdes0: apm_serdes@0 { ++ reg = <3>; ++ }; ++ apm_serdes1: apm_serdes@1 { ++ reg = <5>; ++ }; ++}; ++ ++&mdio_ext { ++ status = "okay"; ++ apm_phy0: apm_phy@0 { ++ reg = <16>; ++ }; ++ apm_phy1: apm_phy@1 { ++ reg = <17>; ++ }; ++}; ++ ++&hwrng { ++ status = "okay"; ++}; ++ ++&iproc_wdt { ++ status = "okay"; ++}; ++ ++&dmac0 { ++ status = "okay"; ++}; ++ ++&pl022 { ++ status = "okay"; ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/boot/dts/broadcom/helix5/helix5.its b/arch/arm64/boot/dts/broadcom/helix5/helix5.its +--- a/arch/arm64/boot/dts/broadcom/helix5/helix5.its 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm64/boot/dts/broadcom/helix5/helix5.its 2018-05-10 11:31:28.641398600 +0800 +@@ -0,0 +1,44 @@ ++/dts-v1/; ++ ++/ { ++ description = "Linux kernel and FDT blob"; ++ #address-cells = <1>; ++ ++ images { ++ kernel_1 { ++ description = "Broadcom iProc Linux"; ++ data = /incbin/("../../../Image.gz"); ++ type = "kernel"; ++ arch = "arm64"; ++ os = "linux"; ++ compression = "gzip"; ++ load = <0x60080000>; ++ entry = <0x60080000>; ++ hash_1 { ++ algo = "crc32"; ++ }; ++ }; ++ ++ fdt_1 { ++ description = "Flattened Device Tree blob - bcm956370.dtb"; ++ data = /incbin/("./bcm956370.dtb"); ++ type = "flat_dt"; ++ arch = "arm64"; ++ compression = "none"; ++ load = <0x60000000>; ++ hash_1 { ++ algo = "crc32"; ++ }; ++ }; ++ }; ++ ++ configurations { ++ default = "conf_1"; ++ conf_1 { ++ description = "Boot Linux kernel with FDT blob "; ++ kernel = "kernel_1"; ++ fdt = "fdt_1"; ++ }; ++ }; ++}; ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/configs/iproc_a72_be_defconfig b/arch/arm64/configs/iproc_a72_be_defconfig +--- a/arch/arm64/configs/iproc_a72_be_defconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm64/configs/iproc_a72_be_defconfig 2018-05-30 15:50:51.028753148 +0800 +@@ -0,0 +1,217 @@ ++CONFIG_CROSS_COMPILE="$CROSS_COMPILE" ++CONFIG_SYSVIPC=y ++# CONFIG_FHANDLE is not set ++CONFIG_USELIB=y ++CONFIG_NO_HZ=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_LOG_BUF_SHIFT=16 ++CONFIG_LOG_CPU_MAX_BUF_SHIFT=13 ++CONFIG_SYSCTL_SYSCALL=y ++# CONFIG_ELF_CORE is not set ++# CONFIG_BASE_FULL is not set ++# CONFIG_EPOLL is not set ++# CONFIG_SIGNALFD is not set ++# CONFIG_TIMERFD is not set ++# CONFIG_EVENTFD is not set ++# CONFIG_SHMEM is not set ++# CONFIG_AIO is not set ++CONFIG_EMBEDDED=y ++# CONFIG_SLUB_DEBUG is not set ++# CONFIG_COMPAT_BRK is not set ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_ARCH_XGS_IPROC=y ++CONFIG_PCI=y ++CONFIG_CPU_BIG_ENDIAN=y ++CONFIG_NR_CPUS=4 ++CONFIG_PREEMPT=y ++CONFIG_HZ_100=y ++# CONFIG_COMPACTION is not set ++CONFIG_CMA=y ++CONFIG_CMA_DEBUG=y ++CONFIG_CMDLINE="console=ttyS0,115200n8 maxcpus=2 mem=496M" ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++# 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 is not set ++CONFIG_IPV6_TUNNEL=y ++CONFIG_NETFILTER=y ++CONFIG_BRIDGE_NETFILTER=y ++CONFIG_NETFILTER_NETLINK_QUEUE=y ++CONFIG_NETFILTER_NETLINK_LOG=y ++CONFIG_NF_CONNTRACK=y ++# CONFIG_NF_CT_PROTO_DCCP is not set ++# CONFIG_NF_CT_PROTO_SCTP is not set ++# CONFIG_NF_CT_PROTO_UDPLITE is not set ++CONFIG_NF_CONNTRACK_FTP=y ++CONFIG_NF_CONNTRACK_TFTP=y ++CONFIG_NETFILTER_XT_MARK=y ++CONFIG_NETFILTER_XT_TARGET_CT=y ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=y ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y ++CONFIG_NETFILTER_XT_MATCH_HELPER=y ++CONFIG_NETFILTER_XT_MATCH_STATE=y ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=y ++CONFIG_NF_CONNTRACK_IPV4=y ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_AH=y ++CONFIG_IP_NF_MATCH_ECN=y ++CONFIG_IP_NF_MATCH_TTL=y ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=y ++CONFIG_IP_NF_MANGLE=y ++CONFIG_IP_NF_TARGET_ECN=y ++CONFIG_IP_NF_TARGET_TTL=y ++CONFIG_IP_NF_RAW=y ++CONFIG_IP_NF_ARPTABLES=y ++CONFIG_IP_NF_ARPFILTER=y ++CONFIG_IP_NF_ARP_MANGLE=y ++CONFIG_NF_CONNTRACK_IPV6=y ++CONFIG_IP6_NF_IPTABLES=y ++CONFIG_IP6_NF_MATCH_RPFILTER=y ++CONFIG_IP6_NF_MATCH_RT=y ++CONFIG_IP6_NF_FILTER=y ++CONFIG_IP6_NF_TARGET_REJECT=y ++CONFIG_IP6_NF_MANGLE=y ++CONFIG_IP6_NF_RAW=y ++CONFIG_BRIDGE=y ++CONFIG_VLAN_8021Q=y ++CONFIG_VLAN_8021Q_GVRP=y ++# CONFIG_WIRELESS is not set ++CONFIG_UEVENT_HELPER_PATH="/sbin/mdev" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=32 ++CONFIG_MTD=y ++CONFIG_MTD_TESTS=m ++CONFIG_MTD_CMDLINE_PARTS=y ++CONFIG_MTD_BLOCK=y ++CONFIG_MTD_CFI=y ++CONFIG_MTD_JEDECPROBE=y ++CONFIG_MTD_CFI_ADV_OPTIONS=y ++CONFIG_MTD_CFI_LE_BYTE_SWAP=y ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_CFI_AMDSTD=y ++CONFIG_MTD_CFI_STAA=y ++CONFIG_MTD_M25P80=y ++CONFIG_MTD_NAND=y ++CONFIG_MTD_NAND_BRCMNAND=y ++CONFIG_MTD_SPI_NOR=y ++CONFIG_MTD_UBI=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_EEPROM_AT24=y ++CONFIG_SCSI=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_CHR_DEV_ST=y ++CONFIG_CHR_DEV_SG=y ++CONFIG_SCSI_CONSTANTS=y ++CONFIG_SCSI_LOGGING=y ++CONFIG_NETDEVICES=y ++CONFIG_BONDING=y ++CONFIG_TIGON3=y ++# CONFIG_BGMAC_PLATFORM is not set ++CONFIG_APM=y ++CONFIG_MDIO_XGS_IPROC=y ++CONFIG_BROADCOM_PHY=y ++CONFIG_XGS_IPROC_SERDES=y ++# CONFIG_WLAN is not set ++# CONFIG_INPUT is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_VT is not set ++# CONFIG_LEGACY_PTYS is not set ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=2 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=2 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_8250_DETECT_IRQ=y ++CONFIG_SERIAL_8250_RSA=y ++CONFIG_SERIAL_8250_DW=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_XGS_IPROC_RNG=y ++CONFIG_I2C=y ++# CONFIG_I2C_COMPAT is not set ++CONFIG_I2C_CHARDEV=y ++# CONFIG_I2C_HELPER_AUTO is not set ++CONFIG_SPI=y ++CONFIG_SPI_PL022=y ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_WATCHDOG=y ++CONFIG_ARM_SP805_WATCHDOG=y ++# CONFIG_VGA_ARB is not set ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_DYNAMIC_MINORS=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PLATFORM=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_XGS_IPROC_DRD=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_BDC_UDC=y ++CONFIG_USB_BDC_XGS_IPROC=y ++CONFIG_USB_G_SERIAL=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_DMADEVICES=y ++CONFIG_DMADEVICES_DEBUG=y ++CONFIG_DMADEVICES_VDEBUG=y ++CONFIG_PL330_DMA=y ++# CONFIG_COMMON_CLK_XGENE is not set ++CONFIG_ACPI=y ++CONFIG_EXT2_FS=y ++CONFIG_EXT3_FS=y ++# CONFIG_DNOTIFY is not set ++CONFIG_AUTOFS4_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_NTFS_FS=y ++# CONFIG_PROC_PAGE_MONITOR is not set ++CONFIG_JFFS2_FS=y ++CONFIG_UBIFS_FS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFSD=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_DEBUG_INFO=y ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++CONFIG_DEBUG_FS=y ++CONFIG_MAGIC_SYSRQ=y ++# CONFIG_SCHED_DEBUG is not set ++CONFIG_RCU_CPU_STALL_TIMEOUT=60 ++# CONFIG_FTRACE is not set ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_ANSI_CPRNG=m ++# CONFIG_CRYPTO_HW is not set ++CONFIG_ARM64_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM64_CE=y ++CONFIG_CRYPTO_SHA2_ARM64_CE=y ++CONFIG_CRYPTO_GHASH_ARM64_CE=y ++CONFIG_CRYPTO_AES_ARM64_CE_CCM=y ++CONFIG_CRYPTO_AES_ARM64_CE_BLK=y ++CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/configs/iproc_a72_defconfig b/arch/arm64/configs/iproc_a72_defconfig +--- a/arch/arm64/configs/iproc_a72_defconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm64/configs/iproc_a72_defconfig 2018-05-30 15:50:51.028753148 +0800 +@@ -0,0 +1,214 @@ ++CONFIG_CROSS_COMPILE="$CROSS_COMPILE" ++CONFIG_SYSVIPC=y ++# CONFIG_FHANDLE is not set ++CONFIG_USELIB=y ++CONFIG_NO_HZ=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_LOG_BUF_SHIFT=16 ++CONFIG_LOG_CPU_MAX_BUF_SHIFT=13 ++CONFIG_SYSCTL_SYSCALL=y ++# CONFIG_ELF_CORE is not set ++# CONFIG_BASE_FULL is not set ++# CONFIG_EPOLL is not set ++# CONFIG_SIGNALFD is not set ++# CONFIG_TIMERFD is not set ++# CONFIG_EVENTFD is not set ++# CONFIG_SHMEM is not set ++# CONFIG_AIO is not set ++CONFIG_EMBEDDED=y ++# CONFIG_SLUB_DEBUG is not set ++# CONFIG_COMPAT_BRK is not set ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_ARCH_XGS_IPROC=y ++CONFIG_PCI=y ++CONFIG_NR_CPUS=4 ++CONFIG_PREEMPT=y ++CONFIG_HZ_100=y ++# CONFIG_COMPACTION is not set ++CONFIG_CMA=y ++CONFIG_CMA_DEBUG=y ++CONFIG_CMDLINE="console=ttyS0,115200n8 maxcpus=2 mem=496M" ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++# 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 is not set ++CONFIG_IPV6_TUNNEL=y ++CONFIG_NETFILTER=y ++CONFIG_BRIDGE_NETFILTER=y ++CONFIG_NETFILTER_NETLINK_QUEUE=y ++CONFIG_NETFILTER_NETLINK_LOG=y ++CONFIG_NF_CONNTRACK=y ++# CONFIG_NF_CT_PROTO_DCCP is not set ++# CONFIG_NF_CT_PROTO_SCTP is not set ++# CONFIG_NF_CT_PROTO_UDPLITE is not set ++CONFIG_NF_CONNTRACK_FTP=y ++CONFIG_NF_CONNTRACK_TFTP=y ++CONFIG_NETFILTER_XT_MARK=y ++CONFIG_NETFILTER_XT_TARGET_CT=y ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=y ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y ++CONFIG_NETFILTER_XT_MATCH_HELPER=y ++CONFIG_NETFILTER_XT_MATCH_STATE=y ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=y ++CONFIG_NF_CONNTRACK_IPV4=y ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_AH=y ++CONFIG_IP_NF_MATCH_ECN=y ++CONFIG_IP_NF_MATCH_TTL=y ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=y ++CONFIG_IP_NF_MANGLE=y ++CONFIG_IP_NF_TARGET_ECN=y ++CONFIG_IP_NF_TARGET_TTL=y ++CONFIG_IP_NF_RAW=y ++CONFIG_IP_NF_ARPTABLES=y ++CONFIG_IP_NF_ARPFILTER=y ++CONFIG_IP_NF_ARP_MANGLE=y ++CONFIG_NF_CONNTRACK_IPV6=y ++CONFIG_IP6_NF_IPTABLES=y ++CONFIG_IP6_NF_MATCH_RPFILTER=y ++CONFIG_IP6_NF_MATCH_RT=y ++CONFIG_IP6_NF_FILTER=y ++CONFIG_IP6_NF_TARGET_REJECT=y ++CONFIG_IP6_NF_MANGLE=y ++CONFIG_IP6_NF_RAW=y ++CONFIG_BRIDGE=y ++CONFIG_VLAN_8021Q=y ++CONFIG_VLAN_8021Q_GVRP=y ++# CONFIG_WIRELESS is not set ++CONFIG_UEVENT_HELPER_PATH="/sbin/mdev" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=32 ++CONFIG_MTD=y ++CONFIG_MTD_TESTS=m ++CONFIG_MTD_CMDLINE_PARTS=y ++CONFIG_MTD_BLOCK=y ++CONFIG_MTD_CFI=y ++CONFIG_MTD_JEDECPROBE=y ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_CFI_AMDSTD=y ++CONFIG_MTD_CFI_STAA=y ++CONFIG_MTD_M25P80=y ++CONFIG_MTD_NAND=y ++CONFIG_MTD_NAND_BRCMNAND=y ++CONFIG_MTD_SPI_NOR=y ++CONFIG_MTD_UBI=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_EEPROM_AT24=y ++CONFIG_SCSI=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_CHR_DEV_ST=y ++CONFIG_CHR_DEV_SG=y ++CONFIG_SCSI_CONSTANTS=y ++CONFIG_SCSI_LOGGING=y ++CONFIG_NETDEVICES=y ++CONFIG_BONDING=y ++CONFIG_TIGON3=y ++# CONFIG_BGMAC_PLATFORM is not set ++CONFIG_APM=y ++CONFIG_MDIO_XGS_IPROC=y ++CONFIG_BROADCOM_PHY=y ++CONFIG_XGS_IPROC_SERDES=y ++# CONFIG_WLAN is not set ++# CONFIG_INPUT is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_VT is not set ++# CONFIG_LEGACY_PTYS is not set ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=2 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=2 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_8250_DETECT_IRQ=y ++CONFIG_SERIAL_8250_RSA=y ++CONFIG_SERIAL_8250_DW=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_XGS_IPROC_RNG=y ++CONFIG_I2C=y ++# CONFIG_I2C_COMPAT is not set ++CONFIG_I2C_CHARDEV=y ++# CONFIG_I2C_HELPER_AUTO is not set ++CONFIG_SPI=y ++CONFIG_SPI_PL022=y ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_WATCHDOG=y ++CONFIG_ARM_SP805_WATCHDOG=y ++# CONFIG_VGA_ARB is not set ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_DYNAMIC_MINORS=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PLATFORM=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_XGS_IPROC_DRD=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_BDC_UDC=y ++CONFIG_USB_BDC_XGS_IPROC=y ++CONFIG_USB_G_SERIAL=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_DMADEVICES=y ++CONFIG_DMADEVICES_DEBUG=y ++CONFIG_DMADEVICES_VDEBUG=y ++CONFIG_PL330_DMA=y ++# CONFIG_COMMON_CLK_XGENE is not set ++CONFIG_ACPI=y ++CONFIG_EXT2_FS=y ++CONFIG_EXT3_FS=y ++# CONFIG_DNOTIFY is not set ++CONFIG_AUTOFS4_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_NTFS_FS=y ++# CONFIG_PROC_PAGE_MONITOR is not set ++CONFIG_JFFS2_FS=y ++CONFIG_UBIFS_FS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFSD=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_DEBUG_INFO=y ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++CONFIG_DEBUG_FS=y ++CONFIG_MAGIC_SYSRQ=y ++# CONFIG_SCHED_DEBUG is not set ++CONFIG_RCU_CPU_STALL_TIMEOUT=60 ++# CONFIG_FTRACE is not set ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_ANSI_CPRNG=m ++# CONFIG_CRYPTO_HW is not set ++CONFIG_ARM64_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM64_CE=y ++CONFIG_CRYPTO_SHA2_ARM64_CE=y ++CONFIG_CRYPTO_GHASH_ARM64_CE=y ++CONFIG_CRYPTO_AES_ARM64_CE_CCM=y ++CONFIG_CRYPTO_AES_ARM64_CE_BLK=y ++CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/arch/arm64/crypto/sha256-core.S b/arch/arm64/crypto/sha256-core.S +--- a/arch/arm64/crypto/sha256-core.S 1970-01-01 08:00:00.000000000 +0800 ++++ b/arch/arm64/crypto/sha256-core.S 2018-05-10 12:01:00.939666414 +0800 +@@ -0,0 +1,2061 @@ ++// Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. ++// ++// Licensed under the OpenSSL license (the "License"). You may not use ++// this file except in compliance with the License. You can obtain a copy ++// in the file LICENSE in the source distribution or at ++// https://www.openssl.org/source/license.html ++ ++// ==================================================================== ++// Written by Andy Polyakov for the OpenSSL ++// project. The module is, however, dual licensed under OpenSSL and ++// CRYPTOGAMS licenses depending on where you obtain it. For further ++// details see http://www.openssl.org/~appro/cryptogams/. ++// ++// Permission to use under GPLv2 terms is granted. ++// ==================================================================== ++// ++// SHA256/512 for ARMv8. ++// ++// Performance in cycles per processed byte and improvement coefficient ++// over code generated with "default" compiler: ++// ++// SHA256-hw SHA256(*) SHA512 ++// Apple A7 1.97 10.5 (+33%) 6.73 (-1%(**)) ++// Cortex-A53 2.38 15.5 (+115%) 10.0 (+150%(***)) ++// Cortex-A57 2.31 11.6 (+86%) 7.51 (+260%(***)) ++// Denver 2.01 10.5 (+26%) 6.70 (+8%) ++// X-Gene 20.0 (+100%) 12.8 (+300%(***)) ++// Mongoose 2.36 13.0 (+50%) 8.36 (+33%) ++// ++// (*) Software SHA256 results are of lesser relevance, presented ++// mostly for informational purposes. ++// (**) The result is a trade-off: it's possible to improve it by ++// 10% (or by 1 cycle per round), but at the cost of 20% loss ++// on Cortex-A53 (or by 4 cycles per round). ++// (***) Super-impressive coefficients over gcc-generated code are ++// indication of some compiler "pathology", most notably code ++// generated with -mgeneral-regs-only is significanty faster ++// and the gap is only 40-90%. ++// ++// October 2016. ++// ++// Originally it was reckoned that it makes no sense to implement NEON ++// version of SHA256 for 64-bit processors. This is because performance ++// improvement on most wide-spread Cortex-A5x processors was observed ++// to be marginal, same on Cortex-A53 and ~10% on A57. But then it was ++// observed that 32-bit NEON SHA256 performs significantly better than ++// 64-bit scalar version on *some* of the more recent processors. As ++// result 64-bit NEON version of SHA256 was added to provide best ++// all-round performance. For example it executes ~30% faster on X-Gene ++// and Mongoose. [For reference, NEON version of SHA512 is bound to ++// deliver much less improvement, likely *negative* on Cortex-A5x. ++// Which is why NEON support is limited to SHA256.] ++ ++#ifndef __KERNEL__ ++# include "arm_arch.h" ++#endif ++ ++.text ++ ++.extern OPENSSL_armcap_P ++.globl sha256_block_data_order ++.type sha256_block_data_order,%function ++.align 6 ++sha256_block_data_order: ++#ifndef __KERNEL__ ++# ifdef __ILP32__ ++ ldrsw x16,.LOPENSSL_armcap_P ++# else ++ ldr x16,.LOPENSSL_armcap_P ++# endif ++ adr x17,.LOPENSSL_armcap_P ++ add x16,x16,x17 ++ ldr w16,[x16] ++ tst w16,#ARMV8_SHA256 ++ b.ne .Lv8_entry ++ tst w16,#ARMV7_NEON ++ b.ne .Lneon_entry ++#endif ++ stp x29,x30,[sp,#-128]! ++ add x29,sp,#0 ++ ++ stp x19,x20,[sp,#16] ++ stp x21,x22,[sp,#32] ++ stp x23,x24,[sp,#48] ++ stp x25,x26,[sp,#64] ++ stp x27,x28,[sp,#80] ++ sub sp,sp,#4*4 ++ ++ ldp w20,w21,[x0] // load context ++ ldp w22,w23,[x0,#2*4] ++ ldp w24,w25,[x0,#4*4] ++ add x2,x1,x2,lsl#6 // end of input ++ ldp w26,w27,[x0,#6*4] ++ adr x30,.LK256 ++ stp x0,x2,[x29,#96] ++ ++.Loop: ++ ldp w3,w4,[x1],#2*4 ++ ldr w19,[x30],#4 // *K++ ++ eor w28,w21,w22 // magic seed ++ str x1,[x29,#112] ++#ifndef __AARCH64EB__ ++ rev w3,w3 // 0 ++#endif ++ ror w16,w24,#6 ++ add w27,w27,w19 // h+=K[i] ++ eor w6,w24,w24,ror#14 ++ and w17,w25,w24 ++ bic w19,w26,w24 ++ add w27,w27,w3 // h+=X[i] ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w20,w21 // a^b, b^c in next round ++ eor w16,w16,w6,ror#11 // Sigma1(e) ++ ror w6,w20,#2 ++ add w27,w27,w17 // h+=Ch(e,f,g) ++ eor w17,w20,w20,ror#9 ++ add w27,w27,w16 // h+=Sigma1(e) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ add w23,w23,w27 // d+=h ++ eor w28,w28,w21 // Maj(a,b,c) ++ eor w17,w6,w17,ror#13 // Sigma0(a) ++ add w27,w27,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ //add w27,w27,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w4,w4 // 1 ++#endif ++ ldp w5,w6,[x1],#2*4 ++ add w27,w27,w17 // h+=Sigma0(a) ++ ror w16,w23,#6 ++ add w26,w26,w28 // h+=K[i] ++ eor w7,w23,w23,ror#14 ++ and w17,w24,w23 ++ bic w28,w25,w23 ++ add w26,w26,w4 // h+=X[i] ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w27,w20 // a^b, b^c in next round ++ eor w16,w16,w7,ror#11 // Sigma1(e) ++ ror w7,w27,#2 ++ add w26,w26,w17 // h+=Ch(e,f,g) ++ eor w17,w27,w27,ror#9 ++ add w26,w26,w16 // h+=Sigma1(e) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ add w22,w22,w26 // d+=h ++ eor w19,w19,w20 // Maj(a,b,c) ++ eor w17,w7,w17,ror#13 // Sigma0(a) ++ add w26,w26,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ //add w26,w26,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w5,w5 // 2 ++#endif ++ add w26,w26,w17 // h+=Sigma0(a) ++ ror w16,w22,#6 ++ add w25,w25,w19 // h+=K[i] ++ eor w8,w22,w22,ror#14 ++ and w17,w23,w22 ++ bic w19,w24,w22 ++ add w25,w25,w5 // h+=X[i] ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w26,w27 // a^b, b^c in next round ++ eor w16,w16,w8,ror#11 // Sigma1(e) ++ ror w8,w26,#2 ++ add w25,w25,w17 // h+=Ch(e,f,g) ++ eor w17,w26,w26,ror#9 ++ add w25,w25,w16 // h+=Sigma1(e) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ add w21,w21,w25 // d+=h ++ eor w28,w28,w27 // Maj(a,b,c) ++ eor w17,w8,w17,ror#13 // Sigma0(a) ++ add w25,w25,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ //add w25,w25,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w6,w6 // 3 ++#endif ++ ldp w7,w8,[x1],#2*4 ++ add w25,w25,w17 // h+=Sigma0(a) ++ ror w16,w21,#6 ++ add w24,w24,w28 // h+=K[i] ++ eor w9,w21,w21,ror#14 ++ and w17,w22,w21 ++ bic w28,w23,w21 ++ add w24,w24,w6 // h+=X[i] ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w25,w26 // a^b, b^c in next round ++ eor w16,w16,w9,ror#11 // Sigma1(e) ++ ror w9,w25,#2 ++ add w24,w24,w17 // h+=Ch(e,f,g) ++ eor w17,w25,w25,ror#9 ++ add w24,w24,w16 // h+=Sigma1(e) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ add w20,w20,w24 // d+=h ++ eor w19,w19,w26 // Maj(a,b,c) ++ eor w17,w9,w17,ror#13 // Sigma0(a) ++ add w24,w24,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ //add w24,w24,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w7,w7 // 4 ++#endif ++ add w24,w24,w17 // h+=Sigma0(a) ++ ror w16,w20,#6 ++ add w23,w23,w19 // h+=K[i] ++ eor w10,w20,w20,ror#14 ++ and w17,w21,w20 ++ bic w19,w22,w20 ++ add w23,w23,w7 // h+=X[i] ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w24,w25 // a^b, b^c in next round ++ eor w16,w16,w10,ror#11 // Sigma1(e) ++ ror w10,w24,#2 ++ add w23,w23,w17 // h+=Ch(e,f,g) ++ eor w17,w24,w24,ror#9 ++ add w23,w23,w16 // h+=Sigma1(e) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ add w27,w27,w23 // d+=h ++ eor w28,w28,w25 // Maj(a,b,c) ++ eor w17,w10,w17,ror#13 // Sigma0(a) ++ add w23,w23,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ //add w23,w23,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w8,w8 // 5 ++#endif ++ ldp w9,w10,[x1],#2*4 ++ add w23,w23,w17 // h+=Sigma0(a) ++ ror w16,w27,#6 ++ add w22,w22,w28 // h+=K[i] ++ eor w11,w27,w27,ror#14 ++ and w17,w20,w27 ++ bic w28,w21,w27 ++ add w22,w22,w8 // h+=X[i] ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w23,w24 // a^b, b^c in next round ++ eor w16,w16,w11,ror#11 // Sigma1(e) ++ ror w11,w23,#2 ++ add w22,w22,w17 // h+=Ch(e,f,g) ++ eor w17,w23,w23,ror#9 ++ add w22,w22,w16 // h+=Sigma1(e) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ add w26,w26,w22 // d+=h ++ eor w19,w19,w24 // Maj(a,b,c) ++ eor w17,w11,w17,ror#13 // Sigma0(a) ++ add w22,w22,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ //add w22,w22,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w9,w9 // 6 ++#endif ++ add w22,w22,w17 // h+=Sigma0(a) ++ ror w16,w26,#6 ++ add w21,w21,w19 // h+=K[i] ++ eor w12,w26,w26,ror#14 ++ and w17,w27,w26 ++ bic w19,w20,w26 ++ add w21,w21,w9 // h+=X[i] ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w22,w23 // a^b, b^c in next round ++ eor w16,w16,w12,ror#11 // Sigma1(e) ++ ror w12,w22,#2 ++ add w21,w21,w17 // h+=Ch(e,f,g) ++ eor w17,w22,w22,ror#9 ++ add w21,w21,w16 // h+=Sigma1(e) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ add w25,w25,w21 // d+=h ++ eor w28,w28,w23 // Maj(a,b,c) ++ eor w17,w12,w17,ror#13 // Sigma0(a) ++ add w21,w21,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ //add w21,w21,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w10,w10 // 7 ++#endif ++ ldp w11,w12,[x1],#2*4 ++ add w21,w21,w17 // h+=Sigma0(a) ++ ror w16,w25,#6 ++ add w20,w20,w28 // h+=K[i] ++ eor w13,w25,w25,ror#14 ++ and w17,w26,w25 ++ bic w28,w27,w25 ++ add w20,w20,w10 // h+=X[i] ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w21,w22 // a^b, b^c in next round ++ eor w16,w16,w13,ror#11 // Sigma1(e) ++ ror w13,w21,#2 ++ add w20,w20,w17 // h+=Ch(e,f,g) ++ eor w17,w21,w21,ror#9 ++ add w20,w20,w16 // h+=Sigma1(e) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ add w24,w24,w20 // d+=h ++ eor w19,w19,w22 // Maj(a,b,c) ++ eor w17,w13,w17,ror#13 // Sigma0(a) ++ add w20,w20,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ //add w20,w20,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w11,w11 // 8 ++#endif ++ add w20,w20,w17 // h+=Sigma0(a) ++ ror w16,w24,#6 ++ add w27,w27,w19 // h+=K[i] ++ eor w14,w24,w24,ror#14 ++ and w17,w25,w24 ++ bic w19,w26,w24 ++ add w27,w27,w11 // h+=X[i] ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w20,w21 // a^b, b^c in next round ++ eor w16,w16,w14,ror#11 // Sigma1(e) ++ ror w14,w20,#2 ++ add w27,w27,w17 // h+=Ch(e,f,g) ++ eor w17,w20,w20,ror#9 ++ add w27,w27,w16 // h+=Sigma1(e) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ add w23,w23,w27 // d+=h ++ eor w28,w28,w21 // Maj(a,b,c) ++ eor w17,w14,w17,ror#13 // Sigma0(a) ++ add w27,w27,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ //add w27,w27,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w12,w12 // 9 ++#endif ++ ldp w13,w14,[x1],#2*4 ++ add w27,w27,w17 // h+=Sigma0(a) ++ ror w16,w23,#6 ++ add w26,w26,w28 // h+=K[i] ++ eor w15,w23,w23,ror#14 ++ and w17,w24,w23 ++ bic w28,w25,w23 ++ add w26,w26,w12 // h+=X[i] ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w27,w20 // a^b, b^c in next round ++ eor w16,w16,w15,ror#11 // Sigma1(e) ++ ror w15,w27,#2 ++ add w26,w26,w17 // h+=Ch(e,f,g) ++ eor w17,w27,w27,ror#9 ++ add w26,w26,w16 // h+=Sigma1(e) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ add w22,w22,w26 // d+=h ++ eor w19,w19,w20 // Maj(a,b,c) ++ eor w17,w15,w17,ror#13 // Sigma0(a) ++ add w26,w26,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ //add w26,w26,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w13,w13 // 10 ++#endif ++ add w26,w26,w17 // h+=Sigma0(a) ++ ror w16,w22,#6 ++ add w25,w25,w19 // h+=K[i] ++ eor w0,w22,w22,ror#14 ++ and w17,w23,w22 ++ bic w19,w24,w22 ++ add w25,w25,w13 // h+=X[i] ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w26,w27 // a^b, b^c in next round ++ eor w16,w16,w0,ror#11 // Sigma1(e) ++ ror w0,w26,#2 ++ add w25,w25,w17 // h+=Ch(e,f,g) ++ eor w17,w26,w26,ror#9 ++ add w25,w25,w16 // h+=Sigma1(e) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ add w21,w21,w25 // d+=h ++ eor w28,w28,w27 // Maj(a,b,c) ++ eor w17,w0,w17,ror#13 // Sigma0(a) ++ add w25,w25,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ //add w25,w25,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w14,w14 // 11 ++#endif ++ ldp w15,w0,[x1],#2*4 ++ add w25,w25,w17 // h+=Sigma0(a) ++ str w6,[sp,#12] ++ ror w16,w21,#6 ++ add w24,w24,w28 // h+=K[i] ++ eor w6,w21,w21,ror#14 ++ and w17,w22,w21 ++ bic w28,w23,w21 ++ add w24,w24,w14 // h+=X[i] ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w25,w26 // a^b, b^c in next round ++ eor w16,w16,w6,ror#11 // Sigma1(e) ++ ror w6,w25,#2 ++ add w24,w24,w17 // h+=Ch(e,f,g) ++ eor w17,w25,w25,ror#9 ++ add w24,w24,w16 // h+=Sigma1(e) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ add w20,w20,w24 // d+=h ++ eor w19,w19,w26 // Maj(a,b,c) ++ eor w17,w6,w17,ror#13 // Sigma0(a) ++ add w24,w24,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ //add w24,w24,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w15,w15 // 12 ++#endif ++ add w24,w24,w17 // h+=Sigma0(a) ++ str w7,[sp,#0] ++ ror w16,w20,#6 ++ add w23,w23,w19 // h+=K[i] ++ eor w7,w20,w20,ror#14 ++ and w17,w21,w20 ++ bic w19,w22,w20 ++ add w23,w23,w15 // h+=X[i] ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w24,w25 // a^b, b^c in next round ++ eor w16,w16,w7,ror#11 // Sigma1(e) ++ ror w7,w24,#2 ++ add w23,w23,w17 // h+=Ch(e,f,g) ++ eor w17,w24,w24,ror#9 ++ add w23,w23,w16 // h+=Sigma1(e) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ add w27,w27,w23 // d+=h ++ eor w28,w28,w25 // Maj(a,b,c) ++ eor w17,w7,w17,ror#13 // Sigma0(a) ++ add w23,w23,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ //add w23,w23,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w0,w0 // 13 ++#endif ++ ldp w1,w2,[x1] ++ add w23,w23,w17 // h+=Sigma0(a) ++ str w8,[sp,#4] ++ ror w16,w27,#6 ++ add w22,w22,w28 // h+=K[i] ++ eor w8,w27,w27,ror#14 ++ and w17,w20,w27 ++ bic w28,w21,w27 ++ add w22,w22,w0 // h+=X[i] ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w23,w24 // a^b, b^c in next round ++ eor w16,w16,w8,ror#11 // Sigma1(e) ++ ror w8,w23,#2 ++ add w22,w22,w17 // h+=Ch(e,f,g) ++ eor w17,w23,w23,ror#9 ++ add w22,w22,w16 // h+=Sigma1(e) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ add w26,w26,w22 // d+=h ++ eor w19,w19,w24 // Maj(a,b,c) ++ eor w17,w8,w17,ror#13 // Sigma0(a) ++ add w22,w22,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ //add w22,w22,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w1,w1 // 14 ++#endif ++ ldr w6,[sp,#12] ++ add w22,w22,w17 // h+=Sigma0(a) ++ str w9,[sp,#8] ++ ror w16,w26,#6 ++ add w21,w21,w19 // h+=K[i] ++ eor w9,w26,w26,ror#14 ++ and w17,w27,w26 ++ bic w19,w20,w26 ++ add w21,w21,w1 // h+=X[i] ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w22,w23 // a^b, b^c in next round ++ eor w16,w16,w9,ror#11 // Sigma1(e) ++ ror w9,w22,#2 ++ add w21,w21,w17 // h+=Ch(e,f,g) ++ eor w17,w22,w22,ror#9 ++ add w21,w21,w16 // h+=Sigma1(e) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ add w25,w25,w21 // d+=h ++ eor w28,w28,w23 // Maj(a,b,c) ++ eor w17,w9,w17,ror#13 // Sigma0(a) ++ add w21,w21,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ //add w21,w21,w17 // h+=Sigma0(a) ++#ifndef __AARCH64EB__ ++ rev w2,w2 // 15 ++#endif ++ ldr w7,[sp,#0] ++ add w21,w21,w17 // h+=Sigma0(a) ++ str w10,[sp,#12] ++ ror w16,w25,#6 ++ add w20,w20,w28 // h+=K[i] ++ ror w9,w4,#7 ++ and w17,w26,w25 ++ ror w8,w1,#17 ++ bic w28,w27,w25 ++ ror w10,w21,#2 ++ add w20,w20,w2 // h+=X[i] ++ eor w16,w16,w25,ror#11 ++ eor w9,w9,w4,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w21,w22 // a^b, b^c in next round ++ eor w16,w16,w25,ror#25 // Sigma1(e) ++ eor w10,w10,w21,ror#13 ++ add w20,w20,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w8,w8,w1,ror#19 ++ eor w9,w9,w4,lsr#3 // sigma0(X[i+1]) ++ add w20,w20,w16 // h+=Sigma1(e) ++ eor w19,w19,w22 // Maj(a,b,c) ++ eor w17,w10,w21,ror#22 // Sigma0(a) ++ eor w8,w8,w1,lsr#10 // sigma1(X[i+14]) ++ add w3,w3,w12 ++ add w24,w24,w20 // d+=h ++ add w20,w20,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w3,w3,w9 ++ add w20,w20,w17 // h+=Sigma0(a) ++ add w3,w3,w8 ++.Loop_16_xx: ++ ldr w8,[sp,#4] ++ str w11,[sp,#0] ++ ror w16,w24,#6 ++ add w27,w27,w19 // h+=K[i] ++ ror w10,w5,#7 ++ and w17,w25,w24 ++ ror w9,w2,#17 ++ bic w19,w26,w24 ++ ror w11,w20,#2 ++ add w27,w27,w3 // h+=X[i] ++ eor w16,w16,w24,ror#11 ++ eor w10,w10,w5,ror#18 ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w20,w21 // a^b, b^c in next round ++ eor w16,w16,w24,ror#25 // Sigma1(e) ++ eor w11,w11,w20,ror#13 ++ add w27,w27,w17 // h+=Ch(e,f,g) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ eor w9,w9,w2,ror#19 ++ eor w10,w10,w5,lsr#3 // sigma0(X[i+1]) ++ add w27,w27,w16 // h+=Sigma1(e) ++ eor w28,w28,w21 // Maj(a,b,c) ++ eor w17,w11,w20,ror#22 // Sigma0(a) ++ eor w9,w9,w2,lsr#10 // sigma1(X[i+14]) ++ add w4,w4,w13 ++ add w23,w23,w27 // d+=h ++ add w27,w27,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ add w4,w4,w10 ++ add w27,w27,w17 // h+=Sigma0(a) ++ add w4,w4,w9 ++ ldr w9,[sp,#8] ++ str w12,[sp,#4] ++ ror w16,w23,#6 ++ add w26,w26,w28 // h+=K[i] ++ ror w11,w6,#7 ++ and w17,w24,w23 ++ ror w10,w3,#17 ++ bic w28,w25,w23 ++ ror w12,w27,#2 ++ add w26,w26,w4 // h+=X[i] ++ eor w16,w16,w23,ror#11 ++ eor w11,w11,w6,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w27,w20 // a^b, b^c in next round ++ eor w16,w16,w23,ror#25 // Sigma1(e) ++ eor w12,w12,w27,ror#13 ++ add w26,w26,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w10,w10,w3,ror#19 ++ eor w11,w11,w6,lsr#3 // sigma0(X[i+1]) ++ add w26,w26,w16 // h+=Sigma1(e) ++ eor w19,w19,w20 // Maj(a,b,c) ++ eor w17,w12,w27,ror#22 // Sigma0(a) ++ eor w10,w10,w3,lsr#10 // sigma1(X[i+14]) ++ add w5,w5,w14 ++ add w22,w22,w26 // d+=h ++ add w26,w26,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w5,w5,w11 ++ add w26,w26,w17 // h+=Sigma0(a) ++ add w5,w5,w10 ++ ldr w10,[sp,#12] ++ str w13,[sp,#8] ++ ror w16,w22,#6 ++ add w25,w25,w19 // h+=K[i] ++ ror w12,w7,#7 ++ and w17,w23,w22 ++ ror w11,w4,#17 ++ bic w19,w24,w22 ++ ror w13,w26,#2 ++ add w25,w25,w5 // h+=X[i] ++ eor w16,w16,w22,ror#11 ++ eor w12,w12,w7,ror#18 ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w26,w27 // a^b, b^c in next round ++ eor w16,w16,w22,ror#25 // Sigma1(e) ++ eor w13,w13,w26,ror#13 ++ add w25,w25,w17 // h+=Ch(e,f,g) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ eor w11,w11,w4,ror#19 ++ eor w12,w12,w7,lsr#3 // sigma0(X[i+1]) ++ add w25,w25,w16 // h+=Sigma1(e) ++ eor w28,w28,w27 // Maj(a,b,c) ++ eor w17,w13,w26,ror#22 // Sigma0(a) ++ eor w11,w11,w4,lsr#10 // sigma1(X[i+14]) ++ add w6,w6,w15 ++ add w21,w21,w25 // d+=h ++ add w25,w25,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ add w6,w6,w12 ++ add w25,w25,w17 // h+=Sigma0(a) ++ add w6,w6,w11 ++ ldr w11,[sp,#0] ++ str w14,[sp,#12] ++ ror w16,w21,#6 ++ add w24,w24,w28 // h+=K[i] ++ ror w13,w8,#7 ++ and w17,w22,w21 ++ ror w12,w5,#17 ++ bic w28,w23,w21 ++ ror w14,w25,#2 ++ add w24,w24,w6 // h+=X[i] ++ eor w16,w16,w21,ror#11 ++ eor w13,w13,w8,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w25,w26 // a^b, b^c in next round ++ eor w16,w16,w21,ror#25 // Sigma1(e) ++ eor w14,w14,w25,ror#13 ++ add w24,w24,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w12,w12,w5,ror#19 ++ eor w13,w13,w8,lsr#3 // sigma0(X[i+1]) ++ add w24,w24,w16 // h+=Sigma1(e) ++ eor w19,w19,w26 // Maj(a,b,c) ++ eor w17,w14,w25,ror#22 // Sigma0(a) ++ eor w12,w12,w5,lsr#10 // sigma1(X[i+14]) ++ add w7,w7,w0 ++ add w20,w20,w24 // d+=h ++ add w24,w24,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w7,w7,w13 ++ add w24,w24,w17 // h+=Sigma0(a) ++ add w7,w7,w12 ++ ldr w12,[sp,#4] ++ str w15,[sp,#0] ++ ror w16,w20,#6 ++ add w23,w23,w19 // h+=K[i] ++ ror w14,w9,#7 ++ and w17,w21,w20 ++ ror w13,w6,#17 ++ bic w19,w22,w20 ++ ror w15,w24,#2 ++ add w23,w23,w7 // h+=X[i] ++ eor w16,w16,w20,ror#11 ++ eor w14,w14,w9,ror#18 ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w24,w25 // a^b, b^c in next round ++ eor w16,w16,w20,ror#25 // Sigma1(e) ++ eor w15,w15,w24,ror#13 ++ add w23,w23,w17 // h+=Ch(e,f,g) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ eor w13,w13,w6,ror#19 ++ eor w14,w14,w9,lsr#3 // sigma0(X[i+1]) ++ add w23,w23,w16 // h+=Sigma1(e) ++ eor w28,w28,w25 // Maj(a,b,c) ++ eor w17,w15,w24,ror#22 // Sigma0(a) ++ eor w13,w13,w6,lsr#10 // sigma1(X[i+14]) ++ add w8,w8,w1 ++ add w27,w27,w23 // d+=h ++ add w23,w23,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ add w8,w8,w14 ++ add w23,w23,w17 // h+=Sigma0(a) ++ add w8,w8,w13 ++ ldr w13,[sp,#8] ++ str w0,[sp,#4] ++ ror w16,w27,#6 ++ add w22,w22,w28 // h+=K[i] ++ ror w15,w10,#7 ++ and w17,w20,w27 ++ ror w14,w7,#17 ++ bic w28,w21,w27 ++ ror w0,w23,#2 ++ add w22,w22,w8 // h+=X[i] ++ eor w16,w16,w27,ror#11 ++ eor w15,w15,w10,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w23,w24 // a^b, b^c in next round ++ eor w16,w16,w27,ror#25 // Sigma1(e) ++ eor w0,w0,w23,ror#13 ++ add w22,w22,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w14,w14,w7,ror#19 ++ eor w15,w15,w10,lsr#3 // sigma0(X[i+1]) ++ add w22,w22,w16 // h+=Sigma1(e) ++ eor w19,w19,w24 // Maj(a,b,c) ++ eor w17,w0,w23,ror#22 // Sigma0(a) ++ eor w14,w14,w7,lsr#10 // sigma1(X[i+14]) ++ add w9,w9,w2 ++ add w26,w26,w22 // d+=h ++ add w22,w22,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w9,w9,w15 ++ add w22,w22,w17 // h+=Sigma0(a) ++ add w9,w9,w14 ++ ldr w14,[sp,#12] ++ str w1,[sp,#8] ++ ror w16,w26,#6 ++ add w21,w21,w19 // h+=K[i] ++ ror w0,w11,#7 ++ and w17,w27,w26 ++ ror w15,w8,#17 ++ bic w19,w20,w26 ++ ror w1,w22,#2 ++ add w21,w21,w9 // h+=X[i] ++ eor w16,w16,w26,ror#11 ++ eor w0,w0,w11,ror#18 ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w22,w23 // a^b, b^c in next round ++ eor w16,w16,w26,ror#25 // Sigma1(e) ++ eor w1,w1,w22,ror#13 ++ add w21,w21,w17 // h+=Ch(e,f,g) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ eor w15,w15,w8,ror#19 ++ eor w0,w0,w11,lsr#3 // sigma0(X[i+1]) ++ add w21,w21,w16 // h+=Sigma1(e) ++ eor w28,w28,w23 // Maj(a,b,c) ++ eor w17,w1,w22,ror#22 // Sigma0(a) ++ eor w15,w15,w8,lsr#10 // sigma1(X[i+14]) ++ add w10,w10,w3 ++ add w25,w25,w21 // d+=h ++ add w21,w21,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ add w10,w10,w0 ++ add w21,w21,w17 // h+=Sigma0(a) ++ add w10,w10,w15 ++ ldr w15,[sp,#0] ++ str w2,[sp,#12] ++ ror w16,w25,#6 ++ add w20,w20,w28 // h+=K[i] ++ ror w1,w12,#7 ++ and w17,w26,w25 ++ ror w0,w9,#17 ++ bic w28,w27,w25 ++ ror w2,w21,#2 ++ add w20,w20,w10 // h+=X[i] ++ eor w16,w16,w25,ror#11 ++ eor w1,w1,w12,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w21,w22 // a^b, b^c in next round ++ eor w16,w16,w25,ror#25 // Sigma1(e) ++ eor w2,w2,w21,ror#13 ++ add w20,w20,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w0,w0,w9,ror#19 ++ eor w1,w1,w12,lsr#3 // sigma0(X[i+1]) ++ add w20,w20,w16 // h+=Sigma1(e) ++ eor w19,w19,w22 // Maj(a,b,c) ++ eor w17,w2,w21,ror#22 // Sigma0(a) ++ eor w0,w0,w9,lsr#10 // sigma1(X[i+14]) ++ add w11,w11,w4 ++ add w24,w24,w20 // d+=h ++ add w20,w20,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w11,w11,w1 ++ add w20,w20,w17 // h+=Sigma0(a) ++ add w11,w11,w0 ++ ldr w0,[sp,#4] ++ str w3,[sp,#0] ++ ror w16,w24,#6 ++ add w27,w27,w19 // h+=K[i] ++ ror w2,w13,#7 ++ and w17,w25,w24 ++ ror w1,w10,#17 ++ bic w19,w26,w24 ++ ror w3,w20,#2 ++ add w27,w27,w11 // h+=X[i] ++ eor w16,w16,w24,ror#11 ++ eor w2,w2,w13,ror#18 ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w20,w21 // a^b, b^c in next round ++ eor w16,w16,w24,ror#25 // Sigma1(e) ++ eor w3,w3,w20,ror#13 ++ add w27,w27,w17 // h+=Ch(e,f,g) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ eor w1,w1,w10,ror#19 ++ eor w2,w2,w13,lsr#3 // sigma0(X[i+1]) ++ add w27,w27,w16 // h+=Sigma1(e) ++ eor w28,w28,w21 // Maj(a,b,c) ++ eor w17,w3,w20,ror#22 // Sigma0(a) ++ eor w1,w1,w10,lsr#10 // sigma1(X[i+14]) ++ add w12,w12,w5 ++ add w23,w23,w27 // d+=h ++ add w27,w27,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ add w12,w12,w2 ++ add w27,w27,w17 // h+=Sigma0(a) ++ add w12,w12,w1 ++ ldr w1,[sp,#8] ++ str w4,[sp,#4] ++ ror w16,w23,#6 ++ add w26,w26,w28 // h+=K[i] ++ ror w3,w14,#7 ++ and w17,w24,w23 ++ ror w2,w11,#17 ++ bic w28,w25,w23 ++ ror w4,w27,#2 ++ add w26,w26,w12 // h+=X[i] ++ eor w16,w16,w23,ror#11 ++ eor w3,w3,w14,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w27,w20 // a^b, b^c in next round ++ eor w16,w16,w23,ror#25 // Sigma1(e) ++ eor w4,w4,w27,ror#13 ++ add w26,w26,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w2,w2,w11,ror#19 ++ eor w3,w3,w14,lsr#3 // sigma0(X[i+1]) ++ add w26,w26,w16 // h+=Sigma1(e) ++ eor w19,w19,w20 // Maj(a,b,c) ++ eor w17,w4,w27,ror#22 // Sigma0(a) ++ eor w2,w2,w11,lsr#10 // sigma1(X[i+14]) ++ add w13,w13,w6 ++ add w22,w22,w26 // d+=h ++ add w26,w26,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w13,w13,w3 ++ add w26,w26,w17 // h+=Sigma0(a) ++ add w13,w13,w2 ++ ldr w2,[sp,#12] ++ str w5,[sp,#8] ++ ror w16,w22,#6 ++ add w25,w25,w19 // h+=K[i] ++ ror w4,w15,#7 ++ and w17,w23,w22 ++ ror w3,w12,#17 ++ bic w19,w24,w22 ++ ror w5,w26,#2 ++ add w25,w25,w13 // h+=X[i] ++ eor w16,w16,w22,ror#11 ++ eor w4,w4,w15,ror#18 ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w26,w27 // a^b, b^c in next round ++ eor w16,w16,w22,ror#25 // Sigma1(e) ++ eor w5,w5,w26,ror#13 ++ add w25,w25,w17 // h+=Ch(e,f,g) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ eor w3,w3,w12,ror#19 ++ eor w4,w4,w15,lsr#3 // sigma0(X[i+1]) ++ add w25,w25,w16 // h+=Sigma1(e) ++ eor w28,w28,w27 // Maj(a,b,c) ++ eor w17,w5,w26,ror#22 // Sigma0(a) ++ eor w3,w3,w12,lsr#10 // sigma1(X[i+14]) ++ add w14,w14,w7 ++ add w21,w21,w25 // d+=h ++ add w25,w25,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ add w14,w14,w4 ++ add w25,w25,w17 // h+=Sigma0(a) ++ add w14,w14,w3 ++ ldr w3,[sp,#0] ++ str w6,[sp,#12] ++ ror w16,w21,#6 ++ add w24,w24,w28 // h+=K[i] ++ ror w5,w0,#7 ++ and w17,w22,w21 ++ ror w4,w13,#17 ++ bic w28,w23,w21 ++ ror w6,w25,#2 ++ add w24,w24,w14 // h+=X[i] ++ eor w16,w16,w21,ror#11 ++ eor w5,w5,w0,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w25,w26 // a^b, b^c in next round ++ eor w16,w16,w21,ror#25 // Sigma1(e) ++ eor w6,w6,w25,ror#13 ++ add w24,w24,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w4,w4,w13,ror#19 ++ eor w5,w5,w0,lsr#3 // sigma0(X[i+1]) ++ add w24,w24,w16 // h+=Sigma1(e) ++ eor w19,w19,w26 // Maj(a,b,c) ++ eor w17,w6,w25,ror#22 // Sigma0(a) ++ eor w4,w4,w13,lsr#10 // sigma1(X[i+14]) ++ add w15,w15,w8 ++ add w20,w20,w24 // d+=h ++ add w24,w24,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w15,w15,w5 ++ add w24,w24,w17 // h+=Sigma0(a) ++ add w15,w15,w4 ++ ldr w4,[sp,#4] ++ str w7,[sp,#0] ++ ror w16,w20,#6 ++ add w23,w23,w19 // h+=K[i] ++ ror w6,w1,#7 ++ and w17,w21,w20 ++ ror w5,w14,#17 ++ bic w19,w22,w20 ++ ror w7,w24,#2 ++ add w23,w23,w15 // h+=X[i] ++ eor w16,w16,w20,ror#11 ++ eor w6,w6,w1,ror#18 ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w24,w25 // a^b, b^c in next round ++ eor w16,w16,w20,ror#25 // Sigma1(e) ++ eor w7,w7,w24,ror#13 ++ add w23,w23,w17 // h+=Ch(e,f,g) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ eor w5,w5,w14,ror#19 ++ eor w6,w6,w1,lsr#3 // sigma0(X[i+1]) ++ add w23,w23,w16 // h+=Sigma1(e) ++ eor w28,w28,w25 // Maj(a,b,c) ++ eor w17,w7,w24,ror#22 // Sigma0(a) ++ eor w5,w5,w14,lsr#10 // sigma1(X[i+14]) ++ add w0,w0,w9 ++ add w27,w27,w23 // d+=h ++ add w23,w23,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ add w0,w0,w6 ++ add w23,w23,w17 // h+=Sigma0(a) ++ add w0,w0,w5 ++ ldr w5,[sp,#8] ++ str w8,[sp,#4] ++ ror w16,w27,#6 ++ add w22,w22,w28 // h+=K[i] ++ ror w7,w2,#7 ++ and w17,w20,w27 ++ ror w6,w15,#17 ++ bic w28,w21,w27 ++ ror w8,w23,#2 ++ add w22,w22,w0 // h+=X[i] ++ eor w16,w16,w27,ror#11 ++ eor w7,w7,w2,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w23,w24 // a^b, b^c in next round ++ eor w16,w16,w27,ror#25 // Sigma1(e) ++ eor w8,w8,w23,ror#13 ++ add w22,w22,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w6,w6,w15,ror#19 ++ eor w7,w7,w2,lsr#3 // sigma0(X[i+1]) ++ add w22,w22,w16 // h+=Sigma1(e) ++ eor w19,w19,w24 // Maj(a,b,c) ++ eor w17,w8,w23,ror#22 // Sigma0(a) ++ eor w6,w6,w15,lsr#10 // sigma1(X[i+14]) ++ add w1,w1,w10 ++ add w26,w26,w22 // d+=h ++ add w22,w22,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w1,w1,w7 ++ add w22,w22,w17 // h+=Sigma0(a) ++ add w1,w1,w6 ++ ldr w6,[sp,#12] ++ str w9,[sp,#8] ++ ror w16,w26,#6 ++ add w21,w21,w19 // h+=K[i] ++ ror w8,w3,#7 ++ and w17,w27,w26 ++ ror w7,w0,#17 ++ bic w19,w20,w26 ++ ror w9,w22,#2 ++ add w21,w21,w1 // h+=X[i] ++ eor w16,w16,w26,ror#11 ++ eor w8,w8,w3,ror#18 ++ orr w17,w17,w19 // Ch(e,f,g) ++ eor w19,w22,w23 // a^b, b^c in next round ++ eor w16,w16,w26,ror#25 // Sigma1(e) ++ eor w9,w9,w22,ror#13 ++ add w21,w21,w17 // h+=Ch(e,f,g) ++ and w28,w28,w19 // (b^c)&=(a^b) ++ eor w7,w7,w0,ror#19 ++ eor w8,w8,w3,lsr#3 // sigma0(X[i+1]) ++ add w21,w21,w16 // h+=Sigma1(e) ++ eor w28,w28,w23 // Maj(a,b,c) ++ eor w17,w9,w22,ror#22 // Sigma0(a) ++ eor w7,w7,w0,lsr#10 // sigma1(X[i+14]) ++ add w2,w2,w11 ++ add w25,w25,w21 // d+=h ++ add w21,w21,w28 // h+=Maj(a,b,c) ++ ldr w28,[x30],#4 // *K++, w19 in next round ++ add w2,w2,w8 ++ add w21,w21,w17 // h+=Sigma0(a) ++ add w2,w2,w7 ++ ldr w7,[sp,#0] ++ str w10,[sp,#12] ++ ror w16,w25,#6 ++ add w20,w20,w28 // h+=K[i] ++ ror w9,w4,#7 ++ and w17,w26,w25 ++ ror w8,w1,#17 ++ bic w28,w27,w25 ++ ror w10,w21,#2 ++ add w20,w20,w2 // h+=X[i] ++ eor w16,w16,w25,ror#11 ++ eor w9,w9,w4,ror#18 ++ orr w17,w17,w28 // Ch(e,f,g) ++ eor w28,w21,w22 // a^b, b^c in next round ++ eor w16,w16,w25,ror#25 // Sigma1(e) ++ eor w10,w10,w21,ror#13 ++ add w20,w20,w17 // h+=Ch(e,f,g) ++ and w19,w19,w28 // (b^c)&=(a^b) ++ eor w8,w8,w1,ror#19 ++ eor w9,w9,w4,lsr#3 // sigma0(X[i+1]) ++ add w20,w20,w16 // h+=Sigma1(e) ++ eor w19,w19,w22 // Maj(a,b,c) ++ eor w17,w10,w21,ror#22 // Sigma0(a) ++ eor w8,w8,w1,lsr#10 // sigma1(X[i+14]) ++ add w3,w3,w12 ++ add w24,w24,w20 // d+=h ++ add w20,w20,w19 // h+=Maj(a,b,c) ++ ldr w19,[x30],#4 // *K++, w28 in next round ++ add w3,w3,w9 ++ add w20,w20,w17 // h+=Sigma0(a) ++ add w3,w3,w8 ++ cbnz w19,.Loop_16_xx ++ ++ ldp x0,x2,[x29,#96] ++ ldr x1,[x29,#112] ++ sub x30,x30,#260 // rewind ++ ++ ldp w3,w4,[x0] ++ ldp w5,w6,[x0,#2*4] ++ add x1,x1,#14*4 // advance input pointer ++ ldp w7,w8,[x0,#4*4] ++ add w20,w20,w3 ++ ldp w9,w10,[x0,#6*4] ++ add w21,w21,w4 ++ add w22,w22,w5 ++ add w23,w23,w6 ++ stp w20,w21,[x0] ++ add w24,w24,w7 ++ add w25,w25,w8 ++ stp w22,w23,[x0,#2*4] ++ add w26,w26,w9 ++ add w27,w27,w10 ++ cmp x1,x2 ++ stp w24,w25,[x0,#4*4] ++ stp w26,w27,[x0,#6*4] ++ b.ne .Loop ++ ++ ldp x19,x20,[x29,#16] ++ add sp,sp,#4*4 ++ ldp x21,x22,[x29,#32] ++ ldp x23,x24,[x29,#48] ++ ldp x25,x26,[x29,#64] ++ ldp x27,x28,[x29,#80] ++ ldp x29,x30,[sp],#128 ++ ret ++.size sha256_block_data_order,.-sha256_block_data_order ++ ++.align 6 ++.type .LK256,%object ++.LK256: ++ .long 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5 ++ .long 0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5 ++ .long 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3 ++ .long 0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174 ++ .long 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc ++ .long 0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da ++ .long 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7 ++ .long 0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967 ++ .long 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13 ++ .long 0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85 ++ .long 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3 ++ .long 0xd192e819,0xd6990624,0xf40e3585,0x106aa070 ++ .long 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5 ++ .long 0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3 ++ .long 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208 ++ .long 0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2 ++ .long 0 //terminator ++.size .LK256,.-.LK256 ++#ifndef __KERNEL__ ++.align 3 ++.LOPENSSL_armcap_P: ++# ifdef __ILP32__ ++ .long OPENSSL_armcap_P-. ++# else ++ .quad OPENSSL_armcap_P-. ++# endif ++#endif ++.asciz "SHA256 block transform for ARMv8, CRYPTOGAMS by " ++.align 2 ++#ifndef __KERNEL__ ++.type sha256_block_armv8,%function ++.align 6 ++sha256_block_armv8: ++.Lv8_entry: ++ stp x29,x30,[sp,#-16]! ++ add x29,sp,#0 ++ ++ ld1 {v0.4s,v1.4s},[x0] ++ adr x3,.LK256 ++ ++.Loop_hw: ++ ld1 {v4.16b-v7.16b},[x1],#64 ++ sub x2,x2,#1 ++ ld1 {v16.4s},[x3],#16 ++ rev32 v4.16b,v4.16b ++ rev32 v5.16b,v5.16b ++ rev32 v6.16b,v6.16b ++ rev32 v7.16b,v7.16b ++ orr v18.16b,v0.16b,v0.16b // offload ++ orr v19.16b,v1.16b,v1.16b ++ ld1 {v17.4s},[x3],#16 ++ add v16.4s,v16.4s,v4.4s ++ .inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s ++ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s ++ .inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b ++ ld1 {v16.4s},[x3],#16 ++ add v17.4s,v17.4s,v5.4s ++ .inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s ++ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s ++ .inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b ++ ld1 {v17.4s},[x3],#16 ++ add v16.4s,v16.4s,v6.4s ++ .inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s ++ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s ++ .inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b ++ ld1 {v16.4s},[x3],#16 ++ add v17.4s,v17.4s,v7.4s ++ .inst 0x5e282887 //sha256su0 v7.16b,v4.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s ++ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s ++ .inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b ++ ld1 {v17.4s},[x3],#16 ++ add v16.4s,v16.4s,v4.4s ++ .inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s ++ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s ++ .inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b ++ ld1 {v16.4s},[x3],#16 ++ add v17.4s,v17.4s,v5.4s ++ .inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s ++ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s ++ .inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b ++ ld1 {v17.4s},[x3],#16 ++ add v16.4s,v16.4s,v6.4s ++ .inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s ++ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s ++ .inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b ++ ld1 {v16.4s},[x3],#16 ++ add v17.4s,v17.4s,v7.4s ++ .inst 0x5e282887 //sha256su0 v7.16b,v4.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s ++ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s ++ .inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b ++ ld1 {v17.4s},[x3],#16 ++ add v16.4s,v16.4s,v4.4s ++ .inst 0x5e2828a4 //sha256su0 v4.16b,v5.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s ++ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s ++ .inst 0x5e0760c4 //sha256su1 v4.16b,v6.16b,v7.16b ++ ld1 {v16.4s},[x3],#16 ++ add v17.4s,v17.4s,v5.4s ++ .inst 0x5e2828c5 //sha256su0 v5.16b,v6.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s ++ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s ++ .inst 0x5e0460e5 //sha256su1 v5.16b,v7.16b,v4.16b ++ ld1 {v17.4s},[x3],#16 ++ add v16.4s,v16.4s,v6.4s ++ .inst 0x5e2828e6 //sha256su0 v6.16b,v7.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s ++ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s ++ .inst 0x5e056086 //sha256su1 v6.16b,v4.16b,v5.16b ++ ld1 {v16.4s},[x3],#16 ++ add v17.4s,v17.4s,v7.4s ++ .inst 0x5e282887 //sha256su0 v7.16b,v4.16b ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s ++ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s ++ .inst 0x5e0660a7 //sha256su1 v7.16b,v5.16b,v6.16b ++ ld1 {v17.4s},[x3],#16 ++ add v16.4s,v16.4s,v4.4s ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s ++ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s ++ ++ ld1 {v16.4s},[x3],#16 ++ add v17.4s,v17.4s,v5.4s ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s ++ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s ++ ++ ld1 {v17.4s},[x3] ++ add v16.4s,v16.4s,v6.4s ++ sub x3,x3,#64*4-16 // rewind ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e104020 //sha256h v0.16b,v1.16b,v16.4s ++ .inst 0x5e105041 //sha256h2 v1.16b,v2.16b,v16.4s ++ ++ add v17.4s,v17.4s,v7.4s ++ orr v2.16b,v0.16b,v0.16b ++ .inst 0x5e114020 //sha256h v0.16b,v1.16b,v17.4s ++ .inst 0x5e115041 //sha256h2 v1.16b,v2.16b,v17.4s ++ ++ add v0.4s,v0.4s,v18.4s ++ add v1.4s,v1.4s,v19.4s ++ ++ cbnz x2,.Loop_hw ++ ++ st1 {v0.4s,v1.4s},[x0] ++ ++ ldr x29,[sp],#16 ++ ret ++.size sha256_block_armv8,.-sha256_block_armv8 ++#endif ++#ifdef __KERNEL__ ++.globl sha256_block_neon ++#endif ++.type sha256_block_neon,%function ++.align 4 ++sha256_block_neon: ++.Lneon_entry: ++ stp x29, x30, [sp, #-16]! ++ mov x29, sp ++ sub sp,sp,#16*4 ++ ++ adr x16,.LK256 ++ add x2,x1,x2,lsl#6 // len to point at the end of inp ++ ++ ld1 {v0.16b},[x1], #16 ++ ld1 {v1.16b},[x1], #16 ++ ld1 {v2.16b},[x1], #16 ++ ld1 {v3.16b},[x1], #16 ++ ld1 {v4.4s},[x16], #16 ++ ld1 {v5.4s},[x16], #16 ++ ld1 {v6.4s},[x16], #16 ++ ld1 {v7.4s},[x16], #16 ++ rev32 v0.16b,v0.16b // yes, even on ++ rev32 v1.16b,v1.16b // big-endian ++ rev32 v2.16b,v2.16b ++ rev32 v3.16b,v3.16b ++ mov x17,sp ++ add v4.4s,v4.4s,v0.4s ++ add v5.4s,v5.4s,v1.4s ++ add v6.4s,v6.4s,v2.4s ++ st1 {v4.4s-v5.4s},[x17], #32 ++ add v7.4s,v7.4s,v3.4s ++ st1 {v6.4s-v7.4s},[x17] ++ sub x17,x17,#32 ++ ++ ldp w3,w4,[x0] ++ ldp w5,w6,[x0,#8] ++ ldp w7,w8,[x0,#16] ++ ldp w9,w10,[x0,#24] ++ ldr w12,[sp,#0] ++ mov w13,wzr ++ eor w14,w4,w5 ++ mov w15,wzr ++ b .L_00_48 ++ ++.align 4 ++.L_00_48: ++ ext v4.16b,v0.16b,v1.16b,#4 ++ add w10,w10,w12 ++ add w3,w3,w15 ++ and w12,w8,w7 ++ bic w15,w9,w7 ++ ext v7.16b,v2.16b,v3.16b,#4 ++ eor w11,w7,w7,ror#5 ++ add w3,w3,w13 ++ mov d19,v3.d[1] ++ orr w12,w12,w15 ++ eor w11,w11,w7,ror#19 ++ ushr v6.4s,v4.4s,#7 ++ eor w15,w3,w3,ror#11 ++ ushr v5.4s,v4.4s,#3 ++ add w10,w10,w12 ++ add v0.4s,v0.4s,v7.4s ++ ror w11,w11,#6 ++ sli v6.4s,v4.4s,#25 ++ eor w13,w3,w4 ++ eor w15,w15,w3,ror#20 ++ ushr v7.4s,v4.4s,#18 ++ add w10,w10,w11 ++ ldr w12,[sp,#4] ++ and w14,w14,w13 ++ eor v5.16b,v5.16b,v6.16b ++ ror w15,w15,#2 ++ add w6,w6,w10 ++ sli v7.4s,v4.4s,#14 ++ eor w14,w14,w4 ++ ushr v16.4s,v19.4s,#17 ++ add w9,w9,w12 ++ add w10,w10,w15 ++ and w12,w7,w6 ++ eor v5.16b,v5.16b,v7.16b ++ bic w15,w8,w6 ++ eor w11,w6,w6,ror#5 ++ sli v16.4s,v19.4s,#15 ++ add w10,w10,w14 ++ orr w12,w12,w15 ++ ushr v17.4s,v19.4s,#10 ++ eor w11,w11,w6,ror#19 ++ eor w15,w10,w10,ror#11 ++ ushr v7.4s,v19.4s,#19 ++ add w9,w9,w12 ++ ror w11,w11,#6 ++ add v0.4s,v0.4s,v5.4s ++ eor w14,w10,w3 ++ eor w15,w15,w10,ror#20 ++ sli v7.4s,v19.4s,#13 ++ add w9,w9,w11 ++ ldr w12,[sp,#8] ++ and w13,w13,w14 ++ eor v17.16b,v17.16b,v16.16b ++ ror w15,w15,#2 ++ add w5,w5,w9 ++ eor w13,w13,w3 ++ eor v17.16b,v17.16b,v7.16b ++ add w8,w8,w12 ++ add w9,w9,w15 ++ and w12,w6,w5 ++ add v0.4s,v0.4s,v17.4s ++ bic w15,w7,w5 ++ eor w11,w5,w5,ror#5 ++ add w9,w9,w13 ++ ushr v18.4s,v0.4s,#17 ++ orr w12,w12,w15 ++ ushr v19.4s,v0.4s,#10 ++ eor w11,w11,w5,ror#19 ++ eor w15,w9,w9,ror#11 ++ sli v18.4s,v0.4s,#15 ++ add w8,w8,w12 ++ ushr v17.4s,v0.4s,#19 ++ ror w11,w11,#6 ++ eor w13,w9,w10 ++ eor v19.16b,v19.16b,v18.16b ++ eor w15,w15,w9,ror#20 ++ add w8,w8,w11 ++ sli v17.4s,v0.4s,#13 ++ ldr w12,[sp,#12] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ ld1 {v4.4s},[x16], #16 ++ add w4,w4,w8 ++ eor v19.16b,v19.16b,v17.16b ++ eor w14,w14,w10 ++ eor v17.16b,v17.16b,v17.16b ++ add w7,w7,w12 ++ add w8,w8,w15 ++ and w12,w5,w4 ++ mov v17.d[1],v19.d[0] ++ bic w15,w6,w4 ++ eor w11,w4,w4,ror#5 ++ add w8,w8,w14 ++ add v0.4s,v0.4s,v17.4s ++ orr w12,w12,w15 ++ eor w11,w11,w4,ror#19 ++ eor w15,w8,w8,ror#11 ++ add v4.4s,v4.4s,v0.4s ++ add w7,w7,w12 ++ ror w11,w11,#6 ++ eor w14,w8,w9 ++ eor w15,w15,w8,ror#20 ++ add w7,w7,w11 ++ ldr w12,[sp,#16] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w3,w3,w7 ++ eor w13,w13,w9 ++ st1 {v4.4s},[x17], #16 ++ ext v4.16b,v1.16b,v2.16b,#4 ++ add w6,w6,w12 ++ add w7,w7,w15 ++ and w12,w4,w3 ++ bic w15,w5,w3 ++ ext v7.16b,v3.16b,v0.16b,#4 ++ eor w11,w3,w3,ror#5 ++ add w7,w7,w13 ++ mov d19,v0.d[1] ++ orr w12,w12,w15 ++ eor w11,w11,w3,ror#19 ++ ushr v6.4s,v4.4s,#7 ++ eor w15,w7,w7,ror#11 ++ ushr v5.4s,v4.4s,#3 ++ add w6,w6,w12 ++ add v1.4s,v1.4s,v7.4s ++ ror w11,w11,#6 ++ sli v6.4s,v4.4s,#25 ++ eor w13,w7,w8 ++ eor w15,w15,w7,ror#20 ++ ushr v7.4s,v4.4s,#18 ++ add w6,w6,w11 ++ ldr w12,[sp,#20] ++ and w14,w14,w13 ++ eor v5.16b,v5.16b,v6.16b ++ ror w15,w15,#2 ++ add w10,w10,w6 ++ sli v7.4s,v4.4s,#14 ++ eor w14,w14,w8 ++ ushr v16.4s,v19.4s,#17 ++ add w5,w5,w12 ++ add w6,w6,w15 ++ and w12,w3,w10 ++ eor v5.16b,v5.16b,v7.16b ++ bic w15,w4,w10 ++ eor w11,w10,w10,ror#5 ++ sli v16.4s,v19.4s,#15 ++ add w6,w6,w14 ++ orr w12,w12,w15 ++ ushr v17.4s,v19.4s,#10 ++ eor w11,w11,w10,ror#19 ++ eor w15,w6,w6,ror#11 ++ ushr v7.4s,v19.4s,#19 ++ add w5,w5,w12 ++ ror w11,w11,#6 ++ add v1.4s,v1.4s,v5.4s ++ eor w14,w6,w7 ++ eor w15,w15,w6,ror#20 ++ sli v7.4s,v19.4s,#13 ++ add w5,w5,w11 ++ ldr w12,[sp,#24] ++ and w13,w13,w14 ++ eor v17.16b,v17.16b,v16.16b ++ ror w15,w15,#2 ++ add w9,w9,w5 ++ eor w13,w13,w7 ++ eor v17.16b,v17.16b,v7.16b ++ add w4,w4,w12 ++ add w5,w5,w15 ++ and w12,w10,w9 ++ add v1.4s,v1.4s,v17.4s ++ bic w15,w3,w9 ++ eor w11,w9,w9,ror#5 ++ add w5,w5,w13 ++ ushr v18.4s,v1.4s,#17 ++ orr w12,w12,w15 ++ ushr v19.4s,v1.4s,#10 ++ eor w11,w11,w9,ror#19 ++ eor w15,w5,w5,ror#11 ++ sli v18.4s,v1.4s,#15 ++ add w4,w4,w12 ++ ushr v17.4s,v1.4s,#19 ++ ror w11,w11,#6 ++ eor w13,w5,w6 ++ eor v19.16b,v19.16b,v18.16b ++ eor w15,w15,w5,ror#20 ++ add w4,w4,w11 ++ sli v17.4s,v1.4s,#13 ++ ldr w12,[sp,#28] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ ld1 {v4.4s},[x16], #16 ++ add w8,w8,w4 ++ eor v19.16b,v19.16b,v17.16b ++ eor w14,w14,w6 ++ eor v17.16b,v17.16b,v17.16b ++ add w3,w3,w12 ++ add w4,w4,w15 ++ and w12,w9,w8 ++ mov v17.d[1],v19.d[0] ++ bic w15,w10,w8 ++ eor w11,w8,w8,ror#5 ++ add w4,w4,w14 ++ add v1.4s,v1.4s,v17.4s ++ orr w12,w12,w15 ++ eor w11,w11,w8,ror#19 ++ eor w15,w4,w4,ror#11 ++ add v4.4s,v4.4s,v1.4s ++ add w3,w3,w12 ++ ror w11,w11,#6 ++ eor w14,w4,w5 ++ eor w15,w15,w4,ror#20 ++ add w3,w3,w11 ++ ldr w12,[sp,#32] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w7,w7,w3 ++ eor w13,w13,w5 ++ st1 {v4.4s},[x17], #16 ++ ext v4.16b,v2.16b,v3.16b,#4 ++ add w10,w10,w12 ++ add w3,w3,w15 ++ and w12,w8,w7 ++ bic w15,w9,w7 ++ ext v7.16b,v0.16b,v1.16b,#4 ++ eor w11,w7,w7,ror#5 ++ add w3,w3,w13 ++ mov d19,v1.d[1] ++ orr w12,w12,w15 ++ eor w11,w11,w7,ror#19 ++ ushr v6.4s,v4.4s,#7 ++ eor w15,w3,w3,ror#11 ++ ushr v5.4s,v4.4s,#3 ++ add w10,w10,w12 ++ add v2.4s,v2.4s,v7.4s ++ ror w11,w11,#6 ++ sli v6.4s,v4.4s,#25 ++ eor w13,w3,w4 ++ eor w15,w15,w3,ror#20 ++ ushr v7.4s,v4.4s,#18 ++ add w10,w10,w11 ++ ldr w12,[sp,#36] ++ and w14,w14,w13 ++ eor v5.16b,v5.16b,v6.16b ++ ror w15,w15,#2 ++ add w6,w6,w10 ++ sli v7.4s,v4.4s,#14 ++ eor w14,w14,w4 ++ ushr v16.4s,v19.4s,#17 ++ add w9,w9,w12 ++ add w10,w10,w15 ++ and w12,w7,w6 ++ eor v5.16b,v5.16b,v7.16b ++ bic w15,w8,w6 ++ eor w11,w6,w6,ror#5 ++ sli v16.4s,v19.4s,#15 ++ add w10,w10,w14 ++ orr w12,w12,w15 ++ ushr v17.4s,v19.4s,#10 ++ eor w11,w11,w6,ror#19 ++ eor w15,w10,w10,ror#11 ++ ushr v7.4s,v19.4s,#19 ++ add w9,w9,w12 ++ ror w11,w11,#6 ++ add v2.4s,v2.4s,v5.4s ++ eor w14,w10,w3 ++ eor w15,w15,w10,ror#20 ++ sli v7.4s,v19.4s,#13 ++ add w9,w9,w11 ++ ldr w12,[sp,#40] ++ and w13,w13,w14 ++ eor v17.16b,v17.16b,v16.16b ++ ror w15,w15,#2 ++ add w5,w5,w9 ++ eor w13,w13,w3 ++ eor v17.16b,v17.16b,v7.16b ++ add w8,w8,w12 ++ add w9,w9,w15 ++ and w12,w6,w5 ++ add v2.4s,v2.4s,v17.4s ++ bic w15,w7,w5 ++ eor w11,w5,w5,ror#5 ++ add w9,w9,w13 ++ ushr v18.4s,v2.4s,#17 ++ orr w12,w12,w15 ++ ushr v19.4s,v2.4s,#10 ++ eor w11,w11,w5,ror#19 ++ eor w15,w9,w9,ror#11 ++ sli v18.4s,v2.4s,#15 ++ add w8,w8,w12 ++ ushr v17.4s,v2.4s,#19 ++ ror w11,w11,#6 ++ eor w13,w9,w10 ++ eor v19.16b,v19.16b,v18.16b ++ eor w15,w15,w9,ror#20 ++ add w8,w8,w11 ++ sli v17.4s,v2.4s,#13 ++ ldr w12,[sp,#44] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ ld1 {v4.4s},[x16], #16 ++ add w4,w4,w8 ++ eor v19.16b,v19.16b,v17.16b ++ eor w14,w14,w10 ++ eor v17.16b,v17.16b,v17.16b ++ add w7,w7,w12 ++ add w8,w8,w15 ++ and w12,w5,w4 ++ mov v17.d[1],v19.d[0] ++ bic w15,w6,w4 ++ eor w11,w4,w4,ror#5 ++ add w8,w8,w14 ++ add v2.4s,v2.4s,v17.4s ++ orr w12,w12,w15 ++ eor w11,w11,w4,ror#19 ++ eor w15,w8,w8,ror#11 ++ add v4.4s,v4.4s,v2.4s ++ add w7,w7,w12 ++ ror w11,w11,#6 ++ eor w14,w8,w9 ++ eor w15,w15,w8,ror#20 ++ add w7,w7,w11 ++ ldr w12,[sp,#48] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w3,w3,w7 ++ eor w13,w13,w9 ++ st1 {v4.4s},[x17], #16 ++ ext v4.16b,v3.16b,v0.16b,#4 ++ add w6,w6,w12 ++ add w7,w7,w15 ++ and w12,w4,w3 ++ bic w15,w5,w3 ++ ext v7.16b,v1.16b,v2.16b,#4 ++ eor w11,w3,w3,ror#5 ++ add w7,w7,w13 ++ mov d19,v2.d[1] ++ orr w12,w12,w15 ++ eor w11,w11,w3,ror#19 ++ ushr v6.4s,v4.4s,#7 ++ eor w15,w7,w7,ror#11 ++ ushr v5.4s,v4.4s,#3 ++ add w6,w6,w12 ++ add v3.4s,v3.4s,v7.4s ++ ror w11,w11,#6 ++ sli v6.4s,v4.4s,#25 ++ eor w13,w7,w8 ++ eor w15,w15,w7,ror#20 ++ ushr v7.4s,v4.4s,#18 ++ add w6,w6,w11 ++ ldr w12,[sp,#52] ++ and w14,w14,w13 ++ eor v5.16b,v5.16b,v6.16b ++ ror w15,w15,#2 ++ add w10,w10,w6 ++ sli v7.4s,v4.4s,#14 ++ eor w14,w14,w8 ++ ushr v16.4s,v19.4s,#17 ++ add w5,w5,w12 ++ add w6,w6,w15 ++ and w12,w3,w10 ++ eor v5.16b,v5.16b,v7.16b ++ bic w15,w4,w10 ++ eor w11,w10,w10,ror#5 ++ sli v16.4s,v19.4s,#15 ++ add w6,w6,w14 ++ orr w12,w12,w15 ++ ushr v17.4s,v19.4s,#10 ++ eor w11,w11,w10,ror#19 ++ eor w15,w6,w6,ror#11 ++ ushr v7.4s,v19.4s,#19 ++ add w5,w5,w12 ++ ror w11,w11,#6 ++ add v3.4s,v3.4s,v5.4s ++ eor w14,w6,w7 ++ eor w15,w15,w6,ror#20 ++ sli v7.4s,v19.4s,#13 ++ add w5,w5,w11 ++ ldr w12,[sp,#56] ++ and w13,w13,w14 ++ eor v17.16b,v17.16b,v16.16b ++ ror w15,w15,#2 ++ add w9,w9,w5 ++ eor w13,w13,w7 ++ eor v17.16b,v17.16b,v7.16b ++ add w4,w4,w12 ++ add w5,w5,w15 ++ and w12,w10,w9 ++ add v3.4s,v3.4s,v17.4s ++ bic w15,w3,w9 ++ eor w11,w9,w9,ror#5 ++ add w5,w5,w13 ++ ushr v18.4s,v3.4s,#17 ++ orr w12,w12,w15 ++ ushr v19.4s,v3.4s,#10 ++ eor w11,w11,w9,ror#19 ++ eor w15,w5,w5,ror#11 ++ sli v18.4s,v3.4s,#15 ++ add w4,w4,w12 ++ ushr v17.4s,v3.4s,#19 ++ ror w11,w11,#6 ++ eor w13,w5,w6 ++ eor v19.16b,v19.16b,v18.16b ++ eor w15,w15,w5,ror#20 ++ add w4,w4,w11 ++ sli v17.4s,v3.4s,#13 ++ ldr w12,[sp,#60] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ ld1 {v4.4s},[x16], #16 ++ add w8,w8,w4 ++ eor v19.16b,v19.16b,v17.16b ++ eor w14,w14,w6 ++ eor v17.16b,v17.16b,v17.16b ++ add w3,w3,w12 ++ add w4,w4,w15 ++ and w12,w9,w8 ++ mov v17.d[1],v19.d[0] ++ bic w15,w10,w8 ++ eor w11,w8,w8,ror#5 ++ add w4,w4,w14 ++ add v3.4s,v3.4s,v17.4s ++ orr w12,w12,w15 ++ eor w11,w11,w8,ror#19 ++ eor w15,w4,w4,ror#11 ++ add v4.4s,v4.4s,v3.4s ++ add w3,w3,w12 ++ ror w11,w11,#6 ++ eor w14,w4,w5 ++ eor w15,w15,w4,ror#20 ++ add w3,w3,w11 ++ ldr w12,[x16] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w7,w7,w3 ++ eor w13,w13,w5 ++ st1 {v4.4s},[x17], #16 ++ cmp w12,#0 // check for K256 terminator ++ ldr w12,[sp,#0] ++ sub x17,x17,#64 ++ bne .L_00_48 ++ ++ sub x16,x16,#256 // rewind x16 ++ cmp x1,x2 ++ mov x17, #64 ++ csel x17, x17, xzr, eq ++ sub x1,x1,x17 // avoid SEGV ++ mov x17,sp ++ add w10,w10,w12 ++ add w3,w3,w15 ++ and w12,w8,w7 ++ ld1 {v0.16b},[x1],#16 ++ bic w15,w9,w7 ++ eor w11,w7,w7,ror#5 ++ ld1 {v4.4s},[x16],#16 ++ add w3,w3,w13 ++ orr w12,w12,w15 ++ eor w11,w11,w7,ror#19 ++ eor w15,w3,w3,ror#11 ++ rev32 v0.16b,v0.16b ++ add w10,w10,w12 ++ ror w11,w11,#6 ++ eor w13,w3,w4 ++ eor w15,w15,w3,ror#20 ++ add v4.4s,v4.4s,v0.4s ++ add w10,w10,w11 ++ ldr w12,[sp,#4] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ add w6,w6,w10 ++ eor w14,w14,w4 ++ add w9,w9,w12 ++ add w10,w10,w15 ++ and w12,w7,w6 ++ bic w15,w8,w6 ++ eor w11,w6,w6,ror#5 ++ add w10,w10,w14 ++ orr w12,w12,w15 ++ eor w11,w11,w6,ror#19 ++ eor w15,w10,w10,ror#11 ++ add w9,w9,w12 ++ ror w11,w11,#6 ++ eor w14,w10,w3 ++ eor w15,w15,w10,ror#20 ++ add w9,w9,w11 ++ ldr w12,[sp,#8] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w5,w5,w9 ++ eor w13,w13,w3 ++ add w8,w8,w12 ++ add w9,w9,w15 ++ and w12,w6,w5 ++ bic w15,w7,w5 ++ eor w11,w5,w5,ror#5 ++ add w9,w9,w13 ++ orr w12,w12,w15 ++ eor w11,w11,w5,ror#19 ++ eor w15,w9,w9,ror#11 ++ add w8,w8,w12 ++ ror w11,w11,#6 ++ eor w13,w9,w10 ++ eor w15,w15,w9,ror#20 ++ add w8,w8,w11 ++ ldr w12,[sp,#12] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ add w4,w4,w8 ++ eor w14,w14,w10 ++ add w7,w7,w12 ++ add w8,w8,w15 ++ and w12,w5,w4 ++ bic w15,w6,w4 ++ eor w11,w4,w4,ror#5 ++ add w8,w8,w14 ++ orr w12,w12,w15 ++ eor w11,w11,w4,ror#19 ++ eor w15,w8,w8,ror#11 ++ add w7,w7,w12 ++ ror w11,w11,#6 ++ eor w14,w8,w9 ++ eor w15,w15,w8,ror#20 ++ add w7,w7,w11 ++ ldr w12,[sp,#16] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w3,w3,w7 ++ eor w13,w13,w9 ++ st1 {v4.4s},[x17], #16 ++ add w6,w6,w12 ++ add w7,w7,w15 ++ and w12,w4,w3 ++ ld1 {v1.16b},[x1],#16 ++ bic w15,w5,w3 ++ eor w11,w3,w3,ror#5 ++ ld1 {v4.4s},[x16],#16 ++ add w7,w7,w13 ++ orr w12,w12,w15 ++ eor w11,w11,w3,ror#19 ++ eor w15,w7,w7,ror#11 ++ rev32 v1.16b,v1.16b ++ add w6,w6,w12 ++ ror w11,w11,#6 ++ eor w13,w7,w8 ++ eor w15,w15,w7,ror#20 ++ add v4.4s,v4.4s,v1.4s ++ add w6,w6,w11 ++ ldr w12,[sp,#20] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ add w10,w10,w6 ++ eor w14,w14,w8 ++ add w5,w5,w12 ++ add w6,w6,w15 ++ and w12,w3,w10 ++ bic w15,w4,w10 ++ eor w11,w10,w10,ror#5 ++ add w6,w6,w14 ++ orr w12,w12,w15 ++ eor w11,w11,w10,ror#19 ++ eor w15,w6,w6,ror#11 ++ add w5,w5,w12 ++ ror w11,w11,#6 ++ eor w14,w6,w7 ++ eor w15,w15,w6,ror#20 ++ add w5,w5,w11 ++ ldr w12,[sp,#24] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w9,w9,w5 ++ eor w13,w13,w7 ++ add w4,w4,w12 ++ add w5,w5,w15 ++ and w12,w10,w9 ++ bic w15,w3,w9 ++ eor w11,w9,w9,ror#5 ++ add w5,w5,w13 ++ orr w12,w12,w15 ++ eor w11,w11,w9,ror#19 ++ eor w15,w5,w5,ror#11 ++ add w4,w4,w12 ++ ror w11,w11,#6 ++ eor w13,w5,w6 ++ eor w15,w15,w5,ror#20 ++ add w4,w4,w11 ++ ldr w12,[sp,#28] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ add w8,w8,w4 ++ eor w14,w14,w6 ++ add w3,w3,w12 ++ add w4,w4,w15 ++ and w12,w9,w8 ++ bic w15,w10,w8 ++ eor w11,w8,w8,ror#5 ++ add w4,w4,w14 ++ orr w12,w12,w15 ++ eor w11,w11,w8,ror#19 ++ eor w15,w4,w4,ror#11 ++ add w3,w3,w12 ++ ror w11,w11,#6 ++ eor w14,w4,w5 ++ eor w15,w15,w4,ror#20 ++ add w3,w3,w11 ++ ldr w12,[sp,#32] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w7,w7,w3 ++ eor w13,w13,w5 ++ st1 {v4.4s},[x17], #16 ++ add w10,w10,w12 ++ add w3,w3,w15 ++ and w12,w8,w7 ++ ld1 {v2.16b},[x1],#16 ++ bic w15,w9,w7 ++ eor w11,w7,w7,ror#5 ++ ld1 {v4.4s},[x16],#16 ++ add w3,w3,w13 ++ orr w12,w12,w15 ++ eor w11,w11,w7,ror#19 ++ eor w15,w3,w3,ror#11 ++ rev32 v2.16b,v2.16b ++ add w10,w10,w12 ++ ror w11,w11,#6 ++ eor w13,w3,w4 ++ eor w15,w15,w3,ror#20 ++ add v4.4s,v4.4s,v2.4s ++ add w10,w10,w11 ++ ldr w12,[sp,#36] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ add w6,w6,w10 ++ eor w14,w14,w4 ++ add w9,w9,w12 ++ add w10,w10,w15 ++ and w12,w7,w6 ++ bic w15,w8,w6 ++ eor w11,w6,w6,ror#5 ++ add w10,w10,w14 ++ orr w12,w12,w15 ++ eor w11,w11,w6,ror#19 ++ eor w15,w10,w10,ror#11 ++ add w9,w9,w12 ++ ror w11,w11,#6 ++ eor w14,w10,w3 ++ eor w15,w15,w10,ror#20 ++ add w9,w9,w11 ++ ldr w12,[sp,#40] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w5,w5,w9 ++ eor w13,w13,w3 ++ add w8,w8,w12 ++ add w9,w9,w15 ++ and w12,w6,w5 ++ bic w15,w7,w5 ++ eor w11,w5,w5,ror#5 ++ add w9,w9,w13 ++ orr w12,w12,w15 ++ eor w11,w11,w5,ror#19 ++ eor w15,w9,w9,ror#11 ++ add w8,w8,w12 ++ ror w11,w11,#6 ++ eor w13,w9,w10 ++ eor w15,w15,w9,ror#20 ++ add w8,w8,w11 ++ ldr w12,[sp,#44] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ add w4,w4,w8 ++ eor w14,w14,w10 ++ add w7,w7,w12 ++ add w8,w8,w15 ++ and w12,w5,w4 ++ bic w15,w6,w4 ++ eor w11,w4,w4,ror#5 ++ add w8,w8,w14 ++ orr w12,w12,w15 ++ eor w11,w11,w4,ror#19 ++ eor w15,w8,w8,ror#11 ++ add w7,w7,w12 ++ ror w11,w11,#6 ++ eor w14,w8,w9 ++ eor w15,w15,w8,ror#20 ++ add w7,w7,w11 ++ ldr w12,[sp,#48] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w3,w3,w7 ++ eor w13,w13,w9 ++ st1 {v4.4s},[x17], #16 ++ add w6,w6,w12 ++ add w7,w7,w15 ++ and w12,w4,w3 ++ ld1 {v3.16b},[x1],#16 ++ bic w15,w5,w3 ++ eor w11,w3,w3,ror#5 ++ ld1 {v4.4s},[x16],#16 ++ add w7,w7,w13 ++ orr w12,w12,w15 ++ eor w11,w11,w3,ror#19 ++ eor w15,w7,w7,ror#11 ++ rev32 v3.16b,v3.16b ++ add w6,w6,w12 ++ ror w11,w11,#6 ++ eor w13,w7,w8 ++ eor w15,w15,w7,ror#20 ++ add v4.4s,v4.4s,v3.4s ++ add w6,w6,w11 ++ ldr w12,[sp,#52] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ add w10,w10,w6 ++ eor w14,w14,w8 ++ add w5,w5,w12 ++ add w6,w6,w15 ++ and w12,w3,w10 ++ bic w15,w4,w10 ++ eor w11,w10,w10,ror#5 ++ add w6,w6,w14 ++ orr w12,w12,w15 ++ eor w11,w11,w10,ror#19 ++ eor w15,w6,w6,ror#11 ++ add w5,w5,w12 ++ ror w11,w11,#6 ++ eor w14,w6,w7 ++ eor w15,w15,w6,ror#20 ++ add w5,w5,w11 ++ ldr w12,[sp,#56] ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w9,w9,w5 ++ eor w13,w13,w7 ++ add w4,w4,w12 ++ add w5,w5,w15 ++ and w12,w10,w9 ++ bic w15,w3,w9 ++ eor w11,w9,w9,ror#5 ++ add w5,w5,w13 ++ orr w12,w12,w15 ++ eor w11,w11,w9,ror#19 ++ eor w15,w5,w5,ror#11 ++ add w4,w4,w12 ++ ror w11,w11,#6 ++ eor w13,w5,w6 ++ eor w15,w15,w5,ror#20 ++ add w4,w4,w11 ++ ldr w12,[sp,#60] ++ and w14,w14,w13 ++ ror w15,w15,#2 ++ add w8,w8,w4 ++ eor w14,w14,w6 ++ add w3,w3,w12 ++ add w4,w4,w15 ++ and w12,w9,w8 ++ bic w15,w10,w8 ++ eor w11,w8,w8,ror#5 ++ add w4,w4,w14 ++ orr w12,w12,w15 ++ eor w11,w11,w8,ror#19 ++ eor w15,w4,w4,ror#11 ++ add w3,w3,w12 ++ ror w11,w11,#6 ++ eor w14,w4,w5 ++ eor w15,w15,w4,ror#20 ++ add w3,w3,w11 ++ and w13,w13,w14 ++ ror w15,w15,#2 ++ add w7,w7,w3 ++ eor w13,w13,w5 ++ st1 {v4.4s},[x17], #16 ++ add w3,w3,w15 // h+=Sigma0(a) from the past ++ ldp w11,w12,[x0,#0] ++ add w3,w3,w13 // h+=Maj(a,b,c) from the past ++ ldp w13,w14,[x0,#8] ++ add w3,w3,w11 // accumulate ++ add w4,w4,w12 ++ ldp w11,w12,[x0,#16] ++ add w5,w5,w13 ++ add w6,w6,w14 ++ ldp w13,w14,[x0,#24] ++ add w7,w7,w11 ++ add w8,w8,w12 ++ ldr w12,[sp,#0] ++ stp w3,w4,[x0,#0] ++ add w9,w9,w13 ++ mov w13,wzr ++ stp w5,w6,[x0,#8] ++ add w10,w10,w14 ++ stp w7,w8,[x0,#16] ++ eor w14,w4,w5 ++ stp w9,w10,[x0,#24] ++ mov w15,wzr ++ mov x17,sp ++ b.ne .L_00_48 ++ ++ ldr x29,[x29] ++ add sp,sp,#16*4+16 ++ ret ++.size sha256_block_neon,.-sha256_block_neon ++#ifndef __KERNEL__ ++.comm OPENSSL_armcap_P,4,4 ++#endif +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/defconfig b/defconfig +--- a/defconfig 1970-01-01 08:00:00.000000000 +0800 ++++ b/defconfig 2018-05-10 15:33:01.717312107 +0800 +@@ -0,0 +1,216 @@ ++CONFIG_CROSS_COMPILE="$CROSS_COMPILE" ++CONFIG_SYSVIPC=y ++# CONFIG_FHANDLE is not set ++CONFIG_USELIB=y ++CONFIG_NO_HZ=y ++CONFIG_IKCONFIG=y ++CONFIG_IKCONFIG_PROC=y ++CONFIG_LOG_BUF_SHIFT=16 ++CONFIG_LOG_CPU_MAX_BUF_SHIFT=13 ++CONFIG_BLK_DEV_INITRD=y ++CONFIG_INITRAMFS_SOURCE="${BR_BINARIES_DIR}/rootfs.cpio" ++CONFIG_SYSCTL_SYSCALL=y ++# CONFIG_ELF_CORE is not set ++# CONFIG_BASE_FULL is not set ++# CONFIG_EPOLL is not set ++# CONFIG_SIGNALFD is not set ++# CONFIG_TIMERFD is not set ++# CONFIG_EVENTFD is not set ++# CONFIG_SHMEM is not set ++# CONFIG_AIO is not set ++CONFIG_EMBEDDED=y ++# CONFIG_SLUB_DEBUG is not set ++# CONFIG_COMPAT_BRK is not set ++CONFIG_MODULES=y ++CONFIG_MODULE_UNLOAD=y ++CONFIG_PARTITION_ADVANCED=y ++CONFIG_ARCH_XGS_IPROC=y ++CONFIG_PCI=y ++CONFIG_NR_CPUS=4 ++CONFIG_PREEMPT=y ++CONFIG_HZ_100=y ++# CONFIG_COMPACTION is not set ++CONFIG_CMA=y ++CONFIG_CMA_DEBUG=y ++CONFIG_CMDLINE="console=ttyS0,115200n8 maxcpus=2 mem=496M" ++CONFIG_NET=y ++CONFIG_PACKET=y ++CONFIG_UNIX=y ++CONFIG_INET=y ++CONFIG_IP_MULTICAST=y ++CONFIG_IP_ADVANCED_ROUTER=y ++CONFIG_IP_MULTIPLE_TABLES=y ++CONFIG_IP_PNP=y ++CONFIG_IP_PNP_DHCP=y ++CONFIG_IP_PNP_BOOTP=y ++# 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 is not set ++CONFIG_IPV6_TUNNEL=y ++CONFIG_NETFILTER=y ++CONFIG_BRIDGE_NETFILTER=y ++CONFIG_NETFILTER_NETLINK_QUEUE=y ++CONFIG_NETFILTER_NETLINK_LOG=y ++CONFIG_NF_CONNTRACK=y ++# CONFIG_NF_CT_PROTO_DCCP is not set ++# CONFIG_NF_CT_PROTO_SCTP is not set ++# CONFIG_NF_CT_PROTO_UDPLITE is not set ++CONFIG_NF_CONNTRACK_FTP=y ++CONFIG_NF_CONNTRACK_TFTP=y ++CONFIG_NETFILTER_XT_MARK=y ++CONFIG_NETFILTER_XT_TARGET_CT=y ++CONFIG_NETFILTER_XT_TARGET_TCPMSS=y ++CONFIG_NETFILTER_XT_MATCH_CONNMARK=y ++CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y ++CONFIG_NETFILTER_XT_MATCH_HELPER=y ++CONFIG_NETFILTER_XT_MATCH_STATE=y ++CONFIG_NETFILTER_XT_MATCH_TCPMSS=y ++CONFIG_NF_CONNTRACK_IPV4=y ++CONFIG_IP_NF_IPTABLES=y ++CONFIG_IP_NF_MATCH_AH=y ++CONFIG_IP_NF_MATCH_ECN=y ++CONFIG_IP_NF_MATCH_TTL=y ++CONFIG_IP_NF_FILTER=y ++CONFIG_IP_NF_TARGET_REJECT=y ++CONFIG_IP_NF_MANGLE=y ++CONFIG_IP_NF_TARGET_ECN=y ++CONFIG_IP_NF_TARGET_TTL=y ++CONFIG_IP_NF_RAW=y ++CONFIG_IP_NF_ARPTABLES=y ++CONFIG_IP_NF_ARPFILTER=y ++CONFIG_IP_NF_ARP_MANGLE=y ++CONFIG_NF_CONNTRACK_IPV6=y ++CONFIG_IP6_NF_IPTABLES=y ++CONFIG_IP6_NF_MATCH_RPFILTER=y ++CONFIG_IP6_NF_MATCH_RT=y ++CONFIG_IP6_NF_FILTER=y ++CONFIG_IP6_NF_TARGET_REJECT=y ++CONFIG_IP6_NF_MANGLE=y ++CONFIG_IP6_NF_RAW=y ++CONFIG_BRIDGE=y ++CONFIG_VLAN_8021Q=y ++CONFIG_VLAN_8021Q_GVRP=y ++# CONFIG_WIRELESS is not set ++CONFIG_UEVENT_HELPER_PATH="/sbin/mdev" ++CONFIG_DEVTMPFS=y ++CONFIG_DEVTMPFS_MOUNT=y ++CONFIG_DMA_CMA=y ++CONFIG_CMA_SIZE_MBYTES=32 ++CONFIG_MTD=y ++CONFIG_MTD_TESTS=m ++CONFIG_MTD_CMDLINE_PARTS=y ++CONFIG_MTD_BLOCK=y ++CONFIG_MTD_CFI=y ++CONFIG_MTD_JEDECPROBE=y ++CONFIG_MTD_CFI_INTELEXT=y ++CONFIG_MTD_CFI_AMDSTD=y ++CONFIG_MTD_CFI_STAA=y ++CONFIG_MTD_M25P80=y ++CONFIG_MTD_NAND=y ++CONFIG_MTD_NAND_BRCMNAND=y ++CONFIG_MTD_SPI_NOR=y ++CONFIG_MTD_UBI=y ++CONFIG_BLK_DEV_RAM=y ++CONFIG_EEPROM_AT24=y ++CONFIG_SCSI=y ++CONFIG_BLK_DEV_SD=y ++CONFIG_CHR_DEV_ST=y ++CONFIG_CHR_DEV_SG=y ++CONFIG_SCSI_CONSTANTS=y ++CONFIG_SCSI_LOGGING=y ++CONFIG_NETDEVICES=y ++CONFIG_BONDING=y ++CONFIG_TIGON3=y ++# CONFIG_BGMAC_PLATFORM is not set ++CONFIG_APM=y ++CONFIG_MDIO_XGS_IPROC=y ++CONFIG_BROADCOM_PHY=y ++CONFIG_XGS_IPROC_SERDES=y ++# CONFIG_WLAN is not set ++# CONFIG_INPUT is not set ++CONFIG_SERIO_LIBPS2=y ++# CONFIG_VT is not set ++# CONFIG_LEGACY_PTYS is not set ++CONFIG_SERIAL_8250=y ++CONFIG_SERIAL_8250_CONSOLE=y ++CONFIG_SERIAL_8250_NR_UARTS=2 ++CONFIG_SERIAL_8250_RUNTIME_UARTS=2 ++CONFIG_SERIAL_8250_EXTENDED=y ++CONFIG_SERIAL_8250_SHARE_IRQ=y ++CONFIG_SERIAL_8250_DETECT_IRQ=y ++CONFIG_SERIAL_8250_RSA=y ++CONFIG_SERIAL_8250_DW=y ++CONFIG_SERIAL_OF_PLATFORM=y ++CONFIG_HW_RANDOM=y ++CONFIG_HW_RANDOM_XGS_IPROC_RNG=y ++CONFIG_I2C=y ++# CONFIG_I2C_COMPAT is not set ++CONFIG_I2C_CHARDEV=y ++# CONFIG_I2C_HELPER_AUTO is not set ++CONFIG_SPI=y ++CONFIG_SPI_PL022=y ++CONFIG_GPIOLIB=y ++CONFIG_GPIO_SYSFS=y ++CONFIG_WATCHDOG=y ++CONFIG_ARM_SP805_WATCHDOG=y ++# CONFIG_VGA_ARB is not set ++CONFIG_USB=y ++CONFIG_USB_ANNOUNCE_NEW_DEVICES=y ++CONFIG_USB_DYNAMIC_MINORS=y ++CONFIG_USB_XHCI_HCD=y ++CONFIG_USB_XHCI_PLATFORM=y ++CONFIG_USB_STORAGE=y ++CONFIG_USB_XGS_IPROC_DRD=y ++CONFIG_USB_GADGET=y ++CONFIG_USB_BDC_UDC=y ++CONFIG_USB_BDC_XGS_IPROC=y ++CONFIG_USB_G_SERIAL=m ++CONFIG_MMC=y ++CONFIG_MMC_SDHCI=y ++CONFIG_DMADEVICES=y ++CONFIG_DMADEVICES_DEBUG=y ++CONFIG_DMADEVICES_VDEBUG=y ++CONFIG_PL330_DMA=y ++# CONFIG_COMMON_CLK_XGENE is not set ++CONFIG_ACPI=y ++CONFIG_EXT2_FS=y ++CONFIG_EXT3_FS=y ++# CONFIG_DNOTIFY is not set ++CONFIG_AUTOFS4_FS=y ++CONFIG_MSDOS_FS=y ++CONFIG_VFAT_FS=y ++CONFIG_NTFS_FS=y ++# CONFIG_PROC_PAGE_MONITOR is not set ++CONFIG_JFFS2_FS=y ++CONFIG_UBIFS_FS=y ++CONFIG_NFS_FS=y ++CONFIG_NFS_V3_ACL=y ++CONFIG_NFS_V4=y ++CONFIG_NFS_SWAP=y ++CONFIG_ROOT_NFS=y ++CONFIG_NFSD=y ++CONFIG_NLS_CODEPAGE_437=y ++CONFIG_NLS_ASCII=y ++CONFIG_NLS_ISO8859_1=y ++CONFIG_DEBUG_INFO=y ++# CONFIG_ENABLE_WARN_DEPRECATED is not set ++# CONFIG_ENABLE_MUST_CHECK is not set ++CONFIG_FRAME_WARN=1024 ++CONFIG_DEBUG_FS=y ++CONFIG_MAGIC_SYSRQ=y ++# CONFIG_SCHED_DEBUG is not set ++CONFIG_RCU_CPU_STALL_TIMEOUT=60 ++# CONFIG_FTRACE is not set ++CONFIG_CRYPTO_CBC=y ++CONFIG_CRYPTO_MD5=y ++CONFIG_CRYPTO_DES=y ++CONFIG_CRYPTO_ANSI_CPRNG=m ++# CONFIG_CRYPTO_HW is not set ++CONFIG_ARM64_CRYPTO=y ++CONFIG_CRYPTO_SHA1_ARM64_CE=y ++CONFIG_CRYPTO_SHA2_ARM64_CE=y ++CONFIG_CRYPTO_GHASH_ARM64_CE=y ++CONFIG_CRYPTO_AES_ARM64_CE_CCM=y ++CONFIG_CRYPTO_AES_ARM64_CE_BLK=y ++CONFIG_CRYPTO_AES_ARM64_NEON_BLK=y +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig +--- a/drivers/char/hw_random/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/char/hw_random/Kconfig 2018-05-10 11:31:29.825399854 +0800 +@@ -112,6 +112,18 @@ config HW_RANDOM_IPROC_RNG200 + + If unsure, say Y. + ++config HW_RANDOM_XGS_IPROC_RNG ++ tristate "Broadcom iProc RNG support" ++ depends on (ARCH_XGS_IPROC && HW_RANDOM) ++ ---help--- ++ This driver provides kernel-side support for the RNG ++ hardware found on the Broadcom iProc SoCs. ++ ++ To compile this driver as a module, choose M here: the ++ module will be called iproc-rng ++ ++ If unsure, say Y. ++ + config HW_RANDOM_GEODE + tristate "AMD Geode HW Random Number Generator support" + depends on X86_32 && PCI +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile +--- a/drivers/char/hw_random/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/char/hw_random/Makefile 2018-05-10 11:31:29.825399854 +0800 +@@ -30,6 +30,7 @@ obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng + obj-$(CONFIG_HW_RANDOM_TPM) += tpm-rng.o + obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o + obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o ++obj-$(CONFIG_HW_RANDOM_XGS_IPROC_RNG) += xgs-iproc-rng100.o iproc-rng200.o + obj-$(CONFIG_HW_RANDOM_MSM) += msm-rng.o + obj-$(CONFIG_HW_RANDOM_ST) += st-rng.o + obj-$(CONFIG_HW_RANDOM_XGENE) += xgene-rng.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/char/hw_random/xgs-iproc-rng100.c b/drivers/char/hw_random/xgs-iproc-rng100.c +--- a/drivers/char/hw_random/xgs-iproc-rng100.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/char/hw_random/xgs-iproc-rng100.c 2018-05-10 11:31:29.829399858 +0800 +@@ -0,0 +1,211 @@ ++/* ++ * Copyright (C) 2017 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++/* Registers for RNG */ ++#define RNG_CTRL_OFFSET 0x00000000 ++#define RNG_CTRL_RESERVED_MASK 0xF00000CC ++#define RNG_CTRL_COMBLK2_OSC_DIS_SHIFT 22 ++#define RNG_CTRL_COMBLK2_OSC_DIS_MASK 0x0FC00000 ++#define RNG_CTRL_COMBLK1_OSC_DIS_SHIFT 16 ++#define RNG_CTRL_COMBLK1_OSC_DIS_MASK 0x003F0000 ++#define RNG_CTRL_JCLK_BYP_DIV_CNT_SHIFT 8 ++#define RNG_CTRL_JCLK_BYP_DIV_CNT_MASK 0x0000FF00 ++#define RNG_CTRL_JCLK_BYP_SRC_SHIFT 5 ++#define RNG_CTRL_JCLK_BYP_SRC_MASK 0x00000020 ++#define RNG_CTRL_JCLK_BYP_SEL_SHIFT 4 ++#define RNG_CTRL_JCLK_BYP_SEL_MASK 0x00000010 ++#define RNG_CTRL_RBG2X_SHIFT 1 ++#define RNG_CTRL_RBG2X_MASK 0x00000002 ++#define RNG_CTRL_RBGEN_SHIFT 0 ++#define RNG_CTRL_RBGEN_MASK 0x00000001 ++ ++#define RNG_STATUS_OFFSET 0x00000004 ++#define RNG_STATUS_RESERVED_MASK 0x00F00000 ++#define RNG_STATUS_RND_VAL_SHIFT 24 ++#define RNG_STATUS_RND_VAL_MASK 0xFF000000 ++#define RNG_STATUS_WARM_CNT_SHIFT 0 ++#define RNG_STATUS_WARM_CNT_MASK 0x000FFFFF ++ ++#define RNG_DATA_OFFSET 0x00000008 ++#define RNG_DATA_RESERVED_MASK 0x00000000 ++#define RNG_DATA_RNG_NUM_SHIFT 0 ++#define RNG_DATA_RNG_NUM_MASK 0xFFFFFFFF ++ ++#define RNG_FF_THRES_OFFSET 0x0000000C ++#define RNG_FF_THRES_RESERVED_MASK 0xFFFFFFE0 ++#define RNG_FF_THRES_RNG_FF_THRESH_SHIFT 0 ++#define RNG_FF_THRES_RNG_FF_THRESH_MASK 0x0000001F ++ ++#define RNG_INT_MASK_OFFSET 0x00000010 ++#define RNG_INT_MASK_RESERVED_MASK 0xFFFFFFFE ++#define RNG_INT_MASK_OFF_SHIFT 0 ++#define RNG_INT_MASK_OFF_MASK 0x00000001 ++ ++static int rng100_read(struct hwrng *rng, void *buf, size_t max, bool wait) ++{ ++ u32 num_words = 0; ++ u32 num_remaining = max; ++ ++ #define MAX_IDLE_TIME (1 * HZ) ++ unsigned long idle_endtime = jiffies + MAX_IDLE_TIME; ++ ++ /* Retrieve HW RNG registers base address. */ ++ void __iomem *base_addr = (void __iomem *)rng->priv; ++ ++ while ((num_remaining > 0) && time_before(jiffies, idle_endtime)) { ++ /* Are there any random numbers available? */ ++ num_words = (ioread32(base_addr + RNG_STATUS_OFFSET) & ++ RNG_STATUS_RND_VAL_MASK) >> RNG_STATUS_RND_VAL_SHIFT; ++ if (num_words > 0) { ++ if (num_remaining >= sizeof(u32)) { ++ /* Buffer has room to store entire word */ ++ *(u32 *)buf = ioread32(base_addr + ++ RNG_DATA_OFFSET); ++ buf += sizeof(u32); ++ num_remaining -= sizeof(u32); ++ } else { ++ /* Buffer can only store partial word */ ++ u32 rnd_number = ioread32(base_addr + ++ RNG_DATA_OFFSET); ++ memcpy(buf, &rnd_number, num_remaining); ++ buf += num_remaining; ++ num_remaining = 0; ++ } ++ ++ /* Reset the IDLE timeout */ ++ idle_endtime = jiffies + MAX_IDLE_TIME; ++ } else if (!wait) { ++ /* Cannot wait, return immediately */ ++ break; ++ } else { ++ /* Can wait, give others chance to run */ ++ cpu_relax(); ++ } ++ } ++ ++ return max - num_remaining; ++} ++ ++static struct hwrng rng100_ops = { ++ .name = "iproc-rng100", ++ .read = rng100_read, ++}; ++ ++static int iproc_rng100_probe(struct platform_device *pdev) ++{ ++ int error; ++ u32 val; ++ struct device *dev = &pdev->dev; ++ void __iomem *base_addr; ++ struct device_node *node = pdev->dev.of_node; ++ ++ pr_info("Broadcom IPROC RNG100 Driver\n"); ++ /* We only accept one device, and it must have an id of -1 */ ++ if (pdev->id != -1) ++ return -ENODEV; ++ ++ base_addr = of_iomap(node, 0); ++ if (!base_addr) { ++ dev_err(&pdev->dev, "can't iomap base_addr for rng100\n"); ++ return -EIO; ++ } ++ rng100_ops.priv = (unsigned long)base_addr; ++ ++ /* Start RNG block */ ++ val = ioread32(base_addr + RNG_CTRL_OFFSET); ++ val |= RNG_CTRL_RBGEN_MASK; ++ iowrite32(val, base_addr + RNG_CTRL_OFFSET); ++ ++ /* Enable RNG RBG2X */ ++ val = ioread32(base_addr + RNG_CTRL_OFFSET); ++ val |= RNG_CTRL_RBG2X_MASK; ++ iowrite32(val, base_addr + RNG_CTRL_OFFSET); ++ ++ /* Disable RNG INTERRUPT */ ++ val = ioread32(base_addr + RNG_INT_MASK_OFFSET); ++ val |= RNG_INT_MASK_OFF_MASK; ++ iowrite32(val, base_addr + RNG_INT_MASK_OFFSET); ++ ++ /* set warmup cycle 0xfff */ ++ iowrite32(RNG_STATUS_WARM_CNT_MASK - ++ (0xfff & RNG_STATUS_WARM_CNT_MASK), ++ base_addr + RNG_STATUS_OFFSET); ++ while ((ioread32(base_addr + RNG_STATUS_OFFSET) & ++ RNG_STATUS_WARM_CNT_MASK) != RNG_STATUS_WARM_CNT_MASK) ++ cpu_relax(); ++ ++ /* register to the Linux RNG framework */ ++ error = hwrng_register(&rng100_ops); ++ if (error) { ++ dev_err(dev, "hwrng registration failed\n"); ++ iounmap(base_addr); ++ return error; ++ } ++ dev_dbg(dev, "hwrng registered\n"); ++ ++ return 0; ++} ++ ++static int iproc_rng100_remove(struct platform_device *pdev) ++{ ++ u32 val; ++ void __iomem *base_addr = (void __iomem *)rng100_ops.priv; ++ ++ hwrng_unregister(&rng100_ops); ++ ++ if (base_addr) { ++ /* Disable RNG hardware */ ++ val = ioread32(base_addr + RNG_CTRL_OFFSET); ++ val &= ~RNG_CTRL_RBGEN_MASK; ++ iowrite32(val, base_addr + RNG_CTRL_OFFSET); ++ ++ val = ioread32(base_addr + RNG_CTRL_OFFSET); ++ val &= ~RNG_CTRL_RBG2X_MASK; ++ iowrite32(val, base_addr + RNG_CTRL_OFFSET); ++ ++ iounmap(base_addr); ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm_iproc_dt_ids[] = { ++ { .compatible = "brcm,iproc-rng100"}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, bcm_iproc_dt_ids); ++ ++static struct platform_driver iproc_rng100_driver = { ++ .driver = { ++ .name = "iproc-rng100", ++ .owner = THIS_MODULE, ++ .of_match_table = bcm_iproc_dt_ids, ++ }, ++ .probe = iproc_rng100_probe, ++ .remove = iproc_rng100_remove, ++}; ++module_platform_driver(iproc_rng100_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("iProc RNG100 Random Number Generator driver"); ++MODULE_LICENSE("GPL v2"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/clk/bcm/Kconfig b/drivers/clk/bcm/Kconfig +--- a/drivers/clk/bcm/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/clk/bcm/Kconfig 2018-05-10 11:31:29.849399879 +0800 +@@ -54,3 +54,11 @@ config CLK_BCM_SR + default ARCH_BCM_IPROC + help + Enable common clock framework support for the Broadcom Stingray SoC ++ ++config CLK_XGS_IPROC ++ bool "BRCM XGS iProc clock support" ++ depends on ARCH_XGS_IPROC || COMPILE_TEST ++ select COMMON_CLK_IPROC ++ default ARCH_XGS_IPROC ++ help ++ Enable clock support for Broadcom XGS iProc SoC +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/clk/bcm/Makefile b/drivers/clk/bcm/Makefile +--- a/drivers/clk/bcm/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/clk/bcm/Makefile 2018-05-10 11:31:29.849399879 +0800 +@@ -12,3 +12,4 @@ obj-$(CONFIG_CLK_BCM_CYGNUS) += clk-cygn + obj-$(CONFIG_CLK_BCM_NSP) += clk-nsp.o + obj-$(CONFIG_CLK_BCM_NS2) += clk-ns2.o + obj-$(CONFIG_CLK_BCM_SR) += clk-sr.o ++obj-$(CONFIG_CLK_XGS_IPROC) += clk-xgs-iproc.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/clk/bcm/clk-iproc-armpll.c b/drivers/clk/bcm/clk-iproc-armpll.c +--- a/drivers/clk/bcm/clk-iproc-armpll.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/clk/bcm/clk-iproc-armpll.c 2018-05-10 11:31:29.853399884 +0800 +@@ -197,9 +197,9 @@ static unsigned long iproc_arm_pll_recal + { + struct iproc_arm_pll *pll = to_iproc_arm_pll(hw); + u32 val; +- int mdiv; ++ u32 mdiv; + u64 ndiv; +- unsigned int pdiv; ++ u32 pdiv; + + /* in bypass mode, use parent rate */ + val = readl(pll->base + IPROC_CLK_PLLARMC_OFFSET); +@@ -226,8 +226,10 @@ static unsigned long iproc_arm_pll_recal + pll->rate = 0; + return 0; + } ++ ++ /* To avoid pll->rate overflow, do divide before multiply */ ++ parent_rate = (parent_rate / pdiv) / mdiv; + pll->rate = (ndiv * parent_rate) >> 20; +- pll->rate = (pll->rate / pdiv) / mdiv; + + pr_debug("%s: ARM PLL rate: %lu. parent rate: %lu\n", __func__, + pll->rate, parent_rate); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/clk/bcm/clk-xgs-iproc.c b/drivers/clk/bcm/clk-xgs-iproc.c +--- a/drivers/clk/bcm/clk-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/clk/bcm/clk-xgs-iproc.c 2018-05-10 11:31:29.853399884 +0800 +@@ -0,0 +1,168 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "clk-iproc.h" ++ ++#define SB2_GEN_PLL_CTRL_1_OFFSET 0x04 ++#define SB2_GEN_PLL_CTRL_3_OFFSET 0x0C ++#define SB2_GEN_PLL_CTRL_5_OFFSET 0x14 ++#define SB2_GEN_PLL_CTRL_1_PDIV_R 27 ++#define SB2_GEN_PLL_CTRL_3_NDIV_INT_R 20 ++#define SB2_GEN_PLL_CTRL_5_CH1_MDIV_R 8 ++#define SB2_GEN_PLL_CTRL_1_PDIV_WIDTH 4 ++#define SB2_GEN_PLL_CTRL_3_NDIV_INT_WIDTH 10 ++#define SB2_GEN_PLL_CTRL_5_CH1_MDIV_WIDTH 8 ++ ++#define GEN_PLL_CTRL1_OFFSET 0x4 ++#define GEN_PLL_CTRL2_OFFSET 0x8 ++#define GEN_PLL_CTRL1_NDIV_INT_R 0 ++#define GEN_PLL_CTRL1_NDIV_INT_WIDTH 10 ++#define GEN_PLL_CTRL1_PDIV_R 10 ++#define GEN_PLL_CTRL2_CH3_MDIV_R 8 ++#define GEN_PLL_CTRL2_CH3_MDIV_WIDTH 8 ++#define GEN_PLL_CTRL1_PDIV_WIDTH_3 3 ++#define GEN_PLL_CTRL1_PDIV_WIDTH_4 4 ++ ++ ++struct iproc_gen_pll { ++ struct clk_hw hw; ++ void __iomem *base; ++ unsigned long rate; ++}; ++ ++#define to_iproc_gen_pll(phw) container_of(phw, struct iproc_gen_pll, hw) ++ ++static u32 genpll_pdiv_width; ++ ++static unsigned long iproc_axi_clk_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ uint32_t ndiv, mdiv, pdiv; ++ struct iproc_gen_pll *pll = to_iproc_gen_pll(hw); ++ ++ ndiv = readl(pll->base + GEN_PLL_CTRL1_OFFSET) >> ++ GEN_PLL_CTRL1_NDIV_INT_R; ++ ndiv &= (1 << GEN_PLL_CTRL1_NDIV_INT_WIDTH) - 1; ++ if (ndiv == 0) ++ ndiv = 1 << GEN_PLL_CTRL1_NDIV_INT_WIDTH; ++ ++ pdiv = readl(pll->base + GEN_PLL_CTRL1_OFFSET) >> GEN_PLL_CTRL1_PDIV_R; ++ pdiv &= (1 << genpll_pdiv_width) -1; ++ if (pdiv == 0) ++ pdiv = 1 << genpll_pdiv_width; ++ ++ mdiv = readl(pll->base + GEN_PLL_CTRL2_OFFSET) >> ++ GEN_PLL_CTRL2_CH3_MDIV_R; ++ mdiv &= (1 << GEN_PLL_CTRL2_CH3_MDIV_WIDTH) - 1; ++ if (mdiv == 0) ++ mdiv = 1 << GEN_PLL_CTRL2_CH3_MDIV_WIDTH; ++ ++ pll->rate = parent_rate * ndiv / pdiv / mdiv; ++ return pll->rate; ++} ++ ++static unsigned long iproc_sb2_axi_clk_recalc_rate(struct clk_hw *hw, ++ unsigned long parent_rate) ++{ ++ uint32_t ndiv, mdiv, pdiv; ++ struct iproc_gen_pll *pll = to_iproc_gen_pll(hw); ++ ++ ndiv = readl(pll->base + SB2_GEN_PLL_CTRL_3_OFFSET) >> ++ SB2_GEN_PLL_CTRL_3_NDIV_INT_R; ++ ndiv &= (1 << SB2_GEN_PLL_CTRL_3_NDIV_INT_WIDTH) - 1; ++ ++ mdiv = readl(pll->base + SB2_GEN_PLL_CTRL_5_OFFSET) >> ++ SB2_GEN_PLL_CTRL_5_CH1_MDIV_R; ++ mdiv &= (1 << SB2_GEN_PLL_CTRL_5_CH1_MDIV_WIDTH) - 1; ++ ++ pdiv = readl(pll->base + SB2_GEN_PLL_CTRL_1_OFFSET) >> ++ SB2_GEN_PLL_CTRL_1_PDIV_R; ++ pdiv &= (1 << SB2_GEN_PLL_CTRL_1_PDIV_WIDTH) - 1; ++ ++ pll->rate = parent_rate * ndiv / pdiv / mdiv; ++ return pll->rate; ++} ++ ++ ++static struct clk_ops iproc_axi_clk_ops = { ++ .recalc_rate = iproc_axi_clk_recalc_rate, ++}; ++ ++void __init xgs_iproc_axi_clk_setup(struct device_node *node) ++{ ++ int ret; ++ struct clk *clk; ++ struct iproc_gen_pll *pll; ++ struct clk_init_data init; ++ const char *parent_name; ++ ++ pll = kzalloc(sizeof(*pll), GFP_KERNEL); ++ if (WARN_ON(!pll)) ++ return; ++ ++ pll->base = of_iomap(node, 0); ++ if (WARN_ON(!pll->base)) ++ goto err_free_pll; ++ ++ init.name = node->name; ++ if (of_device_is_compatible(node, "axi-clk-sb2")) ++ iproc_axi_clk_ops.recalc_rate = iproc_sb2_axi_clk_recalc_rate; ++ if (of_device_is_compatible(node, "axi-clk-hx4") || ++ of_device_is_compatible(node, "axi-clk-hr2")) ++ genpll_pdiv_width = GEN_PLL_CTRL1_PDIV_WIDTH_3; ++ else ++ genpll_pdiv_width = GEN_PLL_CTRL1_PDIV_WIDTH_4; ++ ++ init.ops = &iproc_axi_clk_ops; ++ init.flags = 0; ++ parent_name = of_clk_get_parent_name(node, 0); ++ init.parent_names = (parent_name ? &parent_name : NULL); ++ init.num_parents = (parent_name ? 1 : 0); ++ pll->hw.init = &init; ++ ++ clk = clk_register(NULL, &pll->hw); ++ if (WARN_ON(IS_ERR(clk))) ++ goto err_iounmap; ++ ++ ret = of_clk_add_provider(node, of_clk_src_simple_get, clk); ++ if (WARN_ON(ret)) ++ goto err_clk_unregister; ++ ++ return; ++ ++err_clk_unregister: ++ clk_unregister(clk); ++err_iounmap: ++ iounmap(pll->base); ++err_free_pll: ++ kfree(pll); ++} ++CLK_OF_DECLARE(xgs_iproc_axi_clk, "brcm,xgs-iproc-axi-clk", ++ xgs_iproc_axi_clk_setup); ++ ++ ++static void __init xgs_iproc_armpll_init(struct device_node *node) ++{ ++ iproc_armpll_setup(node); ++} ++CLK_OF_DECLARE(xgs_iproc_armpll, "brcm,xgs-iproc-armpll", ++ xgs_iproc_armpll_init); +\ No newline at end of file +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig +--- a/drivers/gpio/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/gpio/Kconfig 2018-05-10 11:31:30.057400102 +0800 +@@ -143,6 +143,15 @@ config GPIO_BRCMSTB + help + Say yes here to enable GPIO support for Broadcom STB (BCM7XXX) SoCs. + ++config GPIO_XGS_IPROC ++ tristate "BRCM XGS iProc GPIO support" ++ default y if ARCH_XGS_IPROC ++ depends on OF_GPIO && (ARCH_XGS_IPROC || COMPILE_TEST) ++ select GPIO_GENERIC ++ select GPIOLIB_IRQCHIP ++ help ++ Say yes here to enable GPIO support for Broadcom XGS iProc SoCs. ++ + config GPIO_CLPS711X + tristate "CLPS711X GPIO support" + depends on ARCH_CLPS711X || COMPILE_TEST +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/gpio/Makefile b/drivers/gpio/Makefile +--- a/drivers/gpio/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/gpio/Makefile 2018-05-10 11:31:30.057400102 +0800 +@@ -36,6 +36,7 @@ obj-$(CONFIG_GPIO_AXP209) += gpio-axp209 + obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o + obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o + obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o ++obj-$(CONFIG_GPIO_XGS_IPROC) += gpio-xgs-iproc.o + obj-$(CONFIG_GPIO_BT8XX) += gpio-bt8xx.o + obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o + obj-$(CONFIG_GPIO_CS5535) += gpio-cs5535.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/gpio/gpio-xgs-iproc.c b/drivers/gpio/gpio-xgs-iproc.c +--- a/drivers/gpio/gpio-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/gpio/gpio-xgs-iproc.c 2018-05-10 11:31:30.069400115 +0800 +@@ -0,0 +1,739 @@ ++/* ++ * Copyright (C) 2017 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define IPROC_GPIO_CCA_ID 0 ++#define IPROC_GPIO_CCB_ID 1 ++#define IPROC_GPIO_CCG_ID 2 ++ ++#define REGOFFSET_GPIO_DIN 0x0 ++#define REGOFFSET_GPIO_DOUT 0x4 ++#define REGOFFSET_GPIO_OUT_EN 0x8 ++ ++#define CCA_INT_F_GPIOINT 1 ++#define CCA_INT_STS 0x20 ++#define CCA_INT_MASK 0x24 ++#define GPIO_CCA_DIN 0x0 ++#define GPIO_CCA_INT_LEVEL 0x10 ++#define GPIO_CCA_INT_LEVEL_MASK 0x14 ++#define GPIO_CCA_INT_EVENT 0x18 ++#define GPIO_CCA_INT_EVENT_MASK 0x1C ++#define GPIO_CCA_INT_EDGE 0x24 ++ ++#define GPIO_CCB_INT_TYPE 0xC ++#define GPIO_CCB_INT_DE 0x10 ++#define GPIO_CCB_INT_EDGE 0x14 ++#define GPIO_CCB_INT_MSTAT 0x20 ++#define GPIO_CCB_INT_CLR 0x24 ++#define GPIO_CCB_INT_MASK 0x18 ++ ++/* locking wrappers to deal with multiple access to the same gpio bank */ ++#define iproc_gpio_lock(_oc, _fl) spin_lock_irqsave(&(_oc)->lock, _fl) ++#define iproc_gpio_unlock(_oc, _fl) spin_unlock_irqrestore(&(_oc)->lock, _fl) ++ ++struct iproc_gpio_irqcfg { ++ unsigned long flags; ++ irqreturn_t (*handler)(int irq, void *dev); ++ void (*ack)(unsigned int irq); ++ void (*unmask)(unsigned int irq); ++ void (*mask)(unsigned int irq); ++ int (*set_type)(unsigned int irq, unsigned int type); ++}; ++ ++struct iproc_gpio_chip { ++ int id; ++ struct gpio_chip chip; ++ struct iproc_gpio_cfg *config; ++ void __iomem *ioaddr; ++ void __iomem *intr_ioaddr; ++ spinlock_t lock; ++ struct irq_domain *irq_domain; ++ struct resource *resource; ++ int irq; ++ struct iproc_gpio_irqcfg *irqcfg; ++ /* GPIO register bit shift */ ++ int pin_reg_bit_shift; ++}; ++ ++static inline struct iproc_gpio_chip *to_iproc_gpio(struct gpio_chip *gpc) ++{ ++ return container_of(gpc, struct iproc_gpio_chip, chip); ++} ++ ++static u32 _iproc_gpio_readl(struct iproc_gpio_chip *chip, int reg) ++{ ++ return readl(chip->ioaddr + reg); ++} ++ ++static void _iproc_gpio_writel(struct iproc_gpio_chip *chip, u32 val, int reg) ++{ ++ writel(val, chip->ioaddr + reg); ++} ++ ++/* ++@ pin : GPIO register bit ++*/ ++static int iproc_gpio_to_irq(struct iproc_gpio_chip *chip, u32 pin) ++{ ++ return irq_linear_revmap(chip->irq_domain, pin - chip->pin_reg_bit_shift); ++} ++ ++/* returns the corresponding gpio register bit */ ++static int iproc_irq_to_gpio(struct iproc_gpio_chip *chip, u32 irq) ++{ ++ struct irq_data *data = irq_domain_get_irq_data(chip->irq_domain, irq); ++ ++ return data->hwirq + chip->pin_reg_bit_shift; ++} ++ ++static void iproc_gpio_irq_ack(struct irq_data *d) ++{ ++ u32 irq = d->irq; ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ ++ if (ourchip) { ++ struct iproc_gpio_irqcfg *irqcfg = ourchip->irqcfg; ++ if (irqcfg && irqcfg->ack) ++ irqcfg->ack(irq); ++ } ++} ++ ++static void iproc_gpio_irq_unmask(struct irq_data *d) ++{ ++ u32 irq = d->irq; ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ ++ if (ourchip) { ++ struct iproc_gpio_irqcfg *irqcfg = ourchip->irqcfg; ++ if (irqcfg && irqcfg->unmask) ++ irqcfg->unmask(irq); ++ } ++} ++ ++static void iproc_gpio_irq_mask(struct irq_data *d) ++{ ++ u32 irq = d->irq; ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ ++ if (ourchip) { ++ struct iproc_gpio_irqcfg *irqcfg = ourchip->irqcfg; ++ if (irqcfg && irqcfg->mask) ++ irqcfg->mask(irq); ++ } ++} ++ ++ ++static int iproc_gpio_irq_set_type(struct irq_data *d, u32 type) ++{ ++ u32 irq = d->irq; ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ ++ if (ourchip) { ++ struct iproc_gpio_irqcfg *irqcfg = ourchip->irqcfg; ++ if (irqcfg && irqcfg->set_type) ++ return irqcfg->set_type(irq, type); ++ } ++ ++ return -EINVAL; ++} ++ ++static irqreturn_t iproc_gpio_irq_handler_cca(int irq, void *data) ++{ ++ struct iproc_gpio_chip *iproc_gpio = (struct iproc_gpio_chip *)data; ++ struct gpio_chip gc = iproc_gpio->chip; ++ int bit; ++ unsigned long int_bits = 0; ++ u32 int_status; ++ ++ /* go through the entire GPIOs and handle all interrupts */ ++ int_status = readl(iproc_gpio->intr_ioaddr + CCA_INT_STS); ++ if (int_status & CCA_INT_F_GPIOINT) { ++ u32 event, level; ++ ++ /* Get level and edge interrupts */ ++ event = readl(iproc_gpio->ioaddr + GPIO_CCA_INT_EVENT_MASK); ++ event &= readl(iproc_gpio->ioaddr + GPIO_CCA_INT_EVENT); ++ level = readl(iproc_gpio->ioaddr + GPIO_CCA_DIN); ++ level ^= readl(iproc_gpio->ioaddr + GPIO_CCA_INT_LEVEL); ++ level &= readl(iproc_gpio->ioaddr + GPIO_CCA_INT_LEVEL_MASK); ++ int_bits = level | event; ++ ++ for_each_set_bit(bit, &int_bits, gc.ngpio) ++ generic_handle_irq( ++ irq_linear_revmap(iproc_gpio->irq_domain, bit)); ++ } ++ ++ return int_bits ? IRQ_HANDLED : IRQ_NONE; ++} ++ ++ ++static void iproc_gpio_irq_ack_cca(u32 irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ u32 irq_type, event_status = 0; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ irq_type = irq_get_trigger_type(irq); ++ if (irq_type & IRQ_TYPE_EDGE_BOTH) { ++ event_status |= (1 << pin); ++ _iproc_gpio_writel(ourchip, event_status, GPIO_CCA_INT_EVENT); ++ } ++} ++ ++static void iproc_gpio_irq_unmask_cca(u32 irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ u32 int_mask, irq_type, event_mask; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ irq_type = irq_get_trigger_type(irq); ++ event_mask = _iproc_gpio_readl(ourchip, GPIO_CCA_INT_EVENT_MASK); ++ int_mask = _iproc_gpio_readl(ourchip, GPIO_CCA_INT_LEVEL_MASK); ++ ++ if (irq_type & IRQ_TYPE_EDGE_BOTH) { ++ event_mask |= 1 << pin; ++ _iproc_gpio_writel(ourchip, event_mask, GPIO_CCA_INT_EVENT_MASK); ++ } else { ++ int_mask |= 1 << pin; ++ _iproc_gpio_writel(ourchip, int_mask, GPIO_CCA_INT_LEVEL_MASK); ++ } ++} ++ ++static void iproc_gpio_irq_mask_cca(u32 irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ u32 irq_type, int_mask, event_mask; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ irq_type = irq_get_trigger_type(irq); ++ event_mask = _iproc_gpio_readl(ourchip, GPIO_CCA_INT_EVENT_MASK); ++ int_mask = _iproc_gpio_readl(ourchip, GPIO_CCA_INT_LEVEL_MASK); ++ ++ if (irq_type & IRQ_TYPE_EDGE_BOTH) { ++ event_mask &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, event_mask, GPIO_CCA_INT_EVENT_MASK); ++ } else { ++ int_mask &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, int_mask, GPIO_CCA_INT_LEVEL_MASK); ++ } ++} ++ ++static int iproc_gpio_irq_set_type_cca(u32 irq, u32 type) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ u32 event_pol, int_pol; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ ++ switch (type & IRQ_TYPE_SENSE_MASK) { ++ case IRQ_TYPE_EDGE_RISING: ++ event_pol = _iproc_gpio_readl(ourchip, GPIO_CCA_INT_EDGE); ++ event_pol &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, event_pol, GPIO_CCA_INT_EDGE); ++ break; ++ case IRQ_TYPE_EDGE_FALLING: ++ event_pol = _iproc_gpio_readl(ourchip, GPIO_CCA_INT_EDGE); ++ event_pol |= (1 << pin); ++ _iproc_gpio_writel(ourchip, event_pol, GPIO_CCA_INT_EDGE); ++ break; ++ case IRQ_TYPE_LEVEL_HIGH: ++ int_pol = _iproc_gpio_readl(ourchip, GPIO_CCA_INT_LEVEL); ++ int_pol &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, int_pol, GPIO_CCA_INT_LEVEL); ++ break; ++ case IRQ_TYPE_LEVEL_LOW: ++ int_pol = _iproc_gpio_readl(ourchip,GPIO_CCA_INT_LEVEL); ++ int_pol |= (1 << pin); ++ _iproc_gpio_writel(ourchip, int_pol, GPIO_CCA_INT_LEVEL); ++ break; ++ default: ++ /* should not come here */ ++ return -EINVAL; ++ } ++ ++ if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) ++ irq_set_handler_locked(irq_get_irq_data(irq), handle_level_irq); ++ else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) ++ irq_set_handler_locked(irq_get_irq_data(irq), handle_edge_irq); ++ ++ return 0; ++} ++ ++struct iproc_gpio_irqcfg cca_gpio_irqcfg = { ++ /* ++ * Remove IRQF_NO_SUSPEND to be consistent with 8250_core.c setting, ++ * since CCA gpio and uart share the same IRQ. ++ */ ++ .flags = IRQF_SHARED, ++ .handler = iproc_gpio_irq_handler_cca, ++ .ack = iproc_gpio_irq_ack_cca, ++ .mask = iproc_gpio_irq_mask_cca, ++ .unmask = iproc_gpio_irq_unmask_cca, ++ .set_type = iproc_gpio_irq_set_type_cca, ++}; ++ ++static irqreturn_t iproc_gpio_irq_handler_ccb(int irq, void *dev) ++{ ++ struct iproc_gpio_chip *ourchip = dev; ++ int iter, max_pin; ++ u32 val; ++ ++ val = _iproc_gpio_readl(ourchip, GPIO_CCB_INT_MSTAT); ++ if (!val) ++ return IRQ_NONE; ++ ++ /* Max GPIO register bit */ ++ max_pin = ourchip->pin_reg_bit_shift + ourchip->chip.ngpio; ++ for (iter = ourchip->pin_reg_bit_shift; iter < max_pin; iter++) ++ if (val & (1 << iter)) ++ generic_handle_irq(iproc_gpio_to_irq(ourchip, iter)); ++ ++ return IRQ_HANDLED; ++} ++ ++static void iproc_gpio_irq_ack_ccb(u32 irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ u32 int_clear = 0; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ int_clear |= (1 << pin); ++ _iproc_gpio_writel(ourchip, int_clear, GPIO_CCB_INT_CLR); ++} ++ ++static void iproc_gpio_irq_unmask_ccb(u32 irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ u32 int_mask; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ int_mask = _iproc_gpio_readl(ourchip, GPIO_CCB_INT_MASK); ++ int_mask |= (1 << pin); ++ _iproc_gpio_writel(ourchip, int_mask, GPIO_CCB_INT_MASK); ++} ++ ++static void iproc_gpio_irq_mask_ccb(u32 irq) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ u32 int_mask; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ int_mask = _iproc_gpio_readl(ourchip, GPIO_CCB_INT_MASK); ++ int_mask &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, int_mask,GPIO_CCB_INT_MASK); ++} ++ ++static int iproc_gpio_irq_set_type_ccb(u32 irq, u32 type) ++{ ++ struct iproc_gpio_chip *ourchip = irq_get_chip_data(irq); ++ int pin; ++ u32 int_type, int_de, int_edge; ++ ++ pin = iproc_irq_to_gpio(ourchip, irq); ++ int_type = _iproc_gpio_readl(ourchip, GPIO_CCB_INT_TYPE); ++ int_edge = _iproc_gpio_readl(ourchip, GPIO_CCB_INT_EDGE); ++ ++ switch (type) { ++ case IRQ_TYPE_EDGE_BOTH: ++ int_type &= ~(1 << pin); ++ int_de = _iproc_gpio_readl(ourchip, GPIO_CCB_INT_DE); ++ int_de |= (1 << pin); ++ _iproc_gpio_writel(ourchip, int_de, GPIO_CCB_INT_DE); ++ break; ++ case IRQ_TYPE_EDGE_RISING: ++ int_type &= ~(1 << pin); ++ int_edge |= (1 << pin); ++ int_de = _iproc_gpio_readl(ourchip, GPIO_CCB_INT_DE); ++ int_de &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, int_de, GPIO_CCB_INT_DE); ++ break; ++ case IRQ_TYPE_EDGE_FALLING: ++ int_type &= ~(1 << pin); ++ int_edge &= ~(1 << pin); ++ int_de = _iproc_gpio_readl(ourchip, GPIO_CCB_INT_DE); ++ int_de &= ~(1 << pin); ++ _iproc_gpio_writel(ourchip, int_de, GPIO_CCB_INT_DE); ++ break; ++ case IRQ_TYPE_LEVEL_HIGH: ++ int_type |= (1 << pin); ++ int_edge |= (1 << pin); ++ break; ++ case IRQ_TYPE_LEVEL_LOW: ++ int_type |= (1 << pin); ++ int_edge &= ~(1 << pin); ++ break; ++ default: ++ /* should not come here */ ++ return -EINVAL; ++ } ++ ++ _iproc_gpio_writel(ourchip, int_type, GPIO_CCB_INT_TYPE); ++ _iproc_gpio_writel(ourchip, int_edge, GPIO_CCB_INT_EDGE); ++ ++ if (type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_LEVEL_HIGH)) ++ irq_set_handler_locked(irq_get_irq_data(irq), handle_level_irq); ++ else if (type & (IRQ_TYPE_EDGE_FALLING | IRQ_TYPE_EDGE_RISING)) ++ irq_set_handler_locked(irq_get_irq_data(irq), handle_edge_irq); ++ ++ return 0; ++} ++ ++struct iproc_gpio_irqcfg ccb_gpio_irqcfg = { ++ .flags = IRQF_NO_SUSPEND, ++ .handler = iproc_gpio_irq_handler_ccb, ++ .ack = iproc_gpio_irq_ack_ccb, ++ .mask = iproc_gpio_irq_mask_ccb, ++ .unmask = iproc_gpio_irq_unmask_ccb, ++ .set_type = iproc_gpio_irq_set_type_ccb, ++}; ++ ++static struct irq_chip iproc_gpio_irq_chip = { ++ .name = "IPROC-GPIO", ++ .irq_ack = (void *) iproc_gpio_irq_ack, ++ .irq_mask = (void *) iproc_gpio_irq_mask, ++ .irq_unmask = (void *) iproc_gpio_irq_unmask, ++ .irq_set_type = (void *) iproc_gpio_irq_set_type, ++}; ++ ++ ++static int iproc_gpiolib_input(struct gpio_chip *chip, u32 gpio) ++{ ++ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); ++ unsigned long flags; ++ u32 val, nBitMask; ++ int reg_offset; ++ u32 pin_offset = gpio + ourchip->pin_reg_bit_shift; ++ ++ iproc_gpio_lock(ourchip, flags); ++ ++ nBitMask = 1 << pin_offset; ++ reg_offset = REGOFFSET_GPIO_OUT_EN; ++ ++ val = _iproc_gpio_readl(ourchip, reg_offset); ++ val &= ~nBitMask; ++ _iproc_gpio_writel(ourchip, val, reg_offset); ++ ++ iproc_gpio_unlock(ourchip, flags); ++ ++ return 0; ++} ++ ++static int iproc_gpiolib_output(struct gpio_chip *chip, u32 gpio, int value) ++{ ++ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); ++ unsigned long flags, val; ++ u32 nBitMask; ++ int reg_offset; ++ /* GPIO register bit */ ++ u32 pin_offset = gpio + ourchip->pin_reg_bit_shift; ++ ++ iproc_gpio_lock(ourchip, flags); ++ ++ nBitMask = 1 << pin_offset; ++ reg_offset = REGOFFSET_GPIO_OUT_EN; ++ ++ val = _iproc_gpio_readl(ourchip, reg_offset); ++ val |= nBitMask; ++ _iproc_gpio_writel(ourchip, val, reg_offset); ++ ++ iproc_gpio_unlock(ourchip, flags); ++ ++ return 0; ++} ++ ++static void iproc_gpiolib_set(struct gpio_chip *chip, u32 gpio, int value) ++{ ++ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); ++ unsigned long flags, val; ++ u32 nBitMask; ++ /* GPIO register bit */ ++ u32 pin_offset = gpio + ourchip->pin_reg_bit_shift; ++ ++ iproc_gpio_lock(ourchip, flags); ++ ++ nBitMask = 1 << pin_offset; ++ ++ val = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_OUT_EN); ++ val &= nBitMask; ++ ++ /* this function only applies to output pin */ ++ if (!val) ++ return; ++ ++ val = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_DOUT); ++ if (value == 0) ++ /* Set the pin to zero */ ++ val &= ~nBitMask; ++ else ++ /* Set the pin to 1 */ ++ val |= nBitMask; ++ ++ _iproc_gpio_writel(ourchip, val, REGOFFSET_GPIO_DOUT); ++ ++ iproc_gpio_unlock(ourchip, flags); ++} ++ ++static int iproc_gpiolib_get(struct gpio_chip *chip, u32 gpio) ++{ ++ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); ++ unsigned long flags; ++ u32 val, offset, nBitMask; ++ /* GPIO register bit */ ++ u32 pin_offset = gpio + ourchip->pin_reg_bit_shift; ++ ++ iproc_gpio_lock(ourchip, flags); ++ ++ nBitMask = 1 << pin_offset; ++ ++ /* determine the GPIO pin direction */ ++ offset = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_OUT_EN); ++ offset &= nBitMask; ++ ++ if (offset) ++ val = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_DOUT); ++ else ++ val = _iproc_gpio_readl(ourchip, REGOFFSET_GPIO_DIN); ++ ++ val >>= pin_offset; ++ val &= 1; ++ ++ iproc_gpio_unlock(ourchip, flags); ++ ++ return val; ++} ++ ++/* ++@offset : the gpio pin index number from gpiolib view (minus gpio base only) ++*/ ++static int iproc_gpiolib_to_irq(struct gpio_chip *chip, u32 offset) ++{ ++ struct iproc_gpio_chip *ourchip = to_iproc_gpio(chip); ++ ++ return irq_linear_revmap(ourchip->irq_domain, offset); ++} ++ ++static struct __initconst of_device_id bcm_iproc_gpio_of_match[] = { ++ { .compatible = "brcm,iproc-gpio-cca" }, ++ { .compatible = "brcm,iproc-gpio-ccb" }, ++ { .compatible = "brcm,iproc-gpio-ccg" }, ++ {} ++}; ++MODULE_DEVICE_TABLE(of, bcm_iproc_gpio_of_match); ++ ++static int iproc_gpio_probe(struct platform_device *pdev) ++{ ++ struct device_node *dn = pdev->dev.of_node; ++ struct iproc_gpio_chip *iproc_gpio; ++ u32 num_gpios, count; ++ int ret; ++ ++ iproc_gpio = devm_kzalloc(&pdev->dev, sizeof(*iproc_gpio), GFP_KERNEL); ++ if (!iproc_gpio) { ++ dev_err(&pdev->dev, "Error allocating memory\n"); ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(pdev, iproc_gpio); ++ ++ /* Determine type of gpio controller to allocate */ ++ if (of_device_is_compatible(dn, "brcm,iproc-gpio-cca")) { ++ iproc_gpio->chip.label = "gpio_cca"; ++ iproc_gpio->id = IPROC_GPIO_CCA_ID; ++ iproc_gpio->irqcfg = &cca_gpio_irqcfg; ++ ++ iproc_gpio->intr_ioaddr = of_iomap(dn, 1); ++ if (!iproc_gpio->intr_ioaddr) { ++ dev_err(&pdev->dev, "gpio interrupt base addr fail\n"); ++ return -ENOMEM; ++ } ++ ++ dev_info(&pdev->dev, "%s intr_ioaddr: %p\n", ++ iproc_gpio->chip.label, iproc_gpio->intr_ioaddr); ++ } else if (of_device_is_compatible(dn, "brcm,iproc-gpio-ccb")) { ++ iproc_gpio->chip.label = "gpio_ccb"; ++ iproc_gpio->id = IPROC_GPIO_CCB_ID; ++ iproc_gpio->irqcfg = &ccb_gpio_irqcfg; ++ } else if (of_device_is_compatible(dn, "brcm,iproc-gpio-ccg")) { ++ iproc_gpio->chip.label = "gpio_ccg"; ++ iproc_gpio->id = IPROC_GPIO_CCG_ID; ++ iproc_gpio->irqcfg = &ccb_gpio_irqcfg; ++ } else { ++ dev_err(&pdev->dev, "Error parsing device tree of GPIO\n"); ++ return -ENODEV; ++ } ++ ++ /* Map gpio base ioaddr address */ ++ iproc_gpio->ioaddr = of_iomap(dn, 0); ++ if (!iproc_gpio->ioaddr) { ++ dev_err(&pdev->dev, "can't iomap gpio base address\n"); ++ return -ENOMEM; ++ } ++ dev_info(&pdev->dev, "%s ioaddr: %p\n", iproc_gpio->chip.label, ++ iproc_gpio->ioaddr); ++ ++ /* pin_base: gpio pin base */ ++ if (of_property_read_u32(dn, "pin-base", &iproc_gpio->chip.base)) { ++ dev_err(&pdev->dev, "Missing pin-base property\n"); ++ return -EINVAL; ++ } ++ ++ /* pin_reg_bit_shift: GPIO register bit offset */ ++ if (of_property_read_u32(dn, "pin-reg-bit-shift", ++ &iproc_gpio->pin_reg_bit_shift)) { ++ dev_err(&pdev->dev, "Missing pin-reg-bit-shift property\n"); ++ return -EINVAL; ++ } ++ ++ /* Get number of GPIO pin */ ++ if (of_property_read_u32(dn, "ngpios", &num_gpios)) { ++ dev_err(&pdev->dev, "Missing ngpios property\n"); ++ return -EINVAL; ++ } ++ iproc_gpio->chip.ngpio = num_gpios; ++ ++ iproc_gpio->chip.parent = &pdev->dev; ++ iproc_gpio->chip.of_node = dn; ++ ++ iproc_gpio->chip.direction_input = iproc_gpiolib_input; ++ iproc_gpio->chip.direction_output = iproc_gpiolib_output; ++ iproc_gpio->chip.set = iproc_gpiolib_set; ++ iproc_gpio->chip.get = iproc_gpiolib_get; ++ iproc_gpio->chip.to_irq = iproc_gpiolib_to_irq; ++ ++ ret = gpiochip_add_data(&iproc_gpio->chip, iproc_gpio); ++ if (ret) { ++ dev_err(&pdev->dev, "Could not add gpiochip for %s\n", ++ iproc_gpio->chip.label); ++ return ret; ++ } ++ ++ iproc_gpio->irq = platform_get_irq(pdev, 0); ++ ++ if (iproc_gpio->irq < 0) { ++ dev_warn(&pdev->dev, "No IRQ specified for %s\n", ++ iproc_gpio->chip.label); ++ return 0; ++ } ++ ++ /* Create irq domain */ ++ iproc_gpio->irq_domain = irq_domain_add_linear(dn, num_gpios, ++ &irq_domain_simple_ops, iproc_gpio); ++ ++ if (!iproc_gpio->irq_domain) { ++ dev_err(&pdev->dev, "Couldn't allocate IRQ domain\n"); ++ ret = -ENODEV; ++ goto err_irq_domain; ++ } ++ ++ /* Map each gpio pin to an IRQ and set the handler */ ++ for (count = 0; count < num_gpios; count++) { ++ int irq; ++ ++ irq = irq_create_mapping(iproc_gpio->irq_domain, count); ++ irq_set_chip_and_handler(irq, &iproc_gpio_irq_chip, ++ handle_simple_irq); ++ irq_set_chip_data(irq, iproc_gpio); ++ } ++ ++ /* Enable GPIO interrupts for CCA GPIO */ ++ if (iproc_gpio->id == IPROC_GPIO_CCA_ID) { ++ u32 val; ++ val = readl(iproc_gpio->intr_ioaddr + CCA_INT_MASK); ++ val |= CCA_INT_F_GPIOINT; ++ writel(val, iproc_gpio->intr_ioaddr + CCA_INT_MASK); ++ } ++ ++ /* Install ISR for this GPIO controller */ ++ if (iproc_gpio->irqcfg) { ++ struct iproc_gpio_irqcfg *irqcfg = iproc_gpio->irqcfg; ++ if (irqcfg->handler) { ++ ret = request_irq(iproc_gpio->irq, irqcfg->handler, ++ irqcfg->flags, iproc_gpio->chip.label, ++ iproc_gpio); ++ if (ret) { ++ dev_err(&pdev->dev, "Fail to request IRQ%d\n", ++ iproc_gpio->irq); ++ goto err_irq_request; ++ } ++ } else { ++ dev_warn(&pdev->dev, "%s has no isr!\n", ++ iproc_gpio->chip.label); ++ } ++ } ++ ++ return 0; ++ ++err_irq_request: ++ irq_domain_remove(iproc_gpio->irq_domain); ++ iproc_gpio->irq_domain = NULL; ++ ++err_irq_domain: ++ gpiochip_remove(&iproc_gpio->chip); ++ ++ return ret; ++} ++ ++static int __exit iproc_gpio_remove(struct platform_device *pdev) ++{ ++ struct iproc_gpio_chip *iproc_gpio; ++ ++ iproc_gpio = platform_get_drvdata(pdev); ++ if (iproc_gpio == NULL) ++ return -ENODEV; ++ ++ if (iproc_gpio->intr_ioaddr) { ++ /* Disable GPIO interrupts for CCA GPIO */ ++ if (iproc_gpio->id == IPROC_GPIO_CCA_ID) { ++ u32 val; ++ val = readl(iproc_gpio->intr_ioaddr + CCA_INT_MASK); ++ val &= ~(CCA_INT_F_GPIOINT); ++ writel(val, iproc_gpio->intr_ioaddr + CCA_INT_MASK); ++ } ++ } ++ ++ gpiochip_remove(&iproc_gpio->chip); ++ ++ return 0; ++} ++ ++static struct platform_driver bcm_iproc_gpio_driver = { ++ .driver = { ++ .name = "iproc-gpio", ++ .owner = THIS_MODULE, ++ .of_match_table = bcm_iproc_gpio_of_match, ++ }, ++ .probe = iproc_gpio_probe, ++ .remove = iproc_gpio_remove, ++}; ++ ++module_platform_driver(bcm_iproc_gpio_driver); ++ ++MODULE_DESCRIPTION("XGS IPROC GPIO driver"); ++MODULE_LICENSE("GPL v2"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig +--- a/drivers/i2c/busses/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/i2c/busses/Kconfig 2018-05-10 11:31:30.853400956 +0800 +@@ -418,6 +418,26 @@ config I2C_BCM_IPROC + + If you don't know what to do here, say N. + ++config I2C_XGS_IPROC ++ tristate "Broadcom XGS iProc I2C controller" ++ depends on ARCH_XGS_IPROC ++ default ARCH_XGS_IPROC ++ help ++ If you say yes to this option, support will be included for the ++ Broadcom XGS iProc I2C controller. ++ ++ If you don't know what to do here, say N. ++ ++config SMBUS_XGS_IPROC ++ tristate "Broadcom XGS iProc SMBUS controller" ++ depends on ARCH_XGS_IPROC && !I2C_XGS_IPROC ++ default n ++ help ++ If you say yes to this option, support will be included for the ++ Broadcom XGS iProc SMBUS controller. ++ ++ If you don't know what to do here, say N. ++ + config I2C_BCM_KONA + tristate "BCM Kona I2C adapter" + depends on ARCH_BCM_MOBILE +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile +--- a/drivers/i2c/busses/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/i2c/busses/Makefile 2018-05-10 11:31:30.853400956 +0800 +@@ -108,6 +108,8 @@ i2c-octeon-objs := i2c-octeon-core.o i2c + obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o + i2c-thunderx-objs := i2c-octeon-core.o i2c-thunderx-pcidrv.o + obj-$(CONFIG_I2C_THUNDERX) += i2c-thunderx.o ++obj-$(CONFIG_I2C_XGS_IPROC) += i2c-xgs-iproc.o ++obj-$(CONFIG_SMBUS_XGS_IPROC) += xgs_iproc_smbus.o + obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o + obj-$(CONFIG_I2C_XLR) += i2c-xlr.o + obj-$(CONFIG_I2C_XLP9XX) += i2c-xlp9xx.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/i2c-xgs-iproc.c b/drivers/i2c/busses/i2c-xgs-iproc.c +--- a/drivers/i2c/busses/i2c-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/i2c/busses/i2c-xgs-iproc.c 2018-05-10 11:31:30.877400982 +0800 +@@ -0,0 +1,584 @@ ++/* ++ * Copyright (C) 2014 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++/* ++ * This file is based on i2c-bcm-iproc.c with the following changes. ++ * 1. Enable read support with data len >= 64B ++ * 2. Different implementation of write support for data len >= 64B ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define CFG_OFFSET 0x00 ++#define CFG_RESET_SHIFT 31 ++#define CFG_EN_SHIFT 30 ++#define CFG_M_RETRY_CNT_SHIFT 16 ++#define CFG_M_RETRY_CNT_MASK 0x0f ++ ++#define TIM_CFG_OFFSET 0x04 ++#define TIM_CFG_MODE_400_SHIFT 31 ++ ++#define M_FIFO_CTRL_OFFSET 0x0c ++#define M_FIFO_RX_FLUSH_SHIFT 31 ++#define M_FIFO_TX_FLUSH_SHIFT 30 ++#define M_FIFO_RX_CNT_SHIFT 16 ++#define M_FIFO_RX_CNT_MASK 0x7f ++#define M_FIFO_RX_THLD_SHIFT 8 ++#define M_FIFO_RX_THLD_MASK 0x3f ++ ++#define M_CMD_OFFSET 0x30 ++#define M_CMD_START_BUSY_SHIFT 31 ++#define M_CMD_STATUS_SHIFT 25 ++#define M_CMD_STATUS_MASK 0x07 ++#define M_CMD_STATUS_SUCCESS 0x0 ++#define M_CMD_STATUS_LOST_ARB 0x1 ++#define M_CMD_STATUS_NACK_ADDR 0x2 ++#define M_CMD_STATUS_NACK_DATA 0x3 ++#define M_CMD_STATUS_TIMEOUT 0x4 ++#define M_CMD_PROTOCOL_SHIFT 9 ++#define M_CMD_PROTOCOL_MASK 0xf ++#define M_CMD_PROTOCOL_BLK_WR 0x7 ++#define M_CMD_PROTOCOL_BLK_RD 0x8 ++#define M_CMD_PEC_SHIFT 8 ++#define M_CMD_RD_CNT_SHIFT 0 ++#define M_CMD_RD_CNT_MASK 0xff ++ ++#define IE_OFFSET 0x38 ++#define IE_M_RX_FIFO_FULL_SHIFT 31 ++#define IE_M_RX_THLD_SHIFT 30 ++#define IE_M_START_BUSY_SHIFT 28 ++ ++#define IS_OFFSET 0x3c ++#define IS_M_RX_FIFO_FULL_SHIFT 31 ++#define IS_M_RX_THLD_SHIFT 30 ++#define IS_M_START_BUSY_SHIFT 28 ++ ++#define M_TX_OFFSET 0x40 ++#define M_TX_WR_STATUS_SHIFT 31 ++#define M_TX_DATA_SHIFT 0 ++#define M_TX_DATA_MASK 0xff ++ ++#define M_RX_OFFSET 0x44 ++#define M_RX_STATUS_SHIFT 30 ++#define M_RX_STATUS_MASK 0x03 ++#define M_RX_PEC_ERR_SHIFT 29 ++#define M_RX_DATA_SHIFT 0 ++#define M_RX_DATA_MASK 0xff ++ ++#define I2C_TIMEOUT_MSEC 100 ++ ++#define M_TX_RX_FIFO_SIZE 64 ++#define I2C_MAX_DATA_LEN (M_TX_RX_FIFO_SIZE - 1) ++ ++/* ++ * Enable support of EEPROM I2C devices with 2-byte addressing mode ++ * (total size > 256B)and page size >= 64B. ++ */ ++#define CONFIG_ENABLE_WRITE_MSG_SPLIT 1 ++ ++ ++enum bus_speed_index { ++ I2C_SPD_100K = 0, ++ I2C_SPD_400K, ++}; ++ ++struct bcm_iproc_i2c_dev { ++ struct device *device; ++ int irq; ++ ++ void __iomem *base; ++ ++ struct i2c_adapter adapter; ++ unsigned int bus_speed; ++ ++ struct completion done; ++ int xfer_is_done; ++}; ++ ++/* ++ * Can be expanded in the future if more interrupt status bits are utilized ++ */ ++#define ISR_MASK (1 << IS_M_START_BUSY_SHIFT) ++ ++static irqreturn_t bcm_iproc_i2c_isr(int irq, void *data) ++{ ++ struct bcm_iproc_i2c_dev *iproc_i2c = data; ++ u32 status = readl(iproc_i2c->base + IS_OFFSET); ++ ++ status &= ISR_MASK; ++ ++ if (!status) ++ return IRQ_NONE; ++ ++ writel(status, iproc_i2c->base + IS_OFFSET); ++ iproc_i2c->xfer_is_done = 1; ++ complete(&iproc_i2c->done); ++ ++ return IRQ_HANDLED; ++} ++ ++static int bcm_iproc_i2c_check_status(struct bcm_iproc_i2c_dev *iproc_i2c, ++ struct i2c_msg *msg) ++{ ++ u32 val; ++ ++ val = readl(iproc_i2c->base + M_CMD_OFFSET); ++ val = (val >> M_CMD_STATUS_SHIFT) & M_CMD_STATUS_MASK; ++ ++ switch (val) { ++ case M_CMD_STATUS_SUCCESS: ++ return 0; ++ ++ case M_CMD_STATUS_LOST_ARB: ++ dev_dbg(iproc_i2c->device, "lost bus arbitration\n"); ++ return -EAGAIN; ++ ++ case M_CMD_STATUS_NACK_ADDR: ++ dev_dbg(iproc_i2c->device, "NAK addr:0x%02x\n", msg->addr); ++ return -ENXIO; ++ ++ case M_CMD_STATUS_NACK_DATA: ++ dev_dbg(iproc_i2c->device, "NAK data\n"); ++ return -ENXIO; ++ ++ case M_CMD_STATUS_TIMEOUT: ++ dev_dbg(iproc_i2c->device, "bus timeout\n"); ++ return -ETIMEDOUT; ++ ++ default: ++ dev_dbg(iproc_i2c->device, "unknown error code=%d\n", val); ++ return -EIO; ++ } ++} ++ ++static int bcm_iproc_i2c_xfer_one_msg(struct bcm_iproc_i2c_dev *iproc_i2c, ++ struct i2c_msg *msg) ++{ ++ int ret, i; ++ u8 addr; ++ u32 val; ++ unsigned long time_left = msecs_to_jiffies(I2C_TIMEOUT_MSEC); ++ ++ /* check if bus is busy */ ++ if (!!(readl(iproc_i2c->base + M_CMD_OFFSET) & ++ BIT(M_CMD_START_BUSY_SHIFT))) { ++ dev_warn(iproc_i2c->device, "bus is busy\n"); ++ return -EBUSY; ++ } ++ ++ /* format and load slave address into the TX FIFO */ ++ addr = i2c_8bit_addr_from_msg(msg); ++ writel(addr, iproc_i2c->base + M_TX_OFFSET); ++ ++ /* for a write transaction, load data into the TX FIFO */ ++ if (!(msg->flags & I2C_M_RD)) { ++ for (i = 0; i < msg->len; i++) { ++ val = msg->buf[i]; ++ ++ /* mark the last byte */ ++ if (i == msg->len - 1) ++ val |= 1 << M_TX_WR_STATUS_SHIFT; ++ ++ writel(val, iproc_i2c->base + M_TX_OFFSET); ++ } ++ } ++ ++ /* mark as incomplete before starting the transaction */ ++ reinit_completion(&iproc_i2c->done); ++ iproc_i2c->xfer_is_done = 0; ++ ++ /* ++ * Enable the "start busy" interrupt, which will be triggered after the ++ * transaction is done, i.e., the internal start_busy bit, transitions ++ * from 1 to 0. ++ */ ++ writel(1 << IE_M_START_BUSY_SHIFT, iproc_i2c->base + IE_OFFSET); ++ ++ /* ++ * Now we can activate the transfer. For a read operation, specify the ++ * number of bytes to read ++ */ ++ val = 1 << M_CMD_START_BUSY_SHIFT; ++ if (msg->flags & I2C_M_RD) { ++ val |= (M_CMD_PROTOCOL_BLK_RD << M_CMD_PROTOCOL_SHIFT) | ++ (msg->len << M_CMD_RD_CNT_SHIFT); ++ } else { ++ val |= (M_CMD_PROTOCOL_BLK_WR << M_CMD_PROTOCOL_SHIFT); ++ } ++ writel(val, iproc_i2c->base + M_CMD_OFFSET); ++ ++ time_left = wait_for_completion_timeout(&iproc_i2c->done, time_left); ++ ++ /* disable all interrupts */ ++ writel(0, iproc_i2c->base + IE_OFFSET); ++ /* read it back to flush the write */ ++ readl(iproc_i2c->base + IE_OFFSET); ++ ++ /* make sure the interrupt handler isn't running */ ++ synchronize_irq(iproc_i2c->irq); ++ ++ if (!time_left && !iproc_i2c->xfer_is_done) { ++ dev_err(iproc_i2c->device, "transaction timed out\n"); ++ ++ /* flush FIFOs */ ++ val = (1 << M_FIFO_RX_FLUSH_SHIFT) | ++ (1 << M_FIFO_TX_FLUSH_SHIFT); ++ writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); ++ return -ETIMEDOUT; ++ } ++ ++ ret = bcm_iproc_i2c_check_status(iproc_i2c, msg); ++ if (ret) { ++ /* flush both TX/RX FIFOs */ ++ val = (1 << M_FIFO_RX_FLUSH_SHIFT) | ++ (1 << M_FIFO_TX_FLUSH_SHIFT); ++ writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); ++ return ret; ++ } ++ ++ /* ++ * For a read operation, we now need to load the data from FIFO ++ * into the memory buffer ++ */ ++ if (msg->flags & I2C_M_RD) { ++ for (i = 0; i < msg->len; i++) { ++ msg->buf[i] = (readl(iproc_i2c->base + M_RX_OFFSET) >> ++ M_RX_DATA_SHIFT) & M_RX_DATA_MASK; ++ } ++ } ++ ++ return 0; ++} ++ ++static int bcm_iproc_i2c_xfer(struct i2c_adapter *adapter, ++ struct i2c_msg msgs[], int num) ++{ ++ struct bcm_iproc_i2c_dev *iproc_i2c = i2c_get_adapdata(adapter); ++ int ret, i; ++ int xfer_msg_len; ++ u8 addr_h, addr_l; ++ ++ /* go through all messages */ ++ for (i = 0; i < num; i++) { ++ xfer_msg_len = msgs[i].len; ++ ++ while (xfer_msg_len) { ++ if (xfer_msg_len > I2C_MAX_DATA_LEN) ++ msgs[i].len = I2C_MAX_DATA_LEN; ++ ++ ret = bcm_iproc_i2c_xfer_one_msg(iproc_i2c, &msgs[i]); ++ if (ret) { ++ dev_dbg(iproc_i2c->device, "xfer failed\n"); ++ return ret; ++ } ++ ++ xfer_msg_len -= msgs[i].len; ++ if (xfer_msg_len == 0) ++ break; ++ ++#if defined(CONFIG_ENABLE_WRITE_MSG_SPLIT) ++ /* Keep the addr offset for later use */ ++ addr_h = msgs[i].buf[0]; ++ addr_l = msgs[i].buf[1]; ++#endif ++ ++ msgs[i].len = xfer_msg_len; ++ msgs[i].buf += I2C_MAX_DATA_LEN; ++ ++#if defined(CONFIG_ENABLE_WRITE_MSG_SPLIT) ++ if (!(msgs[i].flags & I2C_M_RD)) { ++ /* ++ * For write transfer with len >= 64B, assuming ++ * 2-byte addressing should be reasonable. ++ */ ++ xfer_msg_len += 2; ++ msgs[i].len = xfer_msg_len; ++ /* ++ * Append a new 2-byte address offset. ++ * The upper byte should be unchanged, and the ++ * lower byte is increased by actually written ++ * bytes: (I2C_MAX_DATA_LEN - 2) ++ */ ++ msgs[i].buf -= 2; ++ msgs[i].buf[0] = addr_h; ++ msgs[i].buf[1] = addr_l + I2C_MAX_DATA_LEN - 2; ++ ++ /* ++ * Wait some time so that EEPROM is ready to ++ * respond after previous partial page write. ++ */ ++ if (!(msgs[i].flags & I2C_M_RD)) ++ mdelay(10); ++ } ++#endif /* CONFIG_ENABLE_WRITE_MSG_SPLIT */ ++ } /* while */ ++ } /* for */ ++ ++ return num; ++} ++ ++ ++static uint32_t bcm_iproc_i2c_functionality(struct i2c_adapter *adap) ++{ ++ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; ++} ++ ++static const struct i2c_algorithm bcm_iproc_algo = { ++ .master_xfer = bcm_iproc_i2c_xfer, ++ .functionality = bcm_iproc_i2c_functionality, ++}; ++ ++/* ++ * Don't limit the max write length for Linux I2C core, if support of ++ * write msg split is enabled. ++ * Read msg split is supported, so max_read_len is commented out. ++ */ ++#if !defined(CONFIG_ENABLE_WRITE_MSG_SPLIT) ++static const struct i2c_adapter_quirks bcm_iproc_i2c_quirks = { ++ /* need to reserve one byte in the FIFO for the slave address */ ++ //.max_read_len = M_TX_RX_FIFO_SIZE - 1, ++ .max_write_len = M_TX_RX_FIFO_SIZE - 1, ++}; ++#endif ++ ++static int bcm_iproc_i2c_cfg_speed(struct bcm_iproc_i2c_dev *iproc_i2c) ++{ ++ unsigned int bus_speed; ++ u32 val; ++ int ret = of_property_read_u32(iproc_i2c->device->of_node, ++ "clock-frequency", &bus_speed); ++ if (ret < 0) { ++ dev_info(iproc_i2c->device, ++ "unable to interpret clock-frequency DT property\n"); ++ bus_speed = 100000; ++ } ++ ++ if (bus_speed < 100000) { ++ dev_err(iproc_i2c->device, "%d Hz bus speed not supported\n", ++ bus_speed); ++ dev_err(iproc_i2c->device, ++ "valid speeds are 100khz and 400khz\n"); ++ return -EINVAL; ++ } else if (bus_speed < 400000) { ++ bus_speed = 100000; ++ } else { ++ bus_speed = 400000; ++ } ++ ++ iproc_i2c->bus_speed = bus_speed; ++ val = readl(iproc_i2c->base + TIM_CFG_OFFSET); ++ val &= ~(1 << TIM_CFG_MODE_400_SHIFT); ++ val |= (bus_speed == 400000) << TIM_CFG_MODE_400_SHIFT; ++ writel(val, iproc_i2c->base + TIM_CFG_OFFSET); ++ ++ dev_info(iproc_i2c->device, "bus set to %u Hz\n", bus_speed); ++ ++ return 0; ++} ++ ++static int bcm_iproc_i2c_init(struct bcm_iproc_i2c_dev *iproc_i2c) ++{ ++ u32 val; ++ ++ /* put controller in reset */ ++ val = readl(iproc_i2c->base + CFG_OFFSET); ++ val |= 1 << CFG_RESET_SHIFT; ++ val &= ~(1 << CFG_EN_SHIFT); ++ writel(val, iproc_i2c->base + CFG_OFFSET); ++ ++ /* wait 100 usec per spec */ ++ udelay(100); ++ ++ /* bring controller out of reset */ ++ val &= ~(1 << CFG_RESET_SHIFT); ++ writel(val, iproc_i2c->base + CFG_OFFSET); ++ ++ /* flush TX/RX FIFOs and set RX FIFO threshold to zero */ ++ val = (1 << M_FIFO_RX_FLUSH_SHIFT) | (1 << M_FIFO_TX_FLUSH_SHIFT); ++ writel(val, iproc_i2c->base + M_FIFO_CTRL_OFFSET); ++ ++ /* disable all interrupts */ ++ writel(0, iproc_i2c->base + IE_OFFSET); ++ ++ /* clear all pending interrupts */ ++ writel(0xffffffff, iproc_i2c->base + IS_OFFSET); ++ ++ return 0; ++} ++ ++static void bcm_iproc_i2c_enable_disable(struct bcm_iproc_i2c_dev *iproc_i2c, ++ bool enable) ++{ ++ u32 val; ++ ++ val = readl(iproc_i2c->base + CFG_OFFSET); ++ if (enable) ++ val |= BIT(CFG_EN_SHIFT); ++ else ++ val &= ~BIT(CFG_EN_SHIFT); ++ writel(val, iproc_i2c->base + CFG_OFFSET); ++} ++ ++static int bcm_iproc_i2c_probe(struct platform_device *pdev) ++{ ++ int irq, ret = 0; ++ struct bcm_iproc_i2c_dev *iproc_i2c; ++ struct i2c_adapter *adap; ++ struct resource *res; ++ ++ iproc_i2c = devm_kzalloc(&pdev->dev, sizeof(*iproc_i2c), ++ GFP_KERNEL); ++ if (!iproc_i2c) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, iproc_i2c); ++ iproc_i2c->device = &pdev->dev; ++ init_completion(&iproc_i2c->done); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ iproc_i2c->base = devm_ioremap_resource(iproc_i2c->device, res); ++ if (IS_ERR(iproc_i2c->base)) ++ return PTR_ERR(iproc_i2c->base); ++ ++ ret = bcm_iproc_i2c_init(iproc_i2c); ++ if (ret) ++ return ret; ++ ++ ret = bcm_iproc_i2c_cfg_speed(iproc_i2c); ++ if (ret) ++ return ret; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq <= 0) { ++ dev_err(iproc_i2c->device, "no irq resource\n"); ++ return irq; ++ } ++ iproc_i2c->irq = irq; ++ ++ ret = devm_request_irq(iproc_i2c->device, irq, bcm_iproc_i2c_isr, 0, ++ pdev->name, iproc_i2c); ++ if (ret < 0) { ++ dev_err(iproc_i2c->device, "unable to request irq %i\n", irq); ++ return ret; ++ } ++ ++ bcm_iproc_i2c_enable_disable(iproc_i2c, true); ++ ++ adap = &iproc_i2c->adapter; ++ i2c_set_adapdata(adap, iproc_i2c); ++ strlcpy(adap->name, "Broadcom iProc I2C adapter", sizeof(adap->name)); ++ adap->algo = &bcm_iproc_algo; ++#if !defined(CONFIG_ENABLE_WRITE_MSG_SPLIT) ++ adap->quirks = &bcm_iproc_i2c_quirks; ++#endif ++ adap->dev.parent = &pdev->dev; ++ adap->dev.of_node = pdev->dev.of_node; ++ ++ return i2c_add_adapter(adap); ++} ++ ++static int bcm_iproc_i2c_remove(struct platform_device *pdev) ++{ ++ struct bcm_iproc_i2c_dev *iproc_i2c = platform_get_drvdata(pdev); ++ ++ /* make sure there's no pending interrupt when we remove the adapter */ ++ writel(0, iproc_i2c->base + IE_OFFSET); ++ readl(iproc_i2c->base + IE_OFFSET); ++ synchronize_irq(iproc_i2c->irq); ++ ++ i2c_del_adapter(&iproc_i2c->adapter); ++ bcm_iproc_i2c_enable_disable(iproc_i2c, false); ++ ++ return 0; ++} ++ ++#ifdef CONFIG_PM_SLEEP ++ ++static int bcm_iproc_i2c_suspend(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct bcm_iproc_i2c_dev *iproc_i2c = platform_get_drvdata(pdev); ++ ++ /* make sure there's no pending interrupt when we go into suspend */ ++ writel(0, iproc_i2c->base + IE_OFFSET); ++ readl(iproc_i2c->base + IE_OFFSET); ++ synchronize_irq(iproc_i2c->irq); ++ ++ /* now disable the controller */ ++ bcm_iproc_i2c_enable_disable(iproc_i2c, false); ++ ++ return 0; ++} ++ ++static int bcm_iproc_i2c_resume(struct device *dev) ++{ ++ struct platform_device *pdev = to_platform_device(dev); ++ struct bcm_iproc_i2c_dev *iproc_i2c = platform_get_drvdata(pdev); ++ int ret; ++ u32 val; ++ ++ /* ++ * Power domain could have been shut off completely in system deep ++ * sleep, so re-initialize the block here ++ */ ++ ret = bcm_iproc_i2c_init(iproc_i2c); ++ if (ret) ++ return ret; ++ ++ /* configure to the desired bus speed */ ++ val = readl(iproc_i2c->base + TIM_CFG_OFFSET); ++ val &= ~(1 << TIM_CFG_MODE_400_SHIFT); ++ val |= (iproc_i2c->bus_speed == 400000) << TIM_CFG_MODE_400_SHIFT; ++ writel(val, iproc_i2c->base + TIM_CFG_OFFSET); ++ ++ bcm_iproc_i2c_enable_disable(iproc_i2c, true); ++ ++ return 0; ++} ++ ++static const struct dev_pm_ops bcm_iproc_i2c_pm_ops = { ++ .suspend_late = &bcm_iproc_i2c_suspend, ++ .resume_early = &bcm_iproc_i2c_resume ++}; ++ ++#define BCM_IPROC_I2C_PM_OPS (&bcm_iproc_i2c_pm_ops) ++#else ++#define BCM_IPROC_I2C_PM_OPS NULL ++#endif /* CONFIG_PM_SLEEP */ ++ ++static const struct of_device_id bcm_iproc_i2c_of_match[] = { ++ { .compatible = "brcm,iproc-i2c" }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, bcm_iproc_i2c_of_match); ++ ++static struct platform_driver bcm_iproc_i2c_driver = { ++ .driver = { ++ .name = "bcm-iproc-i2c", ++ .of_match_table = bcm_iproc_i2c_of_match, ++ .pm = BCM_IPROC_I2C_PM_OPS, ++ }, ++ .probe = bcm_iproc_i2c_probe, ++ .remove = bcm_iproc_i2c_remove, ++}; ++module_platform_driver(bcm_iproc_i2c_driver); ++ ++MODULE_DESCRIPTION("Broadcom iProc I2C Driver"); ++MODULE_LICENSE("GPL v2"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/iproc_smbus_regs.h b/drivers/i2c/busses/iproc_smbus_regs.h +--- a/drivers/i2c/busses/iproc_smbus_regs.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/i2c/busses/iproc_smbus_regs.h 2018-05-10 11:31:30.877400982 +0800 +@@ -0,0 +1,287 @@ ++/* ++ * Copyright (C) 2013 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __IPROC_SMBUS_REGS_H__ ++#define __IPROC_SMBUS_REGS_H__ ++ ++/* --- */ ++#define CCB_SMB_CFG_REG 0x0 ++ ++#define CCB_SMB_CFG_RST_MASK 0x80000000 ++#define CCB_SMB_CFG_RST_SHIFT 31 ++ ++#define CCB_SMB_CFG_SMBEN_MASK 0x40000000 ++#define CCB_SMB_CFG_SMBEN_SHIFT 30 ++ ++#define CCB_SMB_CFG_BITBANGEN_MASK 0x20000000 ++#define CCB_SMB_CFG_BITBANGEN_SHIFT 29 ++ ++#define CCB_SMB_CFG_EN_NIC_SMBADDR0_MASK 0x10000000 ++#define CCB_SMB_CFG_EN_NIC_SMBADDR0_SHIFT 28 ++ ++#define CCB_SMB_CFG_PROMISCMODE_MASK 0x08000000 ++#define CCB_SMB_CFG_PROMISCMODE_SHIFT 27 ++ ++#define CCB_SMB_CFG_TSTMPCNTEN_MASK 0x04000000 ++#define CCB_SMB_CFG_TSTMPCNTEN_SHIFT 26 ++ ++#define CCB_SMB_CFG_MSTRRTRYCNT_MASK 0x000F0000 ++#define CCB_SMB_CFG_MSTRRTRYCNT_SHIFT 16 ++ ++ ++/* --- */ ++#define CCB_SMB_TIMGCFG_REG 0x4 ++ ++#define CCB_SMB_TIMGCFG_MODE400_MASK 0x80000000 ++#define CCB_SMB_TIMGCFG_MODE400_SHIFT 31 ++ ++#define CCB_SMB_TIMGCFG_RNDSLVSTR_MASK 0x7F000000 ++#define CCB_SMB_TIMGCFG_RNDSLVSTR_SHIFT 24 ++ ++#define CCB_SMB_TIMGCFG_PERSLVSTR_MASK 0x00FF0000 ++#define CCB_SMB_TIMGCFG_PERSLVSTR_SHIFT 16 ++ ++#define CCB_SMB_TIMGCFG_IDLTIME_MASK 0x0000FF00 ++#define CCB_SMB_TIMGCFG_IDLTIME_SHIFT 8 ++ ++/* --- */ ++#define CCB_SMB_ADDR_REG 0x8 ++ ++#define CCB_SMB_EN_NIC_SMBADDR3_MASK 0x80000000 ++#define CCB_SMB_EN_NIC_SMBADDR3_SHIFT 31 ++ ++#define CCB_SMB_NIC_SMBADDR3_MASK 0x7F000000 ++#define CCB_SMB_NIC_SMBADDR3_SHIFT 24 ++ ++#define CCB_SMB_EN_NIC_SMBADDR2_MASK 0x00800000 ++#define CCB_SMB_EN_NIC_SMBADDR2_SHIFT 23 ++ ++#define CCB_SMB_NIC_SMBADDR2_MASK 0x007F0000 ++#define CCB_SMB_NIC_SMBADDR2_SHIFT 16 ++ ++#define CCB_SMB_EN_NIC_SMBADDR1_MASK 0x00008000 ++#define CCB_SMB_EN_NIC_SMBADDR1_SHIFT 15 ++ ++#define CCB_SMB_NIC_SMBADDR1_MASK 0x00007F00 ++#define CCB_SMB_NIC_SMBADDR1_SHIFT 8 ++ ++#define CCB_SMB_EN_NIC_SMBADDR0_MASK 0x00000080 ++#define CCB_SMB_EN_NIC_SMBADDR0_SHIFT 7 ++ ++#define CCB_SMB_NIC_SMBADDR0_MASK 0x0000007F ++#define CCB_SMB_NIC_SMBADDR0_SHIFT 0 ++ ++/* --- */ ++#define CCB_SMB_MSTRFIFOCTL_REG 0xC ++ ++#define CCB_SMB_MSTRRXFIFOFLSH_MASK 0x80000000 ++#define CCB_SMB_MSTRRXFIFOFLSH_SHIFT 31 ++ ++#define CCB_SMB_MSTRTXFIFOFLSH_MASK 0x40000000 ++#define CCB_SMB_MSTRTXFIFOFLSH_SHIFT 30 ++ ++#define CCB_SMB_MSTRRXPKTCNT_MASK 0x007F0000 ++#define CCB_SMB_MSTRRXPKTCNT_SHIFT 16 ++ ++#define CCB_SMB_MSTRRXFIFOTHR_MASK 0x00003F00 ++#define CCB_SMB_MSTRRXFIFOTHR_SHIFT 8 ++ ++/* --- */ ++#define CCB_SMB_SLVFIFOCTL_REG 0x10 ++ ++#define CCB_SMB_SLVRXFIFOFLSH_MASK 0x80000000 ++#define CCB_SMB_SLVRXFIFOFLSH_SHIFT 31 ++ ++#define CCB_SMB_SLVTXFIFOFLSH_MASK 0x40000000 ++#define CCB_SMB_SLVTXFIFOFLSH_SHIFT 30 ++ ++#define CCB_SMB_SLVRXPKTCNT_MASK 0x007F0000 ++#define CCB_SMB_SLVRXPKTCNT_SHIFT 16 ++ ++#define CCB_SMB_SLVRXFIFOTHR_MASK 0x00003F00 ++#define CCB_SMB_SLVRXFIFOTHR_SHIFT 8 ++ ++/* --- */ ++#define CCB_SMB_BITBANGCTL_REG 0x14 ++ ++#define CCB_SMB_SMBCLKIN_MASK 0x80000000 ++#define CCB_SMB_SMBCLKIN_SHIFT 31 ++ ++#define CCB_SMB_SMBCLKOUTEN_MASK 0x40000000 ++#define CCB_SMB_SMBCLKOUTEN_SHIFT 30 ++ ++#define CCB_SMB_SMBDATAIN_MASK 0x20000000 ++#define CCB_SMB_SMBDATAIN_SHIFT 29 ++ ++#define CCB_SMB_SMBDATAOUTEN_MASK 0x10000000 ++#define CCB_SMB_SMBDATAOUTEN_SHIFT 28 ++ ++/* --- */ ++#define CCB_SMB_MSTRCMD_REG 0x30 ++ ++#define CCB_SMB_MSTRSTARTBUSYCMD_MASK 0x80000000 ++#define CCB_SMB_MSTRSTARTBUSYCMD_SHIFT 31 ++ ++#define CCB_SMB_MSTRABORT_MASK 0x40000000 ++#define CCB_SMB_MSTRABORT_SHIFT 30 ++ ++#define CCB_SMB_MSTRSTS_MASK 0x0E000000 ++#define CCB_SMB_MSTRSTS_SHIFT 25 ++ ++#define CCB_SMB_MSTRSMBUSPROTO_MASK 0x00001E00 ++#define CCB_SMB_MSTRSMBUSPROTO_SHIFT 9 ++ ++#define CCB_SMB_MSTRPEC_MASK 0x00000100 ++#define CCB_SMB_MSTRPEC_SHIFT 8 ++ ++#define CCB_SMB_MSTRRDBYTECNT_MASK 0x000000FF ++#define CCB_SMB_MSTRRDBYTECNT_SHIFT 0 ++ ++/* --- */ ++#define CCB_SMB_SLVCMD_REG 0x34 ++ ++#define CCB_SMB_SLVSTARTBUSYCMD_MASK 0x80000000 ++#define CCB_SMB_SLVSTARTBUSYCMD_SHIFT 31 ++ ++#define CCB_SMB_SLVABORT_MASK 0x40000000 ++#define CCB_SMB_SLVABORT_SHIFT 30 ++ ++#define CCB_SMB_SLVSTS_MASK 0x03800000 ++#define CCB_SMB_SLVSTS_SHIFT 23 ++ ++#define CCB_SMB_SLVPEC_MASK 0x00000100 ++#define CCB_SMB_SLVPEC_SHIFT 8 ++ ++ ++/* --- */ ++#define CCB_SMB_EVTEN_REG 0x38 ++ ++#define CCB_SMB_MSTRRXFIFOFULLEN_MASK 0x80000000 ++#define CCB_SMB_MSTRRXFIFOFULLEN_SHIFT 31 ++ ++#define CCB_SMB_MSTRRXFIFOTHRHITEN_MASK 0x40000000 ++#define CCB_SMB_MSTRRXFIFOTHRHITEN_SHIFT 30 ++ ++#define CCB_SMB_MSTRRXEVTEN_MASK 0x20000000 ++#define CCB_SMB_MSTRRXEVTEN_SHIFT 29 ++ ++#define CCB_SMB_MSTRSTARTBUSYEN_MASK 0x10000000 ++#define CCB_SMB_MSTRSTARTBUSYEN_SHIFT 28 ++ ++#define CCB_SMB_MSTRTXUNDEN_MASK 0x08000000 ++#define CCB_SMB_MSTRTXUNDEN_SHIFT 27 ++ ++ ++#define CCB_SMB_SLVRXFIFOFULLEN_MASK 0x04000000 ++#define CCB_SMB_SLVRXFIFOFULLEN_SHIFT 26 ++ ++#define CCB_SMB_SLVRXFIFOTHRHITEN_MASK 0x02000000 ++#define CCB_SMB_SLVRXFIFOTHRHITEN_SHIFT 25 ++ ++#define CCB_SMB_SLVRXEVTEN_MASK 0x01000000 ++#define CCB_SMB_SLVRXEVTEN_SHIFT 24 ++ ++#define CCB_SMB_SLVSTARTBUSYEN_MASK 0x00800000 ++#define CCB_SMB_SLVSTARTBUSYEN_SHIFT 23 ++ ++#define CCB_SMB_SLVTXUNDEN_MASK 0x00400000 ++#define CCB_SMB_SLVTXUNDEN_SHIFT 22 ++ ++#define CCB_SMB_SLVRDEVTEN_MASK 0x00200000 ++#define CCB_SMB_SLVRDEVTEN_SHIFT 21 ++ ++ ++/* --- */ ++#define CCB_SMB_EVTSTS_REG 0x3C ++ ++#define CCB_SMB_MSTRRXFIFOFULLSTS_MASK 0x80000000 ++#define CCB_SMB_MSTRRXFIFOFULLSTS_SHIFT 31 ++ ++#define CCB_SMB_MSTRRXFIFOTHRHITSTS_MASK 0x40000000 ++#define CCB_SMB_MSTRRXFIFOTHRHITSTS_SHIFT 30 ++ ++#define CCB_SMB_MSTRRXEVTSTS_MASK 0x20000000 ++#define CCB_SMB_MSTRRXEVTSTS_SHIFT 29 ++ ++#define CCB_SMB_MSTRSTARTBUSYSTS_MASK 0x10000000 ++#define CCB_SMB_MSTRSTARTBUSYSTS_SHIFT 28 ++ ++#define CCB_SMB_MSTRTXUNDSTS_MASK 0x08000000 ++#define CCB_SMB_MSTRTXUNDSTS_SHIFT 27 ++ ++ ++#define CCB_SMB_SLVRXFIFOFULLSTS_MASK 0x04000000 ++#define CCB_SMB_SLVRXFIFOFULLSTS_SHIFT 26 ++ ++#define CCB_SMB_SLVRXFIFOTHRHITSTS_MASK 0x02000000 ++#define CCB_SMB_SLVRXFIFOTHRHITSTS_SHIFT 25 ++ ++#define CCB_SMB_SLVRXEVTSTS_MASK 0x01000000 ++#define CCB_SMB_SLVRXEVTSTS_SHIFT 24 ++ ++#define CCB_SMB_SLVSTARTBUSYSTS_MASK 0x00800000 ++#define CCB_SMB_SLVSTARTBUSYSTS_SHIFT 23 ++ ++#define CCB_SMB_SLVTXUNDSTS_MASK 0x00400000 ++#define CCB_SMB_SLVTXUNDSTS_SHIFT 22 ++ ++#define CCB_SMB_SLVRDEVTSTS_MASK 0x00200000 ++#define CCB_SMB_SLVRDEVTSTS_SHIFT 21 ++ ++ ++/* --- */ ++#define CCB_SMB_MSTRDATAWR_REG 0x40 ++ ++#define CCB_SMB_MSTRWRSTS_MASK 0x80000000 ++#define CCB_SMB_MSTRWRSTS_SHIFT 31 ++ ++#define CCB_SMB_MSTRWRDATA_MASK 0x000000FF ++#define CCB_SMB_MSTRWRDATA_SHIFT 0 ++ ++ ++/* --- */ ++#define CCB_SMB_MSTRDATARD_REG 0x44 ++ ++#define CCB_SMB_MSTRRDSTS_MASK 0xC0000000 ++#define CCB_SMB_MSTRRDSTS_SHIFT 30 ++ ++#define CCB_SMB_MSTRRDPECERR_MASK 0x20000000 ++#define CCB_SMB_MSTRRDPECERR_SHIFT 29 ++ ++#define CCB_SMB_MSTRRDDATA_MASK 0x000000FF ++#define CCB_SMB_MSTRRDDATA_SHIFT 0 ++ ++ ++/* --- */ ++#define CCB_SMB_SLVDATAWR_REG 0x48 ++ ++#define CCB_SMB_SLVWRSTS_MASK 0x80000000 ++#define CCB_SMB_SLVWRSTS_SHIFT 31 ++ ++#define CCB_SMB_SLVWRDATA_MASK 0x000000FF ++#define CCB_SMB_SLVWRDATA_SHIFT 0 ++ ++ ++/* --- */ ++#define CCB_SMB_SLVDATARD_REG 0x4C ++ ++#define CCB_SMB_SLVRDSTS_MASK 0xC0000000 ++#define CCB_SMB_SLVRDSTS_SHIFT 30 ++ ++#define CCB_SMB_SLVRDERRSTS_MASK 0x30000000 ++#define CCB_SMB_SLVRDERRSTS_SHIFT 28 ++ ++#define CCB_SMB_SLVRDDATA_MASK 0x000000FF ++#define CCB_SMB_SLVRDDATA_SHIFT 0 ++ ++#endif /* __IPROC_SMBUS_REGS_H__ */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/i2c/busses/xgs_iproc_smbus.c b/drivers/i2c/busses/xgs_iproc_smbus.c +--- a/drivers/i2c/busses/xgs_iproc_smbus.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/i2c/busses/xgs_iproc_smbus.c 2018-05-10 11:31:30.881400987 +0800 +@@ -0,0 +1,1075 @@ ++/* ++ * Copyright (C) 2013 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "iproc_smbus_regs.h" ++ ++/* SMBUS protocol values defined in register 0x30 */ ++#define SMBUS_PROT_QUICK_CMD 0 ++#define SMBUS_PROT_SEND_BYTE 1 ++#define SMBUS_PROT_RECV_BYTE 2 ++#define SMBUS_PROT_WR_BYTE 3 ++#define SMBUS_PROT_RD_BYTE 4 ++#define SMBUS_PROT_WR_WORD 5 ++#define SMBUS_PROT_RD_WORD 6 ++#define SMBUS_PROT_BLK_WR 7 ++#define SMBUS_PROT_BLK_RD 8 ++#define SMBUS_PROT_PROC_CALL 9 ++#define SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL 10 ++ ++#define MSTR_STS_XACT_SUCCESS 0 ++#define DISABLE_INTR 0 ++#define ENABLE_INTR 1 ++#define SMB_MAX_DATA_SIZE 32 ++#define XACT_TIMEOUT msecs_to_jiffies(100) ++#define init_MUTEX(x) sema_init(x,1) ++#define IPROC_SMB_MAX_RETRIES 35 ++ ++#define GETREGFLDVAL(regval, mask, startbit) (((regval) & (mask)) >> (startbit)) ++ ++#define SETREGFLDVAL(regval, fldval, mask, startbit) regval = \ ++ (regval & ~(mask)) | \ ++ ((fldval) << (startbit)) ++ ++typedef enum iproc_smb_clk_freq { ++ I2C_SPEED_100KHz = 0, ++ I2C_SPEED_400KHz = 1, ++ I2C_SPEED_INVALID = 255 ++} smb_clk_freq_t; ++ ++/* Counters will be used mainly for testing and debugging */ ++struct iproc_smb_counters { ++ unsigned int num_read_requests; ++ unsigned int num_write_requests; ++ unsigned int num_read_errors; ++ unsigned int num_write_errors; ++ unsigned int mstr_rx_evt_cnt; /* ISR counter to check recv event */ ++ unsigned int mstr_start_busy_cnt; /* ISR counter to checking xact sts */ ++ unsigned int mstr_rx_fifo_full_cnt; /* ISR counter to detect rx fifo full */ ++ unsigned int last_int_sts; /* last value of intr status reg */ ++}; ++ ++/* This structure will be used internally by the driver to maintain its ++ * configuration information as well as information programmed into the hardware ++ */ ++struct iproc_smb_drv_int_data { ++ struct device *dev; ++ struct iproc_smb_drv_int_data *next; ++ int irq; ++ unsigned int drv_state_init; /* 1 = Initialized, 0 = not initialized */ ++ unsigned int drv_state_open; /* 1 = Accepting transaction requests, ++ 0 = Not accepting transaction requests */ ++ smb_clk_freq_t clk_speed; ++ void __iomem *base; /* virtual base address for register access */ ++ struct i2c_adapter adapter; ++ unsigned int i2c_slave_addr; ++ struct semaphore xfer_lock; /* Lock for data transfer */ ++ struct completion ses_done; /* To signal the command completion */ ++ volatile int debug; ++ unsigned int master_rx_fifo_thr; /* Master FIFO threshold */ ++ unsigned int slave_rx_fifo_thr; /* Slave FIFO threshold */ ++ unsigned int enable_evts; ++ unsigned int evt_enable_bmap; /* Bit map of events enabled by the driver */ ++ struct iproc_smb_counters smb_counters; /* Statistics maintained by driver */ ++}; ++ ++/* Structure used to pass information to read/write functions. */ ++struct iproc_xact_info { ++ bool cmd_valid; /* true if command field below is valid. Otherwise, false */ ++ unsigned short command; /* Passed by caller to send SMBus command code */ ++ unsigned char *data; /* actual data pased by the caller */ ++ unsigned int size; /* Size of data buffer passed */ ++ unsigned short flags; /* Sent by caller specifying PEC, 10-bit addresses */ ++ unsigned char smb_proto; /* SMBus protocol to use to perform transaction */ ++}; ++ ++static irqreturn_t iproc_smb_isr(int irq, void *devid) ++{ ++ struct iproc_smb_drv_int_data *dev = ++ (struct iproc_smb_drv_int_data *)devid; ++ unsigned int intsts; ++ unsigned int regval; ++ ++ intsts = readl(dev->base + CCB_SMB_EVTSTS_REG); ++ dev->smb_counters.last_int_sts = intsts; ++ ++ if (!intsts) ++ /* Likely received a spurious interrupt */ ++ return IRQ_NONE; ++ ++ /* Clear interrupts */ ++ writel(intsts, dev->base + CCB_SMB_EVTSTS_REG); ++ ++ /* Master read or write complete */ ++ if ((intsts & CCB_SMB_MSTRSTARTBUSYEN_MASK) || ++ (intsts & CCB_SMB_MSTRRXEVTSTS_MASK)) { ++ ++ if (intsts & CCB_SMB_MSTRSTARTBUSYEN_MASK) ++ dev->smb_counters.mstr_start_busy_cnt++; ++ ++ if (intsts & CCB_SMB_MSTRRXEVTSTS_MASK) ++ dev->smb_counters.mstr_rx_evt_cnt++; ++ ++ complete(&dev->ses_done); ++ } ++ ++ /* If RX FIFO was full we can either read and then flush the FIFO. ++ * Or, only flush the FIFO, and then the client process can restart ++ * the transaction. ++ * For now, we will flush the later action. ++ */ ++ if (intsts & CCB_SMB_MSTRRXFIFOFULLSTS_MASK) { ++ dev->smb_counters.mstr_rx_fifo_full_cnt++; ++ regval = readl(dev->base + CCB_SMB_MSTRFIFOCTL_REG); ++ regval |= CCB_SMB_MSTRRXFIFOFLSH_MASK; ++ writel(regval, dev->base + CCB_SMB_MSTRFIFOCTL_REG); ++ complete(&dev->ses_done); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++/* ++ * This function set clock frequency for SMBus block. As per hardware ++ * engineering, the clock frequency can be changed dynamically. ++ */ ++static int iproc_smb_set_clk_freq(void __iomem *base_addr, ++ smb_clk_freq_t freq) ++{ ++ unsigned int regval; ++ unsigned int val; ++ ++ switch (freq) { ++ case I2C_SPEED_100KHz: ++ val = 0; ++ break; ++ ++ case I2C_SPEED_400KHz: ++ val = 1; ++ break; ++ ++ default: ++ return -EINVAL; ++ break; ++ } ++ ++ regval = readl(base_addr + CCB_SMB_TIMGCFG_REG); ++ SETREGFLDVAL(regval, val, CCB_SMB_TIMGCFG_MODE400_MASK, ++ CCB_SMB_TIMGCFG_MODE400_SHIFT); ++ writel(regval, base_addr + CCB_SMB_TIMGCFG_REG); ++ ++ return 0; ++} ++ ++static int iproc_smbus_block_init(struct iproc_smb_drv_int_data *dev) ++{ ++ ++ void __iomem *base_addr = dev->base; ++ unsigned int regval; ++ u32 i2c_clk_freq; ++ struct device_node *dn = dev->dev->of_node; ++ ++ /* Flush Tx, Rx FIFOs. Note we are setting the Rx FIFO threshold to 0. ++ * May be OK since we are setting RX_EVENT and RX_FIFO_FULL interrupts ++ */ ++ regval = CCB_SMB_MSTRRXFIFOFLSH_MASK | CCB_SMB_MSTRTXFIFOFLSH_MASK; ++ ++ writel(regval, base_addr + CCB_SMB_MSTRFIFOCTL_REG); ++ ++ /* Enable SMbus block. Note, we are setting MASTER_RETRY_COUNT to zero ++ * since there will be only one master ++ */ ++ regval = CCB_SMB_CFG_SMBEN_MASK; ++ ++ writel(regval, base_addr + CCB_SMB_CFG_REG); ++ ++ /* Wait a minimum of 50 Usec, as per SMB hw doc. But we wait longer */ ++ udelay(100); ++ ++ /* Set default clock frequency */ ++ if (of_property_read_u32(dn, "clock-frequency", &i2c_clk_freq)) ++ /*no property available, use default: 100KHz*/ ++ i2c_clk_freq = I2C_SPEED_100KHz; ++ iproc_smb_set_clk_freq(base_addr, i2c_clk_freq); ++ ++ /* Disable intrs */ ++ regval = 0x0; ++ writel(regval, base_addr + CCB_SMB_EVTEN_REG); ++ ++ /* Clear intrs (W1TC) */ ++ regval = readl(base_addr + CCB_SMB_EVTSTS_REG); ++ writel(regval, base_addr + CCB_SMB_EVTSTS_REG); ++ ++ return(0); ++} ++ ++/* ++ * Function to ensure that the previous transaction was completed before ++ * initiating a new transaction. It can also be used in polling mode to ++ * check status of completion of a command ++ */ ++static int iproc_smb_startbusy_wait(struct iproc_smb_drv_int_data *dev) ++{ ++ unsigned int regval; ++ ++ regval = readl(dev->base + CCB_SMB_MSTRCMD_REG); ++ ++ /* Check if an operation is in progress. During probe it won't be. ++ * But when shutdown/remove was called we want to make sure that ++ * the transaction in progress completed ++ */ ++ if (regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK) { ++ unsigned int i = 0; ++ ++ do { ++ msleep(1); ++ i++; ++ regval = readl(dev->base + CCB_SMB_MSTRCMD_REG); ++ /* If start-busy bit cleared, exit the loop */ ++ } while ((regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK) && ++ (i < IPROC_SMB_MAX_RETRIES)); ++ ++ if (i >= IPROC_SMB_MAX_RETRIES) { ++ dev_err(dev->dev, "START_BUSY bit didn't clear\n"); ++ return -ETIMEDOUT; ++ } ++ } ++ ++ return 0; ++} ++ ++ ++static u32 smbus0_sdaRecoveryCnt=0, smbus0_sdaFailedCnt=0, smbus0_startBusyCnt=0; ++static u32 smbus1_sdaRecoveryCnt=0, smbus1_sdaFailedCnt=0, smbus1_startBusyCnt=0; ++ ++/* ++ * Function to recover SMB hangs caused stuck master START_BUSY. ++ * Returns 0 if recovery procedure executed successfully. ++ * Returns -1 if recovery failed. ++ */ ++static int iproc_smb_startbusy_recovery(struct iproc_smb_drv_int_data *dev) ++{ ++ int rc = -1; ++ unsigned int recoveryCnt; ++ ++ if (dev->adapter.nr == 0) ++ recoveryCnt = ++smbus0_startBusyCnt; ++ else ++ recoveryCnt = ++smbus1_startBusyCnt; ++ ++ dev_info(dev->dev, "START_BUSY recovery #%d \n", recoveryCnt); ++ ++ /* reset the SMBus block, wait a minimum of 50 uSecs and then re-initialize */ ++ writel(CCB_SMB_CFG_RST_MASK, dev->base + CCB_SMB_CFG_REG); ++ udelay(60); ++ ++ if (iproc_smbus_block_init(dev) == 0) ++ rc = 0; ++ ++ return rc; ++} ++ ++ ++/* ++ * Function to recover SMB hang caused by a slave device holding SDA low. ++ * Returns 0 if recovery procedure executed successfully. ++ * Returns -1 if recovery failed. ++ */ ++ ++static int iproc_smb_sda_low_recovery(struct iproc_smb_drv_int_data *dev) ++{ ++ unsigned int bbReg, cfgReg, cfgSave, recoveryCnt, failedCnt, i; ++ int rc = -1; ++ ++ /* enable bit-bang */ ++ cfgSave = readl(dev->base + CCB_SMB_CFG_REG); ++ cfgReg = cfgSave; ++ cfgReg |= CCB_SMB_CFG_BITBANGEN_MASK; ++ writel(cfgReg, dev->base + CCB_SMB_CFG_REG); ++ udelay(50); ++ ++ /* start with clock and SDA set high */ ++ bbReg = readl(dev->base + CCB_SMB_BITBANGCTL_REG); ++ bbReg |= (CCB_SMB_SMBCLKOUTEN_MASK | CCB_SMB_SMBDATAOUTEN_MASK); ++ writel(bbReg, dev->base + CCB_SMB_BITBANGCTL_REG); ++ udelay(5); /* should be sufficient for 100 KHz bus */ ++ ++ /* set up to toggle the clock line with SDA out held high for 9 cycles */ ++ for (i = 0; i < 18; i++) { ++ /* toggle CLK out */ ++ if ( (bbReg & CCB_SMB_SMBCLKOUTEN_MASK) == 0 ) ++ bbReg |= CCB_SMB_SMBCLKOUTEN_MASK; /* set clock high */ ++ else ++ bbReg &= ~CCB_SMB_SMBCLKOUTEN_MASK; /* set clock low */ ++ ++ writel(bbReg, dev->base + CCB_SMB_BITBANGCTL_REG); ++ udelay(5); ++ } ++ ++ /* check bit 29 -- SMBDAT_IN and make sure SDA not being held low any more */ ++ for (i = 0; i < 10; i++) { ++ bbReg = readl(dev->base + CCB_SMB_BITBANGCTL_REG); ++ bbReg &= CCB_SMB_SMBDATAIN_MASK; ++ if (bbReg) ++ break; ++ udelay(1); ++ } ++ ++ if (bbReg == 0) { ++ /* SDA is still low */ ++ if (dev->adapter.nr == 0) ++ failedCnt = ++smbus0_sdaFailedCnt; ++ else ++ failedCnt = ++smbus1_sdaFailedCnt; ++ ++ dev_info(dev->dev, "SDA release #%d FAILED.\n", failedCnt); ++ } else { ++ if (dev->adapter.nr == 0) ++ recoveryCnt = ++smbus0_sdaRecoveryCnt; ++ else ++ recoveryCnt = ++smbus1_sdaRecoveryCnt; ++ ++ dev_info(dev->dev, "SDA release #%d SUCCESS.\n", recoveryCnt); ++ rc = 0; ++ } ++ ++ /* manually issue a stop by transitioning SDA from low to high with clock held high */ ++ bbReg = readl(dev->base + CCB_SMB_BITBANGCTL_REG); ++ bbReg &= ~CCB_SMB_SMBCLKOUTEN_MASK; /* set clock low */ ++ writel(bbReg, dev->base + CCB_SMB_BITBANGCTL_REG); ++ udelay(2); ++ ++ bbReg &= ~CCB_SMB_SMBDATAOUTEN_MASK; /* drop SDA low */ ++ writel(bbReg, dev->base + CCB_SMB_BITBANGCTL_REG); ++ udelay(2); ++ ++ bbReg |= CCB_SMB_SMBCLKOUTEN_MASK; /* set clock high */ ++ writel(bbReg, dev->base + CCB_SMB_BITBANGCTL_REG); ++ udelay(5); ++ ++ bbReg |= CCB_SMB_SMBDATAOUTEN_MASK; /* pull SDA high */ ++ writel(bbReg, dev->base + CCB_SMB_BITBANGCTL_REG); ++ udelay(2); ++ ++ /* disable bit-bang and then re-enable the SMB with the saved configuration */ ++ cfgReg = readl(dev->base + CCB_SMB_CFG_REG); ++ cfgReg &= ~CCB_SMB_CFG_BITBANGEN_MASK; ++ writel(cfgReg, dev->base + CCB_SMB_CFG_REG); ++ udelay(10); ++ ++ writel(cfgSave, dev->base + CCB_SMB_CFG_REG); ++ ++ return rc; ++} ++ ++ ++/* ++ * Function to recover SMB hang caused by a slave device hold SDA low. ++ * Returns 0 if recovery procedure executed successfully. ++ * Returns -1 if recovery failed. ++ */ ++static int iproc_smb_timeout_recovery(struct iproc_smb_drv_int_data *dev) ++{ ++ unsigned int bbReg, mCmdReg; ++ int rc = -1; ++ ++ /* read bit-bang control. If SDA low, attempt SDA release recovery */ ++ bbReg = readl(dev->base + CCB_SMB_BITBANGCTL_REG); ++ ++ if ((bbReg & CCB_SMB_SMBDATAIN_MASK) == 0) ++ if (iproc_smb_sda_low_recovery(dev) == 0) ++ rc = 0; ++ ++ /* regardless of whether there was an SDA hang or not, see if START_BUSY stuck high */ ++ mCmdReg = readl( dev->base + CCB_SMB_MSTRCMD_REG ); ++ if (mCmdReg & CCB_SMB_MSTRSTARTBUSYCMD_MASK) ++ /* attempt to recover the bus */ ++ if (iproc_smb_startbusy_recovery(dev) == 0) ++ rc = 0; ++ ++ return rc; ++} ++ ++/* ++ * Copy data to SMBus's Tx FIFO. Valid for write transactions only ++ * ++ * base_addr: Mapped address of this SMBus instance ++ * dev_addr: SMBus device address. Assuming 7-bit addresses initially ++ * info: Data to copy in to Tx FIFO. For read commands, the size should be ++ * set to zero by the caller ++ * ++ */ ++static void iproc_smb_write_trans_data(void __iomem *base_addr, ++ unsigned short dev_addr, ++ struct iproc_xact_info *info) ++{ ++ unsigned int regval; ++ unsigned int i; ++ unsigned int num_data_bytes = 0; ++ ++ /* Write SMBus device address first */ ++ /* We are assuming 7-bit addresses for now. For 10-bit addresses, ++ * we may have one more write to send the upper 3 bits of 10-bit addr ++ */ ++ writel(dev_addr, base_addr + CCB_SMB_MSTRDATAWR_REG); ++ ++ /* If the protocol needs command code, copy it */ ++ if (info->cmd_valid == true) ++ writel(info->command, base_addr + CCB_SMB_MSTRDATAWR_REG); ++ ++ /* ++ * Depending on the SMBus protocol, we need to write additional ++ * transaction data into Tx FIFO. ++ * Refer to section 5.5 of SMBus spec for sequence for a transaction ++ */ ++ switch (info->smb_proto) { ++ case SMBUS_PROT_RECV_BYTE: ++ /* No additional data to be written */ ++ num_data_bytes = 0; ++ break; ++ ++ case SMBUS_PROT_SEND_BYTE: ++ num_data_bytes = info->size; ++ break; ++ ++ case SMBUS_PROT_RD_BYTE: ++ case SMBUS_PROT_RD_WORD: ++ case SMBUS_PROT_BLK_RD: ++ /* Write slave address with R/W~ set (bit #0) */ ++ writel(dev_addr | 0x1, base_addr + CCB_SMB_MSTRDATAWR_REG); ++ num_data_bytes = 0; ++ break; ++ ++ case SMBUS_PROT_WR_BYTE: ++ case SMBUS_PROT_WR_WORD: ++ /* No additional bytes to be written */ ++ /* Data portion is written in the 'for' loop below */ ++ num_data_bytes = info->size; ++ break; ++ ++ case SMBUS_PROT_BLK_WR: ++ /* 3rd byte is byte count */ ++ writel(info->size, base_addr + CCB_SMB_MSTRDATAWR_REG); ++ num_data_bytes = info->size; ++ break; ++ ++ case SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL: ++ /* Write byte count */ ++ writel(info->size, base_addr + CCB_SMB_MSTRDATAWR_REG); ++ num_data_bytes = info->size; ++ break; ++ ++ default: ++ break; ++ } ++ ++ /* Copy actual data from caller */ ++ for (i = 0; num_data_bytes; --num_data_bytes, i++) { ++ /* For the last byte, set MASTER_WR_STATUS bit. For block rd/wr process ++ * call, we need to program slave addr after copying data byte(s), so ++ * master status bit is set later, after the loop ++ */ ++ if ((num_data_bytes == 1) && ++ (info->smb_proto != SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL)) ++ regval = info->data[i] | CCB_SMB_MSTRWRSTS_MASK; ++ else ++ regval = info->data[i]; ++ ++ writel(regval, base_addr + CCB_SMB_MSTRDATAWR_REG); ++ } ++ ++ if (info->smb_proto == SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL) ++ /* Write device address needed during repeat start condition */ ++ writel(CCB_SMB_MSTRWRSTS_MASK | dev_addr | 0x1, ++ base_addr + CCB_SMB_MSTRDATAWR_REG); ++ ++ return; ++} ++ ++static int iproc_smb_data_send(struct i2c_adapter *adapter, ++ unsigned short addr, ++ struct iproc_xact_info *info) ++{ ++ int rc; ++ unsigned int regval; ++ struct iproc_smb_drv_int_data *dev = i2c_get_adapdata(adapter); ++ unsigned long time_left; ++ ++ /* Make sure the previous transaction completed */ ++ rc = iproc_smb_startbusy_wait(dev); ++ if (rc < 0) { ++ dev_err(dev->dev, "Send: bus is busy, attempt recovery \n"); ++ /* attempt to recover the bus */ ++ if (iproc_smb_startbusy_recovery(dev) != 0) ++ return rc; ++ } ++ ++ if (dev->enable_evts == ENABLE_INTR) { ++ /* Enable start_busy interrupt */ ++ regval = readl(dev->base + CCB_SMB_EVTEN_REG); ++ regval |= CCB_SMB_MSTRSTARTBUSYEN_MASK; ++ writel(regval, dev->base + CCB_SMB_EVTEN_REG); ++ /* Mark as incomplete before sending the data */ ++ reinit_completion(&dev->ses_done); ++ } ++ ++ /* Write transaction bytes to Tx FIFO */ ++ iproc_smb_write_trans_data(dev->base, addr, info); ++ ++ /* Program master command register (0x30) with protocol type and ++ * set start_busy_command bit to initiate the write transaction ++ */ ++ regval = (info->smb_proto << CCB_SMB_MSTRSMBUSPROTO_SHIFT) | ++ CCB_SMB_MSTRSTARTBUSYCMD_MASK; ++ writel(regval, dev->base + CCB_SMB_MSTRCMD_REG); ++ ++ if (dev->enable_evts == ENABLE_INTR) { ++ /* ++ * Block waiting for the transaction to finish. When finished, ++ * we'll be signaled by an interrupt ++ */ ++ time_left = wait_for_completion_timeout(&dev->ses_done, ++ XACT_TIMEOUT); ++ /* Disable start_busy interrupt */ ++ regval = readl(dev->base + CCB_SMB_EVTEN_REG); ++ regval &= ~CCB_SMB_MSTRSTARTBUSYEN_MASK; ++ writel(regval, dev->base + CCB_SMB_EVTEN_REG); ++ ++ if (time_left == 0) { ++ dev_info(dev->dev, "Send: timeout accessing device"); ++ /* attempt to recover the bus */ ++ rc = iproc_smb_timeout_recovery(dev); ++ if (rc != 0) ++ return -ETIMEDOUT; ++ else ++ return -ECOMM; ++ } ++ } ++ ++ regval = readl(dev->base + CCB_SMB_MSTRCMD_REG); ++ ++ /* If start_busy bit cleared, check if there are any errors */ ++ if (!(regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK)) { ++ /* start_busy bit cleared, check master_status field now */ ++ regval &= CCB_SMB_MSTRSTS_MASK; ++ regval >>= CCB_SMB_MSTRSTS_SHIFT; ++ ++ if (regval != MSTR_STS_XACT_SUCCESS) { ++ /* We can flush Tx FIFO here */ ++ dev_err(dev->dev, "Send: Error in transaction\n"); ++ return -EREMOTEIO; ++ } ++ } ++ ++ return 0; ++} ++ ++static int iproc_smb_data_recv(struct i2c_adapter *adapter, ++ unsigned short addr, ++ struct iproc_xact_info *info, ++ unsigned int *num_bytes_read) ++{ ++ int rc; ++ unsigned int regval; ++ struct iproc_smb_drv_int_data *dev = i2c_get_adapdata(adapter); ++ unsigned long time_left; ++ ++ /* Make sure the previous transaction completed */ ++ rc = iproc_smb_startbusy_wait(dev); ++ ++ if (rc < 0) { ++ dev_err(dev->dev, "Receive: bus is busy, attempt recovery \n"); ++ /* attempt to recover the bus */ ++ if (iproc_smb_startbusy_recovery(dev) != 0) ++ return rc; ++ } ++ ++ if (dev->enable_evts == ENABLE_INTR) { ++ /* Enable start_busy interrupt */ ++ regval = readl(dev->base + CCB_SMB_EVTEN_REG); ++ ++ /* Set Rx_event_en bit for notification of reception event */ ++ regval |= (CCB_SMB_MSTRSTARTBUSYEN_MASK); ++ ++ writel(regval, dev->base + CCB_SMB_EVTEN_REG); ++ ++ /* Mark as incomplete before sending the data */ ++ reinit_completion(&dev->ses_done); ++ } ++ ++ /* Program all transaction bytes into master Tx FIFO */ ++ iproc_smb_write_trans_data(dev->base, addr, info); ++ ++ /* Program master command register (0x30) with protocol type and set ++ * start_busy_command bit to initiate the write transaction ++ */ ++ regval = (info->smb_proto << CCB_SMB_MSTRSMBUSPROTO_SHIFT) | ++ CCB_SMB_MSTRSTARTBUSYCMD_MASK | info->size; ++ writel(regval, dev->base + CCB_SMB_MSTRCMD_REG); ++ ++ if (dev->enable_evts == ENABLE_INTR) { ++ /* ++ * Block waiting for the transaction to finish. When finished, ++ * we'll be signaled by an interrupt ++ */ ++ time_left = wait_for_completion_timeout(&dev->ses_done, ++ XACT_TIMEOUT); ++ ++ /* Disable start_busy and rx_event interrupts */ ++ regval = readl(dev->base + CCB_SMB_EVTEN_REG); ++ regval &= ~(CCB_SMB_MSTRSTARTBUSYEN_MASK); ++ writel(regval, dev->base + CCB_SMB_EVTEN_REG); ++ ++ if (time_left == 0) { ++ dev_err(dev->dev, "Receive: timeout accessing device\n"); ++ /* attempt to recover the bus */ ++ rc = iproc_smb_timeout_recovery(dev); ++ if (rc != 0) ++ return -ETIMEDOUT; ++ else ++ return -ECOMM; ++ } ++ } ++ ++ regval = readl(dev->base + CCB_SMB_MSTRCMD_REG); ++ ++ /* If start_busy bit cleared, check if there are any errors */ ++ if (!(regval & CCB_SMB_MSTRSTARTBUSYCMD_MASK)) { ++ /* start_busy bit cleared, check master_status field now */ ++ regval &= CCB_SMB_MSTRSTS_MASK; ++ regval >>= CCB_SMB_MSTRSTS_SHIFT; ++ ++ if (regval != MSTR_STS_XACT_SUCCESS) { ++ /* We can flush Tx FIFO here */ ++ dev_info(dev->dev, "Error in transaction\n"); ++ return -EREMOTEIO; ++ } ++ } ++ ++ /* In the isr we will read the received byte, and also deal with ++ * rx fifo full event. The above check is for timeout error. If needed ++ * we may move it to rx isr ++ */ ++ ++ /* For block read, protocol (hw) returns byte count, as the first byte */ ++ if ((info->smb_proto == SMBUS_PROT_BLK_RD) || ++ (info->smb_proto == SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL)) { ++ int i, adj; ++ ++ /* Read received byte(s) */ ++ regval = readl(dev->base + CCB_SMB_MSTRDATARD_REG); ++ *num_bytes_read = regval & CCB_SMB_MSTRRDDATA_MASK; ++ ++ adj = 0; ++ ++ /* SMBUS spec ver. 3 (2015) extends max block transfer byte count from 32 to 256 */ ++ /* Use SMB_MAX_DATA_SIZE (according to HW FIFO) instead of I2C_SMBUS_BLOCK_MAX (defined in Linux)*/ ++ /* ++ * Current SMBUS HW FIFO length is 64B. For block write xfer, ++ * the first three FIFO entries are for slave adress, register ofFset, ++ * and length count. ++ */ ++ for (i = 0; (i < *num_bytes_read) && (i < (SMB_MAX_DATA_SIZE - adj)); i++) { ++ /* Read Rx FIFO for data bytes */ ++ regval = readl(dev->base + CCB_SMB_MSTRDATARD_REG); ++ info->data[i + adj] = regval & CCB_SMB_MSTRRDDATA_MASK; ++ } ++ ++ *num_bytes_read = i + adj; ++ } ++ else { ++ regval = readl(dev->base + CCB_SMB_MSTRDATARD_REG); ++ *info->data = regval & CCB_SMB_MSTRRDDATA_MASK; ++ *num_bytes_read = 1; ++ if (info->smb_proto == SMBUS_PROT_RD_WORD) { ++ /* Read Rx FIFO for data bytes */ ++ regval = readl(dev->base + CCB_SMB_MSTRDATARD_REG); ++ info->data[1] = regval & CCB_SMB_MSTRRDDATA_MASK; ++ *num_bytes_read = 2; ++ } ++ } ++ ++ return 0; ++} ++ ++static int iproc_smb_xfer(struct i2c_adapter *i2c_adap, u16 addr, ++ unsigned short flags, char read_write, ++ u8 command, int size, union i2c_smbus_data *data) ++{ ++ int rc = 0; ++ struct iproc_smb_drv_int_data *dev = i2c_get_adapdata(i2c_adap); ++ struct iproc_xact_info info; ++ unsigned int num_bytes_read = 0; ++ int smb_xfer_size; ++ ++ down(&dev->xfer_lock); ++ ++ addr <<= 1; ++ ++ switch (size /* protocol */) { ++ case I2C_SMBUS_BYTE: ++ info.cmd_valid = false; ++ info.command = command; /* not used */ ++ if (read_write == I2C_SMBUS_WRITE) ++ info.data = &command; ++ else ++ info.data = &data->byte; ++ info.size = 1; ++ info.flags = flags; ++ if (read_write == I2C_SMBUS_READ) { ++ addr |= 0x1; /* Read operation */ ++ info.smb_proto = SMBUS_PROT_RECV_BYTE; ++ info.data = &data->byte; ++ } ++ else { ++ info.smb_proto = SMBUS_PROT_SEND_BYTE; ++ } ++ break; ++ ++ case I2C_SMBUS_BYTE_DATA: ++ info.cmd_valid = true; ++ info.command = command; ++ info.data = &data->byte; ++ info.size = 1; ++ info.flags = flags; ++ if (read_write == I2C_SMBUS_READ) ++ info.smb_proto = SMBUS_PROT_RD_BYTE; ++ else ++ info.smb_proto = SMBUS_PROT_WR_BYTE; ++ break; ++ ++ case I2C_SMBUS_WORD_DATA: ++ info.cmd_valid = true; ++ info.command = command; ++ info.data = (unsigned char *)(&data->word); ++ info.size = 2; ++ info.flags = flags; ++ if (read_write == I2C_SMBUS_READ) ++ info.smb_proto = SMBUS_PROT_RD_WORD; ++ else ++ info.smb_proto = SMBUS_PROT_WR_WORD; ++ break; ++ ++ case I2C_SMBUS_BLOCK_DATA: ++ case I2C_SMBUS_I2C_BLOCK_DATA: ++ info.cmd_valid = true; ++ info.command = command; ++ info.data = &data->block[1]; ++ info.flags = flags; ++ ++ if (read_write == I2C_SMBUS_READ) { ++ info.smb_proto = SMBUS_PROT_BLK_RD; ++ /* Refer to RD_BYTE_COUNT in reg 0x30 about 'block read' ++ * If '0', protocol(hw) returns data byte count as part of ++ * response. ++ */ ++ info.size = 0; ++ } ++ else { ++ info.smb_proto = SMBUS_PROT_BLK_WR; ++ /* i2c-core passes the length in this field */ ++ info.size = data->block[0]; ++ } ++ break; ++ ++ case I2C_SMBUS_BLOCK_PROC_CALL: ++ info.cmd_valid = true; ++ info.command = command; ++ info.data = &data->block[1]; ++ info.flags = flags; ++ info.size = data->block[0]; ++ info.smb_proto = SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL; ++ break; ++ ++ default: ++ dev_err(dev->dev, "Unsupported transaction\n"); ++ up(&dev->xfer_lock); ++ return -EINVAL; ++ } ++ ++ /* Handle large packet by spliting into SMB_MAX_DATA_SIZE packet */ ++ smb_xfer_size = (int)info.size; ++ if ((info.smb_proto == SMBUS_PROT_BLK_RD) || ++ (info.smb_proto == SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL)) ++ data->block[0] = 0; ++ ++ while (smb_xfer_size) { ++ if (info.size >= SMB_MAX_DATA_SIZE) ++ info.size = SMB_MAX_DATA_SIZE; ++ ++ if (read_write == I2C_SMBUS_READ) { ++ /* Refer to i2c_smbus_read_byte for params passed. */ ++ rc = iproc_smb_data_recv(i2c_adap, addr, &info, ++ &num_bytes_read); ++ /* if failed due to bus hang, but recovered, retry once */ ++ if (rc == -ECOMM) ++ rc = iproc_smb_data_recv(i2c_adap, addr, &info, ++ &num_bytes_read); ++ /* pass the actual amount of data sent by slave */ ++ if ((info.smb_proto == SMBUS_PROT_BLK_RD) || ++ (info.smb_proto == SMBUS_PROT_BLK_WR_BLK_RD_PROC_CALL)) ++ if (rc == 0) ++ data->block[0] += num_bytes_read; ++ } else { ++ /* Refer to i2c_smbus_write_byte params passed. */ ++ rc = iproc_smb_data_send(i2c_adap, addr, &info); ++ /* if failed due to bus hang, but recovered, retry */ ++ if (rc == -ECOMM) ++ rc = iproc_smb_data_send(i2c_adap, addr, &info); ++ } ++ ++ if (rc < 0) { ++ dev_info(dev->dev, "%s error accessing\n", ++ (read_write == I2C_SMBUS_READ) ? "Read" : "Write"); ++ up(&dev->xfer_lock); ++ return -EREMOTEIO; ++ } ++ if (info.size == SMB_MAX_DATA_SIZE) { ++ smb_xfer_size -= SMB_MAX_DATA_SIZE; ++ info.size = smb_xfer_size; ++ info.data += SMB_MAX_DATA_SIZE; ++ /* Adjust I2c device register offset */ ++ info.command += SMB_MAX_DATA_SIZE; ++ } else { ++ break; ++ } ++ } ++ ++ msleep(1); ++ up(&dev->xfer_lock); ++ ++ return (rc); ++} ++ ++static int iproc_intr_enable(struct iproc_smb_drv_int_data *dev, u32 bmap) ++{ ++ void __iomem *base_addr = dev->base; ++ unsigned int regval; ++ ++ regval = readl(base_addr + CCB_SMB_EVTEN_REG); ++ regval |= bmap; ++ writel(regval, base_addr + CCB_SMB_EVTEN_REG); ++ ++ /* ++ * Store all interrupts enabled so far. Note bmap can have only ++ * 'incremental' set of events ++ */ ++ dev->evt_enable_bmap = regval; ++ ++ return 0; ++} ++ ++static int iproc_intr_disable(struct iproc_smb_drv_int_data *dev, u32 bmap) ++{ ++ void __iomem *base_addr = dev->base; ++ unsigned int regval; ++ ++ regval = readl(base_addr + CCB_SMB_EVTEN_REG); ++ regval &= ~bmap; ++ writel(regval, base_addr + CCB_SMB_EVTEN_REG); ++ ++ dev->evt_enable_bmap = regval; ++ ++ return 0; ++} ++ ++/* Verify this sequence with hw engg */ ++static int iproc_smbus_block_deinit(struct iproc_smb_drv_int_data *dev) ++{ ++ unsigned int regval; ++ int rc; ++ ++ /* Disable all interrupts */ ++ regval = 0x0; ++ ++ writel(regval, dev->base + CCB_SMB_EVTEN_REG); ++ ++ /* Check if a transaction is in progress */ ++ rc = iproc_smb_startbusy_wait(dev); ++ if (rc < 0) { ++ dev_err(dev->dev, "A transaction is still in progress"); ++ /* Wait for some time */ ++ udelay(100); ++ } ++ ++ /* Disable SMBus block */ ++ regval = readl(dev->base + CCB_SMB_CFG_REG); ++ regval &= ~CCB_SMB_CFG_SMBEN_MASK; ++ writel(regval, dev->base + CCB_SMB_CFG_REG); ++ ++ /* Wait for some time */ ++ udelay(100); ++ ++ /* Put the block under reset. Note the RESET bit in reg 0x0 is ++ * self clearing ++ */ ++ regval = CCB_SMB_CFG_RST_MASK; ++ writel(regval, dev->base + CCB_SMB_CFG_REG); ++ ++ return 0; ++} ++ ++static u32 iproc_smb_funcs(struct i2c_adapter *adapter) ++{ ++ /* I2C_FUNC_SMBUS_I2C_BLOCK */ ++ return (I2C_FUNC_SMBUS_BYTE | I2C_FUNC_SMBUS_BYTE_DATA | ++ I2C_FUNC_SMBUS_WORD_DATA | I2C_FUNC_SMBUS_BLOCK_DATA); ++} ++ ++static struct i2c_algorithm iproc_smb_algorithm = { ++ /*.name = "iproc-smb", */ ++ .smbus_xfer = iproc_smb_xfer, ++ .master_xfer = NULL, ++ .functionality = iproc_smb_funcs, ++}; ++ ++static int iproc_smb_probe(struct platform_device *pdev) ++{ ++ int rc=0, irq; ++ struct iproc_smb_drv_int_data *dev; ++ struct i2c_adapter *adap; ++ struct resource *res; ++ ++ dev = devm_kzalloc(&pdev->dev, sizeof(*dev), GFP_KERNEL); ++ if (!dev) ++ return -ENOMEM; ++ ++ dev->dev = &pdev->dev; ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ dev->base = devm_ioremap_resource(dev->dev, res); ++ if (IS_ERR(dev->base)) ++ return PTR_ERR(dev->base); ++ ++ /* Get the interrupt number */ ++ irq = platform_get_irq(pdev, 0); ++ if (irq <= 0) { ++ dev_err(dev->dev, "no irq resource\n"); ++ return irq; ++ } ++ ++ init_MUTEX(&dev->xfer_lock); ++ init_completion(&dev->ses_done); ++ dev->irq = irq; ++ ++ /* Default value, can be changed after initial testing */ ++ dev->enable_evts = ENABLE_INTR; ++ ++ platform_set_drvdata(pdev, dev); ++ ++ /* ++ * Init internal regs, disable intrs (and then clear intrs), set fifo ++ * thresholds, etc. ++ */ ++ iproc_smbus_block_init(dev); ++ ++ /* Register ISR handler */ ++ rc = devm_request_irq(dev->dev, dev->irq, iproc_smb_isr, 0, ++ pdev->name, dev); ++ if (rc) { ++ dev_err(dev->dev, "unable to request irq %i\n", irq); ++ goto err_smb_deinit; ++ } ++ ++ adap = &dev->adapter; ++ i2c_set_adapdata(adap, dev); ++ adap->owner = THIS_MODULE; ++ adap->class = UINT_MAX; ++ adap->algo = &iproc_smb_algorithm; ++ adap->dev.parent = &pdev->dev; ++ adap->nr = pdev->id; ++ adap->dev.of_node = pdev->dev.of_node; ++ strlcpy(adap->name, "iproc-smbus", sizeof(adap->name)); ++ ++ rc = i2c_add_numbered_adapter(adap); ++ if (rc) ++ goto err_free_irq; ++ ++ /* Turn on default set of interrupts */ ++ /* ++ * For Rx, enable RX fifo full, threshold hit interrupts. Other rx ++ * interrupts will be set in the read/recv transactions, as required ++ * For Tx, enable fifo under run intr. Other intrs will be set in send ++ * write access functions ++ */ ++ iproc_intr_enable(dev, CCB_SMB_MSTRRXFIFOFULLEN_MASK); ++ ++ return 0; ++ ++err_free_irq: ++ free_irq(dev->irq, dev); ++ ++err_smb_deinit: ++ iproc_smbus_block_deinit(dev); ++ platform_set_drvdata(pdev, NULL); ++ ++ dev_err(dev->dev, "probe failed, error=%d", rc); ++ return (rc); ++} ++ ++static int iproc_smb_remove(struct platform_device *pdev) ++{ ++ struct iproc_smb_drv_int_data *dev = platform_get_drvdata(pdev); ++ unsigned int regval; ++ ++ /* Disable interrupts. */ ++ /* Verify: Should we wait for any in-progress xact to complete? */ ++ synchronize_irq(dev->irq); ++ iproc_intr_disable(dev, ~0); ++ free_irq(dev->irq, dev); ++ ++ /* Disable SMbus block */ ++ regval = readl(dev->base + CCB_SMB_CFG_REG); ++ regval &= ~CCB_SMB_CFG_SMBEN_MASK; ++ writel(regval, dev->base + CCB_SMB_CFG_REG); ++ ++ i2c_del_adapter(&dev->adapter); ++ ++ platform_set_drvdata(pdev, NULL); ++ ++ iproc_smbus_block_deinit(dev); ++ ++ devm_iounmap(&pdev->dev, dev->base); ++ ++ return 0; ++} ++ ++static const struct of_device_id bcm_iproc_smb_of_match[] = { ++ { .compatible = "brcm,iproc-i2c" }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, bcm_iproc_smb_of_match); ++ ++static struct platform_driver bcm_iproc_smbus_driver = { ++ .driver = { ++ .name = "bcm-iproc-smbus", ++ .of_match_table = bcm_iproc_smb_of_match, ++ }, ++ .probe = iproc_smb_probe, ++ .remove = iproc_smb_remove, ++}; ++module_platform_driver(bcm_iproc_smbus_driver); ++ ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_DESCRIPTION("IPROC SMBus Bus Driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig +--- a/drivers/mmc/host/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/mmc/host/Kconfig 2018-05-10 11:31:31.593401757 +0800 +@@ -892,6 +892,16 @@ config MMC_SDHCI_BRCMSTB + + If unsure, say Y. + ++config MMC_SDHCI_XGS_IPROC ++ tristate "Broadcom XGS iProc SD/MMC Card Interface support" ++ depends on ARCH_XGS_IPROC ++ depends on MMC_SDHCI_PLTFM ++ select MMC_SDHCI_IO_ACCESSORS ++ default n ++ help ++ This selects the platform Secure Digital Host Controller Interface. ++ If unsure, say N. ++ + config MMC_SDHCI_XENON + tristate "Marvell Xenon eMMC/SD/SDIO SDHCI driver" + depends on MMC_SDHCI_PLTFM +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile +--- a/drivers/mmc/host/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/mmc/host/Makefile 2018-05-10 11:31:31.593401757 +0800 +@@ -90,6 +90,7 @@ obj-$(CONFIG_MMC_SDHCI_MSM) += sdhci-ms + obj-$(CONFIG_MMC_SDHCI_ST) += sdhci-st.o + obj-$(CONFIG_MMC_SDHCI_MICROCHIP_PIC32) += sdhci-pic32.o + obj-$(CONFIG_MMC_SDHCI_BRCMSTB) += sdhci-brcmstb.o ++obj-$(CONFIG_MMC_SDHCI_XGS_IPROC) += sdhci-bcm-hr3.o + + ifeq ($(CONFIG_CB710_DEBUG),y) + CFLAGS-cb710-mmc += -DDEBUG +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/mmc/host/sdhci-bcm-hr3.c b/drivers/mmc/host/sdhci-bcm-hr3.c +--- a/drivers/mmc/host/sdhci-bcm-hr3.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/mmc/host/sdhci-bcm-hr3.c 2018-05-10 11:31:31.609401775 +0800 +@@ -0,0 +1,458 @@ ++/* ++ * drivers/mmc/host/sdhci-bcm-hr3 - Broadcom HR3 SDHCI Platform driver ++ * ++ * Copyright (C) 2014-2016, Broadcom Corporation. 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 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. ++ * ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "sdhci-pltfm.h" ++ ++struct xgs_iproc_sdhci_host { ++ struct device_node *dn; ++ void __iomem *wrap_base; ++ void __iomem *idm_base; ++ u32 shadow_cmd; ++ u32 shadow_blk; ++}; ++ ++static int iproc_top_sdio_config(void); ++ ++static void iproc_sdhci_writel(struct sdhci_host *host, u32 val, int reg) ++{ ++ /* WAR for SDIO/GPIO setting might be reset by SDK for HR3. */ ++ struct xgs_iproc_sdhci_host *iproc_host = ++ sdhci_pltfm_priv(sdhci_priv(host)); ++ if (of_device_is_compatible(iproc_host->dn, "brcm,iproc-hr3-sdio")) { ++ if (reg == SDHCI_INT_STATUS) { ++ iproc_top_sdio_config(); ++ } ++ } ++ ++ writel(val, host->ioaddr + reg); ++} ++ ++static inline u32 iproc_sdhci_readl(struct sdhci_host *host, int reg) ++{ ++ return readl(host->ioaddr + reg); ++} ++ ++static void iproc_sdhci_writew(struct sdhci_host *host, u16 val, int reg) ++{ ++ struct xgs_iproc_sdhci_host *iproc_host = ++ sdhci_pltfm_priv(sdhci_priv(host)); ++ u32 oldval, newval; ++ u32 word_num = (reg >> 1) & 1; ++ u32 word_shift = word_num * 16; ++ u32 mask = 0xffff << word_shift; ++ ++ if (reg == SDHCI_COMMAND) { ++ if (iproc_host->shadow_blk != 0) { ++ iproc_sdhci_writel(host, iproc_host->shadow_blk, SDHCI_BLOCK_SIZE); ++ iproc_host->shadow_blk = 0; ++ } ++ oldval = iproc_host->shadow_cmd; ++ } else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) { ++ oldval = iproc_host->shadow_blk; ++ } else { ++ oldval = iproc_sdhci_readl(host, reg & ~3); ++ } ++ newval = (oldval & ~mask) | (val << word_shift); ++ ++ if (reg == SDHCI_TRANSFER_MODE) ++ /* Save the transfer mode until the command is issued */ ++ iproc_host->shadow_cmd = newval; ++ else if (reg == SDHCI_BLOCK_SIZE || reg == SDHCI_BLOCK_COUNT) ++ /* Save the block info until the command is issued */ ++ iproc_host->shadow_blk = newval; ++ else ++ /* Command or other regular 32-bit write */ ++ iproc_sdhci_writel(host, newval, reg & ~3); ++} ++ ++static u16 iproc_sdhci_readw(struct sdhci_host *host, int reg) ++{ ++ u32 val, word; ++ u32 word_num = (reg >> 1) & 1; ++ u32 word_shift = word_num * 16; ++ ++ val = iproc_sdhci_readl(host, (reg & ~3)); ++ word = (val >> word_shift) & 0xffff; ++ ++ return word; ++} ++ ++static void iproc_sdhci_writeb(struct sdhci_host *host, u8 val, int reg) ++{ ++ u32 oldval, newval; ++ u32 byte_num = reg & 3; ++ u32 byte_shift = byte_num * 8; ++ u32 mask = 0xff << byte_shift; ++ ++ oldval = iproc_sdhci_readl(host, reg & ~3); ++ newval = (oldval & ~mask) | (val << byte_shift); ++ ++ iproc_sdhci_writel(host, newval, reg & ~3); ++} ++ ++static u8 iproc_sdhci_readb(struct sdhci_host *host, int reg) ++{ ++ u32 val, byte; ++ u32 byte_num = reg & 3; ++ u32 byte_shift = byte_num * 8; ++ ++ val = iproc_sdhci_readl(host, (reg & ~3)); ++ byte = (val >> byte_shift) & 0xff; ++ ++ return byte; ++} ++ ++static u32 iproc_sdhci_get_max_clock(struct sdhci_host *host) ++{ ++ unsigned long max_clock; ++ ++ max_clock = (host->caps & SDHCI_CLOCK_V3_BASE_MASK) ++ >> SDHCI_CLOCK_BASE_SHIFT; ++ max_clock *= 1000000; ++ ++ return max_clock; ++} ++ ++static u32 iproc_sdhci_get_min_clock(struct sdhci_host *host) ++{ ++ return (host->max_clk / SDHCI_MAX_DIV_SPEC_300); ++} ++ ++static int iproc_sdhci_execute_tuning(struct sdhci_host *host, u32 opcode) ++{ ++ /* ++ * Tuning is unnecessary for SDR50 and DDR50; moreover, the IPROC platform ++ * doesn't support SDR104, HS200 and HS400 cards. So, we needn't do anything ++ * for tuning. ++ */ ++ return 0; ++} ++ ++static void iproc_sdhci_set_clock(struct sdhci_host *host, unsigned int clock) ++{ ++ /* ++ * WAR that IPROC SD/MMC host need to set the driver strength ++ * to TYPE_A in 3.3v DS/HS mode even if the driver strength is ++ * meaningless for 3.3V signaling. ++ */ ++ if ((host->timing == MMC_TIMING_LEGACY) || ++ (host->timing == MMC_TIMING_MMC_HS) || ++ (host->timing == MMC_TIMING_SD_HS)) ++ host->mmc->ios.drv_type = MMC_SET_DRIVER_TYPE_A; ++ ++ sdhci_set_clock(host, clock); ++} ++ ++static struct sdhci_ops sdhci_iproc_ops = { ++#ifdef CONFIG_MMC_SDHCI_IO_ACCESSORS ++ .write_l = iproc_sdhci_writel, ++ .write_w = iproc_sdhci_writew, ++ .write_b = iproc_sdhci_writeb, ++ .read_l = iproc_sdhci_readl, ++ .read_w = iproc_sdhci_readw, ++ .read_b = iproc_sdhci_readb, ++#else ++#error The iproc SDHCI driver needs CONFIG_MMC_SDHCI_IO_ACCESSORS to be set ++#endif ++ .reset = sdhci_reset, ++ .set_bus_width = sdhci_set_bus_width, ++ .set_uhs_signaling = sdhci_set_uhs_signaling, ++ .set_clock = iproc_sdhci_set_clock, ++ .get_max_clock = iproc_sdhci_get_max_clock, ++ .get_min_clock = iproc_sdhci_get_min_clock, ++ .platform_execute_tuning = iproc_sdhci_execute_tuning, ++}; ++ ++/* TOP registers */ ++#define TOP_SDIO_MISC_CONTROL 0x0207e500 ++#define TOP_SDIO_MISC_CONTROL__TOP_SDIO_8B_INF 4 ++#define TOP_SDIO_MISC_CONTROL__TOP_SDIO_GPIO_INF_SEL_R 0 ++ ++/* SDIO IDM registers */ ++#define SDIO_IDM0_IO_CONTROL_DIRECT(base) (base + 0x0) ++#define SDIO_IDM0_IO_CONTROL_DIRECT__CMD_COMFLICT_DISABLE 22 ++#define SDIO_IDM0_IO_CONTROL_DIRECT__FEEDBACK_CLK_EN 21 ++#define SDIO_IDM0_IO_CONTROL_DIRECT__clk_enable 0 ++#define SDIO_IDM0_IDM_RESET_CONTROL(base) (base + 0x3F8) ++ ++/* IPROC WRAP registers */ ++#define IPROC_WRAP_SDIO_CONTROL(base) (base + 0xb0) ++#define IPROC_WRAP_SDIO_CONTROL1(base) (base + 0xb4) ++#define IPROC_WRAP_SDIO_CONTROL2(base) (base + 0xb8) ++#define IPROC_WRAP_SDIO_CONTROL3(base) (base + 0xbc) ++#define IPROC_WRAP_SDIO_CONTROL4(base) (base + 0xc0) ++#define IPROC_WRAP_SDIO_CONTROL5(base) (base + 0xc4) ++#define IPROC_WRAP_SDIO_1P8_FAIL_CONTROL(base) (base + 0xc8) ++#define IPROC_WRAP_SDIO_1P8_FAIL_CONTROL__SDIO_VDDO_18V_FAIL_SOVW 1 ++#define IPROC_WRAP_SDIO_1P8_FAIL_CONTROL__SDIO_UHS1_18V_VREG_FAIL 0 ++ ++/* ++ * SDIO_CAPS_L ++ * ++ * Field Bit(s) ++ * =========================== ++ * DDR50 31 ++ * SDR104 30 ++ * SDR50 29 ++ * SLOTTYPE 28:27 ++ * ASYNCHIRQ 26 ++ * SYSBUS64 25 ++ * V18 24 ++ * V3 23 ++ * V33 22 ++ * SUPRSM 21 ++ * SDMA 20 ++ * HSPEED 19 ++ * ADMA2 18 ++ * EXTBUSMED 17 ++ * MAXBLK 16:15 ++ * BCLK 14:7 ++ * TOUT 6 ++ * TOUTFREQ 5:0 ++ */ ++#define SDIO_CAPS_L 0xA17f6470 ++ ++/* ++ * SDIO_CAPS_H ++ * ++ * Field Bit(s) ++ * =========================== ++ * reserved 31:20 ++ * SPIBLOCKMODE 19 ++ * SPIMODE_CAP 18 ++ * CLOCKMULT 17:10 ++ * RETUNE_MODE 9:8 ++ * USETUNE_SDR50 7 ++ * TMRCNT_RETUNE 6:3 ++ * DRVR_TYPED 2 ++ * DRVR_TYPEC 1 ++ * DRVR_TYPEA 0 ++ */ ++#define SDIO_CAPS_H 0x000C000f ++ ++/* ++ * Preset value ++ * ++ * Field Bit(s) ++ * =========================== ++ * Driver Strength 12:11 ++ * Clock Generator 10 ++ * SDCLK Frequeency 9:0 ++ */ ++ ++/* ++ * SDIO_PRESETVAL1 ++ * ++ * Field Bit(s) Description ++ * ============================================================ ++ * DDR50_PRESET 25:13 Preset Value for DDR50 ++ * DEFAULT_PRESET 12:0 Preset Value for Default Speed ++ */ ++#define SDIO_PRESETVAL1 0x01004004 ++ ++/* ++ * SDIO_PRESETVAL2 ++ * ++ * Field Bit(s) Description ++ * ============================================================ ++ * HIGH_SPEED_PRESET 25:13 Preset Value for High Speed ++ * INIT_PRESET 12:0 Preset Value for Initialization ++ */ ++#define SDIO_PRESETVAL2 0x01004100 ++ ++/* ++ * SDIO_PRESETVAL3 ++ * ++ * Field Bit(s) Description ++ * ============================================================ ++ * SDR104_PRESET 25:13 Preset Value for SDR104 ++ * SDR12_PRESET 12:0 Preset Value for SDR12 ++ */ ++#define SDIO_PRESETVAL3 0x00000004 ++ ++/* ++ * SDIO_PRESETVAL4 ++ * ++ * Field Bit(s) Description ++ * ============================================================ ++ * SDR25_PRESET 25:13 Preset Value for SDR25 ++ * SDR50_PRESET 12:0 Preset Value for SDR50 ++ */ ++#define SDIO_PRESETVAL4 0x01005001 ++ ++static int iproc_top_sdio_config(void) ++{ ++ u32 val; ++ ++ val = iproc_cmic_schan_reg32_read(CMIC_BLOCK_TYPE_TOP, TOP_SDIO_MISC_CONTROL); ++ if ((val & 0x1f) != 0x1f) { ++ val |= (0x1 << TOP_SDIO_MISC_CONTROL__TOP_SDIO_8B_INF); ++ val |= (0xf << TOP_SDIO_MISC_CONTROL__TOP_SDIO_GPIO_INF_SEL_R); ++ iproc_cmic_schan_reg32_write(CMIC_BLOCK_TYPE_TOP, TOP_SDIO_MISC_CONTROL, val); ++ } ++ ++ return 0; ++} ++ ++static int iproc_sdio_init(struct xgs_iproc_sdhci_host *iproc_host) ++{ ++ int ret = 0; ++ u32 val; ++ ++ /* Enable SDIO for SDIO/GPIO selection */ ++ ret = iproc_top_sdio_config(); ++ if (ret < 0) ++ return ret; ++ ++ /* Release reset */ ++ writel(0x1, SDIO_IDM0_IDM_RESET_CONTROL(iproc_host->idm_base)); ++ udelay(1000); ++ writel(0x0, SDIO_IDM0_IDM_RESET_CONTROL(iproc_host->idm_base)); ++ ++ /* Enable the SDIO clock */ ++ val = readl(SDIO_IDM0_IO_CONTROL_DIRECT(iproc_host->idm_base)); ++ val |= (1 << SDIO_IDM0_IO_CONTROL_DIRECT__CMD_COMFLICT_DISABLE); ++ val |= (1 << SDIO_IDM0_IO_CONTROL_DIRECT__FEEDBACK_CLK_EN); ++ val |= (1 << SDIO_IDM0_IO_CONTROL_DIRECT__clk_enable); ++ writel(val, SDIO_IDM0_IO_CONTROL_DIRECT(iproc_host->idm_base)); ++ ++ /* Set the 1.8v fail control for HR3. ++ * This setting will not impact the uboot SD/MMC driver, since uboot doesn't ++ * support 1.8v. The 1.8v SDIO will be supportted in Kernel. ++ */ ++ val = readl(IPROC_WRAP_SDIO_1P8_FAIL_CONTROL(iproc_host->wrap_base)); ++ val |= (1 << IPROC_WRAP_SDIO_1P8_FAIL_CONTROL__SDIO_VDDO_18V_FAIL_SOVW); ++ val &= ~(1 << IPROC_WRAP_SDIO_1P8_FAIL_CONTROL__SDIO_UHS1_18V_VREG_FAIL); ++ writel(val, IPROC_WRAP_SDIO_1P8_FAIL_CONTROL(iproc_host->wrap_base)); ++ ++ /* ++ * Configure SDIO host controller capabilities ++ * (common setting for all SDIO controllers) ++ */ ++ writel(SDIO_CAPS_H, IPROC_WRAP_SDIO_CONTROL(iproc_host->wrap_base)); ++ writel(SDIO_CAPS_L, IPROC_WRAP_SDIO_CONTROL1(iproc_host->wrap_base)); ++ ++ /* ++ * Configure SDIO host controller preset values ++ * (common setting for all SDIO controllers) ++ */ ++ writel(SDIO_PRESETVAL1, IPROC_WRAP_SDIO_CONTROL2(iproc_host->wrap_base)); ++ writel(SDIO_PRESETVAL2, IPROC_WRAP_SDIO_CONTROL3(iproc_host->wrap_base)); ++ writel(SDIO_PRESETVAL3, IPROC_WRAP_SDIO_CONTROL4(iproc_host->wrap_base)); ++ writel(SDIO_PRESETVAL4, IPROC_WRAP_SDIO_CONTROL5(iproc_host->wrap_base)); ++ ++ return 0; ++} ++ ++static const struct sdhci_pltfm_data sdhci_iproc_pltfm_data = { ++ .quirks = SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK | ++ SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, ++ /*.quirks2 = SDHCI_QUIRK2_ACMD23_BROKEN,*/ ++ .ops = &sdhci_iproc_ops, ++}; ++ ++static const struct of_device_id sdhci_xgs_iproc_of_match[] = { ++ { .compatible = "brcm,iproc-hr3-sdio", .data = &sdhci_iproc_pltfm_data }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, sdhci_xgs_iproc_of_match); ++ ++static int sdhci_xgs_iproc_probe(struct platform_device *pdev) ++{ ++ const struct of_device_id *match; ++ struct xgs_iproc_sdhci_host *iproc_host; ++ struct sdhci_host *host; ++ const struct sdhci_pltfm_data *pltfm_data; ++ struct sdhci_pltfm_host *pltfm_host; ++ struct resource *res; ++ int ret = 0; ++ ++ match = of_match_device(sdhci_xgs_iproc_of_match, &pdev->dev); ++ if (!match) ++ return -EINVAL; ++ ++ pltfm_data = match->data; ++ host = sdhci_pltfm_init(pdev, pltfm_data, sizeof(*iproc_host)); ++ if (IS_ERR(host)) ++ return PTR_ERR(host); ++ ++ pltfm_host = sdhci_priv(host); ++ iproc_host = sdhci_pltfm_priv(pltfm_host); ++ ++ iproc_host->dn = pdev->dev.of_node; ++ ++ mmc_of_parse(host->mmc); ++ sdhci_get_of_property(pdev); ++ ++ host->hw_name = "XGS-IPROC-SDIO"; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ iproc_host->idm_base = devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(iproc_host->idm_base)) { ++ dev_err(&pdev->dev, "SDIO IDM base ioremap fail\n"); ++ ret = PTR_ERR(iproc_host->idm_base); ++ goto err1; ++ } ++ ++ iproc_host->wrap_base = get_iproc_wrap_ctrl_base(); ++ if (!iproc_host->wrap_base) { ++ dev_err(&pdev->dev, "SDIO wrap ctrl base ioremap fail\n"); ++ ret = -ENXIO; ++ goto err1; ++ } ++ ++ ret = iproc_sdio_init(iproc_host); ++ if (ret < 0) { ++ dev_err(&pdev->dev, "SDIO%d init failed\n", pdev->id); ++ ret = -ENXIO; ++ goto err1; ++ } ++ ++ ret = sdhci_add_host(host); ++ if (ret) { ++ dev_err(&pdev->dev, "SDIO add host fail\n"); ++ goto err1; ++ } ++ ++err1: ++ sdhci_pltfm_free(pdev); ++ return ret; ++} ++ ++static struct platform_driver sdhci_xgs_iproc_driver = { ++ .probe = sdhci_xgs_iproc_probe, ++ .remove = sdhci_pltfm_unregister, ++ .driver = { ++ .name = "iproc-hr3-sdio", ++ .pm = &sdhci_pltfm_pmops, ++ .of_match_table = sdhci_xgs_iproc_of_match, ++ }, ++}; ++ ++module_platform_driver(sdhci_xgs_iproc_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("SDHCI XGS HR3 driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/mtd/maps/Kconfig b/drivers/mtd/maps/Kconfig +--- a/drivers/mtd/maps/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/mtd/maps/Kconfig 2018-05-10 11:31:31.625401792 +0800 +@@ -419,4 +419,13 @@ config MTD_LATCH_ADDR + + If compiled as a module, it will be called latch-addr-flash. + ++config MTD_NOR_XGS_IPROC ++ bool "Broadcom XGS iProc CFI NOR support" ++ depends on (ARCH_XGS_IPROC || COMPILE_TEST) && MTD_CFI ++ default n ++ help ++ This selects a driver for the iProc NOR support. ++ ++ If unsure, say N. ++ + endmenu +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/mtd/maps/Makefile b/drivers/mtd/maps/Makefile +--- a/drivers/mtd/maps/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/mtd/maps/Makefile 2018-05-10 11:31:31.625401792 +0800 +@@ -48,3 +48,4 @@ obj-$(CONFIG_MTD_VMU) += vmu-flash.o + obj-$(CONFIG_MTD_GPIO_ADDR) += gpio-addr-flash.o + obj-$(CONFIG_MTD_LATCH_ADDR) += latch-addr-flash.o + obj-$(CONFIG_MTD_LANTIQ) += lantiq-flash.o ++obj-$(CONFIG_MTD_NOR_XGS_IPROC) += xgs-iproc-flash.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/mtd/maps/xgs-iproc-flash.c b/drivers/mtd/maps/xgs-iproc-flash.c +--- a/drivers/mtd/maps/xgs-iproc-flash.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/mtd/maps/xgs-iproc-flash.c 2018-05-10 11:31:31.629401796 +0800 +@@ -0,0 +1,184 @@ ++/* ++ * Copyright 2017 Broadcom Limited ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++extern void __iomem *get_iproc_dmu_pcu_base(void); ++ ++#define PNOR_DIRECT_CMD_OFFSET 0x10 ++#define PNOR_SET_OPMODE_OFFSET 0X18 ++ ++#define IPROC_STRAP_BOOT_DEV_NAND 1 ++#define IPROC_STRAP_BOOT_DEV_PNOR 4 ++#define ICFG_PNOR_STRAPS__PNOR_SRAM_MW_R 0 ++#define PNOR_set_opmode__set_mw_R 0 ++#define PNOR_direct_cmd__cmd_type_R 21 ++#define IPROC_DMU_STRAPS_OFFSET 0x28 ++#define IPROC_BOOT_STRAP_MASK 0x7 ++ ++struct iproc_nor_mtd { ++ void __iomem *reg_base; ++ void __iomem *reg_strap; ++ struct map_info map; ++ struct mtd_info *mtd; ++}; ++ ++static int xgs_iproc_nor_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ struct device *dev = &pdev->dev; ++ struct iproc_nor_mtd *iproc_data = NULL; ++ struct resource *res; ++ u32 straps, val; ++ u32 strap_boot_dev_shift; ++ void __iomem *reg_base; ++ ++ dev_info(dev, "XGS iProc pnor interface driver\n"); ++ ++ iproc_data = devm_kzalloc(dev, sizeof(*iproc_data), GFP_KERNEL); ++ if (!iproc_data) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, iproc_data); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ iproc_data->reg_base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(iproc_data->reg_base)) { ++ dev_err(dev, "can't ioremap pnor base addr\n"); ++ return PTR_ERR(iproc_data->reg_base); ++ } ++ ++ /* Check boot device */ ++ if (of_machine_is_compatible("brcm,hurricane2") || ++ of_machine_is_compatible("brcm,greyhound")) ++ strap_boot_dev_shift = 9; ++ else ++ strap_boot_dev_shift = 10; ++ ++ straps = readl(get_iproc_dmu_pcu_base() + IPROC_DMU_STRAPS_OFFSET); ++ straps = (straps >> strap_boot_dev_shift) & IPROC_BOOT_STRAP_MASK; ++ ++ if (straps == IPROC_STRAP_BOOT_DEV_NAND) { ++ /* If booting from NAND, PNOR cannot be used */ ++ return -ENODEV; ++ } else if (straps != IPROC_STRAP_BOOT_DEV_PNOR) { ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); ++ iproc_data->reg_strap = devm_ioremap_resource(dev, res); ++ ++ if (!IS_ERR(iproc_data->reg_strap)) { ++ /* Configure controller memory width based on strap */ ++ reg_base = iproc_data->reg_base; ++ straps = readl(iproc_data->reg_strap) & ++ (1 << ICFG_PNOR_STRAPS__PNOR_SRAM_MW_R); ++ ++ if (straps) { ++ /* 16-bit */ ++ val = readl(reg_base + PNOR_SET_OPMODE_OFFSET); ++ val |= (1 << PNOR_set_opmode__set_mw_R); ++ writel(val, reg_base + PNOR_SET_OPMODE_OFFSET); ++ } else { ++ /* 8-bit */ ++ val = readl(reg_base + PNOR_SET_OPMODE_OFFSET); ++ val &= ~(1 << PNOR_set_opmode__set_mw_R); ++ writel(val, reg_base + PNOR_SET_OPMODE_OFFSET); ++ } ++ ++ val = readl(reg_base + PNOR_DIRECT_CMD_OFFSET); ++ val |= (2 << PNOR_direct_cmd__cmd_type_R); ++ writel(val, reg_base + PNOR_DIRECT_CMD_OFFSET); ++ } ++ } ++ ++ mdelay(1); ++ ++ iproc_data->map.bankwidth = 2; ++ iproc_data->map.name = "XGS-IPROC-PNOR-FLASH"; ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ iproc_data->map.phys = res->start; ++ iproc_data->map.size = resource_size(res); ++ iproc_data->map.virt = devm_ioremap_resource(dev, res); ++ ++ if (IS_ERR(iproc_data->map.virt)) { ++ dev_err(dev, "can't ioremap pnor flash addr space\n"); ++ return PTR_ERR(iproc_data->map.virt); ++ } ++ ++ simple_map_init(&iproc_data->map); ++ ++ dev_info(dev, "MTD probing 16 bit PNOR FLASH\n"); ++ iproc_data->mtd = do_map_probe("cfi_probe", &iproc_data->map); ++ if (!iproc_data->mtd) { ++ /* Probe for bankwidth 1 */ ++ dev_info(dev, "MTD probing 8 bit PNOR FLASH\n"); ++ iproc_data->map.bankwidth = 1; ++ iproc_data->mtd = do_map_probe("cfi_probe", &iproc_data->map); ++ } ++ ++ if (iproc_data->mtd) { ++ iproc_data->mtd->owner = THIS_MODULE; ++ iproc_data->mtd->dev.parent = dev; ++ mtd_set_of_node(iproc_data->mtd, np); ++ mtd_device_parse_register(iproc_data->mtd, NULL, NULL, NULL, 0); ++ dev_info(dev, "PNOR MTD partitions parsed!\n"); ++ return 0; ++ } ++ ++ dev_warn(dev, "NO PNOR FLASH found!\n"); ++ ++ return -ENXIO; ++} ++ ++static int xgs_iproc_nor_remove(struct platform_device *pdev) ++{ ++ struct iproc_nor_mtd *iproc_data = platform_get_drvdata(pdev); ++ ++ if (!iproc_data) ++ return 0; ++ ++ if (iproc_data->mtd) { ++ mtd_device_unregister(iproc_data->mtd); ++ map_destroy(iproc_data->mtd); ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id xgs_iproc_nor_dt_ids[] = { ++ { .compatible = "brcm,iproc-nor", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, xgs_iproc_nor_dt_ids); ++ ++static struct platform_driver xgs_iproc_nor_driver = ++{ ++ .driver = { ++ .name = "xgs-iproc-nor", ++ .owner = THIS_MODULE, ++ .of_match_table = xgs_iproc_nor_dt_ids, ++ }, ++ .probe = xgs_iproc_nor_probe, ++ .remove = xgs_iproc_nor_remove, ++}; ++ ++module_platform_driver(xgs_iproc_nor_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("MTD map driver for XGS iProc PNOR controller"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/mtd/nand/brcmnand/brcmnand.c b/drivers/mtd/nand/brcmnand/brcmnand.c +--- a/drivers/mtd/nand/brcmnand/brcmnand.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/mtd/nand/brcmnand/brcmnand.c 2018-05-30 15:50:51.028753148 +0800 +@@ -1220,6 +1220,8 @@ static void brcmnand_send_cmd(struct brc + ctrl->cmd_pending = cmd; + + ret = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY, NAND_CTRL_RDY, 0); ++ /* mark out this warning for XGS iProc */ ++ if (!IS_ENABLED(CONFIG_ARCH_XGS_IPROC)) + WARN_ON(ret); + + mb(); /* flush previous writes */ +@@ -1698,7 +1700,9 @@ static int brcmstb_nand_verify_erased_pa + ret = nand_check_erased_ecc_chunk(buf, chip->ecc.size, + oob, sas, NULL, 0, + chip->ecc.strength); ++ buf += chip->ecc.size; ++ + if (ret < 0) + return ret; + + +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig +--- a/drivers/net/ethernet/broadcom/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/Kconfig 2018-05-10 11:31:31.725401901 +0800 +@@ -171,16 +171,26 @@ config BGMAC_BCMA + config BGMAC_PLATFORM + tristate "Broadcom iProc GBit platform support" + depends on HAS_DMA +- depends on ARCH_BCM_IPROC || COMPILE_TEST ++ depends on ARCH_BCM_IPROC || ARCH_XGS_IPROC || COMPILE_TEST + depends on OF + select BGMAC + select PHYLIB + select FIXED_PHY +- default ARCH_BCM_IPROC ++ default ARCH_BCM_IPROC || ARCH_XGS_IPROC + ---help--- + Say Y here if you want to use the Broadcom iProc Gigabit Ethernet + controller through the generic platform interface + ++config APM ++ tristate "Broadcom iProc AXI Port Macro (APM) support" ++ depends on HAS_DMA ++ depends on ARCH_XGS_IPROC || COMPILE_TEST ++ depends on OF ++ ---help--- ++ This driver supports AXI Port Macro (APM) module. ++ The APM provides a bridge function between a standard Port Macro (PM 4X10) ++ interface and the AXI interconnect (128 bits data bus) for data transfer. ++ + config SYSTEMPORT + tristate "Broadcom SYSTEMPORT internal MAC support" + depends on OF +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/Makefile b/drivers/net/ethernet/broadcom/Makefile +--- a/drivers/net/ethernet/broadcom/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/Makefile 2018-05-10 11:31:31.725401901 +0800 +@@ -16,3 +16,4 @@ obj-$(CONFIG_BGMAC_BCMA) += bgmac-bcma.o + obj-$(CONFIG_BGMAC_PLATFORM) += bgmac-platform.o + obj-$(CONFIG_SYSTEMPORT) += bcmsysport.o + obj-$(CONFIG_BNXT) += bnxt/ ++obj-$(CONFIG_APM) += apm.o apm_ethtool.o pm4x10.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/apm.c b/drivers/net/ethernet/broadcom/apm.c +--- a/drivers/net/ethernet/broadcom/apm.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/apm.c 2018-05-31 15:24:26.196724803 +0800 +@@ -0,0 +1,1414 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include "pm.h" ++#include "apm.h" ++ ++static bool apm_clk_enabled(struct apm *apm); ++ ++static u32 apm_read(struct apm *apm, u16 offset) ++{ ++ return readl(apm->plat.base + offset); ++} ++ ++static void apm_write(struct apm *apm, u16 offset, u32 value) ++{ ++ writel(value, apm->plat.base + offset); ++} ++ ++static u32 apm_idm_read(struct apm *apm, u16 offset) ++{ ++ return readl(apm->plat.idm_base + offset); ++} ++ ++static void apm_idm_write(struct apm *apm, u16 offset, u32 value) ++{ ++ return writel(value, apm->plat.idm_base + offset); ++} ++ ++static bool apm_wait_value(struct apm *apm, u16 reg, u32 mask, ++ u32 value, int timeout) ++{ ++ u32 val; ++ int i; ++ ++ for (i = 0; i < timeout / 10; i++) { ++ val = apm_read(apm, reg); ++ if ((val & mask) == value) ++ return true; ++ udelay(10); ++ } ++ dev_err(apm->dev, "Timeout waiting for reg 0x%X\n", reg); ++ return false; ++} ++ ++/************************************************** ++ * DMA ++ **************************************************/ ++static void apm_dma_tx_reset(struct apm *apm, struct apm_dma_ring *tx_ring) ++{ ++ u32 val; ++ int i; ++ ++ if (!tx_ring->mmio_base) ++ return; ++ ++ /* Suspend DMA TX ring first. ++ * apm_wait_value doesn't support waiting for any of few values, so ++ * implement whole loop here. ++ */ ++ val = apm_read(apm, tx_ring->mmio_base + APM_DMA_TX_CTL); ++ apm_write(apm, tx_ring->mmio_base + APM_DMA_TX_CTL, ++ (val | APM_DMA_TX_SUSPEND)); ++ for (i = 0; i < 10000 / 10; i++) { ++ val = apm_read(apm, tx_ring->mmio_base + APM_DMA_TX_STATUS); ++ val &= APM_DMA_TX_STAT; ++ if (val == APM_DMA_TX_STAT_DISABLED || ++ val == APM_DMA_TX_STAT_IDLEWAIT || ++ val == APM_DMA_TX_STAT_STOPPED) { ++ i = 0; ++ break; ++ } ++ udelay(10); ++ } ++ if (i) { ++ dev_err(apm->dev, "Timeout suspending DMA TX ring 0x%X (APM_DMA_TX_STAT: 0x%08X)\n", ++ tx_ring->mmio_base, val); ++ } ++ ++ /* Disable the transmit channel */ ++ val = apm_read(apm, tx_ring->mmio_base + APM_DMA_TX_CTL); ++ apm_write(apm, tx_ring->mmio_base + APM_DMA_TX_CTL, ++ (val & ~APM_DMA_TX_SUSPEND)); ++ if (!apm_wait_value(apm, tx_ring->mmio_base + APM_DMA_TX_STATUS, ++ APM_DMA_TX_STAT, APM_DMA_TX_STAT_DISABLED, 10000)) { ++ dev_warn(apm->dev, "DMA TX ring 0x%X wasn't disabled on time, waiting additional 300us\n", ++ tx_ring->mmio_base); ++ udelay(300); ++ ++ val = apm_read(apm, tx_ring->mmio_base + APM_DMA_TX_STATUS); ++ if ((val & APM_DMA_TX_STAT) != APM_DMA_TX_STAT_DISABLED) ++ dev_err(apm->dev, "Reset of DMA TX ring 0x%X failed\n", ++ tx_ring->mmio_base); ++ } ++} ++ ++static void apm_dma_tx_enable(struct apm *apm, ++ struct apm_dma_ring *tx_ring) ++{ ++ u32 ctl; ++ ++ ctl = apm_read(apm, tx_ring->mmio_base + APM_DMA_TX_CTL); ++ if (apm->feature_flags & APM_FEAT_TX_MASK_SETUP) { ++ ctl &= ~APM_DMA_TX_BL_MASK; ++ ctl |= APM_DMA_TX_BL_128 << APM_DMA_TX_BL_SHIFT; ++ ++// ctl &= ~APM_DMA_TX_MR_MASK; ++// ctl |= APM_DMA_TX_MR_2 << APM_DMA_TX_MR_SHIFT; ++ ++ ctl &= ~APM_DMA_TX_PC_MASK; ++ ctl |= APM_DMA_TX_PC_16 << APM_DMA_TX_PC_SHIFT; ++ ++ ctl &= ~APM_DMA_TX_PT_MASK; ++ ctl |= APM_DMA_TX_PT_8 << APM_DMA_TX_PT_SHIFT; ++ } ++ ctl |= APM_DMA_TX_ENABLE; ++// ctl |= APM_DMA_TX_PARITY_DISABLE; ++ apm_write(apm, tx_ring->mmio_base + APM_DMA_TX_CTL, ctl); ++} ++ ++static void ++apm_dma_tx_add_buf(struct apm *apm, struct apm_dma_ring *tx_ring, ++ int i, int len, u32 ctl0) ++{ ++ struct apm_slot_info *slot; ++ struct apm_dma_desc *dma_desc; ++ u32 ctl1; ++ ++ if (i == tx_ring->desc_num - 1) ++ ctl0 |= APM_DESC_CTL0_EOT; ++ ++ ctl1 = len & APM_DESC_CTL1_LEN; ++ ++ slot = &tx_ring->slots[i]; ++ dma_desc = &tx_ring->desc_base[i]; ++ dma_desc->addr_low = cpu_to_le32(lower_32_bits(slot->dma_addr)); ++ dma_desc->addr_high = cpu_to_le32(upper_32_bits(slot->dma_addr)); ++ dma_desc->ctl0 = cpu_to_le32(ctl0); ++ dma_desc->ctl1 = cpu_to_le32(ctl1); ++} ++ ++static netdev_tx_t apm_dma_tx_add(struct apm *apm, ++ struct apm_dma_ring *tx_ring, struct sk_buff *skb) ++{ ++ struct device *dma_dev = apm->dma_dev; ++ struct net_device *net_dev = apm->net_dev; ++ int index = tx_ring->end % tx_ring->desc_num; ++ struct apm_slot_info *slot = &tx_ring->slots[index]; ++ int nr_frags; ++ u32 flags; ++ int i; ++ ++ if (skb->len > APM_DESC_CTL1_LEN) { ++ netdev_err(apm->net_dev, "Too long skb (%d)\n", skb->len); ++ goto err_drop; ++ } ++ ++ if (skb->ip_summed == CHECKSUM_PARTIAL) ++ skb_checksum_help(skb); ++ ++ nr_frags = skb_shinfo(skb)->nr_frags; ++ ++ /* ring->end - ring->start will return the number of valid slots, ++ * even when tx_ring->end overflows ++ */ ++ if (tx_ring->end - tx_ring->start + nr_frags + 1 >= tx_ring->desc_num) { ++ netdev_err(apm->net_dev, "TX ring is full, queue should be stopped!\n"); ++ netif_stop_queue(net_dev); ++ return NETDEV_TX_BUSY; ++ } ++ ++ slot->dma_addr = dma_map_single(dma_dev, skb->data, skb_headlen(skb), ++ DMA_TO_DEVICE); ++ if (unlikely(dma_mapping_error(dma_dev, slot->dma_addr))) ++ goto err_dma_head; ++ ++ flags = APM_DESC_CTL0_SOF; ++ if (!nr_frags) ++ flags |= APM_DESC_CTL0_EOF | APM_DESC_CTL0_IOC; ++ ++ apm_dma_tx_add_buf(apm, tx_ring, index, skb->len + 4, flags); ++ flags = 0; ++ ++ for (i = 0; i < nr_frags; i++) { ++ struct skb_frag_struct *frag = &skb_shinfo(skb)->frags[i]; ++ int len = skb_frag_size(frag); ++ ++ index = (index + 1) % tx_ring->desc_num; ++ slot = &tx_ring->slots[index]; ++ slot->dma_addr = skb_frag_dma_map(dma_dev, frag, 0, ++ len, DMA_TO_DEVICE); ++ if (unlikely(dma_mapping_error(dma_dev, slot->dma_addr))) ++ goto err_dma; ++ ++ if (i == nr_frags - 1) ++ flags |= APM_DESC_CTL0_EOF | APM_DESC_CTL0_IOC; ++ ++ apm_dma_tx_add_buf(apm, tx_ring, index, len, flags); ++ } ++ ++ slot->skb = skb; ++ tx_ring->end += nr_frags + 1; ++ netdev_sent_queue(net_dev, skb->len); ++ ++ wmb(); ++ ++ /* Increase tx_ring->end to point empty slot. We tell hardware the first ++ * slot it should *not* read. ++ */ ++ apm_write(apm, tx_ring->mmio_base + APM_DMA_TX_INDEX, ++ tx_ring->index_base + ++ (tx_ring->end % tx_ring->desc_num) * ++ sizeof(struct apm_dma_desc)); ++ ++ if (tx_ring->end - tx_ring->start >= tx_ring->desc_num - 8) ++ netif_stop_queue(net_dev); ++ ++ return NETDEV_TX_OK; ++ ++err_dma: ++ dma_unmap_single(dma_dev, slot->dma_addr, skb_headlen(skb), ++ DMA_TO_DEVICE); ++ ++ while (i-- > 0) { ++ int index = (tx_ring->end + i) % tx_ring->desc_num; ++ struct apm_slot_info *slot = &tx_ring->slots[index]; ++ u32 ctl1 = le32_to_cpu(tx_ring->desc_base[index].ctl1); ++ int len = ctl1 & APM_DESC_CTL1_LEN; ++ ++ dma_unmap_page(dma_dev, slot->dma_addr, len, DMA_TO_DEVICE); ++ } ++ ++err_dma_head: ++ netdev_err(apm->net_dev, "Mapping error of skb on TX ring 0x%X\n", ++ tx_ring->mmio_base); ++ ++err_drop: ++ dev_kfree_skb(skb); ++ net_dev->stats.tx_dropped++; ++ net_dev->stats.tx_errors++; ++ return NETDEV_TX_OK; ++} ++ ++/* Free transmitted packets */ ++static void apm_dma_tx_free(struct apm *apm, struct apm_dma_ring *tx_ring) ++{ ++ struct device *dma_dev = apm->dma_dev; ++ int empty_slot; ++ bool freed = false; ++ unsigned bytes_compl = 0, pkts_compl = 0; ++ ++ /* The last slot that hardware didn't consume yet */ ++ empty_slot = apm_read(apm, tx_ring->mmio_base + APM_DMA_TX_STATUS); ++ empty_slot &= APM_DMA_TX_STATDPTR; ++ empty_slot -= tx_ring->index_base; ++ empty_slot &= APM_DMA_TX_STATDPTR; ++ empty_slot /= sizeof(struct apm_dma_desc); ++ ++ while (tx_ring->start != tx_ring->end) { ++ int index = tx_ring->start % tx_ring->desc_num; ++ struct apm_slot_info *slot = &tx_ring->slots[index]; ++ u32 ctl0, ctl1; ++ int len; ++ ++ if (index == empty_slot) ++ break; ++ ++ ctl0 = le32_to_cpu(tx_ring->desc_base[index].ctl0); ++ ctl1 = le32_to_cpu(tx_ring->desc_base[index].ctl1); ++ len = ctl1 & APM_DESC_CTL1_LEN; ++ if (ctl0 & APM_DESC_CTL0_SOF) ++ /* Unmap no longer used buffer */ ++ dma_unmap_single(dma_dev, slot->dma_addr, len, ++ DMA_TO_DEVICE); ++ else ++ dma_unmap_page(dma_dev, slot->dma_addr, len, ++ DMA_TO_DEVICE); ++ ++ if (slot->skb) { ++ apm->net_dev->stats.tx_bytes += slot->skb->len; ++ apm->net_dev->stats.tx_packets++; ++ bytes_compl += slot->skb->len; ++ pkts_compl++; ++ ++ /* Free memory! :) */ ++ dev_kfree_skb(slot->skb); ++ slot->skb = NULL; ++ } ++ ++ slot->dma_addr = 0; ++ tx_ring->start++; ++ freed = true; ++ } ++ ++ if (!pkts_compl) ++ return; ++ ++ netdev_completed_queue(apm->net_dev, pkts_compl, bytes_compl); ++ ++ if (netif_queue_stopped(apm->net_dev)) ++ netif_wake_queue(apm->net_dev); ++} ++ ++static void apm_dma_rx_reset(struct apm *apm, struct apm_dma_ring *rx_ring) ++{ ++ if (!rx_ring->mmio_base) ++ return; ++ ++ apm_write(apm, rx_ring->mmio_base + APM_DMA_RX_CTL, 0); ++ if (!apm_wait_value(apm, ++ rx_ring->mmio_base + APM_DMA_RX_STATUS, ++ APM_DMA_RX_STAT, APM_DMA_RX_STAT_DISABLED, ++ 10000)) ++ dev_err(apm->dev, "Reset of RX ring 0x%X RX failed\n", ++ rx_ring->mmio_base); ++} ++ ++static void apm_dma_rx_enable(struct apm *apm, ++ struct apm_dma_ring *rx_ring) ++{ ++ u32 ctl; ++ ++ ctl = apm_read(apm, rx_ring->mmio_base + APM_DMA_RX_CTL); ++ ++// /* preserve ONLY bits 16-17 from current hardware value */ ++// ctl &= APM_DMA_RX_ADDREXT_MASK; ++ ++ if (apm->feature_flags & APM_FEAT_RX_MASK_SETUP) { ++ ctl &= ~APM_DMA_RX_BL_MASK; ++ ctl |= APM_DMA_RX_BL_128 << APM_DMA_RX_BL_SHIFT; ++ ++ ctl &= ~APM_DMA_RX_PC_MASK; ++ ctl |= APM_DMA_RX_PC_8 << APM_DMA_RX_PC_SHIFT; ++ ++ ctl &= ~APM_DMA_RX_PT_MASK; ++ ctl |= APM_DMA_RX_PT_1 << APM_DMA_RX_PT_SHIFT; ++ } ++ ctl |= APM_DMA_RX_ENABLE; ++// ctl |= APM_DMA_RX_PARITY_DISABLE; ++ ctl |= APM_DMA_RX_OVERFLOW_CONT; ++ ctl |= APM_RX_FRAME_OFFSET << APM_DMA_RX_FRAME_OFFSET_SHIFT; ++ apm_write(apm, rx_ring->mmio_base + APM_DMA_RX_CTL, ctl); ++} ++ ++static int apm_dma_rx_skb_for_slot(struct apm *apm, ++ struct apm_slot_info *slot) ++{ ++ struct device *dma_dev = apm->dma_dev; ++ dma_addr_t dma_addr; ++ struct apm_rx_header *rx; ++ void *buf; ++ ++ /* Alloc skb */ ++ buf = netdev_alloc_frag(APM_RX_ALLOC_SIZE); ++ if (!buf) ++ return -ENOMEM; ++ ++ /* Poison - if everything goes fine, hardware will overwrite it */ ++ rx = buf + APM_RX_BUF_OFFSET; ++ rx->len = cpu_to_le16(0xdead); ++ rx->flags = cpu_to_le16(0xbeef); ++ ++ /* Map skb for the DMA */ ++ dma_addr = dma_map_single(dma_dev, buf + APM_RX_BUF_OFFSET, ++ APM_RX_BUF_SIZE, DMA_FROM_DEVICE); ++ if (dma_mapping_error(dma_dev, dma_addr)) { ++ netdev_err(apm->net_dev, "DMA mapping error\n"); ++ put_page(virt_to_head_page(buf)); ++ return -ENOMEM; ++ } ++ ++ /* Update the slot */ ++ slot->buf = buf; ++ slot->dma_addr = dma_addr; ++ ++ return 0; ++} ++ ++static void apm_dma_rx_update_index(struct apm *apm, ++ struct apm_dma_ring *rx_ring) ++{ ++ dma_wmb(); ++ ++ apm_write(apm, rx_ring->mmio_base + APM_DMA_RX_INDEX, ++ rx_ring->index_base + ++ rx_ring->end * sizeof(struct apm_dma_desc)); ++} ++ ++static void apm_dma_rx_setup_desc(struct apm *apm, ++ struct apm_dma_ring *rx_ring, int index) ++{ ++ struct apm_dma_desc *dma_desc = rx_ring->desc_base + index; ++ u32 ctl0 = 0, ctl1 = 0; ++ ++ if (index == rx_ring->desc_num - 1) ++ ctl0 |= APM_DESC_CTL0_EOT; ++ ctl1 |= APM_RX_BUF_SIZE & APM_DESC_CTL1_LEN; ++ /* Is there any APM device that requires extension? */ ++ /* ctl1 |= (addrext << B43_DMA64_DCTL1_ADDREXT_SHIFT) & ++ * B43_DMA64_DCTL1_ADDREXT_MASK; ++ */ ++ ++ dma_desc->addr_low = cpu_to_le32(lower_32_bits(rx_ring->slots[index].dma_addr)); ++ dma_desc->addr_high = cpu_to_le32(upper_32_bits(rx_ring->slots[index].dma_addr)); ++ dma_desc->ctl0 = cpu_to_le32(ctl0); ++ dma_desc->ctl1 = cpu_to_le32(ctl1); ++ ++ rx_ring->end = index; ++} ++ ++static void apm_dma_rx_poison_buf(struct device *dma_dev, ++ struct apm_slot_info *slot) ++{ ++ struct apm_rx_header *rx = slot->buf + APM_RX_BUF_OFFSET; ++ ++ dma_sync_single_for_cpu(dma_dev, slot->dma_addr, APM_RX_BUF_SIZE, ++ DMA_FROM_DEVICE); ++ rx->len = cpu_to_le16(0xdead); ++ rx->flags = cpu_to_le16(0xbeef); ++ dma_sync_single_for_device(dma_dev, slot->dma_addr, APM_RX_BUF_SIZE, ++ DMA_FROM_DEVICE); ++} ++ ++static int apm_dma_rx_read(struct apm *apm, struct apm_dma_ring *rx_ring, ++ int weight) ++{ ++ u32 end_slot; ++ int handled = 0; ++ ++ end_slot = apm_read(apm, rx_ring->mmio_base + APM_DMA_RX_STATUS); ++ end_slot &= APM_DMA_RX_STATDPTR; ++ end_slot -= rx_ring->index_base; ++ end_slot &= APM_DMA_RX_STATDPTR; ++ end_slot /= sizeof(struct apm_dma_desc); ++ ++ while (rx_ring->start != end_slot) { ++ struct device *dma_dev = apm->dma_dev; ++ struct apm_slot_info *slot = &rx_ring->slots[rx_ring->start]; ++ struct apm_rx_header *rx = slot->buf + APM_RX_BUF_OFFSET; ++ struct sk_buff *skb; ++ void *buf = slot->buf; ++ dma_addr_t dma_addr = slot->dma_addr; ++ u16 len, flags; ++ ++ do { ++ /* Prepare new skb as replacement */ ++ if (apm_dma_rx_skb_for_slot(apm, slot)) { ++ apm_dma_rx_poison_buf(dma_dev, slot); ++ break; ++ } ++ ++ /* Unmap buffer to make it accessible to the CPU */ ++ dma_unmap_single(dma_dev, dma_addr, ++ APM_RX_BUF_SIZE, DMA_FROM_DEVICE); ++ ++ /* Get info from the header */ ++ len = le16_to_cpu(rx->len); ++ flags = le16_to_cpu(rx->flags); ++ ++ /* Check for poison and drop or pass the packet */ ++ if (len == 0xdead && flags == 0xbeef) { ++ netdev_err(apm->net_dev, "Found poisoned packet at slot %d, DMA issue!\n", ++ rx_ring->start); ++ put_page(virt_to_head_page(buf)); ++ apm->net_dev->stats.rx_errors++; ++ break; ++ } ++ ++ if (len > APM_RX_ALLOC_SIZE) { ++ netdev_err(apm->net_dev, "Found oversized packet at slot %d, DMA issue!\n", ++ rx_ring->start); ++ put_page(virt_to_head_page(buf)); ++ apm->net_dev->stats.rx_length_errors++; ++ apm->net_dev->stats.rx_errors++; ++ break; ++ } ++ ++ /* Omit CRC. */ ++ len -= ETH_FCS_LEN; ++ ++ skb = build_skb(buf, APM_RX_ALLOC_SIZE); ++ if (unlikely(!skb)) { ++ netdev_err(apm->net_dev, "build_skb failed\n"); ++ put_page(virt_to_head_page(buf)); ++ apm->net_dev->stats.rx_errors++; ++ break; ++ } ++ skb_put(skb, APM_RX_FRAME_OFFSET + ++ APM_RX_BUF_OFFSET + len); ++ skb_pull(skb, APM_RX_FRAME_OFFSET + ++ APM_RX_BUF_OFFSET); ++ ++ skb_checksum_none_assert(skb); ++ skb->protocol = eth_type_trans(skb, apm->net_dev); ++ apm->net_dev->stats.rx_bytes += len; ++ apm->net_dev->stats.rx_packets++; ++ napi_gro_receive(&apm->napi, skb); ++ handled++; ++ } while (0); ++ ++ apm_dma_rx_setup_desc(apm, rx_ring, rx_ring->start); ++ ++ if (++rx_ring->start >= rx_ring->desc_num) ++ rx_ring->start = 0; ++ ++ if (handled >= weight) /* Should never be greater */ ++ break; ++ } ++ ++ apm_dma_rx_update_index(apm, rx_ring); ++ ++ return handled; ++} ++ ++/* Does ring support unaligned addressing? */ ++static bool apm_dma_unaligned(struct apm *apm, ++ struct apm_dma_ring *ring, ++ enum apm_dma_ring_type ring_type) ++{ ++ switch (ring_type) { ++ case APM_DMA_RING_TYPE_TX: ++ apm_write(apm, ring->mmio_base + APM_DMA_TX_RINGLO, 0xff0); ++ if (apm_read(apm, ring->mmio_base + APM_DMA_TX_RINGLO)) ++ return true; ++ break; ++ case APM_DMA_RING_TYPE_RX: ++ apm_write(apm, ring->mmio_base + APM_DMA_RX_RINGLO, 0xff0); ++ if (apm_read(apm, ring->mmio_base + APM_DMA_RX_RINGLO)) ++ return true; ++ break; ++ default: ++ return false; ++ } ++ return false; ++} ++ ++static void apm_dma_tx_ring_free(struct apm *apm, ++ struct apm_dma_ring *tx_ring) ++{ ++ struct device *dma_dev = apm->dma_dev; ++ struct apm_dma_desc *dma_desc = tx_ring->desc_base; ++ struct apm_slot_info *slot; ++ int i; ++ ++ for (i = 0; i < tx_ring->desc_num; i++) { ++ int len = dma_desc[i].ctl1 & APM_DESC_CTL1_LEN; ++ ++ slot = &tx_ring->slots[i]; ++ dev_kfree_skb(slot->skb); ++ if (!slot->dma_addr) ++ continue; ++ ++ if (slot->skb) ++ dma_unmap_single(dma_dev, slot->dma_addr, ++ len, DMA_TO_DEVICE); ++ else ++ dma_unmap_page(dma_dev, slot->dma_addr, ++ len, DMA_TO_DEVICE); ++ } ++} ++ ++static void apm_dma_rx_ring_free(struct apm *apm, ++ struct apm_dma_ring *rx_ring) ++{ ++ struct device *dma_dev = apm->dma_dev; ++ struct apm_slot_info *slot; ++ int i; ++ ++ for (i = 0; i < rx_ring->desc_num; i++) { ++ slot = &rx_ring->slots[i]; ++ if (!slot->dma_addr) ++ continue; ++ ++ dma_unmap_single(dma_dev, slot->dma_addr, ++ APM_RX_BUF_SIZE, ++ DMA_FROM_DEVICE); ++ put_page(virt_to_head_page(slot->buf)); ++ slot->dma_addr = 0; ++ } ++} ++ ++static void apm_dma_cleanup(struct apm *apm) ++{ ++ int i; ++ ++ for (i = 0; i < apm->tx_channel; i++) { ++ apm_dma_tx_ring_free(apm, &apm->tx_ring[i]); ++ } ++ ++ apm_dma_rx_ring_free(apm, &apm->rx_ring[0]); ++} ++ ++static void apm_dma_free(struct apm *apm) ++{ ++ struct device *dma_dev = apm->dma_dev; ++ int size; ++ ++ if (apm->desc_buf) { ++ size = (APM_TX_MAX_DESCS + APM_RX_MAX_DESCS) * ++ sizeof(struct apm_dma_desc); ++ dma_free_coherent(dma_dev, size, apm->desc_buf, apm->dma_addr); ++ } ++ ++ if (apm->slot_buf) { ++ kfree(apm->slot_buf); ++ } ++} ++ ++static int apm_dma_alloc(struct apm *apm) ++{ ++ struct device *dma_dev = apm->dma_dev; ++ int size; ++ ++ size = (APM_TX_MAX_DESCS + APM_RX_MAX_DESCS) * ++ sizeof(struct apm_dma_desc); ++ apm->desc_buf = dma_zalloc_coherent(dma_dev, size, ++ &apm->dma_addr, GFP_KERNEL); ++ if (!apm->desc_buf) { ++ dev_err(apm->dev, "Descriptor buffer allocation failed\n"); ++ goto err_dma_free; ++ } ++ memset(apm->desc_buf, 0, size); ++ ++ size = (APM_TX_MAX_DESCS + APM_RX_MAX_DESCS) * ++ sizeof(struct apm_slot_info); ++ apm->slot_buf = kmalloc(size, GFP_KERNEL); ++ if (!apm->slot_buf) { ++ dev_err(apm->dev, "Data buffer allocation failed\n"); ++ goto err_dma_free; ++ } ++ memset(apm->slot_buf, 0, size); ++ return 0; ++ ++err_dma_free: ++ apm_dma_free(apm); ++ return -ENOMEM; ++} ++ ++static int apm_tx_dma_init(struct apm *apm, ++ struct apm_dma_ring *tx_ring, int channel) ++{ ++ const u16 ring_base[] = { APM_DMA_BASE0, APM_DMA_BASE1, ++ APM_DMA_BASE2, APM_DMA_BASE3,}; ++ int desc_num = APM_TX_MAX_DESCS / apm->tx_channel; ++ int offset = channel * desc_num; ++ ++ BUILD_BUG_ON(APM_MAX_TX_RINGS > ARRAY_SIZE(ring_base)); ++ ++ tx_ring->mmio_base = ring_base[channel]; ++ if ((apm->tx_channel == 2) && (channel == 1)) { ++ tx_ring->mmio_base = ring_base[2]; ++ } ++ ++ tx_ring->desc_num = desc_num; ++ tx_ring->desc_base = apm->desc_buf + offset; ++ tx_ring->dma_base = (dma_addr_t)((u32)apm->dma_addr + ++ offset * sizeof(struct apm_dma_desc)); ++ tx_ring->slots = apm->slot_buf + offset; ++ ++ tx_ring->index_base = 0; ++ tx_ring->unaligned = apm_dma_unaligned(apm, ++ tx_ring, APM_DMA_RING_TYPE_TX); ++ if (tx_ring->unaligned) { ++ tx_ring->index_base = lower_32_bits(tx_ring->dma_base); ++ } ++ ++ tx_ring->start = 0; ++ tx_ring->end = 0; /* Points the slot that should *not* be read */ ++ ++ return 0; ++} ++ ++static int apm_rx_dma_init(struct apm *apm, struct apm_dma_ring *rx_ring) ++{ ++ int offset = APM_TX_MAX_DESCS; ++ ++ rx_ring->desc_num = APM_RX_MAX_DESCS; ++ rx_ring->mmio_base = APM_DMA_BASE0; ++ rx_ring->desc_base = apm->desc_buf + offset; ++ rx_ring->dma_base = (dma_addr_t)((u32)apm->dma_addr + ++ offset * sizeof(struct apm_dma_desc)); ++ rx_ring->slots = apm->slot_buf + offset; ++ ++ rx_ring->index_base = 0; ++ rx_ring->unaligned = apm_dma_unaligned(apm, ++ rx_ring, APM_DMA_RING_TYPE_RX); ++ if (rx_ring->unaligned) { ++ rx_ring->index_base = lower_32_bits(rx_ring->dma_base); ++ } ++ ++ rx_ring->start = 0; ++ rx_ring->end = 0; /* Points the slot that should *not* be read */ ++ ++ return 0; ++} ++ ++static int apm_dma_init(struct apm *apm) ++{ ++ struct apm_dma_ring *tx_ring, *rx_ring; ++ int i, err; ++ ++ /* TX DMA init */ ++ for (i = 0; i < apm->tx_channel; i++) { ++ tx_ring = &apm->tx_ring[i]; ++ apm_tx_dma_init(apm, tx_ring, i); ++ ++ if (!tx_ring->unaligned) { ++ apm_dma_tx_enable(apm, tx_ring); ++ } ++ ++ apm_write(apm, tx_ring->mmio_base + APM_DMA_TX_RINGLO, ++ lower_32_bits(tx_ring->dma_base)); ++ apm_write(apm, tx_ring->mmio_base + APM_DMA_TX_RINGHI, ++ upper_32_bits(tx_ring->dma_base)); ++ ++ if (tx_ring->unaligned) { ++ apm_dma_tx_enable(apm, tx_ring); ++ } ++ } ++ ++ /* RX DMA init */ ++ rx_ring = &apm->rx_ring[0]; ++ apm_rx_dma_init(apm, rx_ring); ++ ++ if (!rx_ring->unaligned) { ++ apm_dma_rx_enable(apm, rx_ring); ++ } ++ ++ apm_write(apm, rx_ring->mmio_base + APM_DMA_RX_RINGLO, ++ lower_32_bits(rx_ring->dma_base)); ++ apm_write(apm, rx_ring->mmio_base + APM_DMA_RX_RINGHI, ++ upper_32_bits(rx_ring->dma_base)); ++ ++ if (rx_ring->unaligned) { ++ apm_dma_rx_enable(apm, rx_ring); ++ } ++ ++ for (i = 0; i < rx_ring->desc_num; i++) { ++ err = apm_dma_rx_skb_for_slot(apm, &rx_ring->slots[i]); ++ if (err) { ++ goto error; ++ } ++ apm_dma_rx_setup_desc(apm, rx_ring, i); ++ } ++ apm_dma_rx_update_index(apm, rx_ring); ++ ++ return 0; ++ ++error: ++ apm_dma_cleanup(apm); ++ return err; ++} ++ ++ ++/************************************************** ++ * Chip ops ++ **************************************************/ ++ ++/* TODO: can we just drop @force? Can we don't reset MAC at all if there is ++ * nothing to change? Try if after stabilizng driver. ++ */ ++//static void apm_cmdcfg_maskset(struct apm *apm, u32 mask, u32 set, ++// bool force) ++//{ ++// u32 cmdcfg = apm_read(apm, APM_CMDCFG); ++// u32 new_val = (cmdcfg & mask) | set; ++// u32 cmdcfg_sr; ++// ++// apm_set(apm, APM_CMDCFG, cmdcfg_sr); ++// udelay(2); ++// ++// if (new_val != cmdcfg || force) ++// apm_write(apm, APM_CMDCFG, new_val); ++// ++// apm_mask(apm, APM_CMDCFG, ~cmdcfg_sr); ++// udelay(2); ++//} ++ ++//static void apm_set_rx_mode(struct net_device *net_dev) ++//{ ++// struct apm *apm = netdev_priv(net_dev); ++// ++// if (net_dev->flags & IFF_PROMISC) ++// apm_cmdcfg_maskset(apm, ~0, APM_CMDCFG_PROM, true); ++// else ++// apm_cmdcfg_maskset(apm, ~APM_CMDCFG_PROM, 0, true); ++//} ++ ++static int apm_port_loopback(struct apm *apm, int lb_type) ++{ ++ struct iproc_pm_ops *pm_ops = apm->pm_ops; ++ ++ if (!pm_ops) { ++ dev_err(apm->dev, "(%s) PM does not exist\n", __func__); ++ return -EINVAL; ++ } ++ ++ if (lb_type == APM_LOOPBACK_TYPE_NONE) { ++ pm_ops->port_loopback(apm->land_idx, pmLoopbackMac, 0); ++ pm_ops->port_loopback(apm->land_idx, pmLoopbackPhy, 0); ++ } else if (lb_type == APM_LOOPBACK_TYPE_MAC) { ++ pm_ops->port_loopback(apm->land_idx, pmLoopbackMac, 1); ++ } else if (lb_type == APM_LOOPBACK_TYPE_PHY) { ++ pm_ops->port_loopback(apm->land_idx, pmLoopbackPhy, 1); ++ } ++ return 0; ++} ++ ++static int apm_port_mac_address_set(struct apm *apm, u8 *addr) ++{ ++ struct iproc_pm_ops *pm_ops = apm->pm_ops; ++ ++ if (!pm_ops) { ++ dev_err(apm->dev, "(%s) PM does not exist\n", __func__); ++ return -EINVAL; ++ } ++ ++ return pm_ops->port_mac_addr(apm->land_idx, addr); ++} ++ ++static int apm_port_speed(struct apm *apm) ++{ ++ struct iproc_pm_ops *pm_ops = apm->pm_ops; ++ ++ if (!pm_ops) { ++ dev_err(apm->dev, "(%s) PM does not exist\n", __func__); ++ return -EINVAL; ++ } ++ ++ switch (apm->mac_speed) { ++ case SPEED_10: ++ case SPEED_100: ++ case SPEED_1000: ++ return pm_ops->port_speed(apm->land_idx, apm->mac_speed); ++ default: ++ dev_err(apm->dev, "Unsupported speed: %d\n", apm->mac_speed); ++ } ++ ++ return -EINVAL; ++} ++ ++static int apm_port_enable(struct apm *apm, int enable) ++{ ++ struct iproc_pm_ops *pm_ops = apm->pm_ops; ++ ++ if (!pm_ops) { ++ dev_err(apm->dev, "(%s) PM does not exist\n", __func__); ++ return -EINVAL; ++ } ++ ++ return pm_ops->port_enable(apm->land_idx, enable); ++} ++ ++static int apm_port_stats_clear(struct apm *apm) ++{ ++ struct iproc_pm_ops *pm_ops = apm->pm_ops; ++ ++ if (!pm_ops) { ++ dev_err(apm->dev, "(%s) PM does not exist\n", __func__); ++ return -EINVAL; ++ } ++ ++ return pm_ops->port_stats_clear(apm->land_idx); ++} ++ ++static void apm_chip_init(struct apm *apm) ++{ ++ u32 dev_ctl; ++// u32 cmdcfg; ++ ++ /* 1 interrupt per received frame */ ++ apm_write(apm, APM_INT_RECV_LAZY, 1 << APM_IRL_FC_SHIFT); ++ ++ /* TX QoS mode */ ++ dev_ctl = apm_read(apm, APM_DEV_CTL); ++ if (apm->strict_mode) { ++ dev_ctl |= APM_DC_TSM; ++ } else { ++ dev_ctl &= ~APM_DC_TSM; ++ } ++ apm_write(apm, APM_DEV_CTL, dev_ctl); ++ ++// /* Enable 802.3x tx flow control (honor received PAUSE frames) */ ++// apm_cmdcfg_maskset(apm, ~APM_CMDCFG_RPI, 0, true); ++// ++// /* Activate apm tx & rx */ ++// cmdcfg = apm_read(apm, APM_CMDCFG); ++// cmdcfg |= APM_CMDCFG_TE | APM_CMDCFG_RE; ++// apm_write(apm, APM_CMDCFG, cmdcfg); ++ ++ apm_port_mac_address_set(apm, apm->net_dev->dev_addr); ++ ++ /* Enable the pm port */ ++ apm_port_enable(apm, 1); ++} ++ ++static void apm_chip_reset(struct apm *apm) ++{ ++ int i; ++ ++ if (apm_clk_enabled(apm)) { ++ for (i = 0; i < apm->tx_channel; i++) { ++ apm_dma_tx_reset(apm, &apm->tx_ring[i]); ++ } ++ ++ apm_port_loopback (apm, APM_LOOPBACK_TYPE_NONE); ++ udelay(1); ++ ++ apm_dma_rx_reset(apm, &apm->rx_ring[0]); ++ ++ /* TODO: Clear software multicast filter list */ ++ } ++ ++ /* Disable the pm port */ ++ apm_port_enable(apm, 0); ++ ++ /* Clear the MIB */ ++ apm_port_stats_clear(apm); ++ ++ apm->mac_speed = SPEED_1000; ++ apm->mac_duplex = DUPLEX_FULL; ++ apm_port_speed(apm); ++ ++ if (apm->mii_bus) { ++ apm->mii_bus->reset(apm->mii_bus); ++ } ++ ++ netdev_reset_queue(apm->net_dev); ++} ++ ++ ++static void apm_intrs_on(struct apm *apm) ++{ ++ apm_write(apm, APM_INT_MASK, apm->int_mask); ++} ++ ++static void apm_intrs_off(struct apm *apm) ++{ ++ apm_write(apm, APM_INT_MASK, 0); ++ apm_read(apm, APM_INT_MASK); ++} ++ ++static bool apm_clk_enabled(struct apm *apm) ++{ ++ if ((apm_idm_read(apm, BCMA_IOCTL) & ++ (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC)) != BCMA_IOCTL_CLK) ++ return false; ++ if (apm_idm_read(apm, BCMA_RESET_CTL) & BCMA_RESET_CTL_RESET) ++ return false; ++ return true; ++} ++ ++static void apm_clk_enable(struct apm *apm, u32 flags) ++{ ++ apm_idm_write(apm, BCMA_IOCTL, ++ (BCMA_IOCTL_CLK | BCMA_IOCTL_FGC | flags)); ++ apm_idm_read(apm, BCMA_IOCTL); ++ ++ apm_idm_write(apm, BCMA_RESET_CTL, 0); ++ apm_idm_read(apm, BCMA_RESET_CTL); ++ udelay(1); ++ ++ apm_idm_write(apm, BCMA_IOCTL, (BCMA_IOCTL_CLK | flags)); ++ apm_idm_read(apm, BCMA_IOCTL); ++ udelay(1); ++} ++ ++static irqreturn_t apm_interrupt(int irq, void *dev_id) ++{ ++ struct apm *apm = netdev_priv(dev_id); ++ u32 int_status = apm_read(apm, APM_INT_STATUS); ++ int_status &= apm->int_mask; ++ ++ if (!int_status) ++ return IRQ_NONE; ++ ++ int_status &= ~(APM_IS_TX0 | APM_IS_RX); ++ if (int_status) ++ dev_err(apm->dev, "Unknown IRQs: 0x%08X\n", int_status); ++ ++ /* Disable new interrupts until handling existing ones */ ++ apm_intrs_off(apm); ++ ++ napi_schedule(&apm->napi); ++ ++ return IRQ_HANDLED; ++} ++ ++static int apm_poll(struct napi_struct *napi, int weight) ++{ ++ struct apm *apm = container_of(napi, struct apm, napi); ++ int handled = 0; ++ ++ /* Ack */ ++ apm_write(apm, APM_INT_STATUS, ~0); ++ ++ apm_dma_tx_free(apm, &apm->tx_ring[0]); ++ handled += apm_dma_rx_read(apm, &apm->rx_ring[0], weight); ++ ++ /* Poll again if more events arrived in the meantime */ ++ if (apm_read(apm, APM_INT_STATUS) & (APM_IS_TX0 | APM_IS_RX)) ++ return weight; ++ ++ if (handled < weight) { ++ napi_complete(napi); ++ apm_intrs_on(apm); ++ } ++ ++ return handled; ++} ++ ++/************************************************** ++ * net_device_ops ++ **************************************************/ ++static int apm_open(struct net_device *net_dev) ++{ ++ struct apm *apm = netdev_priv(net_dev); ++ int err = 0; ++ ++ apm_chip_reset(apm); ++ ++ err = apm_dma_init(apm); ++ if (err) ++ return err; ++ ++ /* Specs say about reclaiming rings here, but we do that in DMA init */ ++ apm_chip_init(apm); ++ ++ ++ err = request_irq(apm->irq0, apm_interrupt, IRQF_SHARED, ++ KBUILD_MODNAME, net_dev); ++ if (err < 0) { ++ dev_err(apm->dev, "IRQ 0 request error: %d!\n", err); ++ apm_dma_cleanup(apm); ++ return err; ++ } ++ err = request_irq(apm->irq1, apm_interrupt, IRQF_SHARED, ++ KBUILD_MODNAME, net_dev); ++ if (err < 0) { ++ dev_err(apm->dev, "IRQ 1 request error: %d!\n", err); ++ apm_dma_cleanup(apm); ++ return err; ++ } ++ err = request_irq(apm->irq2, apm_interrupt, IRQF_SHARED, ++ KBUILD_MODNAME, net_dev); ++ if (err < 0) { ++ dev_err(apm->dev, "IRQ 2 request error: %d!\n", err); ++ apm_dma_cleanup(apm); ++ return err; ++ } ++ napi_enable(&apm->napi); ++ ++ phy_start(net_dev->phydev); ++ ++ netif_start_queue(net_dev); ++ ++ apm_intrs_on(apm); ++ ++ return 0; ++} ++ ++static int apm_stop(struct net_device *net_dev) ++{ ++ struct apm *apm = netdev_priv(net_dev); ++ ++ netif_carrier_off(net_dev); ++ ++ phy_stop(net_dev->phydev); ++ ++ napi_disable(&apm->napi); ++ apm_intrs_off(apm); ++ ++ free_irq(apm->irq0, net_dev); ++ free_irq(apm->irq1, net_dev); ++ free_irq(apm->irq2, net_dev); ++ ++ apm_chip_reset(apm); ++ apm_dma_cleanup(apm); ++ ++ return 0; ++} ++ ++static netdev_tx_t apm_start_xmit(struct sk_buff *skb, ++ struct net_device *net_dev) ++{ ++ struct apm *apm = netdev_priv(net_dev); ++ struct apm_dma_ring *tx_ring; ++ u32 channel; ++ ++ /* Remap the priority to 8 priorities first and transmit the packet ++ * to corresponding tx channel. ++ */ ++ channel = (skb->priority % 8) / (8 / apm->tx_channel); ++ channel = 0; // FIXME, GH2 doesn't support multiple channel ++ ++ tx_ring = &apm->tx_ring[channel]; ++ return apm_dma_tx_add(apm, tx_ring, skb); ++} ++ ++static int apm_set_mac_address(struct net_device *net_dev, void *addr) ++{ ++ struct apm *apm = netdev_priv(net_dev); ++ int ret; ++ ++ ret = eth_prepare_mac_addr_change(net_dev, addr); ++ if (ret < 0) ++ return ret; ++ apm_port_mac_address_set(apm, (u8 *)addr); ++ eth_commit_mac_addr_change(net_dev, addr); ++ ++ return 0; ++} ++ ++static int apm_ioctl(struct net_device *net_dev, struct ifreq *ifr, int cmd) ++{ ++ if (!netif_running(net_dev)) ++ return -EINVAL; ++ ++ return phy_mii_ioctl(net_dev->phydev, ifr, cmd); ++} ++ ++static const struct net_device_ops apm_netdev_ops = { ++ .ndo_open = apm_open, ++ .ndo_stop = apm_stop, ++ .ndo_start_xmit = apm_start_xmit, ++// .ndo_set_rx_mode = apm_set_rx_mode, ++ .ndo_set_mac_address = apm_set_mac_address, ++ .ndo_validate_addr = eth_validate_addr, ++ .ndo_do_ioctl = apm_ioctl, ++}; ++ ++/************************************************** ++ * MII ++ **************************************************/ ++static void apm_adjust_link(struct net_device *net_dev) ++{ ++ struct apm *apm = netdev_priv(net_dev); ++ struct phy_device *phy_dev = net_dev->phydev; ++ bool update = false; ++ ++ if (phy_dev->link) { ++ if (phy_dev->speed != apm->mac_speed) { ++ apm->mac_speed = phy_dev->speed; ++ update = true; ++ } ++ ++ if (phy_dev->duplex != apm->mac_duplex) { ++ apm->mac_duplex = phy_dev->duplex; ++ update = true; ++ } ++ } ++ ++ if (update) { ++ apm_port_speed(apm); ++ phy_print_status(phy_dev); ++ } ++} ++ ++static int apm_enet_probe(struct apm *info) ++{ ++ struct net_device *net_dev; ++ struct apm *apm; ++ struct phy_device *phy_dev; ++ int err; ++ ++ /* Allocation and references */ ++ net_dev = alloc_etherdev(sizeof(*apm)); ++ if (!net_dev) ++ return -ENOMEM; ++ ++ net_dev->netdev_ops = &apm_netdev_ops; ++ ++ apm = netdev_priv(net_dev); ++ memcpy(apm, info, sizeof(*apm)); ++ apm->net_dev = net_dev; ++ net_dev->irq = apm->irq0; /* irq1, irq2 ?? */ ++ SET_NETDEV_DEV(net_dev, apm->dev); ++ ++ if (!is_valid_ether_addr(apm->mac_addr)) { ++ dev_err(apm->dev, "Invalid MAC addr: %pM\n", apm->mac_addr); ++ eth_random_addr(apm->mac_addr); ++ dev_warn(apm->dev, "Using random MAC: %pM\n", apm->mac_addr); ++ } ++ ether_addr_copy(net_dev->dev_addr, apm->mac_addr); ++ ++ /* This (reset &) enable is not preset in specs or reference driver but ++ * Broadcom does it in arch PCI code when enabling fake PCI device. ++ */ ++ apm_clk_enable(apm, 0); ++ ++ apm_chip_reset(apm); ++ ++ err = apm_ethtool_init(net_dev); ++ if (err) { ++ dev_err(apm->dev, "Init ethtool failed\n"); ++ goto err_netdev_free; ++ } ++ ++ err = apm_dma_alloc(apm); ++ if (err) { ++ dev_err(apm->dev, "Unable to alloc memory for DMA\n"); ++ goto err_netdev_free; ++ } ++ ++ apm->int_mask = APM_IS_ERRMASK | APM_IS_RX | APM_IS_TX_MASK; ++ ++ netif_napi_add(net_dev, &apm->napi, apm_poll, APM_WEIGHT); ++ ++ /* phy init; serdes init is already done in pm.c */ ++ phy_dev = of_phy_get_and_connect(apm->net_dev, apm->dev->of_node, ++ &apm_adjust_link); ++ if (!phy_dev) { ++ dev_warn(apm->dev, "No phy available in DT"); ++ } ++ ++ net_dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; ++ net_dev->hw_features = net_dev->features; ++ net_dev->vlan_features = net_dev->features; ++ ++ err = register_netdev(apm->net_dev); ++ if (err) { ++ dev_err(apm->dev, "Cannot register net device\n"); ++ goto err_phy_disconnect; ++ } ++ ++ netif_carrier_off(net_dev); ++ ++ return 0; ++ ++err_phy_disconnect: ++ phy_disconnect(net_dev->phydev); ++err_netdev_free: ++ free_netdev(net_dev); ++ ++ return err; ++} ++ ++static void apm_enet_remove(struct apm *apm) ++{ ++ unregister_netdev(apm->net_dev); ++ phy_disconnect(apm->net_dev->phydev); ++ netif_napi_del(&apm->napi); ++ apm_dma_free(apm); ++ free_netdev(apm->net_dev); ++} ++ ++/************************************************** ++ * Platform related code ++ **************************************************/ ++static int apm_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ struct apm *apm; ++ struct resource *regs; ++ const u8 *mac_addr; ++ const char *pm_type; ++ u32 value; ++ ++ apm = devm_kzalloc(&pdev->dev, sizeof(*apm), GFP_KERNEL); ++ if (!apm) { ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(pdev, apm); ++ ++ /* Set the features */ ++ apm->feature_flags |= APM_FEAT_TX_MASK_SETUP; ++ apm->feature_flags |= APM_FEAT_RX_MASK_SETUP; ++ ++ apm->dev = &pdev->dev; ++ apm->dma_dev = &pdev->dev; ++ ++ mac_addr = of_get_mac_address(np); ++ if (mac_addr) ++ ether_addr_copy(apm->mac_addr, mac_addr); ++ else ++ dev_warn(&pdev->dev, "MAC address not present in device tree\n"); ++ ++ apm->irq0 = platform_get_irq(pdev, 0); ++ if (apm->irq0 < 0) { ++ dev_err(&pdev->dev, "Unable to obtain IRQ 0\n"); ++ return apm->irq0; ++ } ++ apm->irq1 = platform_get_irq(pdev, 1); ++ if (apm->irq1 < 0) { ++ dev_err(&pdev->dev, "Unable to obtain IRQ 1\n"); ++ return apm->irq1; ++ } ++ apm->irq2 = platform_get_irq(pdev, 2); ++ if (apm->irq2 < 0) { ++ dev_err(&pdev->dev, "Unable to obtain IRQ 2\n"); ++ return apm->irq2; ++ } ++ ++ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apm_base"); ++ if (!regs) { ++ dev_err(&pdev->dev, "Unable to obtain base resource\n"); ++ return -EINVAL; ++ } ++ ++ apm->plat.base = devm_ioremap_resource(&pdev->dev, regs); ++ if (IS_ERR(apm->plat.base)) ++ return PTR_ERR(apm->plat.base); ++ ++ regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, "idm_base"); ++ if (!regs) { ++ dev_err(&pdev->dev, "Unable to obtain idm resource\n"); ++ return -EINVAL; ++ } ++ ++ apm->plat.idm_base = devm_ioremap_resource(&pdev->dev, regs); ++ if (IS_ERR(apm->plat.idm_base)) { ++ return PTR_ERR(apm->plat.idm_base); ++ } ++ ++ /* Get TX queue number and QoS mode from DTS file */ ++ if (of_property_read_u32(np, "tx-channels", &value)) { ++ /* Set the default TX channel number */ ++ apm->tx_channel = 1; ++ } else { ++ apm->tx_channel = value; ++ if (value == 0) { ++ apm->tx_channel = 1; ++ } else if (value > APM_MAX_TX_RINGS) { ++ apm->tx_channel = APM_MAX_TX_RINGS; ++ } ++ } ++ ++ if (of_property_read_u32(np, "strict-mode", &value)) { ++ /* Set the default strict mode */ ++ apm->strict_mode = true; ++ } else { ++ apm->strict_mode = true; ++ if (value == 0) { ++ apm->strict_mode = false; ++ } ++ } ++ ++ /* Get lane index in PM */ ++ if (of_property_read_u32(np, "land-idx", &value)) { ++ dev_err(&pdev->dev, "Unable to get the PM land index\n"); ++ return -EINVAL; ++ } ++ apm->land_idx = value; ++ ++ /* Get the PM type */ ++ if (of_property_read_string(np, "pm-type", &pm_type)) { ++ dev_err(&pdev->dev, "Unable to get the PM type\n"); ++ return -EINVAL; ++ } ++ ++ if (!strcmp(pm_type, "pm4x10")) { ++ //pm4x10_pm_init(apm->pm_ops); ++ apm->pm_ops = kmalloc(sizeof(struct iproc_pm_ops), GFP_KERNEL); ++ apm->pm_ops->port_enable= pm4x10_pm_xlport_port_config; ++ apm->pm_ops->port_speed = pm4x10_xlport_speed_set; ++ apm->pm_ops->port_loopback = pm4x10_xlport_loopback_set; ++ apm->pm_ops->port_mac_addr = pm4x10_xlport_mac_addr_set; ++ apm->pm_ops->port_stats = pm4x10_xlport_stats_get; ++ apm->pm_ops->port_stats_clear = pm4x10_xlport_mib_reset; ++ pm4x10_pm_init(apm->pm_ops, apm->land_idx); ++ ++ } else { ++ dev_err(&pdev->dev, "Unknown the PM type - %s\n", pm_type); ++ return -EINVAL; ++ } ++ ++ return apm_enet_probe(apm); ++} ++ ++static int apm_remove(struct platform_device *pdev) ++{ ++ struct apm *apm = platform_get_drvdata(pdev); ++ ++ //pm4x10_pm_deinit(apm->pm_ops); ++ kfree(apm->pm_ops); ++ apm->pm_ops = NULL; ++ pm4x10_pm_deinit(apm->pm_ops); ++ apm_enet_remove(apm); ++ ++ return 0; ++} ++ ++static const struct of_device_id apm_of_enet_match[] = { ++ {.compatible = "brcm,xgs-iproc-apm",}, ++ {.compatible = "brcm,xgs-iproc-apm,hx5",}, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, apm_of_enet_match); ++ ++static struct platform_driver apm_enet_driver = { ++ .driver = { ++ .name = "apm-enet", ++ .of_match_table = apm_of_enet_match, ++ }, ++ .probe = apm_probe, ++ .remove = apm_remove, ++}; ++ ++module_platform_driver(apm_enet_driver); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/apm.h b/drivers/net/ethernet/broadcom/apm.h +--- a/drivers/net/ethernet/broadcom/apm.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/apm.h 2018-05-30 15:50:51.028753148 +0800 +@@ -0,0 +1,617 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++#ifndef _APM_H ++#define _APM_H ++ ++#include ++ ++#define APM_DEV_CTL 0x000 ++//#define APM_DC_TSM 0x00000002 ++#define APM_DC_TSM 0x00000001 ++#define APM_DC_ROCS 0x00000002 ++#define APM_DC_CFCO 0x00000004 ++//#define APM_DC_MROR 0x00000010 ++//#define APM_DC_RLSS   0x00000008 ++#define APM_DC_FCM_MASK 0x00000060 ++#define APM_DC_FCM_SHIFT 5 ++//#define APM_DC_NAE 0x00000080 ++//#define APM_DC_TF 0x00000100 ++//#define APM_DC_RDS_MASK 0x00030000 ++//#define APM_DC_RDS_SHIFT 16 ++//#define APM_DC_TDS_MASK 0x000c0000 ++//#define APM_DC_TDS_SHIFT 18 ++ ++#define APM_DEV_STATUS 0x004 /* Configuration of the interface */ ++#define APM_DS_RBF 0x00000001 ++#define APM_DS_RDF 0x00000002 ++#define APM_DS_RIF 0x00000004 ++//#define APM_DS_TBF 0x00000008 ++#define APM_DS_TDF 0x00000010 ++//#define APM_DS_TIF 0x00000020 ++#define APM_DS_PO 0x00000040 ++//#define APM_DS_MM_MASK 0x00000300 /* Mode of the interface */ ++//#define APM_DS_MM_SHIFT 8 ++#define APM_DS_RQS_MASK 0x000f0000 ++#define APM_DS_RQS_SHIFT 16 ++#define APM_DS_TQS_MASK 0x00f00000 ++#define APM_DS_TQS_SHIFT 20 ++#define APM_DS_TOC_MASK 0x3f000000 ++#define APM_DS_TOC_SHIFT 24 ++ ++//#define APM_BIST_STATUS 0x00c ++ ++#define APM_DATA_SWAP_CTL 0x010 ++#define APM_DSC_TBSWD 0x00000001 ++#define APM_DSC_TDS 0x00000002 ++#define APM_DSC_RBSWD 0x00000004 ++#define APM_DSC_RDS 0x00000008 ++ ++#define APM_ERROR_STATIS 0x014 ++#define APM_ES_DESC_READ_ERR_TC0 0x00000001 ++#define APM_ES_DESC_READ_ERR_TC1 0x00000002 ++#define APM_ES_DESC_READ_ERR_TC2 0x00000004 ++#define APM_ES_DESC_READ_ERR_TC3 0x00000008 ++#define APM_ES_DESC_READ_ERR_RC0 0x00000010 ++#define APM_ES_DATA_ERR_TC0 0x00000100 ++#define APM_ES_DATA_ERR_TC1 0x00000200 ++#define APM_ES_DATA_ERR_TC2 0x00000400 ++#define APM_ES_DATA_ERR_TC3 0x00000800 ++#define APM_ES_DATA_ERR_RC0 0x00001000 ++#define APM_ES_DESC_PROT_ERR_TC0 0x00010000 ++#define APM_ES_DESC_PROT_ERR_TC1 0x00020000 ++#define APM_ES_DESC_PROT_ERR_TC2 0x00040000 ++#define APM_ES_DESC_PROT_ERR_TC3 0x00080000 ++#define APM_ES_DESC_PROT_ERR_RC0 0x00100000 ++ ++#define APM_INT_STATUS 0x020 /* Interrupt status */ ++//#define APM_IS_MRO 0x00000001 ++//#define APM_IS_MTO 0x00000002 ++//#define APM_IS_TFD 0x00000004 ++//#define APM_IS_LS 0x00000008 ++//#define APM_IS_MDIO 0x00000010 ++//#define APM_IS_MR 0x00000020 ++//#define APM_IS_MT 0x00000040 ++#define APM_IS_TO 0x00000080 /* Timeout */ ++#define APM_IS_SL_SC 0x00000100 /* Software link status change */ ++#define APM_IS_PM_LS 0x00000200 /* Port Macro link status */ ++#define APM_IS_DESC_ERR 0x00000400 /* Descriptor error */ ++#define APM_IS_DATA_ERR 0x00000800 /* Data error */ ++#define APM_IS_DESC_PROT_ERR 0x00001000 /* Descriptor protocol error */ ++#define APM_IS_RX_DESC_UNDERF 0x00002000 /* Receive descriptor underflow */ ++#define APM_IS_RX_F_OVERF 0x00004000 /* Receive FIFO overflow */ ++//#define APM_IS_TX_F_UNDERF 0x00008000 /* Transmit FIFO underflow */ ++#define APM_IS_RX 0x00010000 /* Interrupt for RX queue 0 */ ++#define APM_IS_RX_INFO_ECC_CORR 0x00100000 /* RXQ info memory corrected error */ ++#define APM_IS_RX_INFO_ECC_UNCORR 0x00200000 /* RXQ info memory uncorrected error */ ++#define APM_IS_AXI_SHARED_ECC_CORR 0x00400000 /* AXI share memory corrected error */ ++#define APM_IS_AXI_SHARED_ECC_UNCORR 0x00800000 /* AXI share memory uncorrected error */ ++#define APM_IS_TX0 0x01000000 /* Interrupt for TX queue 0 */ ++#define APM_IS_TX1 0x02000000 /* Interrupt for TX queue 1 */ ++#define APM_IS_TX2 0x04000000 /* Interrupt for TX queue 2 */ ++#define APM_IS_TX3 0x08000000 /* Interrupt for TX queue 3 */ ++#define APM_IS_ECC_MASK 0x00f00000 ++#define APM_IS_TX_MASK 0x0f000000 ++//#define APM_IS_INTMASK 0x0f01fcff ++#define APM_IS_INTMASK 0x0ff17f80 ++//#define APM_IS_ERRMASK 0x0000fc00 ++#define APM_IS_ERRMASK 0x00007c00 ++ ++#define APM_INT_MASK 0x024 /* Interrupt mask */ ++#define APM_GP_TIMER 0x028 ++ ++#define APM_TXQ_COMMON_CTL 0x040 ++#define APM_TCCTL_FLUSH_CREDIT 0x00000001 ++#define APM_TCCTL_FUNC_MODE_MASK 0x00000006 ++#define APM_TCCTL_FUNC_MODE_SHIFT 1 ++#define APM_FUNC_MODE_SINGLE 0 ++#define APM_FUNC_MODE_DUAL 1 ++#define APM_FUNC_MODE_QUAD 2 ++#define APM_TCCTL_WR_FUNC_MODE 0x00000008 ++#define APM_TCCTL_INTERRUPT_SEL 0x00000010 ++ ++#define APM_TXQ_DATA_TXREQ_CTL0 0x044 ++#define APM_TXQ_DATA_TXREQ_CTL1 0x048 ++#define APM_TXQ_SHARED_BUF_DEPTH0 0x050 ++#define APM_TXQ_SHARED_BUF_DEPTH1 0x054 ++#define APM_RXQ_BUF_DEPTH 0x058 ++#define APM_DMA_TOTAL_OUTSTD_TRANS_LIMIT 0x080 ++#define APM_DMA_RD_PER_ID_OUTSTD_TRANS_LIMIT 0x084 ++#define APM_PKT_DMA_RD_AXI_MAP_CTRL 0x088 ++#define APM_RX_PKT_DMA_WR_AXI_MAP_CTRL 0x08c ++#define APM_TX_PKT_DMA_RD_ARB_CTRL 0x090 ++#define APM_RX_PKT_DMA_RD_ARB_CTRL 0x094 ++#define APM_RX_PKT_DMA_WR_ARB_CTRL 0x098 ++#define APM_RCBUF_MAX_FLIST_ENTRIES 0x09c ++#define APM_STAT_COUNTER_CTL 0x0a0 ++#define APM_STAT_RXQ_TRANSFERRED_PKT_CNT 0x0b0 ++#define APM_STAT_RXQ_COMPLETE_PKT_DROP_CNT 0x0b4 ++#define APM_STAT_RXQ_PARTIAL_PKT_DROP_CNT 0x0b8 ++#define APM_STAT_RXQ_TRUNCATED_PKT_CNT 0x0bc ++#define APM_STAT_TXQ_CH0_GOOD_PKT_CNT 0x0c0 ++#define APM_STAT_TXQ_CH0_ERR_PKT_CNT 0x0c4 ++#define APM_STAT_TXQ_CH1_GOOD_PKT_CNT 0x0c8 ++#define APM_STAT_TXQ_CH1_ERR_PKT_CNT 0x0cc ++#define APM_STAT_TXQ_CH2_GOOD_PKT_CNT 0x0d0 ++#define APM_STAT_TXQ_CH2_ERR_PKT_CNT 0x0d4 ++#define APM_STAT_TXQ_CH3_GOOD_PKT_CNT 0x0d8 ++#define APM_STAT_TXQ_CH3_ERR_PKT_CNT 0x0dc ++#define APM_DBG_TXQ_CH0_STM 0x0e0 ++#define APM_DBG_TXQ_CH1_STM 0x0e4 ++#define APM_DBG_TXQ_CH2_STM 0x0e8 ++#define APM_DBG_TXQ_CH3_STM 0x0ec ++#define APM_DBG_RXQ_STM 0x0f0 ++#define APM_DBG_DMA_HOSTRD_STM 0x0f8 ++#define APM_DBG_DMA_HOSTWR_STM 0x0fc ++ ++#define APM_INT_RECV_LAZY 0x100 ++#define APM_IRL_TO_MASK 0x00ffffff ++#define APM_IRL_TO_SHIFT 0 ++#define APM_IRL_FC_MASK 0xff000000 ++#define APM_IRL_FC_SHIFT 24 /* Shift the number of interrupts triggered per received frame */ ++#define APM_FLOW_CTL_THRESH 0x104 /* Flow control thresholds */ ++#define APM_WRRTHRESH 0x108 ++//#define APM_GMAC_IDLE_CNT_THRESH 0x10c ++//#define APM_PHY_ACCESS 0x180 /* PHY access address */ ++//#define APM_PA_DATA_MASK 0x0000ffff ++//#define APM_PA_ADDR_MASK 0x001f0000 ++//#define APM_PA_ADDR_SHIFT 16 ++//#define APM_PA_REG_MASK 0x1f000000 ++//#define APM_PA_REG_SHIFT 24 ++//#define APM_PA_WRITE 0x20000000 ++//#define APM_PA_START 0x40000000 ++//#define APM_PHY_CNTL 0x188 /* PHY control address */ ++//#define APM_PC_EPA_MASK 0x0000001f ++//#define APM_PC_MCT_MASK 0x007f0000 ++//#define APM_PC_MCT_SHIFT 16 ++//#define APM_PC_MTE 0x00800000 ++//#define APM_TXQ_CTL 0x18c ++//#define APM_TXQ_CTL_DBT_MASK 0x00000fff ++//#define APM_TXQ_CTL_DBT_SHIFT 0 ++#define APM_RXQ_CTL 0x190 ++//#define APM_RXQ_CTL_DBT_MASK 0x00000fff ++#define APM_RXQ_CTL_DBT_MASK 0x00000f7ff ++#define APM_RXQ_CTL_DBT_SHIFT 0 ++//#define APM_RXQ_CTL_PTE 0x00001000 ++//#define APM_RXQ_CTL_MDP_MASK 0x3f000000 ++//#define APM_RXQ_CTL_MDP_SHIFT 24 ++#define APM_RXQ_CTL_RPT_EN 0x40000000 ++ ++//#define APM_GPIO_SELECT 0x194 ++//#define APM_GPIO_OUTPUT_EN 0x198 ++ ++///* For 0x1e0 see BCMA_CLKCTLST. Below are APM specific bits */ ++//#define APM_BCMA_CLKCTLST_MISC_PLL_REQ 0x00000100 ++//#define APM_BCMA_CLKCTLST_MISC_PLL_ST 0x01000000 ++ ++//#define APM_HW_WAR 0x1e4 ++//#define APM_PWR_CTL 0x1e8 ++ ++#define APM_MEM_ECC_CTL 0x1F0 ++#define APM_MEM_ECC_STAT 0x1F4 ++ ++#define APM_DMA_BASE0 0x200 /* Tx and Rx controller */ ++#define APM_DMA_BASE1 0x240 /* Tx controller only */ ++#define APM_DMA_BASE2 0x280 /* Tx controller only */ ++#define APM_DMA_BASE3 0x2C0 /* Tx controller only */ ++ ++//#define APM_TX_GOOD_OCTETS 0x300 ++//#define APM_TX_GOOD_OCTETS_HIGH 0x304 ++//#define APM_TX_GOOD_PKTS 0x308 ++//#define APM_TX_OCTETS 0x30c ++//#define APM_TX_OCTETS_HIGH 0x310 ++//#define APM_TX_PKTS 0x314 ++//#define APM_TX_BROADCAST_PKTS 0x318 ++//#define APM_TX_MULTICAST_PKTS 0x31c ++//#define APM_TX_LEN_64 0x320 ++//#define APM_TX_LEN_65_TO_127 0x324 ++//#define APM_TX_LEN_128_TO_255 0x328 ++//#define APM_TX_LEN_256_TO_511 0x32c ++//#define APM_TX_LEN_512_TO_1023 0x330 ++//#define APM_TX_LEN_1024_TO_1522 0x334 ++//#define APM_TX_LEN_1523_TO_2047 0x338 ++//#define APM_TX_LEN_2048_TO_4095 0x33c ++//#define APM_TX_LEN_4096_TO_8191 0x340 ++//#define APM_TX_LEN_8192_TO_MAX 0x344 ++//#define APM_TX_JABBER_PKTS 0x348 /* Error */ ++//#define APM_TX_OVERSIZE_PKTS 0x34c /* Error */ ++//#define APM_TX_FRAGMENT_PKTS 0x350 ++//#define APM_TX_UNDERRUNS 0x354 /* Error */ ++//#define APM_TX_TOTAL_COLS 0x358 ++//#define APM_TX_SINGLE_COLS 0x35c ++//#define APM_TX_MULTIPLE_COLS 0x360 ++//#define APM_TX_EXCESSIVE_COLS 0x364 /* Error */ ++//#define APM_TX_LATE_COLS 0x368 /* Error */ ++//#define APM_TX_DEFERED 0x36c ++//#define APM_TX_CARRIER_LOST 0x370 ++//#define APM_TX_PAUSE_PKTS 0x374 ++//#define APM_TX_UNI_PKTS 0x378 ++//#define APM_TX_Q0_PKTS 0x37c ++//#define APM_TX_Q0_OCTETS 0x380 ++//#define APM_TX_Q0_OCTETS_HIGH 0x384 ++//#define APM_TX_Q1_PKTS 0x388 ++//#define APM_TX_Q1_OCTETS 0x38c ++//#define APM_TX_Q1_OCTETS_HIGH 0x390 ++//#define APM_TX_Q2_PKTS 0x394 ++//#define APM_TX_Q2_OCTETS 0x398 ++//#define APM_TX_Q2_OCTETS_HIGH 0x39c ++//#define APM_TX_Q3_PKTS 0x3a0 ++//#define APM_TX_Q3_OCTETS 0x3a4 ++//#define APM_TX_Q3_OCTETS_HIGH 0x3a8 ++//#define APM_RX_GOOD_OCTETS 0x3b0 ++//#define APM_RX_GOOD_OCTETS_HIGH 0x3b4 ++//#define APM_RX_GOOD_PKTS 0x3b8 ++//#define APM_RX_OCTETS 0x3bc ++//#define APM_RX_OCTETS_HIGH 0x3c0 ++//#define APM_RX_PKTS 0x3c4 ++//#define APM_RX_BROADCAST_PKTS 0x3c8 ++//#define APM_RX_MULTICAST_PKTS 0x3cc ++//#define APM_RX_LEN_64 0x3d0 ++//#define APM_RX_LEN_65_TO_127 0x3d4 ++//#define APM_RX_LEN_128_TO_255 0x3d8 ++//#define APM_RX_LEN_256_TO_511 0x3dc ++//#define APM_RX_LEN_512_TO_1023 0x3e0 ++//#define APM_RX_LEN_1024_TO_1522 0x3e4 ++//#define APM_RX_LEN_1523_TO_2047 0x3e8 ++//#define APM_RX_LEN_2048_TO_4095 0x3ec ++//#define APM_RX_LEN_4096_TO_8191 0x3f0 ++//#define APM_RX_LEN_8192_TO_MAX 0x3f4 ++//#define APM_RX_JABBER_PKTS 0x3f8 /* Error */ ++//#define APM_RX_OVERSIZE_PKTS 0x3fc /* Error */ ++//#define APM_RX_FRAGMENT_PKTS 0x400 ++//#define APM_RX_MISSED_PKTS 0x404 /* Error */ ++//#define APM_RX_CRC_ALIGN_ERRS 0x408 /* Error */ ++//#define APM_RX_UNDERSIZE 0x40c /* Error */ ++//#define APM_RX_CRC_ERRS 0x410 /* Error */ ++//#define APM_RX_ALIGN_ERRS 0x414 /* Error */ ++//#define APM_RX_SYMBOL_ERRS 0x418 /* Error */ ++//#define APM_RX_PAUSE_PKTS 0x41c ++//#define APM_RX_NONPAUSE_PKTS 0x420 ++//#define APM_RX_SACHANGES 0x424 ++//#define APM_RX_UNI_PKTS 0x428 ++//#define APM_UNIMAC_VERSION 0x800 ++//#define APM_HDBKP_CTL 0x804 ++//#define APM_CMDCFG 0x808 /* Configuration */ ++//#define APM_CMDCFG_TE 0x00000001 /* Set to activate TX */ ++//#define APM_CMDCFG_RE 0x00000002 /* Set to activate RX */ ++//#define APM_CMDCFG_ES_MASK 0x0000000c /* Ethernet speed see gmac_speed */ ++//#define APM_CMDCFG_ES_10 0x00000000 ++//#define APM_CMDCFG_ES_100 0x00000004 ++//#define APM_CMDCFG_ES_1000 0x00000008 ++//#define APM_CMDCFG_ES_2500 0x0000000C ++//#define APM_CMDCFG_PROM 0x00000010 /* Set to activate promiscuous mode */ ++//#define APM_CMDCFG_PAD_EN 0x00000020 ++//#define APM_CMDCFG_CF 0x00000040 ++//#define APM_CMDCFG_PF 0x00000080 ++//#define APM_CMDCFG_RPI 0x00000100 /* Unset to enable 802.3x tx flow control */ ++//#define APM_CMDCFG_TAI 0x00000200 ++//#define APM_CMDCFG_HD 0x00000400 /* Set if in half duplex mode */ ++//#define APM_CMDCFG_HD_SHIFT 10 ++//#define APM_CMDCFG_SR_REV0 0x00000800 /* Set to reset mode, for core rev 0-3 */ ++//#define APM_CMDCFG_SR_REV4 0x00002000 /* Set to reset mode, for core rev >= 4 */ ++//#define APM_CMDCFG_ML 0x00008000 /* Set to activate mac loopback mode */ ++//#define APM_CMDCFG_AE 0x00400000 ++//#define APM_CMDCFG_CFE 0x00800000 ++//#define APM_CMDCFG_NLC 0x01000000 ++//#define APM_CMDCFG_RL 0x02000000 ++//#define APM_CMDCFG_RED 0x04000000 ++//#define APM_CMDCFG_PE 0x08000000 ++//#define APM_CMDCFG_TPI 0x10000000 ++//#define APM_CMDCFG_AT 0x20000000 ++//#define APM_MACADDR_HIGH 0x80c /* High 4 octets of own mac address */ ++//#define APM_MACADDR_LOW 0x810 /* Low 2 octets of own mac address */ ++//#define APM_RXMAX_LENGTH 0x814 /* Max receive frame length with vlan tag */ ++//#define APM_PAUSEQUANTA 0x818 ++//#define APM_MAC_MODE 0x844 ++//#define APM_OUTERTAG 0x848 ++//#define APM_INNERTAG 0x84c ++//#define APM_TXIPG 0x85c ++//#define APM_PAUSE_CTL 0xb30 ++//#define APM_TX_FLUSH 0xb34 ++//#define APM_RX_STATUS 0xb38 ++//#define APM_TX_STATUS 0xb3c ++// ++///* BCMA GMAC core specific IO Control (BCMA_IOCTL) flags */ ++//#define APM_BCMA_IOCTL_SW_CLKEN 0x00000004 /* PHY Clock Enable */ ++//#define APM_BCMA_IOCTL_SW_RESET 0x00000008 /* PHY Reset */ ++// ++///* BCMA GMAC core specific IO status (BCMA_IOST) flags */ ++//#define APM_BCMA_IOST_ATTACHED 0x00000800 ++// ++//#define APM_NUM_MIB_TX_REGS (((APM_TX_Q3_OCTETS_HIGH - APM_TX_GOOD_OCTETS) / 4) + 1) ++//#define APM_NUM_MIB_RX_REGS (((APM_RX_UNI_PKTS - APM_RX_GOOD_OCTETS) / 4) + 1) ++ ++#define APM_DMA_TX_CTL 0x00 ++#define APM_DMA_TX_ENABLE 0x00000001 ++#define APM_DMA_TX_SUSPEND 0x00000002 ++//#define APM_DMA_TX_LOOPBACK 0x00000004 ++//#define APM_DMA_TX_FLUSH 0x00000010 ++//#define APM_DMA_TX_MR_MASK 0x000000C0 /* Multiple outstanding reads */ ++//#define APM_DMA_TX_MR_SHIFT 6 ++//#define APM_DMA_TX_MR_1 0 ++//#define APM_DMA_TX_MR_2 1 ++//#define APM_DMA_TX_PARITY_DISABLE 0x00000800 ++#define APM_DMA_TX_SBAI 0x00002000 ++//#define APM_DMA_TX_ADDREXT_MASK 0x00030000 ++//#define APM_DMA_TX_ADDREXT_SHIFT 16 ++#define APM_DMA_TX_BL_MASK 0x001C0000 /* BurstLen bits */ ++#define APM_DMA_TX_BL_SHIFT 18 ++#define APM_DMA_TX_BL_16 0 ++#define APM_DMA_TX_BL_32 1 ++#define APM_DMA_TX_BL_64 2 ++#define APM_DMA_TX_BL_128 3 ++//#define APM_DMA_TX_BL_256 4 ++//#define APM_DMA_TX_BL_512 5 ++//#define APM_DMA_TX_BL_1024 6 ++#define APM_DMA_TX_PC_MASK 0x00E00000 /* Prefetch control */ ++#define APM_DMA_TX_PC_SHIFT 21 ++#define APM_DMA_TX_PC_0 0 ++#define APM_DMA_TX_PC_4 1 ++#define APM_DMA_TX_PC_8 2 ++#define APM_DMA_TX_PC_16 3 ++#define APM_DMA_TX_PT_MASK 0x03000000 /* Prefetch threshold */ ++#define APM_DMA_TX_PT_SHIFT 24 ++#define APM_DMA_TX_PT_1 0 ++#define APM_DMA_TX_PT_2 1 ++#define APM_DMA_TX_PT_4 2 ++#define APM_DMA_TX_PT_8 3 ++ ++#define APM_DMA_TX_INDEX 0x04 ++#define APM_DMA_TX_RINGLO 0x08 ++#define APM_DMA_TX_RINGHI 0x0C ++#define APM_DMA_TX_STATUS 0x10 ++#define APM_DMA_TX_STATDPTR 0x00001FFF ++#define APM_DMA_TX_STAT 0xF0000000 ++#define APM_DMA_TX_STAT_DISABLED 0x00000000 ++#define APM_DMA_TX_STAT_ACTIVE 0x10000000 ++#define APM_DMA_TX_STAT_IDLEWAIT 0x20000000 ++#define APM_DMA_TX_STAT_STOPPED 0x30000000 ++#define APM_DMA_TX_STAT_SUSP 0x40000000 ++#define APM_DMA_TX_ERROR 0x14 ++#define APM_DMA_TX_ERRDPTR 0x0001FFFF ++#define APM_DMA_TX_ERR 0xF0000000 ++#define APM_DMA_TX_ERR_NOERR 0x00000000 ++#define APM_DMA_TX_ERR_PROT 0x10000000 ++//#define APM_DMA_TX_ERR_UNDERRUN 0x20000000 ++#define APM_DMA_TX_ERR_TRANSFER 0x30000000 ++#define APM_DMA_TX_ERR_DESCREAD 0x40000000 ++#define APM_DMA_TX_ERR_CORE 0x50000000 ++ ++#define APM_DMA_RX_CTL 0x20 ++#define APM_DMA_RX_ENABLE 0x00000001 ++#define APM_DMA_RX_FRAME_OFFSET_MASK 0x000000FE ++#define APM_DMA_RX_FRAME_OFFSET_SHIFT 1 ++//#define APM_DMA_RX_DIRECT_FIFO 0x00000100 ++#define APM_DMA_RX_OVERFLOW_CONT 0x00000400 ++//#define APM_DMA_RX_PARITY_DISABLE 0x00000800 ++//#define APM_DMA_RX_MR_MASK 0x000000C0 /* Multiple outstanding reads */ ++//#define APM_DMA_RX_MR_SHIFT 6 ++//#define APM_DMA_TX_MR_1 0 ++//#define APM_DMA_TX_MR_2 1 ++//#define APM_DMA_RX_ADDREXT_MASK 0x00030000 ++//#define APM_DMA_RX_ADDREXT_SHIFT 16 ++#define APM_DMA_RX_BL_MASK 0x001C0000 /* BurstLen bits */ ++#define APM_DMA_RX_BL_SHIFT 18 ++#define APM_DMA_RX_BL_16 0 ++#define APM_DMA_RX_BL_32 1 ++#define APM_DMA_RX_BL_64 2 ++#define APM_DMA_RX_BL_128 3 ++//#define APM_DMA_RX_BL_256 4 ++//#define APM_DMA_RX_BL_512 5 ++//#define APM_DMA_RX_BL_1024 6 ++#define APM_DMA_RX_PC_MASK 0x00E00000 /* Prefetch control */ ++#define APM_DMA_RX_PC_SHIFT 21 ++#define APM_DMA_RX_PC_0 0 ++#define APM_DMA_RX_PC_4 1 ++#define APM_DMA_RX_PC_8 2 ++#define APM_DMA_RX_PC_16 3 ++#define APM_DMA_RX_PT_MASK 0x03000000 /* Prefetch threshold */ ++#define APM_DMA_RX_PT_SHIFT 24 ++#define APM_DMA_RX_PT_1 0 ++#define APM_DMA_RX_PT_2 1 ++#define APM_DMA_RX_PT_4 2 ++#define APM_DMA_RX_PT_8 3 ++#define APM_DMA_RX_INDEX 0x24 ++#define APM_DMA_RX_RINGLO 0x28 ++#define APM_DMA_RX_RINGHI 0x2C ++#define APM_DMA_RX_STATUS 0x30 ++#define APM_DMA_RX_STATDPTR 0x00001FFF ++#define APM_DMA_RX_STAT 0xF0000000 ++#define APM_DMA_RX_STAT_DISABLED 0x00000000 ++#define APM_DMA_RX_STAT_ACTIVE 0x10000000 ++#define APM_DMA_RX_STAT_IDLEWAIT 0x20000000 ++#define APM_DMA_RX_STAT_STOPPED 0x30000000 ++//#define APM_DMA_RX_STAT_SUSP 0x40000000 ++#define APM_DMA_RX_ERROR 0x34 ++#define APM_DMA_RX_ERRDPTR 0x0001FFFF ++#define APM_DMA_RX_ERR 0xF0000000 ++#define APM_DMA_RX_ERR_NOERR 0x00000000 ++#define APM_DMA_RX_ERR_PROT 0x10000000 ++#define APM_DMA_RX_ERR_UNDERRUN 0x20000000 ++#define APM_DMA_RX_ERR_TRANSFER 0x30000000 ++#define APM_DMA_RX_ERR_DESCREAD 0x40000000 ++#define APM_DMA_RX_ERR_CORE 0x50000000 ++ ++ ++ ++ ++ ++ ++#define APM_DESC_CTL0_CRC 0x00300000 /* CRC mode */ ++#define APM_DESC_CRC_APPEND 0x00000000 /* CRC append mode */ ++#define APM_DESC_CRC_OVERWRITE 0x00100000 /* CRC overwrite mode */ ++#define APM_DESC_CRC_FORWARD 0x00200000 /* CRC forward mode */ ++#define APM_DESC_CTL0_EOT 0x10000000 /* End of ring */ ++#define APM_DESC_CTL0_IOC 0x20000000 /* IRQ on complete */ ++#define APM_DESC_CTL0_EOF 0x40000000 /* End of frame */ ++#define APM_DESC_CTL0_SOF 0x80000000 /* Start of frame */ ++//#define APM_DESC_CTL1_LEN 0x00001FFF ++#define APM_DESC_CTL1_LEN 0x00007FFF ++ ++//#define APM_PHY_NOREGS BRCM_PSEUDO_PHY_ADDR ++//#define APM_PHY_MASK 0x1F ++ ++#define APM_MAX_TX_RINGS 4 ++#define APM_MAX_RX_RINGS 1 ++#define APM_TX_MAX_DESCS 512 ++#define APM_RX_MAX_DESCS 512 ++ ++#define APM_RX_HEADER_LEN 28 /* Last 24 bytes are unused. Well... */ ++#define APM_RX_FRAME_OFFSET 30 /* There are 2 unused bytes between header and real data */ ++#define APM_RX_BUF_OFFSET (NET_SKB_PAD + NET_IP_ALIGN - APM_RX_FRAME_OFFSET) ++#define APM_RX_MAX_FRAME_SIZE 1536 /* Copied from b44/tg3 */ ++#define APM_RX_BUF_SIZE (APM_RX_FRAME_OFFSET + APM_RX_MAX_FRAME_SIZE) ++#define APM_RX_ALLOC_SIZE (SKB_DATA_ALIGN(APM_RX_BUF_SIZE + APM_RX_BUF_OFFSET) + \ ++ SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) ++ ++//#define APM_BFL_ENETROBO 0x0010 /* has ephy roboswitch spi */ ++//#define APM_BFL_ENETADM 0x0080 /* has ADMtek switch */ ++//#define APM_BFL_ENETVLAN 0x0100 /* can do vlan */ ++ ++//#define APM_CHIPCTL_1_IF_TYPE_MASK 0x00000030 ++//#define APM_CHIPCTL_1_IF_TYPE_RMII 0x00000000 ++//#define APM_CHIPCTL_1_IF_TYPE_MII 0x00000010 ++//#define APM_CHIPCTL_1_IF_TYPE_RGMII 0x00000020 ++//#define APM_CHIPCTL_1_SW_TYPE_MASK 0x000000C0 ++//#define APM_CHIPCTL_1_SW_TYPE_EPHY 0x00000000 ++//#define APM_CHIPCTL_1_SW_TYPE_EPHYMII 0x00000040 ++//#define APM_CHIPCTL_1_SW_TYPE_EPHYRMII 0x00000080 ++//#define APM_CHIPCTL_1_SW_TYPE_RGMII 0x000000C0 ++//#define APM_CHIPCTL_1_RXC_DLL_BYPASS 0x00010000 ++// ++//#define APM_CHIPCTL_4_IF_TYPE_MASK 0x00003000 ++//#define APM_CHIPCTL_4_IF_TYPE_RMII 0x00000000 ++//#define APM_CHIPCTL_4_IF_TYPE_MII 0x00001000 ++//#define APM_CHIPCTL_4_IF_TYPE_RGMII 0x00002000 ++//#define APM_CHIPCTL_4_SW_TYPE_MASK 0x0000C000 ++//#define APM_CHIPCTL_4_SW_TYPE_EPHY 0x00000000 ++//#define APM_CHIPCTL_4_SW_TYPE_EPHYMII 0x00004000 ++//#define APM_CHIPCTL_4_SW_TYPE_EPHYRMII 0x00008000 ++//#define APM_CHIPCTL_4_SW_TYPE_RGMII 0x0000C000 ++// ++//#define APM_CHIPCTL_7_IF_TYPE_MASK 0x000000C0 ++//#define APM_CHIPCTL_7_IF_TYPE_RMII 0x00000000 ++//#define APM_CHIPCTL_7_IF_TYPE_MII 0x00000040 ++//#define APM_CHIPCTL_7_IF_TYPE_RGMII 0x00000080 ++ ++#define APM_WEIGHT 64 ++#define ETHER_MAX_LEN 1518 ++ ++/* Feature flags */ ++#define APM_FEAT_TX_MASK_SETUP BIT(0) ++#define APM_FEAT_RX_MASK_SETUP BIT(1) ++ ++/* Loopback flags */ ++#define APM_LOOPBACK_TYPE_NONE 0 ++#define APM_LOOPBACK_TYPE_MAC 1 ++#define APM_LOOPBACK_TYPE_PHY 2 ++ ++struct apm_slot_info { ++ union { ++ struct sk_buff *skb; ++ void *buf; ++ }; ++ dma_addr_t dma_addr; ++}; ++ ++struct apm_dma_desc { ++ __le32 ctl0; ++ __le32 ctl1; ++ __le32 addr_low; ++ __le32 addr_high; ++} __packed; ++ ++enum apm_dma_ring_type { ++ APM_DMA_RING_TYPE_TX = 0, ++ APM_DMA_RING_TYPE_RX, ++ APM_DMA_RING_TYPE_NUM ++}; ++ ++/** ++ * apm_dma_ring - contains info about DMA ring (either TX or RX one) ++ * @start: index of the first slot containing data ++ * @end: index of a slot that can *not* be read (yet) ++ * ++ * Be really aware of the specific @end meaning. It's an index of a slot *after* ++ * the one containing data that can be read. If @start equals @end the ring is ++ * empty. ++ */ ++struct apm_dma_ring { ++ u32 start; ++ u32 end; ++ ++ int desc_num; ++ struct apm_dma_desc *desc_base; ++ dma_addr_t dma_base; ++ u32 index_base; /* Used for unaligned rings only, otherwise 0 */ ++ u16 mmio_base; ++ bool unaligned; ++ ++ struct apm_slot_info *slots; ++}; ++ ++ ++struct apm_rx_header { ++ __le16 len; ++ __le16 flags; ++ __le16 pad[12]; ++}; ++ ++struct apm { ++ union { ++ struct { ++ void *base; ++ void *idm_base; ++ } plat; ++ }; ++ ++ struct device *dev; ++ struct device *dma_dev; ++ ++ struct iproc_pm_ops *pm_ops; ++ u8 land_idx; ++ ++ u8 mac_addr[ETH_ALEN]; ++ u32 feature_flags; ++ ++ struct net_device *net_dev; ++ struct napi_struct napi; ++ struct mii_bus *mii_bus; ++ ++ /* DMA */ ++ struct apm_dma_desc *desc_buf; ++ dma_addr_t dma_addr; ++ struct apm_slot_info *slot_buf; ++ ++ struct apm_dma_ring tx_ring[APM_MAX_TX_RINGS]; ++ struct apm_dma_ring rx_ring[APM_MAX_RX_RINGS]; ++ ++ /* QoS */ ++ u8 tx_channel; ++ bool strict_mode; ++ ++ /* Int */ ++ int irq0; ++ int irq1; ++ int irq2; ++ u32 int_mask; ++ ++ /* Current MAC state */ ++ int mac_speed; ++ int mac_duplex; ++ ++ u8 phyaddr; ++ bool loopback; ++}; ++ ++extern int apm_ethtool_init(struct net_device *net_dev); ++#endif /* _APM_H */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/apm_ethtool.c b/drivers/net/ethernet/broadcom/apm_ethtool.c +--- a/drivers/net/ethernet/broadcom/apm_ethtool.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/apm_ethtool.c 2018-05-10 11:31:31.729401905 +0800 +@@ -0,0 +1,227 @@ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "pm.h" ++#include "apm.h" ++ ++static const struct { ++ const char name[ETH_GSTRING_LEN]; ++} apm_stat_name[] = { ++ { "rx_frames" }, ++ { "rx_frame_good" }, ++ { "rx_bytes" }, ++ { "rx_frame_64" }, ++ { "rx_frame_127" }, ++ { "rx_frame_255" }, ++ { "rx_frame_511" }, ++ { "rx_frame_1023" }, ++ { "rx_frame_1518" }, ++ { "rx_frame_1522" }, ++ { "rx_frame_jumbo" }, ++ { "rx_frame_unicast" }, ++ { "rx_frame_multicast" }, ++ { "rx_frame_broadcast" }, ++ { "rx_frame_control" }, ++ { "rx_frame_pause" }, ++ { "rx_frame_jabber" }, ++ { "rx_frame_fragment" }, ++ { "rx_frame_vlan" }, ++ { "rx_frame_dvlan" }, ++ { "rx_frame_fcs_error" }, ++ { "rx_frame_unsupport" }, ++ { "rx_frame_wrong_sa" }, ++ { "rx_frame_align_err" }, ++ { "rx_frame_length_err" }, ++ { "rx_frame_oversize" }, ++ { "rx_frame_mtu_err" }, ++ { "rx_frame_truncated_err" }, ++ { "rx_frame_undersize" }, ++ { "tx_frames" }, ++ { "tx_frame_good" }, ++ { "tx_bytes" }, ++ { "tx_frame_64" }, ++ { "tx_frame_127" }, ++ { "tx_frame_255" }, ++ { "tx_frame_511" }, ++ { "tx_frame_1023" }, ++ { "tx_frame_1518" }, ++ { "tx_frame_1522" }, ++ { "tx_frame_jumbo" }, ++ { "tx_frame_unicast" }, ++ { "tx_frame_multicast" }, ++ { "tx_frame_broadcast" }, ++ { "tx_frame_control" }, ++ { "tx_frame_pause" }, ++ { "tx_frame_jabber" }, ++ { "tx_frame_fragment" }, ++ { "tx_frame_vlan" }, ++ { "tx_frame_dvlan" }, ++ { "tx_frame_fcs_error" }, ++ { "tx_frame_oversize" }, ++ { "tx_frame_error" }, ++ { "tx_frame_fifo_underrun" }, ++ { "tx_frame_collision" }, ++}; ++ ++static int apm_get_sset_count(struct net_device *net_dev, int sset) ++{ ++ switch (sset) { ++ case ETH_SS_STATS: ++ return ARRAY_SIZE(apm_stat_name); ++ default: ++ return -EOPNOTSUPP; ++ } ++ ++ return 0; ++} ++ ++static void apm_get_strings(struct net_device *net_dev, u32 stringset, ++ u8 *data) ++{ ++ if (stringset == ETH_SS_STATS) { ++ memcpy(data, apm_stat_name, sizeof(apm_stat_name)); ++ } ++} ++ ++static void apm_get_ethtool_stats(struct net_device *net_dev, ++ struct ethtool_stats *ss, uint64_t *data) ++{ ++ struct apm *apm = netdev_priv(net_dev); ++ struct iproc_pm_ops *pm_ops = apm->pm_ops; ++ struct iproc_pm_stats stats; ++ int i = 0; ++ ++ if (pm_ops) { ++ pm_ops->port_stats(apm->land_idx, &stats); ++ ++ data[i++] = stats.rx_frames; ++ data[i++] = stats.rx_frame_good; ++ data[i++] = stats.rx_bytes; ++ data[i++] = stats.rx_frame_64; ++ data[i++] = stats.rx_frame_127; ++ data[i++] = stats.rx_frame_255; ++ data[i++] = stats.rx_frame_511; ++ data[i++] = stats.rx_frame_1023; ++ data[i++] = stats.rx_frame_1518; ++ data[i++] = stats.rx_frame_1522; ++ data[i++] = stats.rx_frame_jumbo; ++ data[i++] = stats.rx_frame_unicast; ++ data[i++] = stats.rx_frame_multicast; ++ data[i++] = stats.rx_frame_broadcast; ++ data[i++] = stats.rx_frame_control; ++ data[i++] = stats.rx_frame_pause; ++ data[i++] = stats.rx_frame_jabber; ++ data[i++] = stats.rx_frame_fragment; ++ data[i++] = stats.rx_frame_vlan; ++ data[i++] = stats.rx_frame_dvlan; ++ data[i++] = stats.rx_frame_fcs_error; ++ data[i++] = stats.rx_frame_unsupport; ++ data[i++] = stats.rx_frame_wrong_sa; ++ data[i++] = stats.rx_frame_align_err; ++ data[i++] = stats.rx_frame_length_err; ++ data[i++] = stats.rx_frame_oversize; ++ data[i++] = stats.rx_frame_mtu_err; ++ data[i++] = stats.rx_frame_truncated_err; ++ data[i++] = stats.rx_frame_undersize; ++ data[i++] = stats.tx_frames; ++ data[i++] = stats.tx_frame_good; ++ data[i++] = stats.tx_bytes; ++ data[i++] = stats.tx_frame_64; ++ data[i++] = stats.tx_frame_127; ++ data[i++] = stats.tx_frame_255; ++ data[i++] = stats.tx_frame_511; ++ data[i++] = stats.tx_frame_1023; ++ data[i++] = stats.tx_frame_1518; ++ data[i++] = stats.tx_frame_1522; ++ data[i++] = stats.tx_frame_jumbo; ++ data[i++] = stats.tx_frame_unicast; ++ data[i++] = stats.tx_frame_multicast; ++ data[i++] = stats.tx_frame_broadcast; ++ data[i++] = stats.tx_frame_control; ++ data[i++] = stats.tx_frame_pause; ++ data[i++] = stats.tx_frame_jabber; ++ data[i++] = stats.tx_frame_fragment; ++ data[i++] = stats.tx_frame_vlan; ++ data[i++] = stats.tx_frame_dvlan; ++ data[i++] = stats.tx_frame_fcs_error; ++ data[i++] = stats.tx_frame_oversize; ++ data[i++] = stats.tx_frame_error; ++ data[i++] = stats.tx_frame_fifo_underrun; ++ data[i++] = stats.tx_frame_collision; ++ } ++} ++ ++static int apm_dump_phy_regs(struct apm *apm, int try_run, char *reg_buf) ++{ ++ struct phy_device *phydev = apm->net_dev->phydev; ++ int idx, len = 0; ++ char *buf, tmp[32]; ++ u16 data = 0; ++ ++ if (phydev) { ++ for (idx = 0; idx < 16; idx++) { ++ if (try_run || !reg_buf) { ++ buf = tmp; ++ } else { ++ buf = reg_buf + len; ++ data = phy_read(phydev, idx); ++ } ++ len += sprintf(buf, "PHY REG %d: 0x%.4x\n", idx, data); ++ } ++ } ++ return len; ++} ++ ++static int apm_get_regs_len(struct net_device *dev) ++{ ++ struct apm *apm = netdev_priv(dev); ++ u32 len = 0; ++ ++ len += apm_dump_phy_regs(apm, 1, NULL); ++ ++ return len; ++} ++ ++static void apm_get_regs(struct net_device *dev, ++ struct ethtool_regs *regs, void *_p) ++{ ++ struct apm *apm = netdev_priv(dev); ++ u32 len = 0; ++ ++ regs->version = 0; ++ ++ /* Dump phy register */ ++ len += apm_dump_phy_regs(apm, 0, (char *)_p + len); ++} ++ ++static void apm_get_drvinfo(struct net_device *net_dev, ++ struct ethtool_drvinfo *info) ++{ ++ strlcpy(info->driver, "apm", sizeof(info->driver)); ++ strlcpy(info->version, "0.1", sizeof(info->version)); ++ strlcpy(info->bus_info, "axi", sizeof(info->bus_info)); ++ info->regdump_len = apm_get_regs_len(net_dev); ++} ++ ++static const struct ethtool_ops apm_ethtool_ops = { ++ .get_regs = apm_get_regs, ++ .get_regs_len = apm_get_regs_len, ++ .get_strings = apm_get_strings, ++ .get_sset_count = apm_get_sset_count, ++ .get_ethtool_stats = apm_get_ethtool_stats, ++ .get_drvinfo = apm_get_drvinfo, ++ .get_link_ksettings = phy_ethtool_get_link_ksettings, ++ .set_link_ksettings = phy_ethtool_set_link_ksettings, ++}; ++ ++int apm_ethtool_init(struct net_device *net_dev) ++{ ++ net_dev->ethtool_ops = &apm_ethtool_ops; ++ return 0; ++} ++ ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/bgmac-platform.c b/drivers/net/ethernet/broadcom/bgmac-platform.c +--- a/drivers/net/ethernet/broadcom/bgmac-platform.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/bgmac-platform.c 2018-05-10 11:31:31.729401905 +0800 +@@ -19,6 +19,12 @@ + #include + #include + #include ++ ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++#include ++#include ++#endif ++ + #include "bgmac.h" + + #define NICPM_PADRING_CFG 0x00000004 +@@ -84,9 +90,16 @@ static void platform_bgmac_clk_enable(st + } + + val = bgmac_idm_read(bgmac, BCMA_IOCTL); ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++ /* To make HX4/KT2 GMAC work */ ++ val |= flags; ++ val &= ~(BGMAC_AWCACHE | BGMAC_ARCACHE | BGMAC_AWUSER | ++ BGMAC_ARUSER); ++#else + /* Some bits of BCMA_IOCTL set by HW/ATF and should not change */ + val |= flags & ~(BGMAC_AWCACHE | BGMAC_ARCACHE | BGMAC_AWUSER | + BGMAC_ARUSER); ++#endif + val |= BGMAC_CLK_EN; + bgmac_idm_write(bgmac, BCMA_IOCTL, val); + bgmac_idm_read(bgmac, BCMA_IOCTL); +@@ -147,18 +160,123 @@ static void bgmac_nicpm_speed_set(struct + bgmac_adjust_link(bgmac->net_dev); + } + ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++#define SERDES_CONTROL_OFFSET 0x1a8 ++#define SC_TX1G_FIFO_RST_MASK 0x00f00000 ++#define SC_TX1G_FIFO_RST_VAL 0x00f00000 ++#define SC_FORCE_SPD_STRAP_MASK 0x00060000 ++#define SC_FORCE_SPD_STRAP_VAL 0x00040000 ++#define SC_FORCE_SPD_100M_VAL 0x00020000 ++#define SC_FORCE_SPD_1G_VAL 0x00040000 ++#define SC_REF_TERM_SEL_MASK 0x00001000 ++#define SC_REFSEL_MASK 0x00000c00 ++#define SC_REFSEL_VAL 0x00000400 ++#define SC_REFDIV_MASK 0x00000300 ++#define SC_REFDIV_VAL 0x00000000 ++#define SC_LCREF_EN_MASK 0x00000040 ++#define SC_RSTB_PLL_MASK 0x00000010 ++#define SC_RSTB_MDIOREGS_MASK 0x00000008 ++#define SC_RSTB_HW_MASK 0x00000004 ++#define SC_IDDQ_MASK 0x00000002 ++#define SC_PWR_DOWN_MASK 0x00000001 ++ ++void amac_serdes_init(struct bgmac *info, struct phy_device *phy_dev) ++{ ++ u32 sdctl; ++ void *serdes_ctl_reg; ++ struct phy_device *phydev = phy_dev; ++ ++ serdes_ctl_reg = info->plat.base + SERDES_CONTROL_OFFSET; ++ ++ sdctl = (SC_TX1G_FIFO_RST_VAL | SC_FORCE_SPD_STRAP_VAL); ++ if (xgs_serdes_hx4_amac(phydev)) ++ sdctl |= (SC_REFSEL_VAL | SC_REF_TERM_SEL_MASK); ++ ++ else if (xgs_serdes_kt2_amac(phydev)) ++ sdctl |= SC_REF_TERM_SEL_MASK; ++ ++ writel(sdctl, serdes_ctl_reg); ++ ++ udelay(1000); ++ ++ sdctl = readl(serdes_ctl_reg); ++ sdctl |= (SC_IDDQ_MASK | SC_PWR_DOWN_MASK); ++ writel(sdctl, serdes_ctl_reg); ++ ++ sdctl = readl(serdes_ctl_reg); ++ sdctl &= ~(SC_IDDQ_MASK | SC_PWR_DOWN_MASK); ++ writel(sdctl, serdes_ctl_reg); ++ ++ /* Bring hardware out of reset */ ++ sdctl = readl(serdes_ctl_reg); ++ sdctl |= SC_RSTB_HW_MASK; ++ writel(sdctl, serdes_ctl_reg); ++ ++ /* Bring MDIOREGS out of reset */ ++ sdctl = readl(serdes_ctl_reg); ++ sdctl |= SC_RSTB_MDIOREGS_MASK; ++ writel(sdctl, serdes_ctl_reg); ++ ++ udelay(1000); ++ ++ /* Bring PLL out of reset */ ++ sdctl = readl(serdes_ctl_reg); ++ sdctl |= SC_RSTB_PLL_MASK; ++ writel(sdctl, serdes_ctl_reg); ++ ++ udelay(1000); ++ ++ return; ++} ++#endif /* IS_ENABLED(CONFIG_ARCH_XGS_IPROC) */ ++ + static int platform_phy_connect(struct bgmac *bgmac) + { + struct phy_device *phy_dev; + +- if (bgmac->plat.nicpm_base) ++ if (bgmac->plat.nicpm_base) { + phy_dev = of_phy_get_and_connect(bgmac->net_dev, + bgmac->dev->of_node, + bgmac_nicpm_speed_set); +- else ++ } ++ else { ++ struct device_node *np = bgmac->dev->of_node; ++ u32 lane; ++ ++ /* For WH2 SGMII case, treat SERDES as PHY */ ++ if (of_device_is_compatible(np, "brcm,xgs-wh2-amac") && ++ is_wh2_amac_sgmii()) { ++ struct device_node *phy_np; ++ phy_interface_t iface = PHY_INTERFACE_MODE_SGMII; ++ ++ phy_np = of_parse_phandle(np, "serdes-phy-handle", 0); ++ if (!phy_np) ++ return -ENODEV; ++ ++ phy_dev = of_phy_find_device(phy_np); ++ if (!phy_dev) ++ return -ENODEV; ++ ++ /* Get lane from DT, otherwise set to default 3 */ ++ if (of_property_read_u32(phy_np, "lane-num", &lane)) ++ lane = 3; ++ xgs_serdes_set_lane(phy_dev, lane); ++ ++ amac_serdes_init(bgmac, phy_dev); ++ ++ phy_connect_direct(bgmac->net_dev, phy_dev, ++ bgmac_adjust_link, iface); ++ ++ put_device(&phy_dev->mdio.dev); ++ of_node_put(phy_np); ++ } ++ else { + phy_dev = of_phy_get_and_connect(bgmac->net_dev, + bgmac->dev->of_node, + bgmac_adjust_link); ++ } ++ } ++ + if (!phy_dev) { + dev_err(bgmac->dev, "PHY connection failed\n"); + return -ENODEV; +@@ -285,6 +403,8 @@ static const struct dev_pm_ops bgmac_pm_ + static const struct of_device_id bgmac_of_enet_match[] = { + {.compatible = "brcm,amac",}, + {.compatible = "brcm,nsp-amac",}, ++ {.compatible = "brcm,xgs-iproc-amac",}, ++ {.compatible = "brcm,xgs-wh2-amac",}, + {.compatible = "brcm,ns2-amac",}, + {}, + }; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/bgmac.c b/drivers/net/ethernet/broadcom/bgmac.c +--- a/drivers/net/ethernet/broadcom/bgmac.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/bgmac.c 2018-05-10 11:31:31.733401909 +0800 +@@ -17,6 +17,13 @@ + #include + #include "bgmac.h" + ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++#include ++#include ++extern bool xgs_mdio_bus_release(void); ++extern void amac_serdes_init(struct bgmac *, struct phy_device *); ++#endif ++ + static bool bgmac_wait_value(struct bgmac *bgmac, u16 reg, u32 mask, + u32 value, int timeout) + { +@@ -1120,6 +1127,7 @@ static void bgmac_chip_init(struct bgmac + + bgmac_write(bgmac, BGMAC_RXMAX_LENGTH, 32 + ETHER_MAX_LEN); + ++ if (!IS_ENABLED(CONFIG_ARCH_XGS_IPROC)) + bgmac_chip_intrs_on(bgmac); + + bgmac_enable(bgmac); +@@ -1197,10 +1204,33 @@ static int bgmac_open(struct net_device + } + napi_enable(&bgmac->napi); + ++ if (IS_ENABLED(CONFIG_ARCH_XGS_IPROC)) { ++ /* Reset emulated MIB statistics to zero */ ++ memset(&bgmac->estats, 0, sizeof(struct bgmac_ethtool_stats)); ++ ++ /* ++ * phy_state_machine reschedule could be stopped due to the code ++ * change in phy.c to handle MDIO bus sharing between iProc and ++ * CIMCd of HX4/KT2. ++ */ ++ if (xgs_mdio_bus_release()) ++ phy_start_machine(net_dev->phydev); ++ } ++ + phy_start(net_dev->phydev); + + netif_start_queue(net_dev); + ++ /* ++ * This interrupt enable was originally set in "bgmac_chip_init" which ++ * was run before "napi_enable". If interrupt events come before ++ * napi_enable was run, the NAPI poll routine "bgmac_poll" will not yet ++ * be available for either handling interrupt events or re-enabling the ++ * AMAC interrupt disabled by "bgmac_interrupt". ++ */ ++ if (IS_ENABLED(CONFIG_ARCH_XGS_IPROC)) ++ bgmac_chip_intrs_on(bgmac); ++ + return 0; + } + +@@ -1379,6 +1409,9 @@ static void bgmac_get_ethtool_stats(stru + const struct bgmac_stat *s; + unsigned int i; + u64 val; ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++ u64 *estats = (u64*)&bgmac->estats; ++#endif + + if (!netif_running(dev)) + return; +@@ -1389,18 +1422,70 @@ static void bgmac_get_ethtool_stats(stru + if (s->size == 8) + val = (u64)bgmac_read(bgmac, s->offset + 4) << 32; + val |= bgmac_read(bgmac, s->offset); ++ if (IS_ENABLED(CONFIG_ARCH_XGS_IPROC)) { ++ estats[i] += val; ++ data[i] = estats[i]; ++ } ++ else { + data[i] = val; + } + } ++} ++ ++static int bgmac_dump_phy_regs(struct bgmac *bgmac, int try_run, char *reg_buf) ++{ ++ struct phy_device *phydev = bgmac->net_dev->phydev; ++ int idx, len = 0; ++ char *buf, tmp[32]; ++ u16 data = 0; ++ ++ if (phydev) { ++ for (idx = 0; idx < 16; idx++) { ++ if (try_run || !reg_buf) { ++ buf = tmp; ++ } else { ++ buf = reg_buf + len; ++ data = phy_read(phydev, idx); ++ } ++ len += sprintf(buf, "PHY REG %d: 0x%.4x\n", idx, data); ++ } ++ } ++ return len; ++} ++ ++static int bgmac_get_regs_len(struct net_device *dev) ++{ ++ struct bgmac *bgmac = netdev_priv(dev); ++ u32 len = 0; ++ ++ len += bgmac_dump_phy_regs(bgmac, 1, NULL); ++ ++ return len; ++} ++ ++static void bgmac_get_regs(struct net_device *dev, ++ struct ethtool_regs *regs, void *_p) ++{ ++ struct bgmac *bgmac = netdev_priv(dev); ++ u32 len = 0; ++ ++ regs->version = 0; ++ ++ /* Dump phy register */ ++ len += bgmac_dump_phy_regs(bgmac, 0, (char *)_p + len); ++} + + static void bgmac_get_drvinfo(struct net_device *net_dev, + struct ethtool_drvinfo *info) + { + strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver)); + strlcpy(info->bus_info, "AXI", sizeof(info->bus_info)); ++ info->regdump_len = bgmac_get_regs_len(net_dev); + } + + static const struct ethtool_ops bgmac_ethtool_ops = { ++ .get_regs = bgmac_get_regs, ++ .get_regs_len = bgmac_get_regs_len, + .get_strings = bgmac_get_strings, + .get_sset_count = bgmac_get_sset_count, + .get_ethtool_stats = bgmac_get_ethtool_stats, +@@ -1431,11 +1516,11 @@ void bgmac_adjust_link(struct net_device + } + } + +- if (update) { ++ if (update) + bgmac_mac_speed(bgmac); ++ + phy_print_status(phy_dev); + } +-} + EXPORT_SYMBOL_GPL(bgmac_adjust_link); + + int bgmac_phy_connect_direct(struct bgmac *bgmac) +@@ -1490,6 +1576,12 @@ int bgmac_enet_probe(struct bgmac *bgmac + { + struct net_device *net_dev = bgmac->net_dev; + int err; ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++ struct device_node *serdes_np; ++ struct device_node *amac_np; ++ struct phy_device *serdes_phy_dev = NULL; ++ static u32 serdes_lane2_init = 0; ++#endif + + net_dev->irq = bgmac->irq; + SET_NETDEV_DEV(net_dev, bgmac->dev); +@@ -1534,6 +1626,37 @@ int bgmac_enet_probe(struct bgmac *bgmac + goto err_dma_free; + } + ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++ /* SERDES init required for HX4/KT2/SB2/GH2/WH2 */ ++ amac_np = bgmac->dev->of_node; ++ serdes_np = of_parse_phandle(amac_np, "serdes-handle", 0); ++ if (serdes_np) ++ serdes_phy_dev = of_phy_find_device(serdes_np); ++ ++ if (serdes_phy_dev) { ++ u32 lane; ++ /* If lane available in DT, set lane num */ ++ if (!of_property_read_u32(serdes_np, "lane-num", &lane)) ++ xgs_serdes_set_lane(serdes_phy_dev, lane); ++ ++ amac_serdes_init(bgmac, serdes_phy_dev); ++ phy_init_hw(serdes_phy_dev); ++ } ++ ++ /* Init SERDES lane 2 required by SDK for HX4/KT2 */ ++ if (!serdes_lane2_init) { ++ /* Use alias defined in DTS rather than full path */ ++ serdes_np = of_find_node_by_path("sdk-serdes-lane2"); ++ if (serdes_np) { ++ serdes_phy_dev = of_phy_find_device(serdes_np); ++ if (serdes_phy_dev) { ++ phy_init_hw(serdes_phy_dev); ++ serdes_lane2_init = 1; ++ } ++ } ++ } ++#endif ++ + net_dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + net_dev->hw_features = net_dev->features; + net_dev->vlan_features = net_dev->features; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/bgmac.h b/drivers/net/ethernet/broadcom/bgmac.h +--- a/drivers/net/ethernet/broadcom/bgmac.h 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/bgmac.h 2018-05-10 11:31:31.733401909 +0800 +@@ -476,6 +476,78 @@ struct bgmac_rx_header { + __le16 pad[12]; + }; + ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++struct bgmac_ethtool_stats { ++ u64 tx_good_octets; ++ u64 tx_good; ++ u64 tx_octets; ++ u64 tx_pkts; ++ u64 tx_broadcast; ++ u64 tx_multicast; ++ u64 tx_64; ++ u64 tx_65_127; ++ u64 tx_128_255; ++ u64 tx_256_511; ++ u64 tx_512_1023; ++ u64 tx_1024_1522; ++ u64 tx_1523_2047; ++ u64 tx_2048_4095; ++ u64 tx_4096_8191; ++ u64 tx_8192_max; ++ u64 tx_jabber; ++ u64 tx_oversize; ++ u64 tx_fragment; ++ u64 tx_underruns; ++ u64 tx_total_cols; ++ u64 tx_single_cols; ++ u64 tx_multiple_cols; ++ u64 tx_excessive_cols; ++ u64 tx_late_cols; ++ u64 tx_defered; ++ u64 tx_carrier_lost; ++ u64 tx_pause; ++ u64 tx_unicast; ++ u64 tx_q0; ++ u64 tx_q0_octets; ++ u64 tx_q1; ++ u64 tx_q1_octets; ++ u64 tx_q2; ++ u64 tx_q2_octets; ++ u64 tx_q3; ++ u64 tx_q3_octets; ++ ++ u64 rx_good_octets; ++ u64 rx_good; ++ u64 rx_octets; ++ u64 rx_pkts; ++ u64 rx_broadcast; ++ u64 rx_multicast; ++ u64 rx_64; ++ u64 rx_65_127; ++ u64 rx_128_255; ++ u64 rx_256_511; ++ u64 rx_512_1023; ++ u64 rx_1024_1522; ++ u64 rx_1523_2047; ++ u64 rx_2048_4095; ++ u64 rx_4096_8191; ++ u64 rx_8192_max; ++ u64 rx_jabber; ++ u64 rx_oversize; ++ u64 rx_fragment; ++ u64 rx_missed; ++ u64 rx_crc_align; ++ u64 rx_undersize; ++ u64 rx_crc; ++ u64 rx_align; ++ u64 rx_symbol; ++ u64 rx_pause; ++ u64 rx_nonpause; ++ u64 rx_sa_changes; ++ u64 rx_unicast; ++}; ++#endif ++ + struct bgmac { + union { + struct { +@@ -520,6 +592,14 @@ struct bgmac { + + bool loopback; + ++#if IS_ENABLED(CONFIG_ARCH_XGS_IPROC) ++ /* For XGS iProc, SW emulated MIB registers are required as the HW ++ * MIB registers will be cleared to zero after reading. ++ * mib_tx_regs/mib_rx_regs defined above seem for the same purpose, ++ * but not used so far. ++ */ ++ struct bgmac_ethtool_stats estats; ++#endif + u32 (*read)(struct bgmac *bgmac, u16 offset); + void (*write)(struct bgmac *bgmac, u16 offset, u32 value); + u32 (*idm_read)(struct bgmac *bgmac, u16 offset); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/merlin16_ucode.h b/drivers/net/ethernet/broadcom/merlin16_ucode.h +--- a/drivers/net/ethernet/broadcom/merlin16_ucode.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/merlin16_ucode.h 2018-05-30 15:50:51.032753168 +0800 +@@ -0,0 +1,1977 @@ ++/* ++ * $Id: merlin16_ucode.c $ ++ * $Copyright: (c) 2013 Broadcom Corporation All Rights Reserved.$ ++ * All Rights Reserved.$ ++ */ ++ ++#define MERLIN16_UCODE_IMAGE_VERSION "D101_0C" /* matches the version number from microcode */ ++#define MERLIN16_UCODE_IMAGE_SIZE 31368 ++#define MERLIN16_UCODE_IMAGE_CRC 0x2C25 ++ ++unsigned short merlin16_ucode_ver = 0xD101; ++unsigned short merlin16_ucode_crc = MERLIN16_UCODE_IMAGE_CRC; ++unsigned short merlin16_ucode_len = MERLIN16_UCODE_IMAGE_SIZE; ++ ++unsigned char merlin16_ucode[] = { ++ 0xf0, 0x0f, 0x00, 0x20, 0x7d, 0x02, 0x00, 0x00, 0x51, 0x74, 0x00, 0x00, 0x5f, 0x74, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x74, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x02, 0x00, 0x00, 0x7b, 0x74, 0x00, 0x00, ++ 0x89, 0x74, 0x00, 0x00, 0x97, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, ++ 0xa5, 0x74, 0x00, 0x00, 0xab, 0x74, 0x00, 0x00, 0xb1, 0x74, 0x00, 0x00, 0xb7, 0x74, 0x00, 0x00, ++ 0xbd, 0x74, 0x00, 0x00, 0xc3, 0x74, 0x00, 0x00, 0xc9, 0x74, 0x00, 0x00, 0xcf, 0x74, 0x00, 0x00, ++ 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, ++ 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, ++ 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, ++ 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, ++ 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, 0xd5, 0x74, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x49, 0x6e, 0x66, 0x35, 0x0c, 0x01, 0xd1, 0x00, 0x00, 0x03, 0x00, 0x01, 0x04, 0x24, 0x00, 0x01, ++ 0x00, 0x01, 0x00, 0x20, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x20, ++ 0x08, 0x00, 0x00, 0x00, 0x80, 0x00, 0x40, 0x00, 0x24, 0x04, 0x00, 0x20, 0x00, 0x0e, 0x00, 0x20, ++ 0x00, 0x0a, 0x00, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x20, 0x44, 0x04, 0x00, 0x20, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0xf0, 0x02, 0xf8, 0x00, 0xf0, 0x3e, 0xf8, 0x0c, 0xa0, 0x30, 0xc8, 0x08, 0x38, 0x24, 0x18, ++ 0x2d, 0x18, 0xa2, 0x46, 0x67, 0x1e, 0xab, 0x46, 0x54, 0x46, 0x5d, 0x46, 0xac, 0x42, 0x01, 0xd1, ++ 0x00, 0xf0, 0x30, 0xf8, 0x7e, 0x46, 0x0f, 0x3e, 0x0f, 0xcc, 0xb6, 0x46, 0x01, 0x26, 0x33, 0x42, ++ 0x00, 0xd0, 0xfb, 0x1a, 0xa2, 0x46, 0xab, 0x46, 0x33, 0x43, 0x18, 0x47, 0x98, 0x78, 0x00, 0x00, ++ 0xb8, 0x78, 0x00, 0x00, 0x10, 0x3a, 0x02, 0xd3, 0x78, 0xc8, 0x78, 0xc1, 0xfa, 0xd8, 0x52, 0x07, ++ 0x01, 0xd3, 0x30, 0xc8, 0x30, 0xc1, 0x01, 0xd5, 0x04, 0x68, 0x0c, 0x60, 0x70, 0x47, 0x00, 0x00, ++ 0x00, 0x23, 0x00, 0x24, 0x00, 0x25, 0x00, 0x26, 0x10, 0x3a, 0x01, 0xd3, 0x78, 0xc1, 0xfb, 0xd8, ++ 0x52, 0x07, 0x00, 0xd3, 0x30, 0xc1, 0x00, 0xd5, 0x0b, 0x60, 0x70, 0x47, 0x1f, 0xb5, 0x1f, 0xbd, ++ 0x10, 0xb5, 0x10, 0xbd, 0x07, 0xf0, 0x92, 0xfb, 0x11, 0x46, 0xff, 0xf7, 0xf7, 0xff, 0x00, 0xf0, ++ 0x3f, 0xf8, 0x07, 0xf0, 0xaa, 0xfb, 0x03, 0xb4, 0xff, 0xf7, 0xf2, 0xff, 0x03, 0xbc, 0x00, 0xf0, ++ 0x34, 0xf8, 0x00, 0x00, 0x70, 0xb5, 0x05, 0x46, 0x0c, 0x46, 0x16, 0x46, 0x02, 0xe0, 0x0f, 0xcc, ++ 0x0f, 0xc5, 0x10, 0x3e, 0x10, 0x2e, 0xfa, 0xd2, 0x08, 0x2e, 0x02, 0xd3, 0x03, 0xcc, 0x03, 0xc5, ++ 0x08, 0x3e, 0x04, 0x2e, 0x07, 0xd3, 0x01, 0xcc, 0x01, 0xc5, 0x36, 0x1f, 0x03, 0xe0, 0x21, 0x78, ++ 0x29, 0x70, 0x64, 0x1c, 0x6d, 0x1c, 0x76, 0x1e, 0xf9, 0xd2, 0x70, 0xbd, 0xfe, 0xe7, 0xfe, 0xe7, ++ 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, ++ 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0xfe, 0xe7, 0x10, 0xb5, 0xff, 0xf7, ++ 0x7f, 0xff, 0x10, 0xbd, 0x0a, 0x46, 0x03, 0x46, 0x70, 0x47, 0xfe, 0xe7, 0x70, 0x47, 0x00, 0x00, ++ 0xff, 0xf7, 0xfc, 0xff, 0x07, 0xf0, 0x3a, 0xf9, 0x07, 0xf0, 0x96, 0xf9, 0x2f, 0x4d, 0x00, 0x20, ++ 0x2c, 0x46, 0x28, 0x60, 0x05, 0x21, 0x09, 0x07, 0x40, 0x18, 0x28, 0x60, 0x07, 0xf0, 0x6a, 0xf8, ++ 0x07, 0xf0, 0x05, 0xf8, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x29, 0x49, 0x81, 0x82, 0x22, 0x68, ++ 0x49, 0x1c, 0x28, 0x48, 0x12, 0x18, 0x11, 0x85, 0x21, 0x68, 0x08, 0x18, 0x80, 0x8e, 0x2f, 0x1f, ++ 0x00, 0x0b, 0x38, 0x70, 0x02, 0xf0, 0x58, 0xfd, 0x07, 0xf0, 0x94, 0xfa, 0x23, 0x49, 0x22, 0x4e, ++ 0x0e, 0x60, 0x03, 0x20, 0x22, 0x68, 0x40, 0x04, 0x82, 0x43, 0x22, 0x60, 0x2f, 0x46, 0x00, 0x24, ++ 0x0d, 0x46, 0x1a, 0xe0, 0x28, 0x68, 0x92, 0x21, 0x09, 0x5c, 0xc0, 0x22, 0x51, 0x43, 0x40, 0x30, ++ 0x81, 0x80, 0x02, 0xf0, 0x8f, 0xfd, 0x28, 0x68, 0x03, 0x22, 0x80, 0x30, 0xc0, 0x7c, 0x52, 0x04, ++ 0x00, 0x02, 0x80, 0x19, 0x28, 0x60, 0x80, 0x30, 0x80, 0x7c, 0x39, 0x68, 0x80, 0x07, 0x91, 0x43, ++ 0x40, 0x0b, 0x01, 0x43, 0x64, 0x1c, 0xe4, 0xb2, 0x39, 0x60, 0x0c, 0x48, 0x00, 0x1f, 0x00, 0x78, ++ 0x84, 0x42, 0xdf, 0xd3, 0x03, 0x24, 0x64, 0x04, 0x00, 0xf0, 0xdf, 0xf9, 0x28, 0x68, 0x80, 0x30, ++ 0xc0, 0x7c, 0x00, 0x02, 0x80, 0x19, 0x28, 0x60, 0x80, 0x30, 0x80, 0x7c, 0x39, 0x68, 0x80, 0x07, ++ 0xa1, 0x43, 0x40, 0x0b, 0x01, 0x43, 0x39, 0x60, 0xee, 0xe7, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, ++ 0xff, 0x7f, 0x00, 0x00, 0xc0, 0xa1, 0x01, 0x00, 0x00, 0x05, 0x00, 0x20, 0x90, 0x00, 0x00, 0x20, ++ 0xfe, 0x48, 0x56, 0x21, 0x00, 0x68, 0x0a, 0x5c, 0x01, 0x46, 0x80, 0x31, 0x01, 0x2a, 0x04, 0xd0, ++ 0x82, 0x79, 0x4a, 0x73, 0xc0, 0x79, 0x88, 0x73, 0x70, 0x47, 0x02, 0x7a, 0x4a, 0x73, 0x40, 0x7a, ++ 0xf9, 0xe7, 0xf7, 0x49, 0x08, 0x5c, 0x70, 0x47, 0x1c, 0xb5, 0x00, 0x21, 0x6a, 0x46, 0x11, 0x80, ++ 0x90, 0x80, 0xf4, 0x49, 0xf2, 0x4a, 0x09, 0x7b, 0xf0, 0x4c, 0x52, 0x5c, 0x21, 0x68, 0x60, 0x31, ++ 0x0b, 0x78, 0x9a, 0x42, 0x17, 0xd9, 0x16, 0x22, 0x8a, 0x56, 0x01, 0x23, 0xdb, 0x07, 0x9a, 0x42, ++ 0x11, 0xd1, 0x00, 0x07, 0x80, 0x0f, 0x02, 0x28, 0x0d, 0xd0, 0x08, 0x20, 0x6b, 0x46, 0x18, 0x80, ++ 0x52, 0x1e, 0x8a, 0x75, 0x09, 0x7d, 0x01, 0x29, 0x01, 0xd0, 0x05, 0xf0, 0x80, 0xfe, 0x20, 0x68, ++ 0x60, 0x30, 0x00, 0x7d, 0x1c, 0xbd, 0x01, 0x20, 0x08, 0x75, 0xf8, 0xe7, 0xe2, 0x48, 0x02, 0x68, ++ 0xe2, 0x49, 0x52, 0x18, 0xd2, 0x8e, 0x03, 0x68, 0x92, 0x04, 0x52, 0x0f, 0x5b, 0x18, 0xdb, 0x8e, ++ 0x00, 0x68, 0x5b, 0x05, 0x5b, 0x0f, 0xd2, 0x18, 0x52, 0x08, 0x40, 0x18, 0xc0, 0x8e, 0x80, 0x06, ++ 0x80, 0x0e, 0x10, 0x18, 0x70, 0x47, 0xd6, 0x49, 0x15, 0x31, 0x08, 0x5c, 0x70, 0x47, 0x7c, 0xb5, ++ 0x05, 0x46, 0xd4, 0x48, 0xd2, 0x49, 0x00, 0x7b, 0x15, 0x31, 0x0c, 0x5c, 0x00, 0x20, 0x69, 0x46, ++ 0x08, 0x80, 0x8d, 0x80, 0xff, 0xf7, 0xda, 0xff, 0xa9, 0x06, 0x89, 0x0f, 0xcb, 0x4d, 0xa0, 0x42, ++ 0x0a, 0xd8, 0x2a, 0x68, 0x60, 0x32, 0x52, 0x7d, 0xa2, 0x42, 0x05, 0xd2, 0x03, 0x29, 0x03, 0xd0, ++ 0x10, 0x21, 0x6a, 0x46, 0x11, 0x80, 0x15, 0xe0, 0x01, 0x26, 0xa0, 0x42, 0x0f, 0xd9, 0x2a, 0x68, ++ 0x60, 0x32, 0x53, 0x7d, 0xa3, 0x42, 0x0a, 0xd2, 0x1b, 0x18, 0x64, 0x00, 0xa3, 0x42, 0x06, 0xd9, ++ 0x02, 0x29, 0x04, 0xd0, 0x20, 0x21, 0x6b, 0x46, 0x19, 0x80, 0xd6, 0x74, 0x02, 0xe0, 0x29, 0x68, ++ 0x60, 0x31, 0xce, 0x74, 0x29, 0x68, 0x60, 0x31, 0x48, 0x75, 0x68, 0x46, 0x00, 0x88, 0x81, 0x06, ++ 0x89, 0x0f, 0x01, 0xd0, 0x05, 0xf0, 0x23, 0xfe, 0x28, 0x68, 0x60, 0x30, 0xc0, 0x7c, 0x7c, 0xbd, ++ 0xf8, 0xb5, 0xb2, 0x4c, 0x03, 0x26, 0x20, 0x68, 0x36, 0x07, 0x40, 0x30, 0xc0, 0x7a, 0x01, 0x27, ++ 0x25, 0x38, 0xb1, 0x4d, 0x03, 0x00, 0x07, 0xf0, 0x63, 0xfa, 0x07, 0x21, 0x6f, 0x8f, 0x81, 0xa1, ++ 0xb1, 0xbf, 0x05, 0x00, 0xb0, 0x8a, 0x07, 0x20, 0xc0, 0x43, 0xb0, 0x82, 0x2a, 0x68, 0x07, 0x21, ++ 0xaa, 0x48, 0x40, 0x30, 0x12, 0x18, 0x11, 0x85, 0xb1, 0x8a, 0x02, 0x21, 0xc9, 0x43, 0xb1, 0x82, ++ 0x2a, 0x68, 0x02, 0x21, 0x10, 0x18, 0x01, 0x84, 0x08, 0x20, 0x07, 0xf0, 0x73, 0xf9, 0x06, 0xf0, ++ 0x23, 0xff, 0x21, 0x68, 0x48, 0x84, 0x00, 0x20, 0x40, 0x31, 0x08, 0x76, 0x20, 0x68, 0x01, 0x46, ++ 0x80, 0x31, 0x8a, 0x7d, 0x00, 0x2a, 0x09, 0xd0, 0x42, 0x7f, 0x52, 0x07, 0x3c, 0xd5, 0x2b, 0x22, ++ 0x40, 0x30, 0x82, 0x72, 0x4f, 0x76, 0x05, 0xf0, 0x16, 0xfe, 0xf8, 0xbd, 0x06, 0xf0, 0x0c, 0xff, ++ 0x81, 0xb2, 0x20, 0x68, 0x42, 0x8c, 0x51, 0x1a, 0x64, 0x29, 0x2b, 0xdb, 0x58, 0x21, 0x09, 0x5c, ++ 0x00, 0x29, 0x02, 0xd1, 0x00, 0x88, 0xc0, 0x05, 0x0d, 0xd4, 0x02, 0x21, 0x0f, 0x20, 0x07, 0xf0, ++ 0x49, 0xf9, 0xb0, 0x8a, 0x01, 0x20, 0xc0, 0x43, 0xb0, 0x82, 0x28, 0x68, 0x0d, 0x21, 0x49, 0x03, ++ 0x40, 0x18, 0x47, 0x86, 0x16, 0xe0, 0xb0, 0x8a, 0x01, 0x20, 0xc0, 0x43, 0xb0, 0x82, 0x28, 0x68, ++ 0x87, 0x49, 0x40, 0x18, 0xc0, 0x8c, 0x3a, 0x46, 0x82, 0x43, 0x28, 0x68, 0x40, 0x18, 0xc2, 0x84, ++ 0x06, 0xf0, 0xe2, 0xfe, 0x21, 0x68, 0x48, 0x84, 0x40, 0x31, 0x0f, 0x76, 0x02, 0x21, 0x1d, 0x20, ++ 0x07, 0xf0, 0x28, 0xf9, 0x25, 0x21, 0x7f, 0xe0, 0x29, 0x68, 0xff, 0x31, 0x01, 0x31, 0x49, 0x8e, ++ 0x89, 0x06, 0x89, 0x0e, 0x40, 0x30, 0x41, 0x80, 0x20, 0x68, 0x26, 0x22, 0x01, 0x46, 0x40, 0x31, ++ 0xca, 0x72, 0x80, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0xb7, 0xd0, 0x48, 0x88, 0xff, 0xf7, 0x37, 0xff, ++ 0x01, 0x28, 0x0d, 0xd0, 0x20, 0x68, 0x28, 0x21, 0x40, 0x30, 0xc1, 0x72, 0x20, 0x68, 0x98, 0x21, ++ 0x09, 0x5c, 0x00, 0x29, 0xa9, 0xd0, 0x14, 0x21, 0x40, 0x30, 0x81, 0x72, 0x26, 0x21, 0x5d, 0xe0, ++ 0x21, 0x68, 0x00, 0x20, 0x40, 0x31, 0x48, 0x80, 0x20, 0x68, 0x27, 0x22, 0x01, 0x46, 0x40, 0x31, ++ 0xca, 0x72, 0x80, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0x97, 0xd0, 0x48, 0x88, 0xff, 0xf7, 0xd4, 0xfe, ++ 0x01, 0x28, 0x0d, 0xd0, 0x20, 0x68, 0x29, 0x21, 0x40, 0x30, 0xc1, 0x72, 0x20, 0x68, 0x98, 0x21, ++ 0x09, 0x5c, 0x00, 0x29, 0x89, 0xd0, 0x14, 0x21, 0x40, 0x30, 0x81, 0x72, 0x27, 0x21, 0x3d, 0xe0, ++ 0x05, 0xf0, 0x99, 0xfd, 0x20, 0x68, 0x2a, 0x21, 0x40, 0x30, 0xc1, 0x72, 0x28, 0x68, 0x57, 0x49, ++ 0x80, 0x31, 0x40, 0x18, 0x80, 0x88, 0x40, 0x07, 0xc0, 0x0f, 0xbd, 0xd0, 0x20, 0x68, 0x99, 0x21, ++ 0x0f, 0x54, 0x2b, 0x21, 0x40, 0x30, 0xc1, 0x72, 0x28, 0x68, 0xff, 0x30, 0x01, 0x30, 0xc0, 0x8d, ++ 0xc0, 0x08, 0xc0, 0x07, 0xc0, 0x0f, 0x00, 0xd0, 0x67, 0xe7, 0x28, 0x68, 0xff, 0x30, 0x01, 0x30, ++ 0xc0, 0x8d, 0x40, 0x07, 0xc0, 0x0f, 0xf7, 0xd1, 0x28, 0x68, 0xff, 0x30, 0x01, 0x30, 0xc0, 0x8d, ++ 0x80, 0x07, 0xc0, 0x0f, 0xf0, 0xd1, 0x28, 0x68, 0xff, 0x30, 0x01, 0x30, 0xc0, 0x8d, 0xc0, 0x07, ++ 0xea, 0xd0, 0xb0, 0x8a, 0x04, 0x20, 0xc0, 0x43, 0xb0, 0x82, 0x2a, 0x68, 0x04, 0x21, 0x3f, 0x48, ++ 0x40, 0x30, 0x10, 0x18, 0x01, 0x84, 0x2c, 0x21, 0x20, 0x68, 0x40, 0x30, 0xc1, 0x72, 0xf8, 0xbd, ++ 0xf8, 0xb5, 0x39, 0x4c, 0x20, 0x68, 0xff, 0x30, 0x01, 0x30, 0x80, 0x8d, 0x33, 0x4a, 0x80, 0x07, ++ 0xc1, 0x0f, 0x36, 0x4f, 0x95, 0x23, 0x10, 0x68, 0x03, 0x25, 0x2d, 0x07, 0x35, 0x4e, 0x40, 0x37, ++ 0x19, 0x54, 0x00, 0x29, 0x19, 0xd0, 0x40, 0x7f, 0x00, 0x07, 0x09, 0xd4, 0x2d, 0x4b, 0x18, 0x22, ++ 0x16, 0x21, 0x17, 0x20, 0x9a, 0x56, 0x59, 0x56, 0x18, 0x56, 0x00, 0x23, 0x06, 0xf0, 0xa1, 0xf9, ++ 0xa8, 0x8a, 0xae, 0x82, 0x21, 0x68, 0x01, 0x20, 0xc9, 0x19, 0x08, 0x84, 0x23, 0x48, 0x00, 0x68, ++ 0x00, 0x78, 0x80, 0x07, 0xc0, 0x17, 0x40, 0x1c, 0xf8, 0xbd, 0xa8, 0x8a, 0xae, 0x82, 0x21, 0x68, ++ 0x04, 0x20, 0xc9, 0x19, 0x08, 0x84, 0x00, 0x20, 0xf8, 0xbd, 0xfe, 0xb5, 0x1b, 0x4d, 0x00, 0x24, ++ 0x28, 0x68, 0x80, 0x30, 0x80, 0x7c, 0x00, 0x28, 0x19, 0xd1, 0x02, 0xf0, 0x0c, 0xfb, 0x0f, 0x27, ++ 0x3f, 0x03, 0x06, 0xf0, 0xdf, 0xfd, 0x1c, 0x4e, 0x00, 0x0c, 0x31, 0x68, 0x09, 0x0c, 0x40, 0x1a, ++ 0xb8, 0x42, 0x0c, 0xdd, 0x19, 0x48, 0xff, 0x21, 0x81, 0x70, 0xf0, 0x21, 0x41, 0x70, 0x04, 0x70, ++ 0x03, 0x20, 0x06, 0xf0, 0xc1, 0xff, 0x30, 0x68, 0x39, 0x04, 0x40, 0x18, 0x30, 0x60, 0x0e, 0x4e, ++ 0x31, 0x68, 0x0f, 0x48, 0x40, 0x30, 0x08, 0x18, 0x00, 0x8d, 0xc0, 0x0b, 0x06, 0xd1, 0x00, 0x23, ++ 0x07, 0x99, 0x1a, 0x46, 0x01, 0x20, 0x00, 0x94, 0x06, 0xf0, 0x73, 0xff, 0x29, 0x68, 0x80, 0x31, ++ 0x88, 0x7a, 0xc8, 0x72, 0x04, 0x48, 0x02, 0x68, 0x0d, 0x20, 0x11, 0xe0, 0x90, 0x00, 0x00, 0x20, ++ 0x9a, 0x79, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, 0x40, 0xa0, 0x01, 0x00, ++ 0x80, 0xa1, 0x01, 0x00, 0xfa, 0xff, 0x00, 0x00, 0x88, 0x00, 0x00, 0x20, 0x8c, 0x00, 0x00, 0x20, ++ 0x40, 0x03, 0x10, 0x18, 0x80, 0x8f, 0xc2, 0x0a, 0x8a, 0x72, 0x01, 0x06, 0xc9, 0x0f, 0x03, 0xd1, ++ 0x80, 0x06, 0x80, 0x0e, 0x01, 0xf0, 0xf6, 0xfe, 0x29, 0x68, 0x48, 0x7c, 0x00, 0x28, 0x09, 0xd0, ++ 0x01, 0x28, 0x26, 0xd0, 0x02, 0x28, 0x22, 0xd0, 0x03, 0x28, 0x23, 0xd0, 0x04, 0x28, 0x24, 0xd0, ++ 0x05, 0x28, 0x25, 0xd0, 0x00, 0x20, 0x52, 0x22, 0x50, 0x54, 0x08, 0x88, 0xfa, 0x4e, 0x82, 0x07, ++ 0x01, 0x24, 0x00, 0x2a, 0x31, 0xdb, 0x80, 0x05, 0x2f, 0xd5, 0x80, 0x31, 0x88, 0x7a, 0x03, 0x28, ++ 0x2b, 0xd9, 0x11, 0x28, 0x29, 0xd0, 0x48, 0x7d, 0x00, 0x28, 0x26, 0xd0, 0xf3, 0x4d, 0x28, 0x68, ++ 0x0d, 0x27, 0x7f, 0x03, 0xc0, 0x19, 0x80, 0x8e, 0xc0, 0x07, 0x0c, 0xd0, 0x1d, 0xe0, 0x00, 0xf0, ++ 0x2e, 0xfe, 0xfe, 0xbd, 0x00, 0xf0, 0xa0, 0xfe, 0xfe, 0xbd, 0x01, 0xf0, 0x57, 0xfc, 0xfe, 0xbd, ++ 0x01, 0xf0, 0x32, 0xf9, 0xfe, 0xbd, 0x06, 0xf0, 0x8f, 0xfd, 0x40, 0x1c, 0xe8, 0x49, 0x40, 0x42, ++ 0x88, 0x42, 0x0a, 0xd3, 0x02, 0x21, 0x1e, 0x20, 0x06, 0xf0, 0xd4, 0xff, 0x03, 0x20, 0x00, 0x07, ++ 0x81, 0x8a, 0x86, 0x82, 0x28, 0x68, 0xc0, 0x19, 0xf0, 0xe2, 0xe2, 0x4d, 0x28, 0x68, 0x80, 0x30, ++ 0xc1, 0x7a, 0x00, 0x29, 0x06, 0xd1, 0x80, 0x7a, 0x00, 0x28, 0x13, 0xd0, 0x01, 0x21, 0x03, 0x20, ++ 0x06, 0xf0, 0xc0, 0xff, 0x28, 0x68, 0x80, 0x30, 0xc1, 0x7a, 0x03, 0x29, 0x01, 0xd9, 0x11, 0x29, ++ 0x08, 0xd1, 0x80, 0x7a, 0x03, 0x28, 0x05, 0xd9, 0x11, 0x28, 0x03, 0xd0, 0x01, 0x21, 0x26, 0x20, ++ 0x06, 0xf0, 0xb0, 0xff, 0xd3, 0x48, 0xd4, 0x4d, 0x00, 0x68, 0x02, 0x46, 0x80, 0x32, 0x91, 0x7a, ++ 0x00, 0x29, 0x21, 0xd0, 0x01, 0x29, 0x7d, 0xd0, 0x02, 0x29, 0x7c, 0xd0, 0x03, 0x29, 0x7b, 0xd0, ++ 0x40, 0x30, 0x82, 0x7a, 0xc8, 0x4f, 0xcb, 0x4d, 0x7f, 0x3f, 0x13, 0x00, 0x07, 0xf0, 0x70, 0xf8, ++ 0x25, 0xfd, 0xfc, 0xfb, 0xfa, 0xfa, 0xfa, 0xf9, 0xf9, 0xf9, 0xf8, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, ++ 0xf2, 0xf1, 0xf0, 0xef, 0xee, 0xed, 0xec, 0xeb, 0xea, 0xea, 0xe9, 0xea, 0xea, 0xea, 0xea, 0xea, ++ 0xe9, 0xea, 0xea, 0xe9, 0xe8, 0xe8, 0xe9, 0x00, 0xd0, 0x7a, 0x00, 0x28, 0x03, 0xd0, 0x02, 0x21, ++ 0x01, 0x20, 0x06, 0xf0, 0x7f, 0xff, 0xb9, 0x4f, 0x39, 0x68, 0xbb, 0x48, 0x08, 0x18, 0x40, 0x8a, ++ 0x40, 0x07, 0x80, 0x0f, 0x24, 0xd0, 0x01, 0x28, 0x2b, 0xd0, 0xb6, 0x4d, 0x28, 0x68, 0x40, 0x30, ++ 0x40, 0x7a, 0x00, 0x28, 0x01, 0xd0, 0x02, 0xf0, 0xa1, 0xf9, 0x28, 0x68, 0x01, 0x21, 0x40, 0x30, ++ 0x81, 0x74, 0x38, 0x68, 0xb1, 0x4d, 0x40, 0x19, 0x00, 0x8e, 0x40, 0x07, 0x80, 0x0f, 0x01, 0x28, ++ 0x7e, 0xd0, 0xaf, 0x4c, 0x20, 0x7d, 0x00, 0x28, 0x00, 0xd0, 0x7b, 0xe7, 0x00, 0x90, 0x03, 0x46, ++ 0x01, 0x22, 0x04, 0x21, 0x01, 0x90, 0x06, 0xf0, 0xdf, 0xfe, 0x01, 0x20, 0x20, 0x75, 0xfe, 0xbd, ++ 0xa4, 0x48, 0x00, 0x68, 0x40, 0x30, 0x40, 0x7a, 0x00, 0x28, 0xf8, 0xd0, 0x02, 0xf0, 0x7e, 0xf9, ++ 0xfe, 0xbd, 0x39, 0x68, 0xa1, 0x48, 0xc0, 0x38, 0x08, 0x18, 0x80, 0x89, 0xc0, 0x07, 0xc0, 0x0f, ++ 0x0b, 0xd0, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x86, 0x82, 0x3a, 0x68, 0x00, 0x20, 0x9b, 0x49, ++ 0xc0, 0x39, 0x51, 0x18, 0x88, 0x81, 0x02, 0xf0, 0x96, 0xf9, 0x03, 0x25, 0x2d, 0x07, 0xa8, 0x8a, ++ 0x02, 0x20, 0xc0, 0x43, 0xa8, 0x82, 0x3a, 0x68, 0x02, 0x20, 0x94, 0x49, 0xc0, 0x39, 0x51, 0x18, ++ 0x48, 0x81, 0x02, 0xe0, 0xb2, 0xe0, 0x2b, 0xe1, 0x12, 0xe2, 0x02, 0xf0, 0x57, 0xf9, 0x8d, 0x48, ++ 0x00, 0x68, 0x00, 0x78, 0xc0, 0x07, 0x01, 0xd0, 0x06, 0xf0, 0xe4, 0xfb, 0x39, 0x68, 0x8a, 0x48, ++ 0x08, 0x18, 0xc0, 0x8a, 0x39, 0x68, 0x00, 0x07, 0x00, 0x0f, 0xff, 0x31, 0x01, 0x31, 0x89, 0x8d, ++ 0x00, 0x23, 0x89, 0x07, 0xc9, 0x0f, 0x09, 0x01, 0x01, 0x43, 0x82, 0x48, 0x00, 0x68, 0x00, 0x88, ++ 0x02, 0x0a, 0x12, 0x02, 0x11, 0x43, 0x00, 0x06, 0x00, 0x0a, 0x01, 0x43, 0x03, 0x20, 0x02, 0x22, ++ 0x01, 0x91, 0x00, 0x90, 0x11, 0x46, 0x01, 0x20, 0x06, 0xf0, 0x86, 0xfe, 0x02, 0xf0, 0x89, 0xfa, ++ 0xff, 0xf7, 0x56, 0xfe, 0x00, 0x28, 0x7b, 0x4b, 0xa8, 0x8a, 0x12, 0xd0, 0x02, 0x20, 0xc0, 0x43, ++ 0xa8, 0x82, 0x3a, 0x68, 0x02, 0x20, 0x78, 0x49, 0x51, 0x18, 0xc8, 0x80, 0xa8, 0x8a, 0xab, 0x82, ++ 0x0d, 0x21, 0x3a, 0x68, 0x89, 0x01, 0xd1, 0x20, 0x40, 0x02, 0x10, 0x18, 0xc1, 0x84, 0x11, 0xe0, ++ 0x1d, 0xe0, 0xab, 0x82, 0xff, 0x21, 0x3a, 0x68, 0x41, 0x31, 0xd1, 0x20, 0x40, 0x02, 0x10, 0x18, ++ 0xc1, 0x84, 0xa8, 0x8a, 0x02, 0x20, 0xc0, 0x43, 0xa8, 0x82, 0x3a, 0x68, 0x00, 0x20, 0x6a, 0x49, ++ 0x51, 0x18, 0xc8, 0x80, 0xa8, 0x8a, 0xae, 0x82, 0x39, 0x68, 0x67, 0x48, 0x40, 0x30, 0x08, 0x18, ++ 0x44, 0x81, 0x60, 0x48, 0x00, 0x68, 0xc1, 0x7a, 0x49, 0x1c, 0xc1, 0x72, 0xfe, 0xbd, 0x03, 0x24, ++ 0x24, 0x07, 0xa0, 0x8a, 0x02, 0x20, 0xc0, 0x43, 0xa0, 0x82, 0x39, 0x68, 0x02, 0x20, 0x49, 0x19, ++ 0x48, 0x85, 0x38, 0x68, 0x40, 0x19, 0x80, 0x8d, 0xc0, 0x07, 0xc0, 0x0f, 0x1e, 0xd0, 0x15, 0xe0, ++ 0x42, 0xe3, 0xc2, 0xe1, 0xdd, 0xe2, 0x57, 0xe3, 0xd6, 0xe3, 0x51, 0xe2, 0xc2, 0xe2, 0xbd, 0xe2, ++ 0x66, 0xe3, 0xf3, 0xe2, 0xd1, 0xe2, 0xae, 0xe2, 0x97, 0xe2, 0x43, 0xe3, 0x2b, 0xe2, 0x03, 0xe2, ++ 0x80, 0xe2, 0xf9, 0xe1, 0xdf, 0xe1, 0xbd, 0xe2, 0xca, 0xe1, 0xc1, 0xe1, 0xa0, 0x8a, 0xa6, 0x82, ++ 0x39, 0x68, 0x00, 0x20, 0x49, 0x19, 0x88, 0x85, 0x02, 0xf0, 0x3c, 0xf9, 0x02, 0xf0, 0xe0, 0xf8, ++ 0x47, 0x48, 0x00, 0x78, 0xc0, 0x07, 0x01, 0xd0, 0x06, 0xf0, 0xe8, 0xfb, 0x44, 0x48, 0x02, 0x21, ++ 0x00, 0x88, 0x00, 0x23, 0x40, 0xba, 0x00, 0x91, 0x01, 0x90, 0x01, 0x22, 0x05, 0x21, 0x18, 0x46, ++ 0x06, 0xf0, 0x0a, 0xfe, 0x3e, 0x49, 0x00, 0x20, 0x08, 0x75, 0x02, 0xf0, 0xc6, 0xf9, 0xa0, 0x8a, ++ 0xa6, 0x82, 0x39, 0x68, 0x01, 0x20, 0x49, 0x19, 0x48, 0x85, 0xfe, 0xbd, 0x01, 0x46, 0x40, 0x31, ++ 0x4a, 0x7a, 0x34, 0x4d, 0x00, 0x2a, 0x05, 0xd0, 0x80, 0x78, 0x00, 0x28, 0x0e, 0xd1, 0x08, 0x7a, ++ 0x00, 0x28, 0x0b, 0xd0, 0x00, 0x20, 0x88, 0x72, 0x2c, 0x4b, 0x18, 0x68, 0x0d, 0x26, 0x76, 0x03, ++ 0x80, 0x19, 0x40, 0x8e, 0x80, 0x07, 0xc0, 0x0f, 0x1d, 0xd0, 0x26, 0xe0, 0x02, 0xf0, 0x8e, 0xf8, ++ 0xff, 0xf7, 0xb6, 0xfd, 0x00, 0x28, 0xef, 0xd0, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x86, 0x82, ++ 0x22, 0x49, 0x0b, 0x68, 0xd1, 0x22, 0x52, 0x02, 0x9b, 0x18, 0xdc, 0x84, 0x83, 0x8a, 0x86, 0x82, ++ 0x0b, 0x68, 0xff, 0x33, 0x01, 0x33, 0x9c, 0x85, 0x83, 0x8a, 0x86, 0x82, 0x09, 0x68, 0x00, 0x20, ++ 0x89, 0x18, 0xc8, 0x84, 0xd8, 0xe7, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x1f, 0x49, 0x81, 0x82, ++ 0x01, 0x20, 0x19, 0x68, 0x40, 0x03, 0x89, 0x19, 0x08, 0x84, 0x18, 0x68, 0x80, 0x19, 0x80, 0x8f, ++ 0xc2, 0x0a, 0x28, 0x68, 0x01, 0x46, 0x80, 0x31, 0x8a, 0x72, 0x01, 0x2a, 0x0c, 0xd0, 0x81, 0x7a, ++ 0x49, 0x1c, 0x81, 0x72, 0x18, 0x68, 0x80, 0x19, 0x40, 0x8f, 0x00, 0x23, 0xc0, 0xb2, 0x02, 0x22, ++ 0x07, 0x21, 0x00, 0x94, 0x01, 0x90, 0x0b, 0xe0, 0xc8, 0x7a, 0x01, 0x28, 0x0b, 0xd0, 0x18, 0x68, ++ 0x80, 0x19, 0x40, 0x8f, 0x00, 0x23, 0xc0, 0xb2, 0x02, 0x22, 0x06, 0x21, 0x00, 0x94, 0x01, 0x90, ++ 0x01, 0x20, 0x06, 0xf0, 0x99, 0xfd, 0x1c, 0xe1, 0xfe, 0xff, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, ++ 0x60, 0xea, 0x00, 0x00, 0x90, 0x00, 0x00, 0x20, 0x00, 0xa3, 0x01, 0x00, 0xc0, 0xa1, 0x01, 0x00, ++ 0x00, 0x04, 0x00, 0x20, 0x0f, 0xfc, 0x00, 0x00, 0xc0, 0xa0, 0x01, 0x00, 0xff, 0xdf, 0x00, 0x00, ++ 0x01, 0x46, 0x40, 0x31, 0x8a, 0x7a, 0xf7, 0x4f, 0x00, 0x2a, 0x4c, 0x72, 0x03, 0xd0, 0x02, 0x20, ++ 0x00, 0x94, 0x01, 0x90, 0x04, 0xe1, 0xca, 0x79, 0x52, 0x08, 0x52, 0x00, 0xca, 0x71, 0x80, 0x78, ++ 0x00, 0x28, 0x58, 0xd1, 0x08, 0x7a, 0x00, 0x28, 0x55, 0xd0, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, ++ 0x20, 0x21, 0xc9, 0x43, 0x81, 0x82, 0xec, 0x48, 0x00, 0x21, 0x02, 0x68, 0x0d, 0x20, 0x40, 0x03, ++ 0x10, 0x18, 0x01, 0x84, 0x02, 0xf0, 0x4f, 0xfb, 0xe7, 0x49, 0x08, 0x68, 0x40, 0x19, 0xc0, 0x8a, ++ 0x09, 0x68, 0x00, 0x07, 0x00, 0x0f, 0xff, 0x31, 0x01, 0x31, 0x89, 0x8d, 0x00, 0x23, 0x89, 0x07, ++ 0xc9, 0x0f, 0x09, 0x01, 0x01, 0x43, 0x38, 0x68, 0x00, 0x88, 0x02, 0x0a, 0x12, 0x02, 0x11, 0x43, ++ 0x00, 0x06, 0x00, 0x0a, 0x01, 0x43, 0x03, 0x20, 0x01, 0x91, 0x00, 0x90, 0x02, 0x22, 0x1a, 0x21, ++ 0x01, 0x20, 0x06, 0xf0, 0x41, 0xfd, 0xd9, 0x48, 0x02, 0x21, 0x00, 0x88, 0x0a, 0x46, 0x40, 0xba, ++ 0x00, 0x91, 0x01, 0x90, 0x00, 0x23, 0x19, 0x21, 0x01, 0x20, 0x06, 0xf0, 0x35, 0xfd, 0x38, 0x68, ++ 0x80, 0x30, 0x84, 0x46, 0x00, 0x7a, 0x40, 0x06, 0x7e, 0xd4, 0xcf, 0x4d, 0x00, 0x22, 0x03, 0x21, ++ 0x09, 0x07, 0x88, 0x8a, 0x84, 0x20, 0xc0, 0x43, 0x88, 0x82, 0xd0, 0x07, 0x2e, 0x68, 0x00, 0x0e, ++ 0xcb, 0x4b, 0xf6, 0x18, 0x00, 0x1d, 0xb0, 0x85, 0x00, 0x20, 0x00, 0x21, 0x10, 0x28, 0x05, 0xd2, ++ 0x1f, 0x23, 0x1b, 0x1a, 0x04, 0xe0, 0x02, 0xf0, 0x76, 0xfa, 0xb5, 0xe7, 0x03, 0x46, 0x10, 0x3b, ++ 0xc4, 0x4f, 0xdb, 0xb2, 0xbe, 0x8a, 0x00, 0x2a, 0x07, 0xd0, 0x1f, 0x26, 0xf6, 0x43, 0xbe, 0x82, ++ 0x2f, 0x68, 0xbf, 0x4e, 0xbe, 0x19, 0xf3, 0x85, 0x06, 0xe0, 0xbf, 0x4e, 0xbe, 0x82, 0x2f, 0x68, ++ 0x1e, 0x02, 0xbb, 0x4b, 0xfb, 0x18, 0x9e, 0x85, 0xb9, 0x4f, 0x00, 0x23, 0x80, 0x37, 0x2e, 0x68, ++ 0xf6, 0x19, 0x36, 0x8a, 0x36, 0x0a, 0xf6, 0x07, 0xf6, 0x0f, 0x01, 0xd0, 0x49, 0x1c, 0xc9, 0xb2, ++ 0x5b, 0x1c, 0xdb, 0xb2, 0x0a, 0x2b, 0xf2, 0xd3, 0x00, 0x28, 0x04, 0xd0, 0x05, 0x29, 0x2d, 0xd8, ++ 0x1f, 0x28, 0x0f, 0xd0, 0x26, 0xe0, 0x05, 0x29, 0x24, 0xd9, 0x00, 0x2a, 0x17, 0xd0, 0xad, 0x48, ++ 0x81, 0x8a, 0x1f, 0x21, 0xc9, 0x43, 0x81, 0x82, 0x2b, 0x68, 0x10, 0x21, 0xa8, 0x48, 0x18, 0x18, ++ 0xc1, 0x85, 0x1b, 0xe0, 0x00, 0x2a, 0x0a, 0xd0, 0xa6, 0x48, 0x81, 0x8a, 0x1f, 0x21, 0xc9, 0x43, ++ 0x81, 0x82, 0x2b, 0x68, 0x10, 0x20, 0xa2, 0x49, 0x59, 0x18, 0xc8, 0x85, 0x0e, 0xe0, 0xa1, 0x48, ++ 0x81, 0x8a, 0xa1, 0x49, 0x81, 0x82, 0x01, 0x20, 0x2b, 0x68, 0x00, 0x03, 0x9c, 0x49, 0x59, 0x18, ++ 0x88, 0x85, 0x03, 0xe0, 0x40, 0x1c, 0xc0, 0xb2, 0x20, 0x28, 0x9e, 0xd3, 0x52, 0x1c, 0xd2, 0xb2, ++ 0x02, 0x2a, 0x8c, 0xd3, 0x97, 0x48, 0x81, 0x8a, 0x04, 0x21, 0xc9, 0x43, 0x81, 0x82, 0x2a, 0x68, ++ 0x00, 0x20, 0x93, 0x49, 0x51, 0x18, 0x00, 0xe0, 0x06, 0xe0, 0x88, 0x85, 0x60, 0x46, 0x00, 0x7a, ++ 0x40, 0x21, 0x08, 0x43, 0x61, 0x46, 0x08, 0x72, 0x8e, 0x48, 0x81, 0x8a, 0x8f, 0x49, 0x81, 0x82, ++ 0x89, 0x48, 0x01, 0x22, 0x01, 0x68, 0x92, 0x03, 0x0d, 0x20, 0x40, 0x03, 0x08, 0x18, 0x02, 0x84, ++ 0x85, 0x48, 0x01, 0x68, 0x0d, 0x20, 0x40, 0x03, 0x08, 0x18, 0x80, 0x8f, 0x81, 0x4d, 0xc0, 0x0a, ++ 0x29, 0x68, 0x80, 0x31, 0x88, 0x72, 0x03, 0x28, 0x05, 0xd0, 0xc9, 0x7a, 0x03, 0x29, 0x08, 0xd9, ++ 0x11, 0x29, 0x06, 0xd0, 0x0d, 0xe0, 0xc8, 0x7a, 0x03, 0x28, 0x0a, 0xd0, 0x01, 0x21, 0x25, 0x20, ++ 0x05, 0xe0, 0x03, 0x28, 0x05, 0xd9, 0x11, 0x28, 0x03, 0xd0, 0x01, 0x21, 0x26, 0x20, 0x06, 0xf0, ++ 0xf1, 0xfc, 0x28, 0x68, 0x40, 0x30, 0x84, 0x74, 0xfe, 0xbd, 0x44, 0x72, 0x00, 0x94, 0x01, 0x94, ++ 0x00, 0x23, 0x02, 0x22, 0x15, 0x21, 0x01, 0x20, 0x06, 0xf0, 0x6e, 0xfc, 0x71, 0x48, 0x81, 0x8a, ++ 0x86, 0x82, 0x6d, 0x48, 0x01, 0x68, 0x0d, 0x20, 0x40, 0x03, 0x08, 0x18, 0x44, 0x86, 0xfe, 0xbd, ++ 0x11, 0x29, 0x0a, 0xd0, 0x00, 0x20, 0xc0, 0x43, 0x06, 0xf0, 0x62, 0xfa, 0x06, 0xf0, 0x75, 0xfa, ++ 0x28, 0x68, 0x8a, 0x21, 0x09, 0x5c, 0x07, 0x29, 0x03, 0xd0, 0x28, 0x68, 0x40, 0x30, 0x84, 0x72, ++ 0xfe, 0xbd, 0x81, 0x78, 0x00, 0x29, 0x06, 0xd1, 0x40, 0x30, 0x01, 0x7a, 0x00, 0x29, 0x02, 0xd0, ++ 0x13, 0x21, 0x81, 0x72, 0xd6, 0xe0, 0x03, 0xf0, 0x17, 0xf9, 0x02, 0x28, 0xf0, 0xd0, 0x5d, 0x48, ++ 0x81, 0x8a, 0x87, 0x82, 0x58, 0x4c, 0x80, 0x23, 0x26, 0x68, 0x0d, 0x22, 0x52, 0x03, 0xb6, 0x18, ++ 0x73, 0x80, 0x83, 0x8a, 0x87, 0x82, 0x21, 0x68, 0x00, 0x20, 0x89, 0x18, 0x48, 0x80, 0x28, 0x68, ++ 0x06, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfe, 0xbd, 0x04, 0xf0, 0xc3, 0xfd, 0x02, 0x28, 0xfa, 0xd0, ++ 0x04, 0xf0, 0xbf, 0xfd, 0x01, 0x28, 0xf6, 0xd0, 0x03, 0xf0, 0xcd, 0xfe, 0x02, 0x28, 0xf2, 0xd0, ++ 0x28, 0x68, 0x53, 0x21, 0x09, 0x5c, 0x00, 0x29, 0x04, 0xd0, 0x01, 0x29, 0x26, 0xd1, 0x01, 0x78, ++ 0x49, 0x07, 0x23, 0xd5, 0x00, 0x78, 0x00, 0x06, 0x20, 0xd4, 0x17, 0x20, 0x00, 0xf0, 0x82, 0xfa, ++ 0x03, 0xf0, 0xca, 0xf8, 0x28, 0x68, 0x05, 0x21, 0x41, 0x84, 0x09, 0x20, 0x03, 0xf0, 0x19, 0xff, ++ 0x03, 0xf0, 0x9a, 0xfc, 0x29, 0x68, 0x60, 0x31, 0x08, 0x70, 0x00, 0xf0, 0x48, 0xfa, 0x28, 0x68, ++ 0x0b, 0x21, 0x40, 0x30, 0x81, 0x72, 0x00, 0xf0, 0x8a, 0xfa, 0x00, 0x28, 0xcb, 0xd0, 0x04, 0xf0, ++ 0x8f, 0xf8, 0x28, 0x68, 0x40, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0xee, 0xd0, 0x28, 0x68, 0x00, 0x23, ++ 0x60, 0x30, 0x02, 0x78, 0x41, 0x78, 0x12, 0x02, 0x80, 0x78, 0x11, 0x43, 0x00, 0x04, 0x01, 0x43, ++ 0x03, 0x20, 0x01, 0x22, 0x01, 0x91, 0x00, 0x90, 0x12, 0x21, 0x10, 0x46, 0x06, 0xf0, 0xe4, 0xfb, ++ 0x28, 0x68, 0x00, 0x21, 0x40, 0x30, 0x81, 0x74, 0x01, 0x75, 0x28, 0x68, 0x01, 0x46, 0x40, 0x31, ++ 0xca, 0x7a, 0x28, 0x2a, 0x01, 0xd0, 0x29, 0x2a, 0x02, 0xd1, 0x0a, 0x7d, 0x01, 0x2a, 0x73, 0xd0, ++ 0xca, 0x7c, 0x00, 0x2a, 0x04, 0xd0, 0x01, 0x2a, 0x0a, 0xd1, 0x03, 0x78, 0x5b, 0x07, 0x07, 0xd5, ++ 0x03, 0x78, 0x1b, 0x06, 0x04, 0xd4, 0x00, 0x23, 0x60, 0x30, 0x83, 0x71, 0x03, 0x72, 0x02, 0xe0, ++ 0x60, 0x30, 0x84, 0x71, 0x04, 0x72, 0x02, 0x2a, 0x27, 0xd3, 0x1a, 0x48, 0x82, 0x8a, 0x0f, 0x22, ++ 0xd2, 0x43, 0x82, 0x82, 0x14, 0x4a, 0x02, 0x24, 0x15, 0x68, 0x0d, 0x23, 0x5b, 0x03, 0xed, 0x18, ++ 0x2c, 0x86, 0x84, 0x8a, 0x16, 0x4c, 0x84, 0x82, 0x12, 0x68, 0x00, 0x15, 0xd2, 0x18, 0x10, 0x86, ++ 0x09, 0x20, 0x27, 0xe1, 0x00, 0x21, 0x81, 0x72, 0x0e, 0x48, 0x82, 0x8a, 0x0f, 0x22, 0xd2, 0x43, ++ 0x82, 0x82, 0x09, 0x4a, 0x13, 0x68, 0x0d, 0x26, 0x76, 0x03, 0x9b, 0x19, 0x19, 0x86, 0x83, 0x8a, ++ 0x0b, 0x4b, 0x83, 0x82, 0x10, 0x68, 0x80, 0x19, 0x01, 0x86, 0x04, 0xf0, 0xb1, 0xfc, 0x00, 0x28, ++ 0x10, 0xd0, 0x60, 0xe7, 0x90, 0x00, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x20, ++ 0x00, 0xa1, 0x01, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0xe0, 0x00, 0x00, 0xff, 0xbf, 0x00, 0x00, ++ 0xff, 0xfc, 0x00, 0x00, 0x52, 0xe0, 0x03, 0xf0, 0x53, 0xfe, 0x02, 0x28, 0xe9, 0xd0, 0x28, 0x68, ++ 0x80, 0x30, 0xc1, 0x7b, 0x00, 0x29, 0x18, 0xd0, 0x00, 0x21, 0xc1, 0x73, 0x04, 0xf0, 0xd2, 0xfd, ++ 0x00, 0x28, 0xde, 0xd1, 0x92, 0x49, 0x0a, 0x68, 0x0d, 0x20, 0x40, 0x03, 0x12, 0x18, 0x92, 0x8e, ++ 0xd2, 0x07, 0x7d, 0xd0, 0x28, 0x68, 0x88, 0x21, 0x09, 0x5c, 0x49, 0x07, 0x79, 0xd5, 0x40, 0x30, ++ 0xc0, 0x7c, 0x00, 0x28, 0x76, 0xd0, 0xe3, 0xe0, 0x44, 0xe0, 0x04, 0xf0, 0xa2, 0xfb, 0x02, 0x28, ++ 0xc7, 0xd0, 0x28, 0x68, 0x40, 0x30, 0x81, 0x79, 0x49, 0x07, 0x05, 0xd5, 0x80, 0x7d, 0x01, 0x28, ++ 0x02, 0xd0, 0x04, 0xf0, 0xd4, 0xf9, 0x01, 0xe0, 0x04, 0xf0, 0x27, 0xfa, 0x02, 0x28, 0xb8, 0xd0, ++ 0x28, 0x68, 0x84, 0x21, 0x09, 0x5c, 0x00, 0x29, 0x4e, 0xd1, 0x60, 0x30, 0x81, 0x79, 0x02, 0x29, ++ 0x02, 0xd0, 0x00, 0x29, 0x02, 0xd0, 0x05, 0xe0, 0x84, 0x71, 0x08, 0xe0, 0x04, 0xf0, 0xb5, 0xfa, ++ 0x02, 0x28, 0xa6, 0xd0, 0x28, 0x68, 0x60, 0x30, 0x80, 0x79, 0x01, 0x28, 0xb3, 0xd1, 0x28, 0x68, ++ 0x60, 0x30, 0x01, 0x7a, 0x02, 0x29, 0x1c, 0xd0, 0x04, 0xf0, 0x93, 0xf8, 0x28, 0x68, 0x60, 0x30, ++ 0x81, 0x79, 0x01, 0x29, 0xa7, 0xd1, 0x00, 0x7a, 0x01, 0x28, 0xa4, 0xd1, 0x28, 0x68, 0x40, 0x30, ++ 0x81, 0x7d, 0x01, 0x29, 0x06, 0xd0, 0x01, 0x7d, 0x49, 0x1c, 0xc9, 0xb2, 0x01, 0x75, 0x04, 0x29, ++ 0x00, 0xd2, 0x3a, 0xe7, 0x29, 0x68, 0x0a, 0x46, 0x40, 0x32, 0xd0, 0x7c, 0x00, 0x28, 0x02, 0xd0, ++ 0x23, 0xe0, 0x04, 0x72, 0xea, 0xe7, 0x08, 0x88, 0x43, 0x07, 0x1e, 0xd5, 0x0b, 0x79, 0x1e, 0x06, ++ 0x05, 0xd5, 0x58, 0x06, 0x40, 0x0e, 0xd0, 0x73, 0x00, 0xf0, 0xee, 0xfb, 0x15, 0xe0, 0x83, 0x06, ++ 0x9b, 0x0f, 0x02, 0x2b, 0x11, 0xd0, 0x92, 0x79, 0x12, 0x07, 0x0e, 0xd5, 0x00, 0x06, 0x0c, 0xd4, ++ 0x80, 0x31, 0x48, 0x7b, 0xc0, 0x06, 0x08, 0xd4, 0x04, 0xf0, 0x92, 0xfe, 0x02, 0x28, 0x97, 0xd0, ++ 0x28, 0x68, 0x80, 0x30, 0x00, 0x79, 0x00, 0x28, 0x8f, 0xd1, 0x95, 0x21, 0x28, 0x68, 0x02, 0xe0, ++ 0x2b, 0xe0, 0x73, 0xe0, 0x68, 0xe0, 0x09, 0x5c, 0x00, 0x29, 0x0d, 0xd0, 0x40, 0x30, 0xc1, 0x7a, ++ 0x2c, 0x29, 0x09, 0xd0, 0x16, 0x21, 0x81, 0x72, 0xff, 0xf7, 0xba, 0xf9, 0x28, 0x68, 0x40, 0x30, ++ 0xc0, 0x7a, 0x2c, 0x28, 0x00, 0xd0, 0xa6, 0xe6, 0x28, 0x68, 0x56, 0x21, 0x09, 0x5c, 0x01, 0x29, ++ 0x00, 0xd1, 0x5b, 0xe7, 0x01, 0x78, 0x09, 0x06, 0xfb, 0xd4, 0x00, 0x21, 0x60, 0x30, 0xc1, 0x71, ++ 0x04, 0xf0, 0x57, 0xfb, 0x02, 0x28, 0xee, 0xd0, 0x28, 0x68, 0x60, 0x30, 0xc0, 0x79, 0x00, 0x28, ++ 0xf6, 0xd0, 0x28, 0x68, 0x80, 0x30, 0xc4, 0x73, 0x3d, 0xe7, 0x03, 0x26, 0x36, 0x07, 0xb2, 0x8a, ++ 0x38, 0x4b, 0xb3, 0x82, 0x36, 0x4a, 0x00, 0x27, 0x11, 0x68, 0x09, 0x18, 0x0f, 0x84, 0xb1, 0x8a, ++ 0xb3, 0x82, 0x12, 0x68, 0x20, 0x21, 0x10, 0x18, 0x01, 0x84, 0x06, 0xf0, 0xd5, 0xf8, 0x40, 0x1c, ++ 0x40, 0x42, 0x01, 0x21, 0xc0, 0x08, 0x09, 0x04, 0x88, 0x42, 0x01, 0xd3, 0x49, 0x1e, 0x00, 0xe0, ++ 0x81, 0xb2, 0x28, 0x68, 0x41, 0x82, 0x01, 0x7b, 0x49, 0x1c, 0x01, 0x73, 0x40, 0x30, 0x04, 0x72, ++ 0x02, 0x21, 0x0e, 0x20, 0x06, 0xf0, 0x0e, 0xfb, 0x28, 0x68, 0x01, 0x46, 0x80, 0x30, 0x42, 0x7d, ++ 0x00, 0x2a, 0x0b, 0xd0, 0x42, 0x7e, 0x00, 0x2a, 0x08, 0xd0, 0xb2, 0x8a, 0x07, 0x22, 0xd2, 0x43, ++ 0xb2, 0x82, 0x1f, 0x4a, 0x12, 0x68, 0x20, 0x4b, 0xd2, 0x18, 0x17, 0x85, 0x07, 0x73, 0x40, 0x31, ++ 0x8c, 0x74, 0x02, 0x20, 0x88, 0x72, 0xfe, 0xbd, 0x03, 0xf0, 0x26, 0xf8, 0x02, 0x28, 0xfa, 0xd0, ++ 0x28, 0x68, 0xfb, 0x22, 0x80, 0x30, 0x01, 0x7a, 0x11, 0x40, 0x01, 0x72, 0x1f, 0x20, 0x03, 0xf0, ++ 0xd8, 0xfd, 0x28, 0x68, 0x15, 0x21, 0x40, 0x30, 0x81, 0x72, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, ++ 0x87, 0x82, 0x0f, 0x48, 0x80, 0x21, 0x02, 0x68, 0x0d, 0x20, 0x40, 0x03, 0x10, 0x18, 0x01, 0x84, ++ 0x29, 0x68, 0xff, 0x20, 0x80, 0x31, 0x88, 0x72, 0x28, 0x68, 0x40, 0x30, 0x84, 0x74, 0x00, 0xf0, ++ 0xe6, 0xf8, 0x00, 0x28, 0xd7, 0xd0, 0x28, 0x68, 0x01, 0x7a, 0xc9, 0x09, 0xe5, 0xd1, 0x90, 0x21, ++ 0x09, 0x5c, 0x00, 0x29, 0xe1, 0xd1, 0x40, 0x30, 0x84, 0x75, 0xff, 0xf7, 0x91, 0xf8, 0x67, 0xe6, ++ 0x84, 0x00, 0x00, 0x20, 0xdf, 0xff, 0x00, 0x00, 0x80, 0xa0, 0x01, 0x00, 0x00, 0x28, 0x16, 0xd0, ++ 0x01, 0x28, 0x15, 0xd0, 0x00, 0x21, 0x40, 0x00, 0x40, 0x08, 0x49, 0x1c, 0x40, 0x00, 0x49, 0xb2, ++ 0x00, 0x28, 0xfa, 0xda, 0xc0, 0x0d, 0xe0, 0x22, 0x10, 0x40, 0xca, 0x17, 0xd2, 0x0e, 0x52, 0x18, ++ 0x52, 0x09, 0x52, 0x01, 0x89, 0x1a, 0x1f, 0x22, 0x51, 0x1a, 0x40, 0x18, 0xc0, 0xb2, 0x70, 0x47, ++ 0xe0, 0x20, 0x70, 0x47, 0xf0, 0xb5, 0x03, 0x24, 0x24, 0x07, 0xa1, 0x8a, 0xfa, 0x49, 0xa1, 0x82, ++ 0x00, 0x28, 0x01, 0xdd, 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0xf8, 0x4a, 0x89, 0x02, 0xf8, 0x4e, ++ 0x89, 0x18, 0x32, 0x68, 0x0d, 0x27, 0x7f, 0x03, 0xd2, 0x19, 0x11, 0x81, 0x01, 0x23, 0x00, 0x21, ++ 0x5b, 0x02, 0x45, 0x42, 0x07, 0xe0, 0xa2, 0x8a, 0xf2, 0x4a, 0xa2, 0x82, 0x32, 0x68, 0xd2, 0x19, ++ 0x13, 0x81, 0x49, 0x1c, 0x49, 0xb2, 0x00, 0x28, 0x01, 0xdb, 0x02, 0x46, 0x00, 0xe0, 0x2a, 0x46, ++ 0x8a, 0x42, 0xf0, 0xdc, 0xf0, 0xbd, 0xf0, 0xb5, 0xeb, 0x48, 0x53, 0x21, 0x00, 0x68, 0x01, 0x23, ++ 0x09, 0x5c, 0x0d, 0x27, 0x03, 0x24, 0xe7, 0x4a, 0x5b, 0x02, 0x7f, 0x03, 0x24, 0x07, 0xe4, 0x4d, ++ 0x00, 0x29, 0x0c, 0xd0, 0x26, 0x21, 0x41, 0x5e, 0xe4, 0x4e, 0x08, 0x46, 0x11, 0x30, 0x0c, 0xd0, ++ 0x0f, 0x29, 0x17, 0xd0, 0xa0, 0x8a, 0xa2, 0x82, 0x28, 0x68, 0xc0, 0x19, 0x03, 0x81, 0xa0, 0x8a, ++ 0xa2, 0x82, 0x28, 0x68, 0xc0, 0x19, 0x03, 0x81, 0x1b, 0xe0, 0x3e, 0x20, 0xc0, 0x43, 0xff, 0xf7, ++ 0xb1, 0xff, 0x01, 0x20, 0xff, 0xf7, 0xae, 0xff, 0xa0, 0x8a, 0xff, 0x20, 0xa0, 0x82, 0x01, 0x20, ++ 0x80, 0x02, 0x0b, 0xe0, 0x3e, 0x20, 0xc0, 0x43, 0xff, 0xf7, 0xa4, 0xff, 0x01, 0x20, 0xff, 0xf7, ++ 0xa1, 0xff, 0xa0, 0x8a, 0xff, 0x20, 0xa0, 0x82, 0x01, 0x20, 0xc0, 0x02, 0x29, 0x68, 0x89, 0x19, ++ 0x88, 0x84, 0xcd, 0x48, 0x00, 0x68, 0xc1, 0x8c, 0x49, 0x1c, 0xc1, 0x84, 0xf0, 0xbd, 0x30, 0xb5, ++ 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0xca, 0x4a, 0x82, 0x82, 0xc5, 0x49, 0x00, 0x24, 0x0d, 0x68, ++ 0xc6, 0x4b, 0xed, 0x18, 0x2c, 0x84, 0x84, 0x8a, 0x82, 0x82, 0x0c, 0x68, 0x52, 0x1c, 0xe3, 0x18, ++ 0x1a, 0x84, 0x82, 0x8a, 0x80, 0x22, 0xd2, 0x43, 0x82, 0x82, 0x09, 0x68, 0x80, 0x20, 0x0d, 0x22, ++ 0x52, 0x03, 0x89, 0x18, 0x08, 0x84, 0xbc, 0x48, 0xff, 0x21, 0x00, 0x68, 0x80, 0x30, 0x81, 0x72, ++ 0x30, 0xbd, 0xb7, 0x48, 0x00, 0x68, 0xb9, 0x49, 0x40, 0x18, 0x80, 0x8e, 0x80, 0x04, 0x80, 0x16, ++ 0x40, 0x42, 0x70, 0x47, 0x30, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x8a, 0x13, 0x8a, 0x82, ++ 0x42, 0x42, 0x92, 0x06, 0x0d, 0x23, 0xd2, 0x0d, 0x5b, 0x02, 0xd4, 0x18, 0xac, 0x4b, 0x1d, 0x68, ++ 0xae, 0x4a, 0xad, 0x18, 0xec, 0x82, 0x8c, 0x8a, 0xad, 0x4c, 0x8c, 0x82, 0x1b, 0x68, 0x61, 0x1c, ++ 0x9a, 0x18, 0xd1, 0x82, 0xa8, 0x49, 0x09, 0x68, 0x60, 0x31, 0x48, 0x70, 0x30, 0xbd, 0xa6, 0x48, ++ 0x00, 0x68, 0x80, 0x30, 0x80, 0x7a, 0x07, 0x28, 0x01, 0xd0, 0x00, 0x20, 0x70, 0x47, 0x01, 0x20, ++ 0x70, 0x47, 0x70, 0xb5, 0xa0, 0x48, 0x00, 0x21, 0x04, 0x68, 0x22, 0x7f, 0xa3, 0x7d, 0x9a, 0x42, ++ 0x01, 0xd3, 0xd0, 0x1a, 0x02, 0xe0, 0xbf, 0x20, 0xc0, 0x1a, 0x80, 0x18, 0xc5, 0xb2, 0xe0, 0x8c, ++ 0x63, 0x28, 0x01, 0xd1, 0x01, 0x21, 0xc9, 0x03, 0xbf, 0x2a, 0x01, 0xd3, 0x00, 0x20, 0x00, 0xe0, ++ 0x50, 0x1c, 0xc0, 0xb2, 0x83, 0x42, 0x02, 0xd1, 0x01, 0x26, 0xb6, 0x03, 0x31, 0x43, 0x9a, 0x42, ++ 0x02, 0xd1, 0x01, 0x22, 0x52, 0x03, 0x11, 0x43, 0x29, 0x43, 0xa1, 0x82, 0x70, 0xbd, 0x70, 0xb5, ++ 0xff, 0xf7, 0xd7, 0xff, 0x05, 0x46, 0xff, 0xf7, 0xca, 0xff, 0x00, 0x28, 0x63, 0xd0, 0x8a, 0x4c, ++ 0x21, 0x68, 0x08, 0x7d, 0xbb, 0x28, 0x5e, 0xd2, 0x26, 0x22, 0x8a, 0x5e, 0x63, 0x2a, 0x5a, 0xd0, ++ 0x40, 0x31, 0xce, 0x7c, 0x82, 0x48, 0x85, 0x49, 0x86, 0x4b, 0x00, 0x2e, 0x16, 0xd0, 0x10, 0x32, ++ 0x1f, 0x2a, 0x02, 0x68, 0x1d, 0xd8, 0x56, 0x18, 0x28, 0x22, 0xb2, 0x5e, 0x00, 0x68, 0x92, 0x02, ++ 0x40, 0x18, 0x40, 0x8d, 0xc0, 0xb2, 0x10, 0x43, 0xff, 0xf7, 0xd8, 0xfe, 0x02, 0x46, 0x20, 0x68, ++ 0x44, 0x21, 0x09, 0x5a, 0x00, 0x7f, 0x08, 0x18, 0x1a, 0x54, 0x1c, 0xe0, 0x02, 0x68, 0x56, 0x18, ++ 0x30, 0x22, 0xb2, 0x5e, 0x00, 0x68, 0x92, 0x02, 0x40, 0x18, 0x40, 0x8e, 0x80, 0x05, 0x80, 0x0d, ++ 0x07, 0xe0, 0x56, 0x18, 0x2c, 0x22, 0xb2, 0x5e, 0x00, 0x68, 0x92, 0x02, 0x40, 0x18, 0xc0, 0x8d, ++ 0xc0, 0xb2, 0x10, 0x43, 0xff, 0xf7, 0xba, 0xfe, 0x01, 0x46, 0x20, 0x68, 0x44, 0x22, 0x12, 0x5a, ++ 0x00, 0x7f, 0x10, 0x18, 0x19, 0x54, 0x20, 0x68, 0x05, 0x77, 0xff, 0xf7, 0x5a, 0xff, 0x1f, 0x21, ++ 0xc8, 0x42, 0x1c, 0xdc, 0x20, 0x68, 0x44, 0x22, 0x12, 0x5a, 0x04, 0x7f, 0x00, 0x21, 0x12, 0x19, ++ 0x99, 0x54, 0x01, 0x7f, 0xbf, 0x29, 0x01, 0xd3, 0x00, 0x21, 0x00, 0xe0, 0x49, 0x1c, 0x01, 0x77, ++ 0x26, 0x21, 0x41, 0x5e, 0x1f, 0x29, 0x07, 0xda, 0xff, 0xf7, 0xdd, 0xfe, 0x1f, 0x20, 0xff, 0xf7, ++ 0x49, 0xff, 0xff, 0xf7, 0x1c, 0xff, 0x70, 0xbd, 0x63, 0x21, 0xc1, 0x84, 0x70, 0xbd, 0xff, 0xf7, ++ 0x38, 0xff, 0x40, 0x1e, 0x40, 0xb2, 0xf2, 0xe7, 0xf0, 0xb5, 0xff, 0xf7, 0x62, 0xff, 0x07, 0x46, ++ 0xff, 0xf7, 0x55, 0xff, 0x00, 0x28, 0x6f, 0xd0, 0x4f, 0x4e, 0x30, 0x68, 0x01, 0x7d, 0xbb, 0x29, ++ 0x6a, 0xd2, 0x26, 0x21, 0x41, 0x5e, 0x63, 0x29, 0x66, 0xd0, 0x40, 0x30, 0xc0, 0x7c, 0x48, 0x4c, ++ 0x4a, 0x4d, 0x4c, 0x4b, 0x00, 0x28, 0x0b, 0xd0, 0x10, 0x31, 0x20, 0x68, 0x1f, 0x29, 0x12, 0xd8, ++ 0x41, 0x19, 0x28, 0x20, 0x08, 0x5e, 0x21, 0x68, 0x80, 0x02, 0x49, 0x19, 0x49, 0x8d, 0x11, 0xe0, ++ 0x20, 0x68, 0x41, 0x19, 0x30, 0x20, 0x08, 0x5e, 0x21, 0x68, 0x80, 0x02, 0x49, 0x19, 0x49, 0x8e, ++ 0x89, 0x05, 0x89, 0x0d, 0x07, 0xe0, 0x41, 0x19, 0x2c, 0x20, 0x08, 0x5e, 0x21, 0x68, 0x80, 0x02, ++ 0x49, 0x19, 0xc9, 0x8d, 0xc9, 0xb2, 0x08, 0x43, 0xff, 0xf7, 0x50, 0xfe, 0x01, 0x46, 0x30, 0x68, ++ 0x44, 0x22, 0x12, 0x5a, 0x00, 0x7f, 0x10, 0x18, 0x19, 0x54, 0x30, 0x68, 0x26, 0x21, 0x07, 0x77, ++ 0x41, 0x5e, 0x1f, 0x29, 0x02, 0xda, 0xff, 0xf7, 0x86, 0xfe, 0x2b, 0xe0, 0x44, 0x22, 0x12, 0x5a, ++ 0x00, 0x21, 0xd2, 0x19, 0x99, 0x54, 0x01, 0x7f, 0xbf, 0x29, 0x01, 0xd3, 0x00, 0x21, 0x00, 0xe0, ++ 0x49, 0x1c, 0x01, 0x77, 0xff, 0xf7, 0xdd, 0xfe, 0x1e, 0x27, 0xff, 0x43, 0xb8, 0x42, 0x24, 0xdd, ++ 0x30, 0x68, 0x40, 0x30, 0xc0, 0x7c, 0x00, 0x28, 0x17, 0xd0, 0x04, 0x20, 0xff, 0xf7, 0x42, 0xfe, ++ 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0xff, 0x21, 0x81, 0x82, 0x01, 0x20, 0x21, 0x68, 0x40, 0x02, ++ 0x49, 0x19, 0x88, 0x84, 0x30, 0x68, 0xc7, 0x84, 0xff, 0xf7, 0xc3, 0xfe, 0x40, 0x1e, 0x40, 0xb2, ++ 0xff, 0xf7, 0xc8, 0xfe, 0xff, 0xf7, 0x9b, 0xfe, 0xf0, 0xbd, 0x3e, 0x20, 0xc0, 0x43, 0xff, 0xf7, ++ 0x29, 0xfe, 0x01, 0x20, 0xff, 0xf7, 0x26, 0xfe, 0xec, 0xe7, 0x31, 0x68, 0x63, 0x20, 0xc8, 0x84, ++ 0xf0, 0xbd, 0x10, 0xb5, 0x05, 0xf0, 0x3e, 0xfe, 0x0f, 0x49, 0x02, 0x0c, 0x09, 0x68, 0x08, 0x87, ++ 0xca, 0x86, 0x88, 0x84, 0x4a, 0x84, 0x10, 0xbd, 0x10, 0xb5, 0x09, 0x4a, 0x11, 0x68, 0x0e, 0x4b, ++ 0xc9, 0x18, 0x89, 0x8e, 0x00, 0x24, 0x49, 0x04, 0x04, 0x70, 0x48, 0x08, 0x11, 0x68, 0xc9, 0x18, ++ 0xc9, 0x8e, 0x08, 0x43, 0x10, 0xbd, 0x00, 0x00, 0x80, 0x8b, 0x00, 0x00, 0x01, 0x20, 0x00, 0x00, ++ 0x84, 0x00, 0x00, 0x20, 0xff, 0xfd, 0x00, 0x00, 0x90, 0x00, 0x00, 0x20, 0x40, 0xa0, 0x01, 0x00, ++ 0xff, 0x7f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x80, 0xa1, 0x01, 0x00, 0x10, 0xb5, 0x03, 0x20, ++ 0x00, 0x07, 0x81, 0x8a, 0xff, 0x21, 0x04, 0x31, 0x81, 0x82, 0xff, 0x4a, 0x00, 0x21, 0x14, 0x68, ++ 0xfe, 0x4b, 0xe4, 0x18, 0x21, 0x84, 0x84, 0x8a, 0x81, 0x82, 0x14, 0x68, 0xe4, 0x18, 0x61, 0x84, ++ 0x84, 0x8a, 0x81, 0x82, 0x14, 0x68, 0xe4, 0x18, 0xa1, 0x84, 0x84, 0x8a, 0x81, 0x82, 0x10, 0x68, ++ 0xc0, 0x18, 0xc1, 0x84, 0xce, 0xe7, 0x10, 0xb5, 0x04, 0x46, 0xff, 0xf7, 0xdf, 0xff, 0x03, 0x21, ++ 0x09, 0x07, 0x88, 0x8a, 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0xef, 0x48, 0xe2, 0x06, 0x03, 0x68, ++ 0xd2, 0x0e, 0x0d, 0x24, 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, 0xec, 0x4a, 0x8a, 0x82, ++ 0x04, 0x68, 0x0b, 0x14, 0xe9, 0x4a, 0xa4, 0x18, 0x23, 0x84, 0x8b, 0x8a, 0xff, 0x23, 0x8b, 0x82, ++ 0x01, 0x23, 0x04, 0x68, 0x9b, 0x02, 0xa4, 0x18, 0xa3, 0x84, 0x8b, 0x8a, 0x03, 0x23, 0xdb, 0x43, ++ 0x8b, 0x82, 0x00, 0x68, 0x03, 0x21, 0x80, 0x18, 0xc1, 0x84, 0xa3, 0xe7, 0x10, 0xb5, 0x1f, 0x20, ++ 0xff, 0xf7, 0xd1, 0xff, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x30, 0x21, 0xc9, 0x43, 0x81, 0x82, ++ 0xd9, 0x49, 0x10, 0x22, 0x0b, 0x68, 0x0d, 0x24, 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x84, 0x82, 0x8a, ++ 0xd8, 0x4a, 0x82, 0x82, 0x01, 0x20, 0x09, 0x68, 0x80, 0x02, 0xd7, 0x4a, 0x89, 0x18, 0x48, 0x84, ++ 0x88, 0xe7, 0xf8, 0xb5, 0xd5, 0x4e, 0x26, 0x21, 0x30, 0x68, 0x41, 0x5e, 0x0c, 0x12, 0x4d, 0xb2, ++ 0x29, 0x46, 0x1f, 0x31, 0x3f, 0x29, 0x04, 0xd2, 0x1f, 0x2c, 0x02, 0xdc, 0x1f, 0x21, 0xcc, 0x42, ++ 0x09, 0xda, 0x01, 0x22, 0xe1, 0xb2, 0xd2, 0x03, 0x89, 0x18, 0x81, 0x82, 0x80, 0x30, 0x44, 0x70, ++ 0x85, 0x70, 0x01, 0x20, 0xf8, 0xbd, 0xff, 0xf7, 0x04, 0xfe, 0x31, 0x68, 0x40, 0x31, 0x48, 0x76, ++ 0x28, 0x46, 0xff, 0xf7, 0x07, 0xfe, 0xff, 0xf7, 0xc1, 0xff, 0x31, 0x68, 0x53, 0x20, 0x40, 0x5c, ++ 0x00, 0x28, 0x0e, 0xd0, 0x03, 0x20, 0x10, 0x27, 0x00, 0x07, 0xff, 0x22, 0xba, 0x4b, 0xfc, 0x42, ++ 0x09, 0xda, 0x67, 0x00, 0x40, 0x37, 0xcf, 0x84, 0x87, 0x8a, 0x82, 0x82, 0x01, 0x22, 0x52, 0x02, ++ 0x0a, 0xe0, 0xcc, 0x84, 0x0f, 0xe0, 0x0f, 0x2c, 0x0b, 0xdd, 0x67, 0x00, 0x3c, 0x3f, 0xcf, 0x84, ++ 0x87, 0x8a, 0x82, 0x82, 0x01, 0x22, 0xd2, 0x02, 0x1b, 0x68, 0xb0, 0x48, 0x18, 0x18, 0x82, 0x84, ++ 0x01, 0xe0, 0x60, 0x00, 0xc8, 0x84, 0xc8, 0x8c, 0x40, 0xb2, 0xff, 0xf7, 0x43, 0xfd, 0x68, 0x46, ++ 0xff, 0xf7, 0x2a, 0xff, 0xff, 0xf7, 0x1d, 0xff, 0xff, 0xf7, 0xa9, 0xfd, 0x30, 0x68, 0x01, 0x21, ++ 0x81, 0x82, 0x80, 0x30, 0x44, 0x70, 0x85, 0x70, 0x00, 0x20, 0xf8, 0xbd, 0xf0, 0xb5, 0xa2, 0x4c, ++ 0x21, 0x68, 0x0d, 0x23, 0x5b, 0x03, 0xc9, 0x18, 0x89, 0x8a, 0xa4, 0x4a, 0x09, 0x12, 0x15, 0x68, ++ 0x77, 0x22, 0x52, 0x5d, 0x09, 0x18, 0x51, 0x18, 0x49, 0x00, 0x49, 0xb2, 0x49, 0x10, 0x03, 0x22, ++ 0x12, 0x07, 0x96, 0x8a, 0x9a, 0x4e, 0x0c, 0x36, 0x96, 0x82, 0x01, 0x26, 0x27, 0x68, 0x76, 0x03, ++ 0xff, 0x18, 0x3e, 0x81, 0x0f, 0x06, 0x97, 0x4e, 0x97, 0x8a, 0x96, 0x82, 0x05, 0xd5, 0x27, 0x68, ++ 0x00, 0x26, 0xff, 0x18, 0x3e, 0x81, 0x49, 0x42, 0x04, 0xe0, 0x01, 0x26, 0x27, 0x68, 0xb6, 0x02, ++ 0xff, 0x18, 0x3e, 0x81, 0x96, 0x8a, 0x7f, 0x26, 0xf6, 0x43, 0x96, 0x82, 0x27, 0x68, 0x01, 0x26, ++ 0xff, 0x18, 0x3e, 0x81, 0x00, 0x26, 0x0a, 0xe0, 0x94, 0x8a, 0x8d, 0x4c, 0x94, 0x82, 0x86, 0x4f, ++ 0x01, 0x24, 0x3f, 0x68, 0x64, 0x02, 0xff, 0x18, 0x3c, 0x81, 0x76, 0x1c, 0x76, 0xb2, 0x8e, 0x42, ++ 0xf2, 0xdb, 0x40, 0x35, 0x28, 0x74, 0xf0, 0xbd, 0xf0, 0xb5, 0x7f, 0x4d, 0x29, 0x68, 0x0d, 0x26, ++ 0x76, 0x03, 0x89, 0x19, 0x89, 0x8a, 0x03, 0x24, 0x08, 0x18, 0x40, 0x00, 0x40, 0xb2, 0x40, 0x10, ++ 0x24, 0x07, 0xa1, 0x8a, 0x7a, 0x49, 0x0c, 0x31, 0xa1, 0x82, 0x01, 0x21, 0x2a, 0x68, 0x89, 0x03, ++ 0x92, 0x19, 0x11, 0x81, 0x03, 0x06, 0x00, 0x21, 0x00, 0x2b, 0x76, 0x4a, 0xa3, 0x8a, 0xa2, 0x82, ++ 0x04, 0xda, 0x2a, 0x68, 0x92, 0x19, 0x11, 0x81, 0x40, 0x42, 0x04, 0xe0, 0x01, 0x22, 0x2b, 0x68, ++ 0x92, 0x02, 0x9b, 0x19, 0x1a, 0x81, 0x71, 0x4a, 0x71, 0x4f, 0x12, 0x68, 0x40, 0x32, 0x93, 0x7b, ++ 0x01, 0x22, 0x52, 0x02, 0x00, 0x2b, 0x13, 0xd0, 0xa1, 0x8a, 0x7f, 0x21, 0xc9, 0x43, 0xa1, 0x82, ++ 0x2b, 0x68, 0x01, 0x21, 0x9b, 0x19, 0x19, 0x81, 0x00, 0x21, 0x06, 0xe0, 0xa3, 0x8a, 0xa7, 0x82, ++ 0x2b, 0x68, 0x9b, 0x19, 0x1a, 0x81, 0x49, 0x1c, 0x49, 0xb2, 0x81, 0x42, 0xf6, 0xdb, 0xf0, 0xbd, ++ 0xa3, 0x8a, 0x64, 0x4b, 0xa3, 0x82, 0x40, 0x06, 0x01, 0x23, 0x40, 0x0e, 0xdb, 0x02, 0xc0, 0x18, ++ 0x2b, 0x68, 0x9b, 0x19, 0x18, 0x81, 0xa0, 0x8a, 0xa7, 0x82, 0x28, 0x68, 0x80, 0x19, 0x02, 0x81, ++ 0xa0, 0x8a, 0x5c, 0x48, 0x7f, 0x30, 0xa0, 0x82, 0x28, 0x68, 0x80, 0x19, 0x01, 0x81, 0xf0, 0xbd, ++ 0x0f, 0x30, 0x40, 0x10, 0x70, 0x47, 0x10, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x8a, 0x13, ++ 0x8a, 0x82, 0xc0, 0x05, 0x11, 0x22, 0xc0, 0x0d, 0x52, 0x02, 0x83, 0x18, 0x4a, 0x4a, 0x14, 0x68, ++ 0x4a, 0x48, 0x24, 0x18, 0xe3, 0x82, 0x8b, 0x8a, 0x4f, 0x4b, 0x8b, 0x82, 0x12, 0x68, 0x59, 0x1c, ++ 0x10, 0x18, 0xc1, 0x82, 0x6e, 0xe6, 0x10, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x8a, 0x13, ++ 0x8a, 0x82, 0xc0, 0x05, 0x09, 0x22, 0xc0, 0x0d, 0x92, 0x02, 0x83, 0x18, 0x3e, 0x4a, 0x14, 0x68, ++ 0x3e, 0x48, 0x24, 0x18, 0xe3, 0x82, 0x8b, 0x8a, 0x43, 0x4b, 0x8b, 0x82, 0x12, 0x68, 0x59, 0x1c, ++ 0x10, 0x18, 0xc1, 0x82, 0x56, 0xe6, 0x10, 0xb5, 0x3c, 0x4c, 0x20, 0x68, 0xc2, 0x7d, 0x01, 0x46, ++ 0x53, 0x07, 0x40, 0x31, 0x00, 0x2b, 0x14, 0xda, 0x92, 0x07, 0x0d, 0xd4, 0x81, 0x21, 0x41, 0x56, ++ 0x0f, 0x31, 0x48, 0x10, 0xff, 0xf7, 0xd7, 0xff, 0x21, 0x68, 0x82, 0x20, 0x08, 0x56, 0x0f, 0x30, ++ 0x40, 0x10, 0xff, 0xf7, 0xb8, 0xff, 0x0d, 0xe0, 0x0f, 0x20, 0x08, 0x56, 0xff, 0xf7, 0x54, 0xff, ++ 0x08, 0xe0, 0x19, 0x20, 0x08, 0x56, 0xff, 0xf7, 0xd5, 0xfc, 0x21, 0x68, 0x50, 0x20, 0x08, 0x56, ++ 0xff, 0xf7, 0x04, 0xff, 0x21, 0x68, 0x01, 0x20, 0x48, 0x74, 0x2b, 0xe6, 0x70, 0xb5, 0x06, 0x46, ++ 0x05, 0xf0, 0x50, 0xfc, 0x25, 0x4d, 0x04, 0x46, 0x28, 0x68, 0x22, 0x30, 0x05, 0xf0, 0x64, 0xff, ++ 0x01, 0x46, 0x10, 0x20, 0xc1, 0x41, 0x60, 0x1a, 0x30, 0x60, 0x2d, 0x68, 0x28, 0x46, 0x36, 0x30, ++ 0x05, 0xf0, 0x5a, 0xff, 0x01, 0x46, 0x10, 0x20, 0xc1, 0x41, 0x20, 0x48, 0x6a, 0x7c, 0x61, 0x1a, ++ 0x40, 0x7c, 0x05, 0x2a, 0x04, 0xd0, 0x40, 0x04, 0x88, 0x42, 0x03, 0xd2, 0x01, 0x20, 0x70, 0xbd, ++ 0xc0, 0x01, 0xf9, 0xe7, 0x00, 0x20, 0x70, 0xbd, 0xf8, 0xb5, 0x14, 0x48, 0x00, 0x68, 0x80, 0x8a, ++ 0x00, 0x04, 0x18, 0xd4, 0x03, 0x26, 0x36, 0x07, 0xb0, 0x8a, 0x15, 0x4f, 0xb7, 0x82, 0x0a, 0x4c, ++ 0x20, 0x21, 0x22, 0x68, 0x0d, 0x20, 0x40, 0x03, 0x10, 0x18, 0x41, 0x84, 0x68, 0x46, 0xff, 0xf7, ++ 0xc5, 0xff, 0x00, 0x25, 0x01, 0x28, 0x1d, 0xd0, 0xb0, 0x8a, 0xb7, 0x82, 0x21, 0x68, 0x0d, 0x20, ++ 0x40, 0x03, 0x08, 0x18, 0x45, 0x84, 0xf8, 0xbd, 0x84, 0x00, 0x00, 0x20, 0x40, 0xa0, 0x01, 0x00, ++ 0xf3, 0x8f, 0x00, 0x00, 0xff, 0xfb, 0x00, 0x00, 0x80, 0xa1, 0x01, 0x00, 0x90, 0x00, 0x00, 0x20, ++ 0xff, 0xfd, 0x00, 0x00, 0x80, 0xf7, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, ++ 0xdf, 0xff, 0x00, 0x00, 0xff, 0xf7, 0x77, 0xff, 0xf9, 0x48, 0x53, 0x21, 0x00, 0x68, 0x09, 0x5c, ++ 0x00, 0x29, 0x0e, 0xd0, 0x81, 0x22, 0x11, 0x56, 0xf6, 0x4a, 0x10, 0x31, 0x1f, 0x29, 0x21, 0x68, ++ 0x0a, 0xd8, 0x8b, 0x18, 0x28, 0x21, 0x59, 0x5e, 0x23, 0x68, 0x89, 0x02, 0x9a, 0x18, 0x52, 0x8d, ++ 0x09, 0xe0, 0x05, 0x83, 0x45, 0x83, 0x0b, 0xe0, 0x8b, 0x18, 0x2c, 0x21, 0x59, 0x5e, 0x23, 0x68, ++ 0x89, 0x02, 0x9a, 0x18, 0xd2, 0x8d, 0xd2, 0xb2, 0x11, 0x43, 0x0a, 0x0c, 0x02, 0x83, 0x41, 0x83, ++ 0xe9, 0x49, 0x81, 0x82, 0xbf, 0xe7, 0x30, 0xb5, 0xff, 0xf7, 0x3b, 0xfc, 0xe4, 0x4d, 0x29, 0x68, ++ 0x40, 0x31, 0x48, 0x76, 0x1f, 0x20, 0xff, 0xf7, 0x3d, 0xfc, 0x1e, 0x21, 0x28, 0x68, 0xc9, 0x43, ++ 0xc1, 0x84, 0x40, 0x30, 0xc0, 0x7c, 0x00, 0x28, 0x1d, 0xd0, 0x02, 0x20, 0xff, 0xf7, 0x9a, 0xfb, ++ 0x28, 0x68, 0x00, 0x24, 0x04, 0x85, 0x04, 0x77, 0x84, 0x75, 0x1f, 0x20, 0xff, 0xf7, 0xbb, 0xfd, ++ 0x28, 0x68, 0x53, 0x21, 0x09, 0x5c, 0x00, 0x29, 0x0b, 0xd0, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, ++ 0xff, 0x22, 0x8a, 0x82, 0xd5, 0x4a, 0x01, 0x21, 0x12, 0x68, 0x49, 0x02, 0xd1, 0x4b, 0xd2, 0x18, ++ 0x91, 0x84, 0x84, 0x82, 0x30, 0xbd, 0x1f, 0x20, 0xc0, 0x43, 0xff, 0xf7, 0x7b, 0xfb, 0x01, 0x20, ++ 0xdc, 0xe7, 0x10, 0xb5, 0x04, 0x46, 0xff, 0xf7, 0x81, 0xfd, 0x03, 0x21, 0x09, 0x07, 0x88, 0x8a, ++ 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0xc9, 0x48, 0xe2, 0x06, 0x03, 0x68, 0xd2, 0x0e, 0x0d, 0x24, ++ 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, 0xc5, 0x4a, 0x8a, 0x82, 0xc5, 0x4b, 0x04, 0x68, ++ 0xc0, 0x4a, 0xa4, 0x18, 0x23, 0x84, 0x8b, 0x8a, 0xff, 0x23, 0x8b, 0x82, 0x01, 0x21, 0x00, 0x68, ++ 0x89, 0x02, 0x80, 0x18, 0x81, 0x84, 0x4d, 0xe5, 0x00, 0xb5, 0xff, 0xf7, 0xe2, 0xfb, 0xb8, 0x49, ++ 0x59, 0x22, 0x09, 0x68, 0x50, 0x54, 0x00, 0x20, 0x08, 0x77, 0x88, 0x75, 0x1c, 0x20, 0xff, 0xf7, ++ 0xd0, 0xff, 0x00, 0xbd, 0x00, 0xb5, 0xff, 0xf7, 0xe6, 0xfe, 0xff, 0xf7, 0x4f, 0xfd, 0x03, 0x20, ++ 0x00, 0x07, 0x81, 0x8a, 0x30, 0x21, 0xc9, 0x43, 0x81, 0x82, 0xb0, 0x49, 0x00, 0x20, 0x09, 0x68, ++ 0x0d, 0x22, 0x52, 0x03, 0x89, 0x18, 0x48, 0x84, 0x00, 0xbd, 0x10, 0xb5, 0x00, 0x23, 0x00, 0x28, ++ 0x1c, 0xd0, 0xad, 0x4c, 0x00, 0x22, 0xa0, 0x42, 0x00, 0xd9, 0x20, 0x46, 0x52, 0x1c, 0x40, 0x00, ++ 0x52, 0xb2, 0x00, 0x28, 0xfa, 0xda, 0xd4, 0x17, 0xe4, 0x0e, 0xa4, 0x18, 0x64, 0x09, 0x64, 0x01, ++ 0x12, 0x1b, 0x1f, 0x24, 0xa2, 0x1a, 0xd2, 0xb2, 0x0a, 0x70, 0x08, 0x2a, 0x09, 0xd2, 0x00, 0x0e, ++ 0x00, 0x06, 0xa2, 0x1a, 0xd0, 0x40, 0xc0, 0xb2, 0x0b, 0x70, 0x0b, 0xe5, 0x0b, 0x70, 0x00, 0x20, ++ 0x08, 0xe5, 0x00, 0x0e, 0xd2, 0x1f, 0x0a, 0x70, 0x04, 0xe5, 0xf0, 0xb5, 0x03, 0x24, 0x24, 0x07, ++ 0xa1, 0x8a, 0x9a, 0x49, 0xa1, 0x82, 0x00, 0x28, 0x01, 0xdd, 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, ++ 0x97, 0x4a, 0x89, 0x02, 0x91, 0x4e, 0x89, 0x18, 0x32, 0x68, 0x0d, 0x27, 0x7f, 0x03, 0xd2, 0x19, ++ 0x11, 0x81, 0x01, 0x23, 0x00, 0x21, 0x5b, 0x02, 0x45, 0x42, 0x07, 0xe0, 0xa2, 0x8a, 0x91, 0x4a, ++ 0xa2, 0x82, 0x32, 0x68, 0xd2, 0x19, 0x13, 0x81, 0x49, 0x1c, 0x49, 0xb2, 0x00, 0x28, 0x01, 0xdb, ++ 0x02, 0x46, 0x00, 0xe0, 0x2a, 0x46, 0x8a, 0x42, 0xf0, 0xdc, 0xf0, 0xbd, 0xf0, 0xb5, 0x0e, 0x27, ++ 0x00, 0x22, 0x82, 0x4d, 0x88, 0x4e, 0xff, 0x43, 0x7d, 0x4c, 0x0f, 0x23, 0x00, 0x29, 0x16, 0xd0, ++ 0x00, 0x28, 0x09, 0xd0, 0x10, 0x46, 0x09, 0xe0, 0x29, 0x68, 0x89, 0x19, 0x89, 0x88, 0x89, 0x06, ++ 0x89, 0x16, 0x79, 0x1a, 0xc1, 0x84, 0xf0, 0xbd, 0x1f, 0x46, 0x18, 0x46, 0xff, 0xf7, 0x53, 0xfe, ++ 0x20, 0x68, 0xc1, 0x7d, 0x09, 0x09, 0xc9, 0x43, 0x89, 0x07, 0xed, 0xd1, 0xf0, 0xbd, 0x00, 0x28, ++ 0x01, 0xd0, 0x10, 0x46, 0x01, 0xe0, 0x1f, 0x46, 0x18, 0x46, 0xff, 0xf7, 0x2c, 0xfe, 0x28, 0x68, ++ 0x80, 0x19, 0x40, 0x88, 0x21, 0x68, 0x80, 0x06, 0x80, 0x16, 0x38, 0x1a, 0xc8, 0x84, 0xf0, 0xbd, ++ 0x40, 0x00, 0x0f, 0x38, 0x40, 0xb2, 0x70, 0x47, 0x30, 0xb5, 0x65, 0x4c, 0x00, 0x20, 0x21, 0x68, ++ 0x66, 0x4a, 0x08, 0x85, 0x10, 0x68, 0x6c, 0x4b, 0xc0, 0x18, 0x80, 0x88, 0x80, 0x06, 0x80, 0x16, ++ 0xff, 0xf7, 0xee, 0xff, 0x21, 0x68, 0x80, 0x31, 0x48, 0x70, 0x10, 0x68, 0xc0, 0x18, 0x40, 0x88, ++ 0x80, 0x06, 0x80, 0x16, 0xff, 0xf7, 0xe4, 0xff, 0x21, 0x68, 0x01, 0x22, 0x0b, 0x46, 0x80, 0x33, ++ 0x98, 0x70, 0x9a, 0x56, 0x00, 0x2a, 0x01, 0xdb, 0x15, 0x46, 0x00, 0xe0, 0x55, 0x42, 0x00, 0x28, ++ 0x01, 0xdb, 0x03, 0x46, 0x00, 0xe0, 0x43, 0x42, 0x9d, 0x42, 0x03, 0xdd, 0x0b, 0x8d, 0x04, 0x25, ++ 0x2b, 0x43, 0x0b, 0x85, 0x00, 0x2a, 0x03, 0xdd, 0x0a, 0x8d, 0x02, 0x23, 0x1a, 0x43, 0x0a, 0x85, ++ 0x00, 0x28, 0x03, 0xdd, 0x08, 0x8d, 0x01, 0x22, 0x10, 0x43, 0x08, 0x85, 0xca, 0x7d, 0x90, 0x06, ++ 0x80, 0x0f, 0x13, 0xd0, 0x01, 0x28, 0x20, 0xd0, 0x02, 0x28, 0x21, 0xd0, 0x03, 0x28, 0x0c, 0xd1, ++ 0x08, 0x8d, 0x01, 0x21, 0x80, 0x07, 0xc0, 0x0f, 0xff, 0xf7, 0x80, 0xff, 0x20, 0x68, 0x00, 0x8d, ++ 0xc0, 0x07, 0xc0, 0x0f, 0x00, 0x21, 0xff, 0xf7, 0x79, 0xff, 0x30, 0xbd, 0x28, 0x20, 0x08, 0x5e, ++ 0x04, 0x28, 0x01, 0xdb, 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0x04, 0x28, 0x02, 0xdb, 0x80, 0x07, ++ 0xc0, 0x0f, 0xf0, 0xe7, 0xc0, 0x07, 0xc0, 0x0f, 0xed, 0xe7, 0xd0, 0x07, 0xc0, 0x0f, 0xe9, 0xe7, ++ 0xd0, 0x07, 0xc0, 0x0f, 0x01, 0x21, 0xe6, 0xe7, 0xf8, 0xb5, 0xff, 0xf7, 0xd2, 0xfa, 0x30, 0x4c, ++ 0x59, 0x22, 0x21, 0x68, 0x00, 0x27, 0x50, 0x54, 0x8f, 0x82, 0xc8, 0x7d, 0x39, 0x4d, 0x03, 0x07, ++ 0x36, 0x48, 0x37, 0x4a, 0xab, 0x8a, 0xa8, 0x82, 0x04, 0xd5, 0x2c, 0x48, 0x00, 0x68, 0x80, 0x18, ++ 0x07, 0x80, 0x04, 0xe0, 0x29, 0x48, 0x08, 0x23, 0x00, 0x68, 0x80, 0x18, 0x03, 0x80, 0xc8, 0x7d, ++ 0x1e, 0x26, 0x40, 0x07, 0x40, 0x0f, 0xf6, 0x43, 0x03, 0x00, 0x05, 0xf0, 0x99, 0xfd, 0x08, 0x05, ++ 0x0e, 0x17, 0x2d, 0x5d, 0x5d, 0x85, 0x8d, 0x5f, 0x1f, 0x20, 0xff, 0xf7, 0xb3, 0xfa, 0x21, 0x68, ++ 0x50, 0x20, 0x08, 0x56, 0xff, 0xf7, 0xe2, 0xfc, 0x14, 0xe0, 0x30, 0x46, 0xff, 0xf7, 0xaa, 0xfa, ++ 0x21, 0x68, 0x50, 0x20, 0x08, 0x56, 0xff, 0xf7, 0xd9, 0xfc, 0x20, 0xe0, 0x00, 0x20, 0xff, 0xf7, ++ 0xa1, 0xfa, 0x20, 0x68, 0x40, 0x30, 0xc0, 0x7c, 0x00, 0x28, 0x07, 0xd0, 0x01, 0x20, 0xc0, 0x43, ++ 0xff, 0xf7, 0x00, 0xfa, 0x21, 0x68, 0x1f, 0x20, 0xc8, 0x84, 0x37, 0xe0, 0x20, 0x20, 0xff, 0xf7, ++ 0xf9, 0xf9, 0x00, 0x20, 0xc0, 0x43, 0xf3, 0xe7, 0x00, 0x20, 0xff, 0xf7, 0x8b, 0xfa, 0x20, 0x68, ++ 0x40, 0x30, 0xc0, 0x7c, 0x00, 0x28, 0x05, 0xd0, 0x02, 0x20, 0xff, 0xf7, 0xeb, 0xf9, 0x20, 0x68, ++ 0xc6, 0x84, 0x23, 0xe0, 0x1f, 0x20, 0xc0, 0x43, 0xff, 0xf7, 0xe4, 0xf9, 0x01, 0x20, 0xf4, 0xe7, ++ 0x90, 0x00, 0x00, 0x20, 0x40, 0xa0, 0x01, 0x00, 0x01, 0xec, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, ++ 0xf3, 0x0f, 0x00, 0x00, 0x0c, 0xb0, 0x00, 0x00, 0xff, 0xff, 0x7f, 0x00, 0x80, 0x8b, 0x00, 0x00, ++ 0x01, 0x40, 0x00, 0x00, 0xff, 0xfd, 0x00, 0x00, 0x80, 0xa2, 0x01, 0x00, 0xf7, 0xff, 0x00, 0x00, ++ 0x80, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x30, 0xff, 0xf7, 0x16, 0xff, 0x20, 0x68, 0xc0, 0x7d, ++ 0x40, 0x07, 0x15, 0xd4, 0xff, 0xf7, 0x12, 0xfc, 0x20, 0x68, 0x53, 0x21, 0x09, 0x5c, 0x00, 0x29, ++ 0x0c, 0xd0, 0xc0, 0x7d, 0x80, 0x07, 0x09, 0xd5, 0xa8, 0x8a, 0xff, 0x20, 0xa8, 0x82, 0xf9, 0x48, ++ 0x01, 0x21, 0x00, 0x68, 0xc9, 0x02, 0xf8, 0x4a, 0x80, 0x18, 0x81, 0x84, 0xff, 0xf7, 0x17, 0xfa, ++ 0xff, 0xf7, 0x87, 0xfb, 0x20, 0x68, 0x5e, 0x30, 0xff, 0xf7, 0x8e, 0xfb, 0x20, 0x68, 0x87, 0x75, ++ 0x07, 0x77, 0x47, 0x87, 0x87, 0x87, 0xae, 0xe5, 0x20, 0x20, 0xff, 0xf7, 0x8e, 0xfe, 0x00, 0x20, ++ 0xc0, 0x43, 0xff, 0xf7, 0x8a, 0xfe, 0x95, 0xe7, 0x1f, 0x20, 0xc0, 0x43, 0xff, 0xf7, 0x85, 0xfe, ++ 0x01, 0x20, 0xff, 0xf7, 0x82, 0xfe, 0xa2, 0xe7, 0x10, 0xb5, 0x05, 0xf0, 0xab, 0xf9, 0xe7, 0x49, ++ 0x09, 0x68, 0x88, 0x84, 0x00, 0x0c, 0x48, 0x84, 0x0c, 0xe5, 0x7c, 0xb5, 0x06, 0x46, 0x08, 0x68, ++ 0x69, 0x46, 0xc0, 0x08, 0xff, 0xf7, 0x49, 0xfe, 0xe0, 0x4d, 0x44, 0x22, 0x29, 0x68, 0xe0, 0x4c, ++ 0x52, 0x5a, 0x0b, 0x7f, 0xd2, 0x18, 0xa0, 0x54, 0x08, 0x7f, 0xbf, 0x28, 0x01, 0xd3, 0xbf, 0x20, ++ 0x00, 0xe0, 0x40, 0x1c, 0x08, 0x77, 0x01, 0xa9, 0x30, 0x68, 0xff, 0xf7, 0x36, 0xfe, 0x69, 0x46, ++ 0x09, 0x78, 0x0a, 0x01, 0x69, 0x46, 0x09, 0x79, 0x0a, 0x43, 0x29, 0x68, 0x0b, 0x46, 0x40, 0x33, ++ 0x9d, 0x88, 0x0e, 0x7f, 0xad, 0x19, 0x62, 0x55, 0x0a, 0x7f, 0xbf, 0x2a, 0x01, 0xd3, 0xbf, 0x22, ++ 0x00, 0xe0, 0x52, 0x1c, 0xd2, 0xb2, 0x0a, 0x77, 0x9b, 0x88, 0x9a, 0x18, 0xa0, 0x54, 0x08, 0x7f, ++ 0xbf, 0x28, 0x01, 0xd3, 0xbf, 0x20, 0x00, 0xe0, 0x40, 0x1c, 0x08, 0x77, 0x7c, 0xbd, 0x70, 0xb5, ++ 0xc6, 0x4a, 0x0e, 0x23, 0x14, 0x68, 0x00, 0x25, 0xe3, 0x84, 0xc2, 0x4b, 0xc5, 0x4c, 0x00, 0x29, ++ 0x2b, 0xd0, 0x00, 0x28, 0x18, 0x68, 0x11, 0xd0, 0x00, 0x19, 0x80, 0x88, 0x80, 0x06, 0x80, 0x16, ++ 0xff, 0xf7, 0x86, 0xfe, 0x11, 0x68, 0x81, 0x26, 0x8e, 0x57, 0xb0, 0x42, 0x1a, 0xda, 0x18, 0x68, ++ 0x00, 0x19, 0x80, 0x88, 0x80, 0x06, 0x80, 0x16, 0x40, 0x1c, 0x10, 0xe0, 0x00, 0x19, 0x80, 0x88, ++ 0x80, 0x06, 0x80, 0x16, 0xff, 0xf7, 0x74, 0xfe, 0x11, 0x68, 0x81, 0x26, 0x8e, 0x57, 0xb0, 0x42, ++ 0x08, 0xdd, 0x18, 0x68, 0x00, 0x19, 0x80, 0x88, 0x80, 0x06, 0x80, 0x16, 0x40, 0x1e, 0xff, 0xf7, ++ 0xa2, 0xfc, 0x70, 0xbd, 0x10, 0x68, 0xc5, 0x84, 0x70, 0xbd, 0x00, 0x28, 0x18, 0x68, 0x11, 0xd0, ++ 0x00, 0x19, 0x40, 0x88, 0x80, 0x06, 0x80, 0x16, 0xff, 0xf7, 0x5a, 0xfe, 0x11, 0x68, 0x82, 0x26, ++ 0x8e, 0x57, 0xb0, 0x42, 0xee, 0xda, 0x18, 0x68, 0x00, 0x19, 0x40, 0x88, 0x80, 0x06, 0x80, 0x16, ++ 0x40, 0x1c, 0x10, 0xe0, 0x00, 0x19, 0x40, 0x88, 0x80, 0x06, 0x80, 0x16, 0xff, 0xf7, 0x48, 0xfe, ++ 0x11, 0x68, 0x82, 0x26, 0x8e, 0x57, 0xb0, 0x42, 0xdc, 0xdd, 0x18, 0x68, 0x00, 0x19, 0x40, 0x88, ++ 0x80, 0x06, 0x80, 0x16, 0x40, 0x1e, 0xff, 0xf7, 0x5e, 0xfc, 0x70, 0xbd, 0xf0, 0xb5, 0x85, 0xb0, ++ 0x00, 0x20, 0x69, 0x46, 0x95, 0x4f, 0x08, 0x72, 0x38, 0x68, 0x81, 0x8a, 0x09, 0x04, 0x7d, 0xd4, ++ 0x03, 0x25, 0x2d, 0x07, 0xa9, 0x8a, 0x20, 0x21, 0xc9, 0x43, 0xa9, 0x82, 0x8d, 0x4c, 0x20, 0x21, ++ 0x22, 0x68, 0x0d, 0x26, 0x76, 0x03, 0x92, 0x19, 0x51, 0x84, 0x53, 0x21, 0x09, 0x5c, 0x00, 0x29, ++ 0x11, 0xd0, 0x26, 0x21, 0x41, 0x5e, 0x10, 0x31, 0x1f, 0x29, 0x02, 0xd9, 0xc0, 0x7d, 0x80, 0x07, ++ 0x0d, 0xd4, 0x20, 0x68, 0x84, 0x49, 0x42, 0x18, 0x28, 0x20, 0x10, 0x5e, 0x22, 0x68, 0x80, 0x02, ++ 0x51, 0x18, 0x49, 0x8d, 0x0c, 0xe0, 0x02, 0xa8, 0xff, 0xf7, 0xa6, 0xfa, 0x0a, 0xe0, 0x20, 0x68, ++ 0x7d, 0x49, 0x42, 0x18, 0x2c, 0x20, 0x10, 0x5e, 0x22, 0x68, 0x80, 0x02, 0x51, 0x18, 0xc9, 0x8d, ++ 0xc9, 0xb2, 0x08, 0x43, 0x00, 0x90, 0x01, 0xa8, 0xff, 0xf7, 0x78, 0xfc, 0x03, 0x90, 0x77, 0x48, ++ 0x07, 0x68, 0x38, 0x46, 0x3a, 0x30, 0x05, 0xf0, 0xdf, 0xfb, 0x10, 0x21, 0xc8, 0x41, 0x00, 0x99, ++ 0x40, 0x18, 0x88, 0x42, 0x01, 0xd2, 0x00, 0x20, 0xc0, 0x43, 0x03, 0x99, 0x00, 0x90, 0x01, 0x29, ++ 0x21, 0xd0, 0xf9, 0x8c, 0x00, 0x29, 0x1e, 0xd0, 0x6f, 0x49, 0x89, 0x7c, 0x09, 0x01, 0x81, 0x42, ++ 0x7c, 0xd2, 0x27, 0x22, 0x01, 0x99, 0x12, 0x02, 0x91, 0x42, 0x05, 0xd8, 0x6b, 0x4a, 0x91, 0x42, ++ 0x74, 0xd9, 0xf9, 0x7d, 0x49, 0x06, 0x71, 0xd5, 0x01, 0xa9, 0x68, 0x46, 0xff, 0xf7, 0xfd, 0xfe, ++ 0x62, 0x4a, 0x11, 0x68, 0xcb, 0x7d, 0xd8, 0x07, 0x65, 0x48, 0x08, 0x5e, 0x20, 0xd0, 0x00, 0x28, ++ 0x1c, 0xda, 0x40, 0x1c, 0x1f, 0xe0, 0x01, 0xa9, 0x68, 0x46, 0xff, 0xf7, 0xee, 0xfe, 0x68, 0x46, ++ 0x00, 0x7a, 0x00, 0x28, 0x10, 0xd0, 0x00, 0x20, 0x01, 0x21, 0x80, 0x03, 0xc9, 0x03, 0x41, 0x18, ++ 0x03, 0x98, 0x40, 0x03, 0x01, 0x43, 0x55, 0x48, 0x00, 0x68, 0x00, 0xe0, 0x02, 0xe0, 0x02, 0x7f, ++ 0x11, 0x43, 0x81, 0x82, 0x05, 0xb0, 0xf0, 0xbd, 0x01, 0x20, 0xed, 0xe7, 0x00, 0x20, 0x02, 0xe0, ++ 0x00, 0x28, 0xfb, 0xdd, 0x40, 0x1e, 0xc8, 0x84, 0x98, 0x07, 0x40, 0xd5, 0x53, 0x20, 0x47, 0x5c, ++ 0x01, 0x20, 0x50, 0x4a, 0x40, 0x02, 0x00, 0x2f, 0x01, 0xd0, 0x5f, 0x07, 0x05, 0xd5, 0xa9, 0x8a, ++ 0xaa, 0x82, 0x21, 0x68, 0x89, 0x19, 0x08, 0x81, 0x66, 0xe0, 0xdb, 0x07, 0xff, 0x27, 0x00, 0x2b, ++ 0x13, 0xd0, 0x26, 0x23, 0xcb, 0x5e, 0x10, 0x33, 0x12, 0xd1, 0x3e, 0x20, 0xc0, 0x43, 0xff, 0xf7, ++ 0x39, 0xf8, 0x01, 0x20, 0xff, 0xf7, 0x36, 0xf8, 0xa8, 0x8a, 0xaf, 0x82, 0x01, 0x21, 0x22, 0x68, ++ 0x89, 0x02, 0x39, 0x48, 0x10, 0x18, 0x81, 0x84, 0x4e, 0xe0, 0xc9, 0x8c, 0x0f, 0x29, 0x05, 0xd0, ++ 0xa9, 0x8a, 0xaa, 0x82, 0x21, 0x68, 0x89, 0x19, 0x08, 0x81, 0xd8, 0xe7, 0x3f, 0x20, 0xff, 0xf7, ++ 0x21, 0xf8, 0x00, 0x20, 0xc0, 0x43, 0xff, 0xf7, 0x1d, 0xf8, 0xa8, 0x8a, 0xaf, 0x82, 0x01, 0x20, ++ 0x22, 0x68, 0x80, 0x02, 0x2c, 0x49, 0x51, 0x18, 0x88, 0x84, 0x35, 0xe0, 0x64, 0xe0, 0x2b, 0x4f, ++ 0x58, 0x07, 0x2d, 0xd5, 0x98, 0x06, 0x80, 0x0f, 0x06, 0xd0, 0x01, 0x28, 0x15, 0xd0, 0x02, 0x28, ++ 0x16, 0xd0, 0x03, 0x28, 0x28, 0xd1, 0x17, 0xe0, 0x28, 0x20, 0x08, 0x5e, 0x04, 0x28, 0x01, 0xdb, ++ 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0x03, 0x28, 0x02, 0xdb, 0x80, 0x07, 0xc0, 0x0f, 0x01, 0xe0, ++ 0xc0, 0x07, 0xc0, 0x0f, 0xff, 0xf7, 0xab, 0xfe, 0x16, 0xe0, 0xd8, 0x07, 0xc0, 0x0f, 0x0d, 0xe0, ++ 0xd8, 0x07, 0xc0, 0x0f, 0x01, 0x21, 0xf5, 0xe7, 0x08, 0x8d, 0x01, 0x21, 0x80, 0x07, 0xc0, 0x0f, ++ 0xff, 0xf7, 0x9d, 0xfe, 0x38, 0x68, 0x00, 0x8d, 0xc0, 0x07, 0xc0, 0x0f, 0x00, 0x21, 0xe9, 0xe7, ++ 0xc8, 0x8c, 0x40, 0xb2, 0xff, 0xf7, 0x76, 0xf8, 0xff, 0xf7, 0x4e, 0xfe, 0x0f, 0x48, 0x00, 0x27, ++ 0x00, 0x68, 0x47, 0x87, 0x87, 0x87, 0xff, 0xf7, 0x42, 0xf8, 0x02, 0xa8, 0xff, 0xf7, 0xbc, 0xf9, ++ 0x00, 0x90, 0xa8, 0x8a, 0x20, 0x20, 0xc0, 0x43, 0xa8, 0x82, 0x20, 0x68, 0x80, 0x19, 0x47, 0x84, ++ 0x06, 0x48, 0x00, 0x68, 0xc1, 0x8c, 0x02, 0x7f, 0x49, 0x06, 0x49, 0x0c, 0x0a, 0x43, 0x82, 0x82, ++ 0x60, 0xe7, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, 0x40, 0xa0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x20, ++ 0x00, 0x01, 0x00, 0x20, 0x80, 0xa2, 0x01, 0x00, 0x00, 0x04, 0x00, 0x20, 0xcc, 0x07, 0x00, 0x00, ++ 0x26, 0x00, 0x00, 0x00, 0xff, 0xfd, 0x00, 0x00, 0x01, 0x0c, 0x79, 0x87, 0xb8, 0x87, 0xff, 0xf7, ++ 0x16, 0xf8, 0xa8, 0x8a, 0x20, 0x20, 0xc0, 0x43, 0xa8, 0x82, 0x21, 0x68, 0x00, 0x20, 0x89, 0x19, ++ 0x48, 0x84, 0xd5, 0xe7, 0xf0, 0xb5, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0xfa, 0x49, 0x81, 0x82, ++ 0xfa, 0x49, 0x00, 0x22, 0x0c, 0x68, 0x0d, 0x23, 0x5b, 0x03, 0xe4, 0x18, 0x62, 0x80, 0x84, 0x8a, ++ 0x01, 0x26, 0x86, 0x82, 0x69, 0x24, 0x0d, 0x68, 0x24, 0x01, 0xed, 0x18, 0xac, 0x80, 0x84, 0x8a, ++ 0x94, 0x1e, 0x84, 0x82, 0x0c, 0x68, 0xe4, 0x18, 0xe2, 0x80, 0x84, 0x8a, 0xf0, 0x4c, 0x84, 0x82, ++ 0x0c, 0x68, 0xe4, 0x18, 0x22, 0x81, 0x84, 0x8a, 0xee, 0x4c, 0x84, 0x82, 0x0c, 0x68, 0xe4, 0x18, ++ 0x22, 0x84, 0x84, 0x8a, 0xec, 0x4d, 0x85, 0x82, 0x0c, 0x68, 0xe4, 0x18, 0x62, 0x84, 0x84, 0x8a, ++ 0xea, 0x4c, 0x84, 0x82, 0x0f, 0x68, 0xdc, 0x10, 0xff, 0x18, 0x3c, 0x85, 0x84, 0x8a, 0x1f, 0x24, ++ 0xe4, 0x43, 0x84, 0x82, 0x0f, 0x68, 0x0d, 0x24, 0xff, 0x18, 0x7c, 0x85, 0x84, 0x8a, 0xe4, 0x4c, ++ 0x84, 0x82, 0x0c, 0x68, 0xe3, 0x18, 0x1e, 0x86, 0x83, 0x8a, 0xe2, 0x4b, 0x83, 0x82, 0x0c, 0x68, ++ 0xe1, 0x4b, 0xe4, 0x18, 0x22, 0x80, 0x84, 0x8a, 0xe0, 0x4e, 0x86, 0x82, 0x0c, 0x68, 0xe4, 0x18, ++ 0x62, 0x80, 0x84, 0x8a, 0x86, 0x82, 0x0c, 0x68, 0xe4, 0x18, 0xa2, 0x80, 0x84, 0x8a, 0xb4, 0x1c, ++ 0x84, 0x82, 0x0e, 0x68, 0xf6, 0x18, 0xf2, 0x80, 0x86, 0x8a, 0x84, 0x82, 0x0e, 0x68, 0xf6, 0x18, ++ 0x32, 0x81, 0x86, 0x8a, 0x84, 0x82, 0x0c, 0x68, 0xe4, 0x18, 0x62, 0x81, 0x84, 0x8a, 0xd4, 0x4c, ++ 0x84, 0x82, 0x0c, 0x68, 0xe4, 0x18, 0xa2, 0x81, 0x84, 0x8a, 0xc0, 0x24, 0xe4, 0x43, 0x84, 0x82, ++ 0x0e, 0x68, 0x40, 0x24, 0xf6, 0x18, 0xf4, 0x81, 0x84, 0x8a, 0x01, 0x24, 0xa4, 0x03, 0x84, 0x82, ++ 0x0c, 0x68, 0xe4, 0x18, 0xe2, 0x82, 0x84, 0x8a, 0xff, 0x24, 0x04, 0x34, 0x84, 0x82, 0x0c, 0x68, ++ 0xe4, 0x18, 0x22, 0x84, 0x84, 0x8a, 0x82, 0x82, 0x0c, 0x68, 0xe4, 0x18, 0x62, 0x84, 0x84, 0x8a, ++ 0x82, 0x82, 0x0c, 0x68, 0xe4, 0x18, 0xa2, 0x84, 0x84, 0x8a, 0x82, 0x82, 0x0c, 0x68, 0xe3, 0x18, ++ 0xda, 0x84, 0x83, 0x8a, 0x19, 0x23, 0xdb, 0x43, 0x83, 0x82, 0x0e, 0x68, 0x10, 0x24, 0xba, 0x4b, ++ 0x40, 0x33, 0xf6, 0x18, 0x34, 0x80, 0x84, 0x8a, 0x0f, 0x24, 0xe4, 0x43, 0x84, 0x82, 0x0c, 0x68, ++ 0xe4, 0x18, 0x62, 0x80, 0x84, 0x8a, 0xb0, 0x4c, 0x29, 0x34, 0x84, 0x82, 0x0e, 0x68, 0xf6, 0x18, ++ 0xb2, 0x80, 0x86, 0x8a, 0x84, 0x82, 0x0f, 0x68, 0x04, 0x26, 0xff, 0x18, 0x3e, 0x84, 0x86, 0x8a, ++ 0x84, 0x82, 0x0e, 0x68, 0xf3, 0x18, 0x1a, 0x85, 0x83, 0x8a, 0x82, 0x82, 0x0e, 0x68, 0xaa, 0x4b, ++ 0x80, 0x33, 0xf6, 0x18, 0x32, 0x80, 0x86, 0x8a, 0x82, 0x82, 0x0e, 0x68, 0xf6, 0x18, 0x72, 0x80, ++ 0x86, 0x8a, 0x84, 0x82, 0x0c, 0x68, 0xe3, 0x18, 0x9a, 0x80, 0x83, 0x8a, 0x85, 0x82, 0x0b, 0x68, ++ 0xa1, 0x4c, 0xc0, 0x34, 0x1b, 0x19, 0xda, 0x84, 0x83, 0x8a, 0x9d, 0x4b, 0xf1, 0x3b, 0x83, 0x82, ++ 0x08, 0x68, 0xa0, 0x49, 0x40, 0x18, 0x42, 0x84, 0xf0, 0xbd, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, ++ 0x00, 0x22, 0x8a, 0x82, 0x91, 0x49, 0x00, 0x02, 0x09, 0x68, 0x0d, 0x22, 0x52, 0x03, 0x89, 0x18, ++ 0x80, 0x30, 0x48, 0x83, 0x70, 0x47, 0x10, 0xb5, 0x00, 0x22, 0x11, 0x46, 0x96, 0x4c, 0x07, 0xe0, ++ 0xc3, 0x07, 0x02, 0xd0, 0x4b, 0x00, 0xe3, 0x5a, 0x5a, 0x40, 0x49, 0x1c, 0x89, 0xb2, 0x40, 0x08, ++ 0x00, 0x28, 0xf5, 0xd1, 0x10, 0x46, 0x27, 0xe5, 0xf0, 0xb5, 0x84, 0x48, 0x86, 0x4d, 0x00, 0x68, ++ 0x30, 0x35, 0x0d, 0x21, 0x49, 0x03, 0x40, 0x18, 0x86, 0x8b, 0x00, 0x27, 0x3c, 0x46, 0x09, 0xe0, ++ 0x38, 0x5d, 0x29, 0x0a, 0x48, 0x40, 0xff, 0xf7, 0xde, 0xff, 0x29, 0x02, 0x48, 0x40, 0x64, 0x1c, ++ 0x85, 0xb2, 0xa4, 0xb2, 0xb4, 0x42, 0xf3, 0xd3, 0x28, 0x46, 0xf0, 0xbd, 0x03, 0x22, 0x12, 0x07, ++ 0x93, 0x8a, 0x00, 0x23, 0x93, 0x82, 0x09, 0x07, 0x00, 0x01, 0x09, 0x0f, 0x08, 0x43, 0x00, 0x02, ++ 0x80, 0x21, 0x40, 0x30, 0x08, 0x43, 0x71, 0x49, 0x09, 0x68, 0x0d, 0x22, 0x52, 0x03, 0x89, 0x18, ++ 0x48, 0x83, 0x70, 0x47, 0xfe, 0xb5, 0x02, 0x46, 0x78, 0x48, 0x6c, 0x4f, 0x40, 0x7d, 0x00, 0x26, ++ 0xc0, 0x00, 0x01, 0x90, 0x76, 0x48, 0x13, 0x00, 0x04, 0x68, 0x21, 0x46, 0x80, 0x31, 0x00, 0x91, ++ 0x25, 0x46, 0x74, 0x49, 0x40, 0x35, 0x05, 0xf0, 0xe3, 0xf9, 0x15, 0x0c, 0x19, 0x18, 0x18, 0x8b, ++ 0xb8, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0, 0xef, 0xee, 0xed, 0x18, 0xec, 0xeb, 0xea, 0xe9, 0xe8, 0xe7, ++ 0x18, 0x00, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0xc0, 0x21, 0xc9, 0x43, 0x81, 0x82, 0x3a, 0x68, ++ 0x80, 0x21, 0x0d, 0x20, 0x40, 0x03, 0x10, 0x18, 0x41, 0x83, 0xfe, 0xbd, 0x57, 0x49, 0x09, 0x68, ++ 0x0d, 0x27, 0x7f, 0x03, 0xc9, 0x19, 0x49, 0x8b, 0x09, 0x0a, 0x06, 0xd0, 0x01, 0x29, 0x0a, 0xd0, ++ 0x02, 0x29, 0x2c, 0xd0, 0x01, 0x21, 0x08, 0x46, 0x34, 0xe1, 0xa8, 0x7c, 0x00, 0x28, 0xec, 0xd0, ++ 0x01, 0x20, 0x60, 0x74, 0xfb, 0xe1, 0x05, 0x46, 0x00, 0x98, 0x04, 0x21, 0x82, 0x7c, 0x57, 0x48, ++ 0x08, 0x24, 0x43, 0x7e, 0x9a, 0x42, 0x10, 0xd0, 0x83, 0x7e, 0x9a, 0x42, 0x02, 0xd1, 0x05, 0x21, ++ 0x09, 0x24, 0x0a, 0xe0, 0xc3, 0x7e, 0x9a, 0x42, 0x02, 0xd1, 0x06, 0x21, 0x0a, 0x24, 0x04, 0xe0, ++ 0x00, 0x7f, 0x82, 0x42, 0x01, 0xd1, 0x07, 0x21, 0x0b, 0x24, 0x08, 0x46, 0x00, 0xf0, 0x93, 0xff, ++ 0x20, 0x46, 0x00, 0xf0, 0x90, 0xff, 0x29, 0x68, 0x01, 0x20, 0x48, 0x74, 0xd7, 0xe1, 0x01, 0x21, ++ 0x69, 0x72, 0x66, 0x74, 0xfd, 0xf7, 0x84, 0xfe, 0x38, 0x48, 0x01, 0x68, 0xc9, 0x19, 0x89, 0x8e, ++ 0xc9, 0x07, 0x09, 0xd0, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x20, 0x22, 0xd2, 0x43, 0x8a, 0x82, ++ 0x00, 0x68, 0x20, 0x21, 0xc0, 0x19, 0x01, 0x84, 0x00, 0x20, 0xff, 0xf7, 0x36, 0xff, 0x3c, 0x49, ++ 0x3a, 0x4a, 0x09, 0x68, 0x53, 0x7e, 0x80, 0x31, 0x89, 0x7c, 0x04, 0x20, 0x08, 0x24, 0x99, 0x42, ++ 0x10, 0xd0, 0x93, 0x7e, 0x99, 0x42, 0x02, 0xd1, 0x05, 0x20, 0x09, 0x24, 0x0a, 0xe0, 0xd3, 0x7e, ++ 0x99, 0x42, 0x02, 0xd1, 0x06, 0x20, 0x0a, 0x24, 0x04, 0xe0, 0x12, 0x7f, 0x91, 0x42, 0x01, 0xd1, ++ 0x07, 0x20, 0x0b, 0x24, 0x00, 0xf0, 0x4d, 0xff, 0x20, 0x46, 0x00, 0xf0, 0x4a, 0xff, 0xfe, 0xbd, ++ 0x38, 0x68, 0x0d, 0x24, 0x64, 0x03, 0x00, 0x19, 0x40, 0x8b, 0x00, 0x0a, 0x06, 0xd0, 0x01, 0x28, ++ 0x0b, 0xd0, 0x02, 0x28, 0x13, 0xd0, 0x03, 0x28, 0x94, 0xd1, 0x17, 0xe0, 0x03, 0x20, 0x00, 0x07, ++ 0x81, 0x8a, 0x86, 0x82, 0x04, 0xf0, 0xf6, 0xfd, 0x05, 0xe0, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, ++ 0x86, 0x82, 0x04, 0xf0, 0xea, 0xfd, 0x39, 0x68, 0x09, 0x19, 0x88, 0x83, 0x7f, 0xe1, 0x03, 0x20, ++ 0x00, 0x07, 0x81, 0x8a, 0x86, 0x82, 0x00, 0x98, 0x80, 0x7c, 0xf4, 0xe7, 0x03, 0x20, 0x00, 0x07, ++ 0x81, 0x8a, 0x86, 0x82, 0x04, 0xf0, 0x08, 0xfe, 0xed, 0xe7, 0x3a, 0x68, 0x0d, 0x21, 0x49, 0x03, ++ 0x52, 0x18, 0x52, 0x8b, 0x12, 0x0a, 0x92, 0x1e, 0x13, 0x00, 0x05, 0xf0, 0x21, 0xf9, 0x05, 0x55, ++ 0x62, 0x7b, 0x8d, 0x33, 0x04, 0x00, 0xc2, 0xe7, 0x7f, 0xf8, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, ++ 0x80, 0x81, 0x00, 0x00, 0x1f, 0xbf, 0x00, 0x00, 0xcf, 0xff, 0x00, 0x00, 0xff, 0x83, 0x00, 0x00, ++ 0xf0, 0xfc, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x40, 0xa0, 0x01, 0x00, 0xfd, 0x13, 0x00, 0x00, ++ 0xc0, 0xc0, 0x00, 0x00, 0x80, 0xa1, 0x01, 0x00, 0xc4, 0x79, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, ++ 0x90, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x20, 0xf9, 0xe1, 0x88, 0xe1, 0xd9, 0xe1, 0xc3, 0xe1, ++ 0x44, 0xe1, 0xef, 0xe0, 0xdb, 0xe0, 0xc7, 0xe0, 0xb8, 0xe0, 0xa5, 0xe0, 0x98, 0xe0, 0x8e, 0xe0, ++ 0x82, 0xe0, 0x79, 0xe0, 0x62, 0x7c, 0x02, 0x2a, 0x01, 0xd3, 0x11, 0x46, 0x3c, 0xe1, 0xeb, 0x7c, ++ 0x01, 0x2b, 0x70, 0xd8, 0xab, 0x7c, 0x00, 0x2b, 0x01, 0xd1, 0x00, 0x2a, 0x87, 0xd0, 0x2a, 0x76, ++ 0x38, 0x68, 0x0d, 0x46, 0x40, 0x19, 0x80, 0x8b, 0xe0, 0x84, 0xfe, 0xf7, 0xd2, 0xff, 0x01, 0x00, ++ 0x01, 0xd0, 0x06, 0x20, 0x4e, 0xe0, 0xff, 0x48, 0x05, 0x21, 0x00, 0x68, 0x41, 0x74, 0x03, 0x21, ++ 0x09, 0x07, 0x8a, 0x8a, 0x8e, 0x82, 0x56, 0xe1, 0xa8, 0x7c, 0x00, 0x28, 0x02, 0xd1, 0x60, 0x7c, ++ 0x00, 0x28, 0xa8, 0xd0, 0x60, 0x7c, 0x28, 0x76, 0x01, 0x20, 0x60, 0x74, 0xff, 0xf7, 0xf4, 0xf9, ++ 0x05, 0xe1, 0x01, 0x21, 0x07, 0x46, 0x69, 0x72, 0x60, 0x7c, 0x02, 0x28, 0x0a, 0xd3, 0xf2, 0x48, ++ 0xf3, 0x4c, 0x06, 0x60, 0xf1, 0x48, 0x60, 0x81, 0x20, 0x81, 0x41, 0x1c, 0xf1, 0x48, 0x05, 0xf0, ++ 0x6f, 0xf8, 0x66, 0x75, 0xff, 0xf7, 0xee, 0xf9, 0x38, 0x68, 0x58, 0x21, 0x09, 0x5c, 0x41, 0x74, ++ 0x86, 0x82, 0xec, 0xe0, 0x60, 0x7c, 0x02, 0x28, 0x11, 0xd2, 0xe9, 0x7c, 0x01, 0x29, 0xb8, 0xd8, ++ 0xa9, 0x7c, 0x00, 0x29, 0x01, 0xd1, 0x00, 0x28, 0xb8, 0xd0, 0xe5, 0x49, 0x01, 0x20, 0x48, 0x75, ++ 0x60, 0x7c, 0x28, 0x76, 0x02, 0x20, 0x18, 0xe0, 0x60, 0x7c, 0x02, 0x28, 0x03, 0xd3, 0x01, 0x99, ++ 0x01, 0x43, 0xc9, 0xb2, 0xe0, 0xe0, 0xe9, 0x7c, 0x01, 0x29, 0xa2, 0xd8, 0xa9, 0x7c, 0x00, 0x29, ++ 0x05, 0xd1, 0x02, 0xe0, 0xff, 0xf7, 0x7a, 0xfe, 0xfe, 0xbd, 0x00, 0x28, 0xfc, 0xd0, 0xd8, 0x49, ++ 0x01, 0x20, 0x48, 0x75, 0x60, 0x7c, 0x28, 0x76, 0x03, 0x20, 0x60, 0x74, 0xff, 0xf7, 0x53, 0xf9, ++ 0xfe, 0xf7, 0x6d, 0xfd, 0xbb, 0xe0, 0xda, 0xe0, 0x38, 0x68, 0x0d, 0x22, 0x52, 0x03, 0x80, 0x18, ++ 0x40, 0x8b, 0x00, 0x0a, 0x20, 0x5c, 0x2a, 0xe0, 0x39, 0x68, 0x0d, 0x20, 0x40, 0x03, 0x09, 0x18, ++ 0x49, 0x8b, 0x3a, 0x68, 0x09, 0x0a, 0x10, 0x18, 0x80, 0x8b, 0x60, 0x54, 0xa7, 0xe0, 0x38, 0x68, ++ 0x0d, 0x22, 0x52, 0x03, 0x80, 0x18, 0x40, 0x8b, 0x01, 0x0a, 0xc5, 0x48, 0x40, 0x5c, 0x16, 0xe0, ++ 0x38, 0x68, 0x0d, 0x21, 0x49, 0x03, 0x40, 0x18, 0x80, 0x8b, 0x3a, 0x68, 0x51, 0x18, 0x49, 0x8b, ++ 0x0a, 0x0a, 0xbf, 0x49, 0x88, 0x54, 0x92, 0xe0, 0x38, 0x68, 0x0d, 0x22, 0x52, 0x03, 0x80, 0x18, ++ 0x40, 0x8b, 0x00, 0x0a, 0x21, 0x18, 0x49, 0x78, 0x20, 0x5c, 0x09, 0x02, 0x08, 0x43, 0x03, 0x21, ++ 0x09, 0x07, 0x8b, 0x8a, 0x8e, 0x82, 0x39, 0x68, 0x89, 0x18, 0xfe, 0xe6, 0x38, 0x68, 0x0d, 0x21, ++ 0x49, 0x03, 0x40, 0x18, 0x80, 0x8b, 0x3a, 0x68, 0x51, 0x18, 0x49, 0x8b, 0x09, 0x0a, 0x60, 0x54, ++ 0x00, 0x0a, 0x61, 0x18, 0x48, 0x70, 0x72, 0xe0, 0x38, 0x68, 0x0d, 0x23, 0x5b, 0x03, 0xc0, 0x18, ++ 0x40, 0x8b, 0xab, 0x4a, 0x00, 0x0a, 0x11, 0x18, 0x49, 0x78, 0x10, 0x5c, 0x09, 0x02, 0x08, 0x43, ++ 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x8e, 0x82, 0x39, 0x68, 0xc9, 0x18, 0xdd, 0xe6, 0x38, 0x68, ++ 0x0d, 0x21, 0x49, 0x03, 0x40, 0x18, 0x80, 0x8b, 0x3a, 0x68, 0x03, 0x0a, 0x52, 0x18, 0x52, 0x8b, ++ 0x14, 0x0a, 0x9f, 0x4a, 0xa4, 0x18, 0x63, 0x70, 0x3b, 0x68, 0x59, 0x18, 0x49, 0x8b, 0x09, 0x0a, ++ 0x50, 0x54, 0x4c, 0xe0, 0x60, 0x7c, 0x02, 0x28, 0x4d, 0xd2, 0x38, 0x68, 0x0d, 0x23, 0x5b, 0x03, ++ 0xc0, 0x18, 0x40, 0x8b, 0x00, 0x0a, 0x10, 0xd0, 0x01, 0x28, 0x23, 0xd0, 0x02, 0x28, 0x00, 0xd0, ++ 0x72, 0xe7, 0x93, 0x48, 0x90, 0x49, 0x46, 0x75, 0x0e, 0x60, 0x90, 0x49, 0x41, 0x81, 0x01, 0x81, ++ 0x49, 0x1c, 0x90, 0x48, 0x04, 0xf0, 0xac, 0xff, 0x2f, 0xe0, 0x00, 0x23, 0x00, 0x96, 0x1a, 0x46, ++ 0x11, 0x21, 0x02, 0x20, 0x01, 0x96, 0x04, 0xf0, 0x97, 0xfe, 0x89, 0x49, 0x01, 0x20, 0x48, 0x75, ++ 0x48, 0x89, 0x86, 0x4a, 0x08, 0x81, 0x90, 0x42, 0x01, 0xd1, 0x00, 0x20, 0x00, 0xe0, 0x40, 0x1c, ++ 0x08, 0x81, 0x1c, 0xe0, 0x82, 0x4c, 0x22, 0x89, 0x88, 0x5c, 0x61, 0x89, 0x8a, 0x42, 0x03, 0xd1, ++ 0xff, 0x21, 0x01, 0x31, 0x08, 0x43, 0x06, 0xe0, 0x7c, 0x49, 0x8a, 0x42, 0x01, 0xd1, 0x00, 0x22, ++ 0x00, 0xe0, 0x52, 0x1c, 0x22, 0x81, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x8e, 0x82, 0x3a, 0x68, ++ 0xc1, 0xb2, 0xd2, 0x18, 0x91, 0x83, 0x00, 0x0a, 0x01, 0xd0, 0x01, 0x20, 0x00, 0xe0, 0x00, 0x20, ++ 0xff, 0xf7, 0x73, 0xfd, 0xfe, 0xbd, 0x00, 0x21, 0x05, 0x20, 0x2b, 0xe7, 0x61, 0x7c, 0x02, 0x29, ++ 0x04, 0xd3, 0x01, 0x98, 0x08, 0x43, 0xc1, 0xb2, 0x0c, 0x20, 0x23, 0xe7, 0x3a, 0x68, 0x0d, 0x20, ++ 0x40, 0x03, 0x12, 0x18, 0x52, 0x8b, 0x12, 0x0a, 0x52, 0x07, 0x05, 0xd5, 0x3b, 0x68, 0x6a, 0x4a, ++ 0x9b, 0x18, 0x5b, 0x8e, 0xdb, 0x07, 0x05, 0xd0, 0xeb, 0x7c, 0x01, 0x2b, 0x09, 0xd9, 0x02, 0x21, ++ 0x0d, 0x20, 0x0f, 0xe7, 0x38, 0x68, 0x80, 0x18, 0x40, 0x8e, 0xc1, 0x07, 0xc9, 0x0f, 0x08, 0x20, ++ 0x08, 0xe7, 0xab, 0x7c, 0x00, 0x2b, 0x01, 0xd1, 0x00, 0x29, 0xd3, 0xd0, 0x5c, 0x4b, 0x01, 0x21, ++ 0x59, 0x75, 0x61, 0x7c, 0x29, 0x76, 0x04, 0x21, 0x61, 0x74, 0x39, 0x68, 0x05, 0x46, 0x48, 0x19, ++ 0x40, 0x8b, 0x00, 0x0a, 0xe0, 0x75, 0xff, 0xf7, 0xbf, 0xf9, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, ++ 0x86, 0x82, 0x50, 0x48, 0x00, 0x68, 0x39, 0x68, 0xc0, 0x8c, 0x49, 0x19, 0x35, 0xe6, 0x01, 0x21, ++ 0x69, 0x72, 0x4d, 0x48, 0x00, 0x21, 0x01, 0x60, 0x4c, 0x48, 0x4d, 0x4e, 0x41, 0x1c, 0x70, 0x81, ++ 0x30, 0x81, 0x4c, 0x48, 0x04, 0xf0, 0x24, 0xff, 0x00, 0x20, 0x70, 0x75, 0xe0, 0x7d, 0x41, 0x07, ++ 0x15, 0xd5, 0x44, 0x4c, 0x80, 0x07, 0x0e, 0xd4, 0x00, 0x99, 0x01, 0x20, 0x08, 0x56, 0x0f, 0x30, ++ 0x40, 0x10, 0xfe, 0xf7, 0x68, 0xff, 0x21, 0x68, 0x82, 0x20, 0x08, 0x56, 0x0f, 0x30, 0x40, 0x10, ++ 0xfe, 0xf7, 0x49, 0xff, 0x03, 0xe0, 0x0f, 0x20, 0x28, 0x56, 0xfe, 0xf7, 0xe5, 0xfe, 0xff, 0xf7, ++ 0x89, 0xf8, 0x38, 0x48, 0x00, 0x21, 0x00, 0x68, 0x81, 0x82, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, ++ 0x08, 0x22, 0xd2, 0x43, 0x8a, 0x82, 0x3a, 0x68, 0x08, 0x21, 0x38, 0x4b, 0xd2, 0x18, 0x11, 0x80, ++ 0x58, 0x21, 0x09, 0x5c, 0x41, 0x74, 0x7a, 0xe7, 0xa8, 0x88, 0xa2, 0x7d, 0x80, 0x18, 0x08, 0x5c, ++ 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x8e, 0x82, 0x3a, 0x68, 0x0d, 0x21, 0x49, 0x03, 0x51, 0x18, ++ 0x88, 0x83, 0xa0, 0x7d, 0xbf, 0x28, 0x01, 0xd3, 0x00, 0x20, 0x00, 0xe0, 0x40, 0x1c, 0xa0, 0x75, ++ 0x65, 0xe7, 0xaa, 0x88, 0xa0, 0x7d, 0x13, 0x18, 0xcb, 0x5c, 0xbf, 0x28, 0x01, 0xd3, 0x00, 0x20, ++ 0x00, 0xe0, 0x40, 0x1c, 0xc0, 0xb2, 0xa0, 0x75, 0x12, 0x18, 0x89, 0x5c, 0xbf, 0x28, 0x01, 0xd3, ++ 0x00, 0x20, 0x00, 0xe0, 0x40, 0x1c, 0xa0, 0x75, 0x03, 0x20, 0x00, 0x07, 0x82, 0x8a, 0x86, 0x82, ++ 0x18, 0x02, 0x08, 0x43, 0x3a, 0x68, 0x0d, 0x21, 0x49, 0x03, 0x51, 0x18, 0xc5, 0xe5, 0x03, 0x20, ++ 0x00, 0x07, 0x81, 0x8a, 0x86, 0x82, 0xff, 0xf7, 0xd7, 0xfc, 0xf3, 0xe7, 0x70, 0xb5, 0x01, 0xf0, ++ 0x63, 0xfa, 0x10, 0x49, 0x00, 0x20, 0x0b, 0x68, 0x11, 0x49, 0x18, 0x86, 0x1a, 0x46, 0x58, 0x86, ++ 0x80, 0x32, 0x90, 0x72, 0x1c, 0x46, 0xd0, 0x72, 0x40, 0x34, 0x20, 0x72, 0x60, 0x72, 0xa0, 0x72, ++ 0xe0, 0x72, 0x20, 0x73, 0xd0, 0x73, 0xa0, 0x73, 0x89, 0x7f, 0xe1, 0x73, 0x19, 0x46, 0x20, 0x74, ++ 0x60, 0x31, 0xc8, 0x75, 0x10, 0x71, 0x50, 0x71, 0x20, 0x75, 0xa0, 0x75, 0x08, 0x71, 0x48, 0x71, ++ 0x50, 0x72, 0x0d, 0xe0, 0x90, 0x00, 0x00, 0x20, 0x88, 0x00, 0x00, 0x20, 0xff, 0x02, 0x00, 0x00, ++ 0x00, 0x04, 0x00, 0x20, 0x00, 0x01, 0x00, 0x20, 0x80, 0xa1, 0x01, 0x00, 0x80, 0xa0, 0x01, 0x00, ++ 0xe0, 0x77, 0x58, 0x85, 0x88, 0x71, 0xc8, 0x71, 0x08, 0x72, 0x98, 0x85, 0xd8, 0x85, 0x48, 0x72, ++ 0x08, 0x75, 0xc8, 0x74, 0x48, 0x75, 0x88, 0x75, 0x48, 0x76, 0x88, 0x76, 0xc8, 0x76, 0x08, 0x77, ++ 0x90, 0x75, 0x10, 0x76, 0x01, 0x25, 0xd5, 0x75, 0x60, 0x80, 0x50, 0x76, 0x90, 0x76, 0xd0, 0x76, ++ 0x58, 0x82, 0x58, 0x73, 0x98, 0x73, 0xd8, 0x73, 0x18, 0x74, 0x48, 0x77, 0x88, 0x77, 0xc8, 0x77, ++ 0x10, 0x70, 0x08, 0x76, 0x90, 0x71, 0x98, 0x86, 0x10, 0x74, 0x70, 0xbd, 0x10, 0xb5, 0xff, 0xf7, ++ 0x89, 0xfb, 0xff, 0xf7, 0xa3, 0xff, 0x00, 0x21, 0x01, 0x20, 0x01, 0xf0, 0x81, 0xfb, 0x00, 0x21, ++ 0x02, 0x20, 0x01, 0xf0, 0x7d, 0xfb, 0x00, 0x21, 0x03, 0x20, 0x01, 0xf0, 0x79, 0xfb, 0x00, 0x21, ++ 0x04, 0x20, 0x01, 0xf0, 0x75, 0xfb, 0x00, 0x21, 0x05, 0x20, 0x01, 0xf0, 0x71, 0xfb, 0x62, 0xe4, ++ 0xf8, 0x48, 0x00, 0x68, 0xf8, 0x49, 0x40, 0x18, 0x80, 0x8a, 0xf8, 0x49, 0x00, 0x06, 0x02, 0x0f, ++ 0x08, 0x7c, 0xd2, 0x1e, 0x0b, 0x2a, 0x02, 0xd3, 0x10, 0x22, 0x10, 0x43, 0x01, 0xe0, 0xef, 0x22, ++ 0x10, 0x40, 0x08, 0x74, 0x70, 0x47, 0x70, 0xb5, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0xf0, 0x49, ++ 0x81, 0x82, 0xec, 0x49, 0x01, 0x22, 0x0c, 0x68, 0xd2, 0x02, 0xeb, 0x4b, 0x40, 0x3b, 0xe4, 0x18, ++ 0x22, 0x85, 0x82, 0x8a, 0x40, 0x22, 0xd2, 0x43, 0x82, 0x82, 0x0c, 0x68, 0x40, 0x22, 0xe4, 0x18, ++ 0x22, 0x84, 0xe6, 0x4a, 0xd2, 0x7b, 0x00, 0x2a, 0x2b, 0xd1, 0x82, 0x8a, 0xe5, 0x4a, 0x82, 0x82, ++ 0x0d, 0x68, 0x84, 0x14, 0xe0, 0x4a, 0xad, 0x18, 0xec, 0x81, 0x85, 0x8a, 0xe2, 0x4d, 0x85, 0x82, ++ 0x0e, 0x68, 0x80, 0x25, 0xb6, 0x18, 0xf5, 0x81, 0x85, 0x8a, 0xe0, 0x4d, 0x85, 0x82, 0x0d, 0x68, ++ 0xad, 0x18, 0xec, 0x80, 0x84, 0x8a, 0xde, 0x4c, 0x84, 0x82, 0xff, 0x24, 0x0d, 0x68, 0xc1, 0x34, ++ 0xad, 0x18, 0xec, 0x80, 0x84, 0x8a, 0x78, 0x24, 0xe4, 0x43, 0x84, 0x82, 0x0d, 0x68, 0x08, 0x24, ++ 0xaa, 0x18, 0x14, 0x80, 0x82, 0x8a, 0xd7, 0x4a, 0x82, 0x82, 0x09, 0x68, 0xa0, 0x02, 0xc9, 0x18, ++ 0xc8, 0x84, 0x70, 0xbd, 0x70, 0x47, 0x70, 0xb5, 0x04, 0xf0, 0xdc, 0xfa, 0xcb, 0x4a, 0xd1, 0x88, ++ 0x00, 0x29, 0x14, 0xd0, 0xcb, 0x08, 0xc0, 0x1a, 0x08, 0x18, 0xd0, 0x80, 0x10, 0x7b, 0x01, 0x21, ++ 0x14, 0x28, 0x0e, 0xd2, 0xcc, 0x4b, 0xcd, 0x4d, 0x43, 0x43, 0x5b, 0x19, 0x9b, 0x12, 0xd4, 0x88, ++ 0x5b, 0x1c, 0x5b, 0x10, 0x9c, 0x42, 0x04, 0xdc, 0xd1, 0x74, 0x40, 0x1c, 0x0f, 0xe0, 0xc0, 0x00, ++ 0xeb, 0xe7, 0x00, 0x28, 0x0d, 0xd0, 0xc4, 0x4b, 0xc5, 0x4d, 0x43, 0x43, 0x5b, 0x19, 0x9b, 0x12, ++ 0xd4, 0x88, 0x5b, 0x1c, 0x5b, 0x10, 0x9c, 0x42, 0x03, 0xdb, 0xd1, 0x74, 0x40, 0x1e, 0x10, 0x73, ++ 0x70, 0xbd, 0x00, 0x20, 0xd0, 0x74, 0x70, 0xbd, 0x70, 0xb5, 0x24, 0x21, 0xb3, 0x48, 0x04, 0xf0, ++ 0xb7, 0xfd, 0xb2, 0x4c, 0x26, 0x20, 0x20, 0x80, 0xba, 0x48, 0xa0, 0x80, 0x0c, 0x20, 0xa0, 0x73, ++ 0x0b, 0x20, 0x00, 0x26, 0x20, 0x73, 0xe6, 0x74, 0x26, 0x75, 0x66, 0x75, 0x04, 0xf0, 0x9a, 0xfa, ++ 0xc0, 0x00, 0xe0, 0x80, 0x00, 0x25, 0xff, 0xf7, 0xb6, 0xff, 0x6d, 0x1c, 0xed, 0xb2, 0x08, 0x2d, ++ 0xf9, 0xd3, 0xa4, 0x48, 0x00, 0x68, 0xa4, 0x49, 0x40, 0x18, 0xc0, 0x8f, 0x28, 0x21, 0x00, 0x07, ++ 0x00, 0x0f, 0xe0, 0x73, 0x26, 0x74, 0x01, 0x20, 0x60, 0x73, 0xa1, 0x75, 0x04, 0x21, 0xe1, 0x75, ++ 0x10, 0x21, 0x21, 0x76, 0x66, 0x76, 0xa0, 0x76, 0x02, 0x20, 0xe0, 0x76, 0x03, 0x20, 0x20, 0x77, ++ 0x24, 0x20, 0x60, 0x77, 0x20, 0x20, 0xa0, 0x77, 0x05, 0x20, 0xe6, 0x77, 0xc0, 0x01, 0x20, 0x84, ++ 0x0b, 0x20, 0x80, 0x01, 0x60, 0x84, 0x5f, 0x21, 0xc9, 0x00, 0x9f, 0x48, 0x04, 0xf0, 0x78, 0xfd, ++ 0x9e, 0x48, 0x06, 0x60, 0x9e, 0x48, 0x60, 0x81, 0x20, 0x81, 0x41, 0x1c, 0x9a, 0x48, 0x04, 0xf0, ++ 0x6f, 0xfd, 0x70, 0xbd, 0x10, 0xb5, 0x9b, 0x48, 0x00, 0x21, 0x00, 0x68, 0x0a, 0x23, 0x02, 0x46, ++ 0x01, 0x80, 0x40, 0x32, 0x93, 0x71, 0xd1, 0x71, 0xc1, 0x72, 0x81, 0x72, 0x01, 0x73, 0x41, 0x73, ++ 0x81, 0x73, 0x01, 0x74, 0xc1, 0x73, 0x41, 0x82, 0x41, 0x74, 0x91, 0x74, 0x01, 0x71, 0x81, 0x71, ++ 0xc1, 0x71, 0x01, 0x72, 0x41, 0x72, 0x41, 0x77, 0x02, 0x22, 0x42, 0x71, 0x01, 0x22, 0x82, 0x70, ++ 0x80, 0x30, 0x01, 0x72, 0xff, 0xf7, 0x92, 0xfe, 0x01, 0xe7, 0x70, 0xb5, 0x7b, 0x4a, 0x79, 0x4b, ++ 0xd0, 0x7b, 0x00, 0x28, 0x22, 0xd1, 0x18, 0x68, 0x77, 0x4c, 0x00, 0x19, 0x80, 0x8a, 0x0f, 0x21, ++ 0x00, 0x06, 0x00, 0x0f, 0x09, 0x1a, 0x03, 0x20, 0x00, 0x07, 0x85, 0x8a, 0x77, 0x4d, 0x0f, 0x3d, ++ 0x85, 0x82, 0x8d, 0x02, 0x1e, 0x68, 0x0d, 0x43, 0x36, 0x19, 0xb5, 0x84, 0x85, 0x8a, 0x0f, 0x25, ++ 0xed, 0x43, 0x85, 0x82, 0x1d, 0x68, 0x2c, 0x19, 0xa1, 0x85, 0x81, 0x8a, 0x2a, 0x21, 0xc9, 0x43, ++ 0x81, 0x82, 0x19, 0x68, 0x2a, 0x20, 0x78, 0x4c, 0x09, 0x19, 0x88, 0x81, 0x19, 0x68, 0x76, 0x48, ++ 0x40, 0x30, 0x09, 0x18, 0x09, 0x8c, 0xc9, 0x06, 0xc9, 0x0e, 0x51, 0x76, 0x19, 0x68, 0x09, 0x18, ++ 0x49, 0x8c, 0xc9, 0x06, 0xc9, 0x0e, 0x91, 0x76, 0x19, 0x68, 0x09, 0x18, 0x89, 0x8c, 0xc9, 0x06, ++ 0xc9, 0x0e, 0xd1, 0x76, 0x19, 0x68, 0x08, 0x18, 0xc0, 0x8c, 0xc0, 0x06, 0xc0, 0x0e, 0x10, 0x77, ++ 0x70, 0xbd, 0xf8, 0xb5, 0x57, 0x4d, 0x29, 0x68, 0x67, 0x48, 0xc0, 0x30, 0x08, 0x18, 0xc0, 0x8a, ++ 0x64, 0x4f, 0x01, 0x07, 0x38, 0x68, 0x09, 0x0f, 0x40, 0x30, 0xc1, 0x74, 0x53, 0x48, 0x03, 0x24, ++ 0xc0, 0x7b, 0x51, 0x4e, 0x24, 0x07, 0x00, 0x28, 0x2e, 0xd1, 0x28, 0x68, 0x80, 0x19, 0x80, 0x8a, ++ 0x0f, 0x21, 0x00, 0x06, 0x00, 0x0f, 0x0b, 0x1a, 0xa0, 0x8a, 0x5c, 0x48, 0xa0, 0x82, 0x2a, 0x68, ++ 0x19, 0x03, 0x49, 0x48, 0x40, 0x38, 0x12, 0x18, 0x11, 0x85, 0xa1, 0x8a, 0x0f, 0x21, 0xc9, 0x43, ++ 0xa1, 0x82, 0x29, 0x68, 0x09, 0x18, 0x4b, 0x85, 0xa1, 0x8a, 0x03, 0x21, 0xc9, 0x43, 0xa1, 0x82, ++ 0x2a, 0x68, 0x03, 0x21, 0x10, 0x18, 0x01, 0x86, 0xa0, 0x8a, 0x78, 0x20, 0xc0, 0x43, 0xa0, 0x82, ++ 0x29, 0x68, 0xd8, 0x00, 0x89, 0x19, 0x08, 0x80, 0xa0, 0x8a, 0x02, 0x20, 0xc0, 0x43, 0xa0, 0x82, ++ 0x29, 0x68, 0x02, 0x20, 0x89, 0x19, 0x48, 0x82, 0xfd, 0xf7, 0xfa, 0xf9, 0x38, 0x68, 0x36, 0x4a, ++ 0x01, 0x78, 0x47, 0x4b, 0x4f, 0x07, 0xc0, 0x3a, 0x00, 0x21, 0x00, 0x2f, 0x09, 0xdb, 0x53, 0x27, ++ 0x3f, 0x5c, 0x00, 0x2f, 0x0b, 0xd1, 0x31, 0x4f, 0x3f, 0x78, 0xbf, 0x06, 0xff, 0x0e, 0x06, 0x2f, ++ 0x05, 0xd3, 0xa7, 0x8a, 0xa3, 0x82, 0x2b, 0x68, 0x9b, 0x18, 0x19, 0x80, 0x05, 0xe0, 0xa7, 0x8a, ++ 0xa3, 0x82, 0x2f, 0x68, 0x04, 0x23, 0xbf, 0x18, 0x3b, 0x80, 0x03, 0x78, 0x5b, 0x07, 0x12, 0xd4, ++ 0x53, 0x23, 0x1b, 0x5c, 0x00, 0x2b, 0x0e, 0xd1, 0x24, 0x4b, 0x1b, 0x78, 0x9b, 0x06, 0xdb, 0x0e, ++ 0x0e, 0x2b, 0x08, 0xd9, 0xa3, 0x8a, 0x80, 0x23, 0xdb, 0x43, 0xa3, 0x82, 0x2f, 0x68, 0x80, 0x23, ++ 0xba, 0x18, 0x13, 0x80, 0x06, 0xe0, 0xa3, 0x8a, 0x80, 0x23, 0xdb, 0x43, 0xa3, 0x82, 0x2b, 0x68, ++ 0x9a, 0x18, 0x11, 0x80, 0x02, 0x78, 0x52, 0x07, 0x14, 0xd5, 0x53, 0x22, 0x12, 0x5c, 0x00, 0x2a, ++ 0x10, 0xd1, 0x16, 0x4a, 0x12, 0x78, 0x92, 0x06, 0xd2, 0x0e, 0x16, 0x2a, 0x0a, 0xd9, 0xa2, 0x8a, ++ 0x02, 0x22, 0xd2, 0x43, 0xa2, 0x82, 0x2f, 0x68, 0x02, 0x22, 0x0f, 0x4b, 0x40, 0x3b, 0xfb, 0x18, ++ 0x9a, 0x85, 0x08, 0xe0, 0xa2, 0x8a, 0x02, 0x22, 0xd2, 0x43, 0xa2, 0x82, 0x2b, 0x68, 0x0a, 0x4a, ++ 0x40, 0x3a, 0x9a, 0x18, 0x91, 0x85, 0x02, 0x78, 0x53, 0x07, 0x09, 0x4a, 0xa3, 0x8a, 0xa2, 0x82, ++ 0x30, 0xd5, 0x01, 0x23, 0x2f, 0x68, 0xdb, 0x02, 0x03, 0x4a, 0x40, 0x3a, 0xba, 0x18, 0x53, 0x85, ++ 0x2c, 0xe0, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, 0x40, 0xa1, 0x01, 0x00, 0x00, 0x04, 0x00, 0x20, ++ 0xff, 0xf7, 0x00, 0x00, 0xff, 0xe1, 0x00, 0x00, 0x1f, 0xfe, 0x00, 0x00, 0xff, 0xc3, 0x00, 0x00, ++ 0x3f, 0xfc, 0x00, 0x00, 0xff, 0xdf, 0x00, 0x00, 0x99, 0x56, 0xfc, 0xff, 0xe6, 0xf7, 0xd3, 0x00, ++ 0x5a, 0x60, 0xda, 0x00, 0x01, 0xd1, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, 0x88, 0x00, 0x00, 0x20, ++ 0xff, 0x02, 0x00, 0x00, 0x90, 0x00, 0x00, 0x20, 0x40, 0xa2, 0x01, 0x00, 0xff, 0x0f, 0x00, 0x00, ++ 0xfb, 0xff, 0x00, 0x00, 0x2b, 0x68, 0xfe, 0x4a, 0x9a, 0x18, 0x51, 0x85, 0x2a, 0x68, 0xff, 0x32, ++ 0x01, 0x32, 0x92, 0x8d, 0x92, 0x07, 0xd3, 0x0f, 0x02, 0x46, 0x80, 0x32, 0x53, 0x75, 0x94, 0x46, ++ 0x00, 0x2b, 0xf8, 0x4a, 0xa3, 0x8a, 0xa2, 0x82, 0x02, 0xd0, 0x1b, 0x23, 0x5b, 0x01, 0x01, 0xe0, ++ 0x11, 0x23, 0x5b, 0x01, 0x2f, 0x68, 0xf2, 0x4a, 0x80, 0x32, 0xba, 0x18, 0x13, 0x80, 0x62, 0x46, ++ 0x52, 0x7d, 0x00, 0x2a, 0x07, 0xd0, 0xa2, 0x8a, 0xef, 0x4a, 0xa2, 0x82, 0x07, 0x22, 0x2b, 0x68, ++ 0xd2, 0x02, 0x9b, 0x19, 0x5a, 0x81, 0xa2, 0x8a, 0x01, 0x22, 0xd2, 0x43, 0xa2, 0x82, 0x2f, 0x68, ++ 0x01, 0x22, 0x0d, 0x23, 0x5b, 0x03, 0xfb, 0x18, 0x5a, 0x80, 0x40, 0x30, 0xc2, 0x7c, 0xe5, 0x48, ++ 0x92, 0x1e, 0xe0, 0x30, 0x13, 0x00, 0x04, 0xf0, 0x33, 0xfc, 0x08, 0x05, 0x05, 0x05, 0x0a, 0x0a, ++ 0x05, 0x05, 0x0a, 0x14, 0xa2, 0x8a, 0xa0, 0x82, 0xff, 0x22, 0x01, 0x32, 0x03, 0xe0, 0xa2, 0x8a, ++ 0xa0, 0x82, 0x01, 0x22, 0x52, 0x02, 0x2b, 0x68, 0x0d, 0x20, 0x40, 0x03, 0x18, 0x18, 0xc2, 0x80, ++ 0x06, 0xe0, 0xa2, 0x8a, 0xa0, 0x82, 0x2a, 0x68, 0x0d, 0x20, 0x40, 0x03, 0x10, 0x18, 0xc1, 0x80, ++ 0x2a, 0x68, 0xd6, 0x48, 0x10, 0x18, 0xc0, 0x8e, 0x00, 0x07, 0x00, 0x0f, 0x01, 0x28, 0x0f, 0xd0, ++ 0x04, 0x28, 0xa0, 0x8a, 0xd2, 0x48, 0xa0, 0x82, 0x28, 0x68, 0x11, 0xd0, 0x80, 0x19, 0x01, 0x80, ++ 0xa0, 0x8a, 0x01, 0x20, 0xc0, 0x43, 0xa0, 0x82, 0x28, 0x68, 0x80, 0x19, 0x41, 0x80, 0xf8, 0xbd, ++ 0xa0, 0x8a, 0xcb, 0x48, 0xa0, 0x82, 0x2a, 0x68, 0x80, 0x20, 0x92, 0x19, 0x10, 0x80, 0xef, 0xe7, ++ 0x80, 0x19, 0x01, 0x80, 0xa0, 0x8a, 0x01, 0x20, 0xc0, 0x43, 0xa0, 0x82, 0x29, 0x68, 0x01, 0x20, ++ 0x89, 0x19, 0x48, 0x80, 0xf8, 0xbd, 0xf8, 0xb5, 0x1f, 0x20, 0x01, 0xf0, 0x9e, 0xfd, 0x01, 0xf0, ++ 0x2b, 0xfb, 0xc0, 0x4f, 0x03, 0x24, 0x39, 0x68, 0x60, 0x31, 0x08, 0x70, 0x24, 0x07, 0xa0, 0x8a, ++ 0x09, 0x20, 0xc0, 0x43, 0xa0, 0x82, 0xbc, 0x4d, 0x08, 0x20, 0x29, 0x68, 0xb4, 0x4e, 0x80, 0x3e, ++ 0x89, 0x19, 0x08, 0x80, 0x00, 0x20, 0xfe, 0xf7, 0xf5, 0xf8, 0xb8, 0x49, 0xb8, 0x4a, 0xc8, 0x7f, ++ 0x03, 0x06, 0x15, 0xd5, 0xa3, 0x8a, 0xa2, 0x82, 0x40, 0x06, 0x40, 0x0e, 0x2a, 0x68, 0x92, 0x19, ++ 0x50, 0x80, 0xb0, 0x48, 0x00, 0x27, 0x00, 0x68, 0x02, 0x46, 0x40, 0x32, 0xd6, 0x7c, 0x33, 0x00, ++ 0x04, 0xf0, 0xbe, 0xfb, 0x09, 0x1b, 0x19, 0x43, 0x14, 0x43, 0x43, 0x14, 0x43, 0x14, 0x43, 0x00, ++ 0x38, 0x68, 0x03, 0x88, 0x9c, 0x46, 0x1b, 0x06, 0xeb, 0xd4, 0x83, 0x79, 0xdb, 0x07, 0xe8, 0xd1, ++ 0x63, 0x46, 0xa0, 0x8a, 0x5b, 0x07, 0xa2, 0x82, 0x07, 0x20, 0xdf, 0xe7, 0x2a, 0x21, 0xd1, 0x73, ++ 0x15, 0x21, 0x11, 0x74, 0x0d, 0xe0, 0xd7, 0x73, 0x0a, 0xe0, 0x03, 0x79, 0x1e, 0x06, 0x02, 0xd5, ++ 0x59, 0x06, 0x49, 0x0e, 0x03, 0xe0, 0x03, 0x78, 0x5b, 0x07, 0x1e, 0xd5, 0x49, 0x7f, 0xd1, 0x73, ++ 0x17, 0x74, 0x60, 0x30, 0xc7, 0x75, 0x0f, 0x20, 0x96, 0x4e, 0x10, 0x56, 0xfe, 0xf7, 0x2c, 0xfb, ++ 0x31, 0x68, 0x50, 0x20, 0x08, 0x56, 0xfe, 0xf7, 0xe1, 0xfa, 0x30, 0x68, 0x95, 0x4f, 0x00, 0x78, ++ 0x40, 0x07, 0x1b, 0xd5, 0x01, 0xf0, 0xef, 0xfd, 0x30, 0x68, 0x01, 0x78, 0x49, 0x07, 0x15, 0xd5, ++ 0x40, 0x30, 0xc0, 0x7c, 0x01, 0x28, 0x02, 0xd0, 0x10, 0xe0, 0x89, 0x7f, 0xdf, 0xe7, 0xa0, 0x8a, ++ 0x10, 0x20, 0xc0, 0x43, 0xa0, 0x82, 0x2a, 0x68, 0x10, 0x21, 0x81, 0x48, 0x12, 0x18, 0xd1, 0x84, ++ 0xa1, 0x8a, 0xa7, 0x82, 0x2a, 0x68, 0x20, 0x21, 0x10, 0x18, 0xc1, 0x84, 0xa0, 0x8a, 0xa7, 0x82, ++ 0x29, 0x68, 0x20, 0x20, 0x0d, 0x22, 0x52, 0x03, 0x89, 0x18, 0x08, 0x84, 0x30, 0x68, 0x01, 0x21, ++ 0x40, 0x30, 0x81, 0x73, 0xf8, 0xbd, 0x10, 0xb5, 0x7a, 0x4c, 0x20, 0x68, 0x60, 0x30, 0x00, 0x78, ++ 0x01, 0xf0, 0x0b, 0xfd, 0x21, 0x68, 0x61, 0x20, 0x08, 0x56, 0xfe, 0xf7, 0x73, 0xf8, 0x21, 0x68, ++ 0x00, 0x20, 0x40, 0x31, 0x88, 0x73, 0x0f, 0x20, 0x08, 0x56, 0xfe, 0xf7, 0xe5, 0xfa, 0x21, 0x68, ++ 0x50, 0x20, 0x08, 0x56, 0xfe, 0xf7, 0x9a, 0xfa, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x20, 0x21, ++ 0xc9, 0x43, 0x81, 0x82, 0x6c, 0x49, 0x20, 0x20, 0x09, 0x68, 0x0d, 0x22, 0x52, 0x03, 0x89, 0x18, ++ 0x08, 0x84, 0x20, 0x68, 0x01, 0x21, 0x40, 0x30, 0x81, 0x73, 0xa8, 0xe4, 0x30, 0xb5, 0x66, 0x4c, ++ 0x20, 0x68, 0x5f, 0x4d, 0xc0, 0x3d, 0x40, 0x19, 0xc0, 0x8e, 0x21, 0x68, 0x80, 0x04, 0x40, 0x0f, ++ 0x49, 0x19, 0xc9, 0x8e, 0x49, 0x05, 0x49, 0x0f, 0x40, 0x18, 0x21, 0x68, 0x40, 0x08, 0x49, 0x19, ++ 0xc9, 0x8e, 0x89, 0x06, 0x89, 0x0e, 0x43, 0x18, 0x20, 0x68, 0x40, 0x19, 0x00, 0x8f, 0x21, 0x68, ++ 0x80, 0x04, 0x40, 0x0f, 0x49, 0x19, 0x09, 0x8f, 0xc9, 0x06, 0xc9, 0x0e, 0x40, 0x18, 0x21, 0x68, ++ 0x49, 0x19, 0x09, 0x8f, 0x89, 0x09, 0xc9, 0x07, 0xc9, 0x0f, 0x00, 0xd0, 0x40, 0x42, 0x21, 0x68, ++ 0x49, 0x19, 0x09, 0x8f, 0x22, 0x68, 0x49, 0x05, 0x49, 0x0f, 0x52, 0x19, 0x12, 0x8f, 0xd2, 0x06, ++ 0xd2, 0x0e, 0x89, 0x18, 0x22, 0x68, 0x52, 0x19, 0x12, 0x8f, 0x52, 0x09, 0xd2, 0x07, 0xd2, 0x0f, ++ 0x00, 0xd0, 0x49, 0x42, 0x40, 0x18, 0x42, 0x10, 0x20, 0x68, 0x40, 0x19, 0x40, 0x8f, 0x80, 0x06, ++ 0x81, 0x16, 0x20, 0x68, 0x40, 0x19, 0x40, 0x8f, 0x24, 0x68, 0x40, 0x05, 0xc0, 0x16, 0x65, 0x19, ++ 0x3a, 0x24, 0x2c, 0x5f, 0xe4, 0x12, 0x00, 0x2b, 0x00, 0xda, 0x5b, 0x42, 0x00, 0x2a, 0x00, 0xda, ++ 0x52, 0x42, 0x9a, 0x18, 0x00, 0x29, 0x00, 0xda, 0x49, 0x42, 0x51, 0x18, 0x00, 0x28, 0x00, 0xda, ++ 0x40, 0x42, 0x08, 0x18, 0x00, 0x2c, 0x00, 0xda, 0x64, 0x42, 0x00, 0x19, 0x80, 0xb2, 0x30, 0xbd, ++ 0xf0, 0xb5, 0x35, 0x4c, 0x21, 0x68, 0x2e, 0x48, 0xc0, 0x38, 0x09, 0x18, 0xc9, 0x8e, 0x22, 0x68, ++ 0x89, 0x04, 0x49, 0x0f, 0x12, 0x18, 0xd2, 0x8e, 0x52, 0x05, 0x52, 0x0f, 0x89, 0x18, 0x22, 0x68, ++ 0x49, 0x08, 0x12, 0x18, 0xd2, 0x8e, 0x92, 0x06, 0x92, 0x0e, 0x8e, 0x18, 0x21, 0x68, 0x09, 0x18, ++ 0x09, 0x8f, 0x22, 0x68, 0x89, 0x04, 0x49, 0x0f, 0x12, 0x18, 0x12, 0x8f, 0xd2, 0x06, 0xd2, 0x0e, ++ 0x89, 0x18, 0x22, 0x68, 0x12, 0x18, 0x12, 0x8f, 0x92, 0x09, 0xd2, 0x07, 0xd2, 0x0f, 0x00, 0xd0, ++ 0x49, 0x42, 0x22, 0x68, 0x12, 0x18, 0x12, 0x8f, 0x23, 0x68, 0x52, 0x05, 0x52, 0x0f, 0x1b, 0x18, ++ 0x1b, 0x8f, 0xdb, 0x06, 0xdb, 0x0e, 0xd2, 0x18, 0x23, 0x68, 0x1b, 0x18, 0x1b, 0x8f, 0x5b, 0x09, ++ 0xdb, 0x07, 0xdb, 0x0f, 0x00, 0xd0, 0x52, 0x42, 0x89, 0x18, 0x4a, 0x10, 0x21, 0x68, 0x10, 0x48, ++ 0xc0, 0x38, 0x09, 0x18, 0x49, 0x8f, 0x27, 0x68, 0x89, 0x06, 0x89, 0x16, 0x55, 0x18, 0x4b, 0x00, ++ 0x5d, 0x19, 0x3f, 0x18, 0x7f, 0x8f, 0x7f, 0x05, 0xff, 0x16, 0x7f, 0x00, 0xed, 0x19, 0x27, 0x68, ++ 0x3f, 0x18, 0x3a, 0x20, 0x38, 0x5e, 0xc0, 0x12, 0x28, 0x18, 0x0a, 0x4d, 0x2d, 0x68, 0x2d, 0x88, ++ 0xaf, 0x06, 0xbf, 0x0f, 0x02, 0x2f, 0x28, 0xd1, 0x6d, 0x07, 0x26, 0xd5, 0x50, 0x00, 0x13, 0xe0, ++ 0x00, 0xa1, 0x01, 0x00, 0x1f, 0xfc, 0x00, 0x00, 0xff, 0xc7, 0x00, 0x00, 0x00, 0xa3, 0x01, 0x00, ++ 0x7f, 0xff, 0xff, 0xff, 0x90, 0x00, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, 0x00, 0x04, 0x00, 0x20, ++ 0xf0, 0xff, 0x00, 0x00, 0xdf, 0xff, 0x00, 0x00, 0x80, 0x19, 0x40, 0x18, 0x22, 0x68, 0xc1, 0x18, ++ 0x2e, 0x48, 0x12, 0x18, 0x52, 0x8f, 0x52, 0x05, 0xd2, 0x16, 0x52, 0x00, 0x89, 0x18, 0x22, 0x68, ++ 0x12, 0x18, 0x3a, 0x20, 0x10, 0x5e, 0xc0, 0x12, 0x08, 0x18, 0xf0, 0xbd, 0x00, 0xb5, 0xff, 0xf7, ++ 0x15, 0xff, 0x81, 0x00, 0x40, 0x00, 0x08, 0x18, 0x80, 0xb2, 0x00, 0xbd, 0x00, 0xb5, 0x00, 0x22, ++ 0xfd, 0xf7, 0x57, 0xff, 0x00, 0x28, 0x01, 0xda, 0x40, 0x42, 0x01, 0x22, 0x20, 0x49, 0x09, 0x68, ++ 0x1e, 0x4b, 0x40, 0x33, 0xc9, 0x18, 0x09, 0x88, 0xc9, 0x08, 0xc9, 0x07, 0xc9, 0x0f, 0x02, 0xd0, ++ 0x40, 0x00, 0x1c, 0x49, 0x02, 0xe0, 0x1b, 0x49, 0x40, 0x00, 0x40, 0x39, 0x08, 0x5e, 0x00, 0x2a, ++ 0x01, 0xd0, 0x40, 0x42, 0x00, 0xb2, 0x00, 0xbd, 0x10, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, ++ 0x8a, 0x13, 0x8a, 0x82, 0x12, 0x4a, 0x80, 0x06, 0x14, 0x68, 0xc3, 0x0d, 0x0f, 0x48, 0x24, 0x18, ++ 0xe3, 0x82, 0x8b, 0x8a, 0x10, 0x4b, 0x8b, 0x82, 0x12, 0x68, 0x59, 0x1c, 0x10, 0x18, 0xc1, 0x82, ++ 0x82, 0xe4, 0xc2, 0x06, 0xd2, 0x0e, 0x01, 0x21, 0x91, 0x40, 0x40, 0x09, 0x0b, 0x4a, 0x80, 0x00, ++ 0x80, 0x18, 0x01, 0x60, 0x70, 0x47, 0xc2, 0x06, 0xd2, 0x0e, 0x01, 0x21, 0x91, 0x40, 0x07, 0x4a, ++ 0x40, 0x09, 0x80, 0x00, 0x80, 0x32, 0x80, 0x18, 0x01, 0x60, 0x70, 0x47, 0x40, 0xa0, 0x01, 0x00, ++ 0x84, 0x00, 0x00, 0x20, 0x14, 0x7a, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x00, 0xe1, 0x00, 0xe0, ++ 0x70, 0xb5, 0xfd, 0x49, 0x00, 0x25, 0x0a, 0x68, 0x11, 0x46, 0x40, 0x31, 0x13, 0x46, 0x60, 0x33, ++ 0xcd, 0x75, 0x4d, 0x77, 0x1d, 0x73, 0xd5, 0x83, 0x1c, 0x46, 0x15, 0x84, 0x00, 0x28, 0x09, 0xd0, ++ 0x0f, 0x24, 0xe4, 0x43, 0x01, 0x28, 0x08, 0xd0, 0x00, 0x23, 0x02, 0x28, 0x1a, 0xd0, 0x03, 0x28, ++ 0x17, 0xd0, 0x05, 0xe0, 0x0f, 0x23, 0xe5, 0x77, 0x02, 0xe0, 0x80, 0x32, 0x23, 0x46, 0x15, 0x70, ++ 0x10, 0x24, 0x0c, 0x57, 0x02, 0x28, 0x0d, 0xd0, 0x03, 0x28, 0x0b, 0xd0, 0x4b, 0x76, 0xcd, 0x76, ++ 0x48, 0x7e, 0x88, 0x76, 0x18, 0x46, 0xfd, 0xf7, 0xe5, 0xfe, 0x20, 0x46, 0xfe, 0xf7, 0x16, 0xf9, ++ 0x70, 0xbd, 0x0f, 0x24, 0x4c, 0x76, 0xf2, 0xe7, 0x70, 0xb5, 0xe3, 0x4c, 0x00, 0x25, 0x21, 0x68, ++ 0x0a, 0x46, 0x40, 0x32, 0x0b, 0x46, 0x60, 0x33, 0xd5, 0x75, 0x00, 0x28, 0x07, 0xd0, 0x01, 0x28, ++ 0x0c, 0xd0, 0xd5, 0x76, 0x02, 0x28, 0x1d, 0xd0, 0x03, 0x28, 0x22, 0xd0, 0x0f, 0xe0, 0xc8, 0x7b, ++ 0xc6, 0x08, 0xd6, 0x76, 0xdb, 0x7f, 0x00, 0x02, 0xc0, 0x18, 0x07, 0xe0, 0x08, 0x7c, 0xc3, 0x08, ++ 0x5b, 0x42, 0xd3, 0x76, 0x03, 0x02, 0x80, 0x20, 0x40, 0x5c, 0x18, 0x18, 0x88, 0x84, 0x95, 0x76, ++ 0x1b, 0x20, 0x10, 0x56, 0xfd, 0xf7, 0xb6, 0xfe, 0x21, 0x68, 0x5a, 0x20, 0x08, 0x56, 0xfe, 0xf7, ++ 0xe5, 0xf8, 0x70, 0xbd, 0x48, 0x7b, 0xc5, 0x08, 0x6d, 0x42, 0x95, 0x76, 0x00, 0x02, 0x5b, 0x7f, ++ 0x04, 0xe0, 0x88, 0x7b, 0xc5, 0x08, 0x95, 0x76, 0x9b, 0x7f, 0x00, 0x02, 0xc0, 0x18, 0x88, 0x84, ++ 0xe6, 0xe7, 0xf0, 0xb5, 0xc4, 0x4c, 0x94, 0x46, 0x24, 0x68, 0x08, 0x9a, 0x01, 0x25, 0x05, 0x9f, ++ 0x06, 0x9e, 0x60, 0x34, 0x01, 0x2a, 0x03, 0xd0, 0x00, 0x29, 0x16, 0xdb, 0x01, 0x21, 0x0a, 0xe0, ++ 0x00, 0x29, 0x06, 0xd0, 0x02, 0xda, 0x00, 0x2b, 0x03, 0xdc, 0x0e, 0xe0, 0x00, 0x2b, 0xf5, 0xda, ++ 0x60, 0x46, 0x25, 0x73, 0x05, 0xe0, 0x07, 0x9a, 0x51, 0x43, 0x40, 0x1a, 0x00, 0x21, 0x40, 0xb2, ++ 0x21, 0x73, 0xb0, 0x42, 0x04, 0xdd, 0x30, 0x46, 0x05, 0xe0, 0x00, 0x21, 0xc9, 0x43, 0xf2, 0xe7, ++ 0xb8, 0x42, 0x01, 0xda, 0x38, 0x46, 0x25, 0x73, 0xf0, 0xbd, 0xf0, 0xb5, 0x85, 0xb0, 0x05, 0x00, ++ 0x4c, 0xd0, 0x1e, 0x20, 0xc0, 0x43, 0x01, 0x2d, 0x01, 0xd0, 0x03, 0x2d, 0x46, 0xd0, 0x00, 0x22, ++ 0xa9, 0x49, 0x1e, 0x23, 0x09, 0x68, 0x20, 0x24, 0xcb, 0x5e, 0x0c, 0x5f, 0x9b, 0x02, 0x23, 0x43, ++ 0x0c, 0x46, 0x40, 0x34, 0xe6, 0x7c, 0x0f, 0x3b, 0x01, 0x2e, 0xa4, 0x4e, 0x36, 0x68, 0xa4, 0x4f, ++ 0x37, 0xd0, 0xf6, 0x19, 0x36, 0x8e, 0xce, 0x83, 0xa0, 0x4e, 0x36, 0x68, 0xf6, 0x19, 0x76, 0x8e, ++ 0xb6, 0x05, 0xb6, 0x0d, 0x0e, 0x84, 0x1e, 0x26, 0x8e, 0x5f, 0x20, 0x27, 0xcf, 0x5f, 0xb6, 0x02, ++ 0x3e, 0x43, 0x19, 0x21, 0x0f, 0x3e, 0x61, 0x56, 0xb4, 0x46, 0x4e, 0x1c, 0x02, 0x2e, 0x01, 0xd9, ++ 0x49, 0x10, 0x61, 0x76, 0x61, 0x7f, 0x5a, 0x27, 0x49, 0x1c, 0xce, 0xb2, 0x92, 0x49, 0x66, 0x77, ++ 0x09, 0x68, 0x05, 0x2e, 0xcf, 0x57, 0x1d, 0xd8, 0x19, 0x21, 0x61, 0x56, 0x00, 0x26, 0x01, 0x92, ++ 0x02, 0x91, 0x00, 0x90, 0x03, 0x96, 0x1b, 0x22, 0xa2, 0x56, 0x38, 0x46, 0x61, 0x46, 0xff, 0xf7, ++ 0x88, 0xff, 0x89, 0x49, 0x09, 0x68, 0x40, 0x31, 0xce, 0x75, 0x23, 0xe0, 0x1f, 0x22, 0x00, 0x20, ++ 0xb6, 0xe7, 0xf6, 0x19, 0x36, 0x8d, 0xce, 0x83, 0x84, 0x4e, 0x36, 0x68, 0xf6, 0x19, 0x76, 0x8d, ++ 0xf6, 0xb2, 0xc7, 0xe7, 0x01, 0x21, 0x07, 0x2e, 0x12, 0xd8, 0x19, 0x26, 0xa6, 0x57, 0x01, 0x92, ++ 0x03, 0x91, 0x00, 0x90, 0x02, 0x96, 0x1b, 0x22, 0xa2, 0x56, 0x38, 0x46, 0x61, 0x46, 0xff, 0xf7, ++ 0x68, 0xff, 0x79, 0x49, 0x6c, 0x22, 0x09, 0x68, 0x52, 0x5c, 0x40, 0x31, 0xca, 0x75, 0x01, 0xe0, ++ 0x38, 0x46, 0xe1, 0x75, 0x74, 0x4c, 0x21, 0x68, 0x40, 0x31, 0x8a, 0x7e, 0xca, 0x76, 0x88, 0x76, ++ 0x00, 0x2d, 0x0a, 0xd0, 0x01, 0x2d, 0x08, 0xd0, 0xfe, 0xf7, 0x28, 0xf8, 0x20, 0x68, 0x01, 0x46, ++ 0x40, 0x30, 0xc2, 0x7d, 0x01, 0x2a, 0x03, 0xd0, 0x0f, 0xe0, 0xfd, 0xf7, 0xeb, 0xfd, 0xf5, 0xe7, ++ 0x00, 0x2d, 0x0d, 0xd0, 0x01, 0x2d, 0x13, 0xd0, 0x6a, 0x4a, 0x02, 0x2d, 0x82, 0x56, 0x17, 0xd0, ++ 0x00, 0x2a, 0x00, 0xda, 0x52, 0x42, 0xd0, 0x00, 0x88, 0x73, 0x00, 0x20, 0x05, 0xb0, 0xf0, 0xbd, ++ 0x1a, 0x22, 0x82, 0x56, 0x00, 0x2a, 0x00, 0xda, 0x52, 0x42, 0xd0, 0x00, 0xc8, 0x73, 0xf4, 0xe7, ++ 0x1a, 0x22, 0x82, 0x56, 0x00, 0x2a, 0x00, 0xda, 0x52, 0x42, 0xd0, 0x00, 0x08, 0x74, 0xec, 0xe7, ++ 0x00, 0x2a, 0x00, 0xda, 0x52, 0x42, 0xd0, 0x00, 0x48, 0x73, 0xe6, 0xe7, 0xf8, 0xb5, 0x56, 0x4e, ++ 0x04, 0x46, 0x30, 0x68, 0x53, 0x21, 0x0b, 0x5c, 0x00, 0x25, 0x54, 0x49, 0x01, 0x2b, 0x54, 0x4a, ++ 0x0b, 0x68, 0x17, 0xd0, 0x9b, 0x18, 0x1b, 0x8e, 0xc3, 0x83, 0x09, 0x68, 0x89, 0x18, 0x49, 0x8e, ++ 0x89, 0x05, 0x89, 0x0d, 0x01, 0x84, 0xfd, 0xf7, 0xa4, 0xfd, 0x31, 0x68, 0x0b, 0x46, 0x40, 0x33, ++ 0xd8, 0x76, 0x02, 0x2c, 0x0e, 0xd0, 0x03, 0x2c, 0x0f, 0xd0, 0x01, 0x2c, 0x10, 0xd0, 0x00, 0x2c, ++ 0x11, 0xd0, 0x12, 0xe0, 0x9b, 0x18, 0x1b, 0x8d, 0xc3, 0x83, 0x09, 0x68, 0x89, 0x18, 0x49, 0x8d, ++ 0xc9, 0xb2, 0xe7, 0xe7, 0x79, 0x20, 0x45, 0x5c, 0x07, 0xe0, 0x7a, 0x20, 0x45, 0x5c, 0x04, 0xe0, ++ 0x7b, 0x20, 0x45, 0x5c, 0x01, 0xe0, 0x7c, 0x20, 0x45, 0x5c, 0xca, 0x8b, 0x00, 0x20, 0x00, 0x2a, ++ 0x05, 0xd0, 0x0a, 0x20, 0x0c, 0xe0, 0x52, 0x10, 0x40, 0x1c, 0x0a, 0x84, 0x40, 0xb2, 0x20, 0x22, ++ 0x8a, 0x5e, 0x00, 0x2a, 0xf7, 0xdc, 0x07, 0xe0, 0x52, 0x10, 0x40, 0x1c, 0xca, 0x83, 0x40, 0xb2, ++ 0x1e, 0x22, 0x8a, 0x5e, 0x00, 0x2a, 0xf7, 0xdc, 0x00, 0x1f, 0x40, 0xb2, 0x8a, 0x8c, 0xc0, 0x01, ++ 0xd2, 0x08, 0xc0, 0x10, 0x1f, 0x27, 0x10, 0x1a, 0x3f, 0x02, 0x02, 0x2c, 0x05, 0xd0, 0x03, 0x2c, ++ 0x03, 0xd0, 0x01, 0x2c, 0x01, 0xd0, 0x00, 0x2c, 0x02, 0xd1, 0xb8, 0x42, 0x00, 0xdd, 0x38, 0x46, ++ 0xc2, 0x04, 0x16, 0x0c, 0xea, 0x00, 0x12, 0x18, 0x8e, 0x84, 0x02, 0x2c, 0x05, 0xd0, 0x03, 0x2c, ++ 0x03, 0xd0, 0x01, 0x2c, 0x01, 0xd0, 0x00, 0x2c, 0x02, 0xd1, 0xba, 0x42, 0x00, 0xdd, 0x3a, 0x46, ++ 0xd0, 0x04, 0x00, 0x0c, 0x42, 0x05, 0x1f, 0x27, 0x12, 0x0e, 0x7d, 0x42, 0x00, 0x2c, 0x0a, 0xd0, ++ 0x03, 0x2c, 0x08, 0xd0, 0xc0, 0x0a, 0x40, 0x42, 0x01, 0x2c, 0x07, 0xd0, 0x02, 0x2c, 0x11, 0xd0, ++ 0x03, 0x2c, 0x0f, 0xd0, 0x19, 0xe0, 0xc0, 0x0a, 0x00, 0x2c, 0xf5, 0xd1, 0x1f, 0x28, 0x01, 0xdd, ++ 0xdf, 0x76, 0x12, 0xe0, 0xa8, 0x42, 0x01, 0xda, 0xdd, 0x76, 0x0e, 0xe0, 0x00, 0x28, 0x0c, 0xd0, ++ 0xd8, 0x76, 0x0a, 0xe0, 0x1f, 0x28, 0x01, 0xdd, 0x9f, 0x76, 0x06, 0xe0, 0xa8, 0x42, 0x01, 0xda, ++ 0x9d, 0x76, 0x02, 0xe0, 0x00, 0x28, 0x00, 0xd0, 0x98, 0x76, 0x01, 0x20, 0xd8, 0x75, 0x00, 0x2c, ++ 0x12, 0xd0, 0x01, 0x2c, 0x16, 0xd0, 0x02, 0x2c, 0x1b, 0xd0, 0x30, 0x0a, 0x88, 0x73, 0x60, 0x31, ++ 0x8e, 0x77, 0x8a, 0x76, 0x00, 0x20, 0xf8, 0xbd, 0x90, 0x00, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, ++ 0x40, 0xa0, 0x01, 0x00, 0x1a, 0x00, 0x00, 0x00, 0x30, 0x0a, 0xc8, 0x73, 0x60, 0x31, 0xce, 0x77, ++ 0x0a, 0x77, 0xef, 0xe7, 0x30, 0x0a, 0x08, 0x74, 0x80, 0x20, 0x46, 0x54, 0x60, 0x31, 0xca, 0x76, ++ 0xe8, 0xe7, 0x30, 0x0a, 0x48, 0x73, 0x60, 0x31, 0x4e, 0x77, 0x4a, 0x76, 0xe2, 0xe7, 0x30, 0xb5, ++ 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x80, 0x22, 0xd2, 0x43, 0x8a, 0x82, 0xfe, 0x4a, 0xc4, 0x01, ++ 0x15, 0x68, 0xfe, 0x4b, 0xed, 0x18, 0xec, 0x81, 0x8c, 0x8a, 0x40, 0x24, 0xe4, 0x43, 0x8c, 0x82, ++ 0x11, 0x68, 0x80, 0x01, 0xc9, 0x18, 0xc8, 0x81, 0x30, 0xbd, 0x10, 0xb5, 0x03, 0x21, 0x09, 0x07, ++ 0x8a, 0x8a, 0x8a, 0x13, 0x8a, 0x82, 0xc0, 0x05, 0x15, 0x22, 0xc0, 0x0d, 0x52, 0x02, 0x83, 0x18, ++ 0xf1, 0x4a, 0x14, 0x68, 0xf1, 0x48, 0x24, 0x18, 0xe3, 0x82, 0x8b, 0x8a, 0xf0, 0x4b, 0x8b, 0x82, ++ 0x12, 0x68, 0x59, 0x1c, 0x10, 0x18, 0xc1, 0x82, 0x10, 0xbd, 0x10, 0xb5, 0x03, 0x21, 0x09, 0x07, ++ 0x8a, 0x8a, 0x8a, 0x13, 0x8a, 0x82, 0xc0, 0x05, 0x0b, 0x22, 0xc0, 0x0d, 0x92, 0x02, 0x83, 0x18, ++ 0xe5, 0x4a, 0x14, 0x68, 0xe5, 0x48, 0x24, 0x18, 0xe3, 0x82, 0x8b, 0x8a, 0xe4, 0x4b, 0x8b, 0x82, ++ 0x12, 0x68, 0x59, 0x1c, 0x10, 0x18, 0xc1, 0x82, 0x10, 0xbd, 0x10, 0xb5, 0x03, 0x21, 0x09, 0x07, ++ 0x8a, 0x8a, 0x8a, 0x13, 0x8a, 0x82, 0xc0, 0x05, 0x13, 0x22, 0xc0, 0x0d, 0x52, 0x02, 0x83, 0x18, ++ 0xd9, 0x4a, 0x14, 0x68, 0xd9, 0x48, 0x24, 0x18, 0xe3, 0x82, 0x8b, 0x8a, 0xd8, 0x4b, 0x8b, 0x82, ++ 0x12, 0x68, 0x59, 0x1c, 0x10, 0x18, 0xc1, 0x82, 0x10, 0xbd, 0x10, 0xb5, 0x03, 0x21, 0x09, 0x07, ++ 0x8a, 0x8a, 0x8a, 0x13, 0x8a, 0x82, 0xc0, 0x05, 0x05, 0x22, 0xc0, 0x0d, 0xd2, 0x02, 0x83, 0x18, ++ 0xcd, 0x4a, 0x14, 0x68, 0xcd, 0x48, 0x24, 0x18, 0xe3, 0x82, 0x8b, 0x8a, 0xcc, 0x4b, 0x8b, 0x82, ++ 0x12, 0x68, 0x59, 0x1c, 0x10, 0x18, 0xc1, 0x82, 0x10, 0xbd, 0x10, 0xb5, 0x00, 0x24, 0x00, 0x28, ++ 0x06, 0xdd, 0x20, 0x46, 0xff, 0xf7, 0xe1, 0xff, 0x20, 0x46, 0xff, 0xf7, 0xc6, 0xff, 0x10, 0xbd, ++ 0x00, 0x28, 0x20, 0x46, 0x05, 0xda, 0xff, 0xf7, 0xa8, 0xff, 0x20, 0x46, 0xff, 0xf7, 0x8d, 0xff, ++ 0x10, 0xbd, 0xfd, 0xf7, 0x60, 0xff, 0x20, 0x46, 0xfd, 0xf7, 0x45, 0xff, 0x10, 0xbd, 0x10, 0xb5, ++ 0xbc, 0x4b, 0x8a, 0x40, 0x1b, 0x68, 0x02, 0x40, 0x1c, 0x8e, 0x84, 0x43, 0x14, 0x43, 0x1c, 0x86, ++ 0x10, 0xbd, 0x10, 0xb5, 0xb7, 0x4b, 0x8a, 0x40, 0x1b, 0x68, 0x02, 0x40, 0x5c, 0x8e, 0x84, 0x43, ++ 0x14, 0x43, 0x5c, 0x86, 0x10, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0xfd, 0xf7, 0xc7, 0xfd, 0x03, 0x21, ++ 0x09, 0x07, 0x88, 0x8a, 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0xab, 0x48, 0xe2, 0x06, 0x03, 0x68, ++ 0xd2, 0x0e, 0x0d, 0x24, 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, 0xaa, 0x4a, 0x8a, 0x82, ++ 0xaa, 0x4b, 0x04, 0x68, 0xa5, 0x4a, 0xa4, 0x18, 0x23, 0x84, 0x8b, 0x8a, 0xff, 0x23, 0x8b, 0x82, ++ 0x01, 0x21, 0x00, 0x68, 0x89, 0x02, 0x80, 0x18, 0x81, 0x84, 0x10, 0xbd, 0x10, 0xb5, 0x04, 0x46, ++ 0xfd, 0xf7, 0xa4, 0xfd, 0x03, 0x21, 0x09, 0x07, 0x88, 0x8a, 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, ++ 0x99, 0x48, 0xe2, 0x06, 0x03, 0x68, 0xd2, 0x0e, 0x0d, 0x24, 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, ++ 0x8a, 0x8a, 0x99, 0x4a, 0x8a, 0x82, 0x09, 0x23, 0x04, 0x68, 0x1b, 0x03, 0x93, 0x4a, 0xa4, 0x18, ++ 0x23, 0x84, 0x8b, 0x8a, 0xff, 0x23, 0x8b, 0x82, 0x01, 0x21, 0x00, 0x68, 0x89, 0x02, 0x80, 0x18, ++ 0x81, 0x84, 0x10, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0xfd, 0xf7, 0x80, 0xfd, 0x03, 0x21, 0x09, 0x07, ++ 0x88, 0x8a, 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0x87, 0x48, 0xe2, 0x06, 0x03, 0x68, 0xd2, 0x0e, ++ 0x0d, 0x24, 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, 0x87, 0x4a, 0x20, 0x3a, 0x8a, 0x82, ++ 0x86, 0x4b, 0x04, 0x68, 0x14, 0x33, 0x81, 0x4a, 0xa4, 0x18, 0x23, 0x84, 0x8b, 0x8a, 0x00, 0x23, ++ 0x8b, 0x82, 0x83, 0x4b, 0x04, 0x68, 0xa4, 0x18, 0x63, 0x84, 0x8b, 0x8a, 0xff, 0x23, 0x8b, 0x82, ++ 0x01, 0x21, 0x00, 0x68, 0x89, 0x02, 0x80, 0x18, 0x81, 0x84, 0x10, 0xbd, 0x00, 0x28, 0x00, 0xda, ++ 0xc0, 0x43, 0x80, 0xb2, 0x70, 0x47, 0xff, 0xb5, 0x76, 0x4c, 0x07, 0x46, 0x20, 0x68, 0x00, 0x22, ++ 0x09, 0x9e, 0x0a, 0x9d, 0x60, 0x30, 0x94, 0x46, 0x00, 0x29, 0x03, 0xd0, 0x04, 0xda, 0x00, 0x2b, ++ 0x04, 0xdc, 0x14, 0xe0, 0x01, 0x21, 0x19, 0xe0, 0x00, 0x2b, 0x0e, 0xda, 0x08, 0x46, 0xff, 0xf7, ++ 0xe5, 0xff, 0x01, 0x46, 0x18, 0x46, 0xff, 0xf7, 0xe1, 0xff, 0x81, 0x42, 0x00, 0xd3, 0x02, 0x9f, ++ 0x21, 0x68, 0x01, 0x20, 0x60, 0x31, 0x08, 0x73, 0x09, 0xe0, 0x01, 0x21, 0x01, 0xe0, 0x00, 0x21, ++ 0xc9, 0x43, 0x0b, 0x9b, 0x59, 0x43, 0x79, 0x1a, 0x4f, 0xb2, 0x00, 0x21, 0x01, 0x73, 0xaf, 0x42, ++ 0x01, 0xdd, 0x2f, 0x46, 0x02, 0xe0, 0xb7, 0x42, 0x04, 0xda, 0x37, 0x46, 0x21, 0x68, 0x01, 0x22, ++ 0x60, 0x31, 0x0a, 0x73, 0xaf, 0x42, 0x01, 0xd0, 0xb7, 0x42, 0x01, 0xd1, 0x01, 0x20, 0x84, 0x46, ++ 0x20, 0x68, 0x61, 0x46, 0x60, 0x30, 0x82, 0x72, 0xc1, 0x72, 0x38, 0x46, 0x04, 0xb0, 0xf0, 0xbd, ++ 0xf0, 0xb5, 0x04, 0x24, 0xa6, 0x46, 0x01, 0x27, 0x06, 0x9d, 0x00, 0x24, 0x05, 0x9e, 0xbc, 0x46, ++ 0xa8, 0x42, 0x36, 0xdc, 0xaa, 0x42, 0x34, 0xdc, 0xb0, 0x42, 0x32, 0xdb, 0xb2, 0x42, 0x30, 0xdb, ++ 0x07, 0x9f, 0x4d, 0x42, 0x5e, 0x42, 0x87, 0x42, 0x0e, 0xd1, 0x00, 0x29, 0x29, 0xd0, 0x90, 0x42, ++ 0x01, 0xdd, 0x60, 0x1e, 0x84, 0x46, 0x00, 0x29, 0x00, 0xda, 0x29, 0x46, 0x08, 0xb2, 0x00, 0x2b, ++ 0x00, 0xda, 0x33, 0x46, 0x19, 0xb2, 0x10, 0xe0, 0x97, 0x42, 0x1a, 0xd1, 0x00, 0x2b, 0x18, 0xd0, ++ 0x82, 0x42, 0x02, 0xdd, 0x00, 0x20, 0xc0, 0x43, 0x84, 0x46, 0x00, 0x2b, 0x00, 0xda, 0x33, 0x46, ++ 0x18, 0xb2, 0x00, 0x29, 0x00, 0xda, 0x29, 0x46, 0x09, 0xb2, 0x00, 0x22, 0x01, 0x23, 0xdb, 0x03, ++ 0x88, 0x42, 0x08, 0xda, 0x09, 0x1a, 0x64, 0x00, 0xc9, 0x03, 0xc9, 0x18, 0x64, 0xb2, 0x09, 0x14, ++ 0x08, 0xe0, 0x00, 0x20, 0xf0, 0xbd, 0x64, 0x00, 0x64, 0x1c, 0x40, 0x1a, 0xc0, 0x03, 0xc0, 0x18, ++ 0x64, 0xb2, 0x00, 0x14, 0x52, 0x1c, 0xd2, 0xb2, 0x72, 0x45, 0xe9, 0xd9, 0x64, 0x1c, 0x60, 0x10, ++ 0x61, 0x46, 0x49, 0x1c, 0xee, 0xd1, 0x40, 0x42, 0x40, 0xb2, 0xf0, 0xbd, 0xf0, 0xb5, 0x04, 0x46, ++ 0x87, 0xb0, 0x01, 0x20, 0x05, 0x90, 0x2b, 0x48, 0x23, 0x4f, 0x00, 0x2c, 0x08, 0xdd, 0x39, 0x68, ++ 0x09, 0x18, 0x09, 0x89, 0x89, 0x06, 0x8e, 0x16, 0x39, 0x68, 0x08, 0x18, 0xc0, 0x88, 0x11, 0xe0, ++ 0x39, 0x68, 0x00, 0x2c, 0x07, 0xda, 0x09, 0x18, 0x89, 0x89, 0x89, 0x06, 0x8e, 0x16, 0x39, 0x68, ++ 0x08, 0x18, 0x40, 0x89, 0x06, 0xe0, 0x09, 0x18, 0x89, 0x88, 0x89, 0x06, 0x8e, 0x16, 0x39, 0x68, ++ 0x08, 0x18, 0x40, 0x88, 0x80, 0x06, 0x85, 0x16, 0x16, 0x48, 0x00, 0x68, 0x01, 0x46, 0x40, 0x31, ++ 0x8c, 0x46, 0x49, 0x7f, 0x00, 0x29, 0x76, 0xd1, 0x3a, 0x68, 0x10, 0x49, 0x52, 0x18, 0x28, 0x21, ++ 0x51, 0x5e, 0x1f, 0x22, 0x03, 0x91, 0x05, 0x9b, 0x51, 0x42, 0x02, 0x93, 0x01, 0x92, 0x00, 0x91, ++ 0x1e, 0x23, 0xc3, 0x5e, 0x60, 0x46, 0x18, 0x22, 0x82, 0x56, 0x30, 0x46, 0x03, 0x99, 0xff, 0xf7, ++ 0x22, 0xff, 0x04, 0x90, 0x07, 0x48, 0x6c, 0x21, 0x00, 0x68, 0x09, 0x5c, 0x00, 0x29, 0x2f, 0xd0, ++ 0x1f, 0x22, 0x51, 0x42, 0x04, 0x9b, 0x0f, 0xe0, 0x84, 0x00, 0x00, 0x20, 0x40, 0xa0, 0x01, 0x00, ++ 0xff, 0x7f, 0x00, 0x00, 0x90, 0x00, 0x00, 0x20, 0xf3, 0x0f, 0x00, 0x00, 0x0c, 0xa0, 0x00, 0x00, ++ 0x20, 0x20, 0x00, 0x00, 0x80, 0xa2, 0x01, 0x00, 0x02, 0x93, 0x01, 0x92, 0x00, 0x91, 0x1e, 0x23, ++ 0x58, 0x22, 0xc3, 0x5e, 0x82, 0x56, 0x30, 0x46, 0x03, 0x99, 0xff, 0xf7, 0x41, 0xff, 0x01, 0x46, ++ 0xfe, 0x48, 0x5b, 0x22, 0x00, 0x68, 0x00, 0x2c, 0x11, 0x54, 0x02, 0xdd, 0x60, 0x30, 0x41, 0x74, ++ 0x06, 0xe0, 0x00, 0x2c, 0x02, 0xda, 0x60, 0x30, 0xc1, 0x73, 0x01, 0xe0, 0x60, 0x30, 0x41, 0x73, ++ 0xf6, 0x48, 0x00, 0x68, 0x01, 0x46, 0x40, 0x31, 0x0e, 0x76, 0x03, 0x9a, 0xc2, 0x83, 0x60, 0x30, ++ 0x00, 0x7b, 0x48, 0x77, 0x00, 0x2c, 0x03, 0xdd, 0x04, 0x98, 0xff, 0xf7, 0x1e, 0xfe, 0x07, 0xe0, ++ 0x04, 0x98, 0x00, 0x2c, 0x02, 0xda, 0xff, 0xf7, 0xe8, 0xfd, 0x01, 0xe0, 0xfd, 0xf7, 0xa3, 0xfd, ++ 0xea, 0x4e, 0x30, 0x68, 0x60, 0x30, 0x01, 0x7b, 0x00, 0x29, 0x25, 0xd0, 0x00, 0x2c, 0x0b, 0xdd, ++ 0x82, 0x7a, 0x05, 0x21, 0x20, 0x20, 0xff, 0xf7, 0x3a, 0xfe, 0x30, 0x68, 0x05, 0x21, 0x60, 0x30, ++ 0xc2, 0x7a, 0x20, 0x20, 0x16, 0xe0, 0x17, 0xe0, 0x82, 0x7a, 0x00, 0x2c, 0x09, 0xda, 0x01, 0x21, ++ 0x02, 0x20, 0xff, 0xf7, 0x2c, 0xfe, 0x30, 0x68, 0x01, 0x21, 0x60, 0x30, 0xc2, 0x7a, 0x02, 0x20, ++ 0x08, 0xe0, 0x03, 0x21, 0x08, 0x20, 0xff, 0xf7, 0x22, 0xfe, 0x30, 0x68, 0x03, 0x21, 0x60, 0x30, ++ 0xc2, 0x7a, 0x08, 0x20, 0xff, 0xf7, 0x25, 0xfe, 0xd4, 0x4e, 0x31, 0x68, 0x08, 0x46, 0x40, 0x30, ++ 0x82, 0x7f, 0x00, 0x2a, 0x77, 0xd1, 0x3b, 0x68, 0xd1, 0x4a, 0x9b, 0x18, 0x2c, 0x22, 0x9a, 0x5e, ++ 0x1f, 0x23, 0x03, 0x92, 0x5a, 0x42, 0x05, 0x9f, 0x01, 0x93, 0x00, 0x92, 0x02, 0x97, 0x20, 0x23, ++ 0x19, 0x22, 0xcb, 0x5e, 0x82, 0x56, 0x28, 0x46, 0x03, 0x99, 0xff, 0xf7, 0x8c, 0xfe, 0x07, 0x46, ++ 0x30, 0x68, 0x6c, 0x21, 0x09, 0x5c, 0x00, 0x29, 0x1c, 0xd0, 0x1f, 0x21, 0x4a, 0x42, 0x00, 0x92, ++ 0x01, 0x91, 0x02, 0x97, 0x20, 0x23, 0x59, 0x22, 0xc3, 0x5e, 0x82, 0x56, 0x28, 0x46, 0x03, 0x99, ++ 0xff, 0xf7, 0xbe, 0xfe, 0x01, 0x46, 0x5a, 0x22, 0x30, 0x68, 0x00, 0x2c, 0x11, 0x54, 0x02, 0xdd, ++ 0x60, 0x30, 0x81, 0x74, 0x06, 0xe0, 0x00, 0x2c, 0x02, 0xda, 0x60, 0x30, 0x01, 0x74, 0x01, 0xe0, ++ 0x60, 0x30, 0x81, 0x73, 0x30, 0x68, 0x01, 0x46, 0x40, 0x31, 0x4d, 0x76, 0x03, 0x9a, 0x02, 0x84, ++ 0x60, 0x30, 0x00, 0x7b, 0x88, 0x77, 0x00, 0x2c, 0x03, 0xdd, 0x38, 0x46, 0xff, 0xf7, 0x85, 0xfd, ++ 0x07, 0xe0, 0x00, 0x2c, 0x38, 0x46, 0x02, 0xda, 0xff, 0xf7, 0x4f, 0xfd, 0x01, 0xe0, 0xfd, 0xf7, ++ 0x0a, 0xfd, 0x30, 0x68, 0x60, 0x30, 0x01, 0x7b, 0x00, 0x29, 0x24, 0xd0, 0x00, 0x2c, 0x0a, 0xdd, ++ 0x82, 0x7a, 0x04, 0x21, 0x10, 0x20, 0xff, 0xf7, 0xba, 0xfd, 0x30, 0x68, 0x04, 0x21, 0x60, 0x30, ++ 0xc2, 0x7a, 0x10, 0x20, 0x15, 0xe0, 0x82, 0x7a, 0x00, 0x2c, 0x09, 0xda, 0x00, 0x21, 0x01, 0x20, ++ 0xff, 0xf7, 0xad, 0xfd, 0x30, 0x68, 0x00, 0x21, 0x60, 0x30, 0xc2, 0x7a, 0x01, 0x20, 0x08, 0xe0, ++ 0x02, 0x21, 0x04, 0x20, 0xff, 0xf7, 0xa3, 0xfd, 0x30, 0x68, 0x02, 0x21, 0x60, 0x30, 0xc2, 0x7a, ++ 0x04, 0x20, 0xff, 0xf7, 0xa6, 0xfd, 0x30, 0x68, 0x40, 0x30, 0x41, 0x7f, 0x00, 0x29, 0x04, 0xd0, ++ 0x81, 0x7f, 0x00, 0x29, 0x01, 0xd0, 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0xc1, 0x75, 0x07, 0xb0, ++ 0xf0, 0xbd, 0xf0, 0xb5, 0x8d, 0x48, 0x07, 0x27, 0x03, 0x68, 0xff, 0x43, 0x60, 0x33, 0x58, 0x7c, ++ 0x59, 0x7b, 0xfa, 0x10, 0x40, 0x1a, 0x40, 0xb2, 0xb8, 0x42, 0x01, 0xdc, 0x01, 0x21, 0x04, 0xe0, ++ 0x08, 0x28, 0x01, 0xdb, 0x11, 0x46, 0x00, 0xe0, 0x00, 0x21, 0x86, 0x4c, 0x20, 0x68, 0x86, 0x4e, ++ 0x80, 0x19, 0x00, 0x89, 0x1e, 0x25, 0x80, 0x06, 0x80, 0x16, 0x40, 0x18, 0xed, 0x43, 0xa8, 0x42, ++ 0x01, 0xda, 0x28, 0x46, 0x02, 0xe0, 0x1f, 0x28, 0x00, 0xdd, 0x1f, 0x20, 0x99, 0x7c, 0x9b, 0x7b, ++ 0xc9, 0x1a, 0x49, 0xb2, 0xb9, 0x42, 0x01, 0xdc, 0x01, 0x22, 0x02, 0xe0, 0x08, 0x29, 0x00, 0xda, ++ 0x00, 0x22, 0x21, 0x68, 0x89, 0x19, 0xc9, 0x88, 0x89, 0x06, 0x89, 0x16, 0x8c, 0x18, 0xac, 0x42, ++ 0x01, 0xda, 0x2c, 0x46, 0x02, 0xe0, 0x1f, 0x2c, 0x00, 0xdd, 0x1f, 0x24, 0xff, 0xf7, 0x1d, 0xfd, ++ 0x20, 0x46, 0xff, 0xf7, 0x02, 0xfd, 0xf0, 0xbd, 0x6c, 0x48, 0x00, 0x22, 0x00, 0x68, 0xc2, 0x83, ++ 0x01, 0x46, 0x02, 0x84, 0x40, 0x31, 0x4a, 0x75, 0xca, 0x75, 0x0a, 0x76, 0x4a, 0x76, 0x8a, 0x76, ++ 0xca, 0x76, 0x4a, 0x77, 0x8a, 0x77, 0x84, 0x21, 0x09, 0x5c, 0x01, 0x29, 0x01, 0xd0, 0x42, 0x84, ++ 0xc2, 0x84, 0x82, 0x84, 0x02, 0x85, 0x70, 0x47, 0x70, 0xb5, 0x60, 0x4c, 0x20, 0x68, 0x40, 0x30, ++ 0x81, 0x7a, 0x03, 0x29, 0x5a, 0xd0, 0x00, 0x25, 0xed, 0x43, 0x04, 0x29, 0x1f, 0xd0, 0x05, 0x29, ++ 0x37, 0xd0, 0x01, 0x20, 0xff, 0xf7, 0x93, 0xfc, 0x03, 0x21, 0x09, 0x07, 0x88, 0x8a, 0x10, 0x20, ++ 0xc0, 0x43, 0x88, 0x82, 0x57, 0x49, 0x10, 0x20, 0x09, 0x68, 0x55, 0x4a, 0x40, 0x32, 0x89, 0x18, ++ 0x08, 0x80, 0x28, 0x46, 0xff, 0xf7, 0xf9, 0xfc, 0xff, 0xf7, 0xc6, 0xff, 0x09, 0x20, 0xff, 0xf7, ++ 0x22, 0xfd, 0xfd, 0xf7, 0x4c, 0xf9, 0x20, 0x68, 0x04, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfd, 0xf7, ++ 0x8e, 0xf9, 0x00, 0x28, 0x45, 0xd0, 0x28, 0x46, 0xff, 0xf7, 0x28, 0xfe, 0x20, 0x68, 0x40, 0x30, ++ 0xc0, 0x7d, 0x00, 0x28, 0xed, 0xd0, 0x00, 0x20, 0xff, 0xf7, 0xdf, 0xfc, 0xff, 0xf7, 0xac, 0xff, ++ 0x09, 0x20, 0xff, 0xf7, 0x2b, 0xfd, 0xfd, 0xf7, 0x32, 0xf9, 0x20, 0x68, 0x05, 0x21, 0x40, 0x30, ++ 0x81, 0x72, 0xfd, 0xf7, 0x74, 0xf9, 0x00, 0x28, 0x2b, 0xd0, 0x00, 0x20, 0xff, 0xf7, 0x0e, 0xfe, ++ 0x20, 0x68, 0x40, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0xed, 0xd0, 0x00, 0x20, 0xfd, 0xf7, 0x4a, 0xf9, ++ 0x01, 0x20, 0xff, 0xf7, 0xc2, 0xfc, 0xff, 0xf7, 0x8f, 0xff, 0x09, 0x20, 0xfd, 0xf7, 0x31, 0xfd, ++ 0xfd, 0xf7, 0x15, 0xf9, 0x20, 0x68, 0x03, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfd, 0xf7, 0x57, 0xf9, ++ 0x00, 0x28, 0x0e, 0xd0, 0x01, 0x20, 0xff, 0xf7, 0xf1, 0xfd, 0x20, 0x68, 0x40, 0x30, 0xc0, 0x7d, ++ 0x00, 0x28, 0xed, 0xd0, 0xff, 0xf7, 0x35, 0xff, 0x00, 0x20, 0xff, 0xf7, 0x30, 0xfc, 0x00, 0x20, ++ 0x70, 0xbd, 0x02, 0x20, 0x70, 0xbd, 0xf0, 0xb5, 0x26, 0x4a, 0x1e, 0x27, 0xff, 0x43, 0x1f, 0x26, ++ 0x10, 0x68, 0x85, 0xb0, 0x79, 0x11, 0x22, 0x4b, 0xc4, 0x18, 0x30, 0x20, 0x20, 0x5e, 0x1f, 0x28, ++ 0x01, 0xdd, 0x4c, 0x0c, 0x0c, 0xe0, 0x20, 0x24, 0xe0, 0x42, 0x01, 0xda, 0x0c, 0x46, 0x07, 0xe0, ++ 0x12, 0x68, 0x80, 0x02, 0xd2, 0x18, 0x52, 0x8e, 0x92, 0x05, 0x92, 0x0d, 0x10, 0x43, 0x04, 0xb2, ++ 0x16, 0x48, 0x10, 0x23, 0x02, 0x68, 0x10, 0x46, 0x40, 0x30, 0xc3, 0x56, 0x03, 0x93, 0x02, 0x91, ++ 0x00, 0x97, 0x01, 0x96, 0x20, 0x23, 0xd3, 0x5e, 0x18, 0x22, 0x82, 0x56, 0x21, 0x46, 0x03, 0x98, ++ 0xff, 0xf7, 0x19, 0xfd, 0x05, 0x46, 0x0d, 0x48, 0x6c, 0x21, 0x00, 0x68, 0x09, 0x5c, 0x00, 0x29, ++ 0x12, 0xd0, 0x29, 0x01, 0x81, 0x86, 0x00, 0x97, 0x01, 0x96, 0x02, 0x95, 0x20, 0x23, 0x58, 0x22, ++ 0xc3, 0x5e, 0x82, 0x56, 0x21, 0x46, 0x03, 0x98, 0xff, 0xf7, 0x4a, 0xfd, 0x01, 0x46, 0x03, 0x48, ++ 0x00, 0x68, 0x82, 0x8e, 0x89, 0x18, 0x81, 0x86, 0x00, 0x48, 0x07, 0xe0, 0x90, 0x00, 0x00, 0x20, ++ 0x40, 0xa0, 0x01, 0x00, 0x84, 0x00, 0x00, 0x20, 0x80, 0xa2, 0x01, 0x00, 0x00, 0x68, 0x03, 0x9a, ++ 0x01, 0x46, 0x40, 0x31, 0x0a, 0x76, 0x04, 0x84, 0x60, 0x30, 0x00, 0x7b, 0xc8, 0x75, 0x28, 0x46, ++ 0xfd, 0xf7, 0xfc, 0xfa, 0x05, 0xb0, 0xf0, 0xbd, 0xf8, 0xb5, 0xfe, 0x4c, 0x03, 0x25, 0x20, 0x68, ++ 0x2d, 0x07, 0x40, 0x30, 0x80, 0x7a, 0xfc, 0x4e, 0xfc, 0x4f, 0x0c, 0x28, 0x21, 0xd0, 0xff, 0xf7, ++ 0x03, 0xff, 0x20, 0x68, 0x40, 0x30, 0x01, 0x7c, 0x41, 0x76, 0xfd, 0xf7, 0xaa, 0xf8, 0x21, 0x68, ++ 0x40, 0x31, 0x88, 0x76, 0x00, 0x20, 0xfd, 0xf7, 0xe1, 0xfa, 0x00, 0x20, 0xfd, 0xf7, 0xaa, 0xf8, ++ 0xa8, 0x8a, 0xae, 0x82, 0x3a, 0x68, 0x01, 0x21, 0x0d, 0x20, 0x40, 0x03, 0x10, 0x18, 0xc1, 0x80, ++ 0x09, 0x20, 0xff, 0xf7, 0x8f, 0xfc, 0xfd, 0xf7, 0x72, 0xf8, 0x20, 0x68, 0x0c, 0x21, 0x40, 0x30, ++ 0x81, 0x72, 0xfd, 0xf7, 0xb4, 0xf8, 0x00, 0x28, 0x07, 0xd0, 0xff, 0xf7, 0x6c, 0xff, 0x21, 0x68, ++ 0x40, 0x31, 0xc8, 0x7d, 0x00, 0x28, 0x02, 0xd0, 0x04, 0xe0, 0x02, 0x20, 0xf8, 0xbd, 0x48, 0x7d, ++ 0x20, 0x28, 0xe8, 0xd3, 0xa8, 0x8a, 0xae, 0x82, 0x3b, 0x68, 0x00, 0x22, 0x0d, 0x20, 0x40, 0x03, ++ 0x18, 0x18, 0xc2, 0x80, 0x19, 0x20, 0x08, 0x56, 0xfd, 0xf7, 0xb0, 0xfa, 0x21, 0x68, 0x5a, 0x20, ++ 0x08, 0x56, 0xfd, 0xf7, 0x77, 0xf8, 0x00, 0x20, 0xf8, 0xbd, 0x70, 0xb5, 0x0d, 0x46, 0x03, 0x00, ++ 0x03, 0xf0, 0x4e, 0xfb, 0x06, 0x0e, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e, 0x08, 0x24, 0x08, 0xe0, ++ 0x10, 0x24, 0x06, 0xe0, 0x20, 0x24, 0x04, 0xe0, 0x40, 0x24, 0x02, 0xe0, 0x80, 0x24, 0x00, 0xe0, ++ 0x00, 0x24, 0xfd, 0xf7, 0xd3, 0xf9, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x1f, 0x21, 0xc9, 0x43, ++ 0x81, 0x82, 0xca, 0x49, 0xea, 0x06, 0x0b, 0x68, 0xd2, 0x0e, 0x0d, 0x25, 0x6d, 0x03, 0x5b, 0x19, ++ 0x5a, 0x85, 0x82, 0x8a, 0xc6, 0x4a, 0x82, 0x82, 0x0d, 0x68, 0x20, 0x23, 0xc5, 0x4a, 0xad, 0x18, ++ 0x2b, 0x84, 0x83, 0x8a, 0x00, 0x23, 0x83, 0x82, 0xc3, 0x4b, 0x0d, 0x68, 0xad, 0x18, 0x6b, 0x84, ++ 0x83, 0x8a, 0xff, 0x23, 0x83, 0x82, 0x09, 0x68, 0x20, 0x02, 0x89, 0x18, 0x88, 0x84, 0x70, 0xbd, ++ 0xf0, 0xb5, 0x03, 0x22, 0xcf, 0x05, 0x12, 0x07, 0xff, 0x0d, 0x96, 0x13, 0xb7, 0x4c, 0xb9, 0x4d, ++ 0x03, 0x00, 0x03, 0xf0, 0x0d, 0xfb, 0x06, 0x44, 0x04, 0x45, 0xb1, 0xb6, 0xbb, 0x44, 0x46, 0x29, ++ 0x01, 0xdd, 0x46, 0x21, 0x01, 0xe0, 0x3f, 0x29, 0x02, 0xdd, 0x08, 0x46, 0x3f, 0x38, 0x00, 0xe0, ++ 0x00, 0x20, 0x93, 0x8a, 0x40, 0xb2, 0x03, 0x23, 0x9b, 0x03, 0x93, 0x82, 0xc3, 0x05, 0x01, 0x26, ++ 0xdb, 0x0d, 0xb6, 0x02, 0x27, 0x68, 0x9e, 0x19, 0x7f, 0x19, 0xfe, 0x82, 0x96, 0x8a, 0xab, 0x4e, ++ 0x96, 0x82, 0x27, 0x68, 0x76, 0x1c, 0x7f, 0x19, 0xfe, 0x82, 0x97, 0x8a, 0x03, 0x27, 0xbf, 0x03, ++ 0x97, 0x82, 0x7f, 0x11, 0xdb, 0x19, 0x27, 0x68, 0x7f, 0x19, 0xfb, 0x82, 0x93, 0x8a, 0x73, 0x1e, ++ 0x93, 0x82, 0x23, 0x68, 0x5b, 0x19, 0xde, 0x82, 0x93, 0x8a, 0x03, 0x23, 0x9b, 0x03, 0x93, 0x82, ++ 0x08, 0x1a, 0xc0, 0x05, 0x21, 0x68, 0xc0, 0x0d, 0xff, 0x30, 0x49, 0x19, 0xff, 0x30, 0x02, 0x30, ++ 0xc8, 0x82, 0x90, 0x8a, 0x70, 0x1e, 0x90, 0x82, 0x20, 0x68, 0x40, 0x19, 0xc6, 0x82, 0xf0, 0xbd, ++ 0x0b, 0x46, 0x1f, 0x33, 0x48, 0x42, 0x3e, 0x2b, 0x06, 0xd9, 0x00, 0x29, 0x01, 0xdb, 0x0b, 0x46, ++ 0x00, 0xe0, 0x03, 0x46, 0x1f, 0x3b, 0x00, 0xe0, 0x00, 0x23, 0x97, 0x8a, 0x5b, 0xb2, 0x03, 0x26, ++ 0xb6, 0x03, 0x96, 0x82, 0xde, 0x05, 0xf6, 0x0d, 0x05, 0x27, 0x7f, 0x02, 0x87, 0x4c, 0xb4, 0x46, ++ 0xf7, 0x19, 0x26, 0x68, 0x76, 0x19, 0xf7, 0x82, 0x97, 0x8a, 0x88, 0x4f, 0x97, 0x82, 0x26, 0x68, ++ 0x7f, 0x1c, 0x76, 0x19, 0xf7, 0x82, 0x97, 0x8a, 0x03, 0x27, 0xbf, 0x03, 0x97, 0x82, 0x66, 0x46, ++ 0x3f, 0x11, 0xf6, 0x19, 0x27, 0x68, 0x7f, 0x19, 0xfe, 0x82, 0x97, 0x8a, 0x7f, 0x4f, 0x97, 0x82, ++ 0x24, 0x68, 0x7f, 0x1c, 0x64, 0x19, 0xe7, 0x82, 0x94, 0x8a, 0x03, 0x24, 0xa4, 0x03, 0x94, 0x82, ++ 0x00, 0x29, 0x00, 0xdb, 0x08, 0x46, 0xc0, 0x1a, 0xc0, 0x05, 0x01, 0x23, 0xc0, 0x0d, 0xdb, 0x02, ++ 0xc3, 0x18, 0x72, 0x48, 0x04, 0x68, 0x64, 0x19, 0xe3, 0x82, 0x93, 0x8a, 0x73, 0x4b, 0x93, 0x82, ++ 0x07, 0x68, 0x5c, 0x1c, 0x7f, 0x19, 0xfc, 0x82, 0x96, 0x8a, 0x03, 0x26, 0xb6, 0x03, 0x96, 0x82, ++ 0x05, 0x26, 0xc9, 0x0f, 0xb6, 0x02, 0x07, 0x68, 0x8e, 0x19, 0x7f, 0x19, 0xfe, 0x82, 0x96, 0x8a, ++ 0x93, 0x82, 0x06, 0x68, 0x76, 0x19, 0xf4, 0x82, 0x96, 0x8a, 0x03, 0x26, 0xb6, 0x03, 0x96, 0x82, ++ 0x0b, 0x26, 0x76, 0x02, 0x89, 0x19, 0x06, 0x68, 0x76, 0x19, 0xf1, 0x82, 0x91, 0x8a, 0x93, 0x82, ++ 0x00, 0x68, 0x40, 0x19, 0xc4, 0x82, 0xf0, 0xbd, 0x90, 0x8a, 0x96, 0x82, 0x07, 0x20, 0x40, 0x02, ++ 0x08, 0xe0, 0x90, 0x8a, 0x96, 0x82, 0x01, 0x20, 0x00, 0x03, 0x03, 0xe0, 0x90, 0x8a, 0x96, 0x82, ++ 0x09, 0x20, 0x40, 0x02, 0x21, 0x68, 0x38, 0x18, 0x49, 0x19, 0xc8, 0x82, 0x90, 0x8a, 0x57, 0x48, ++ 0x90, 0x82, 0x21, 0x68, 0x40, 0x1c, 0x49, 0x19, 0xc8, 0x82, 0xf0, 0xbd, 0x0f, 0xb4, 0xfe, 0xb5, ++ 0x08, 0xaf, 0xbc, 0x7b, 0xfb, 0x7b, 0x3d, 0x7c, 0x7f, 0x7c, 0x26, 0x46, 0x00, 0x2a, 0x01, 0xd1, ++ 0x1c, 0x46, 0x33, 0x46, 0x01, 0x29, 0x02, 0xd0, 0x49, 0x1c, 0x0c, 0xd0, 0x18, 0xe0, 0x07, 0x2c, ++ 0x01, 0xd2, 0x64, 0x1c, 0x0a, 0xe0, 0x00, 0x2b, 0x01, 0xd0, 0x5b, 0x1e, 0xdb, 0xb2, 0xbd, 0x42, ++ 0x0e, 0xd2, 0x6d, 0x1c, 0x0b, 0xe0, 0x00, 0x2c, 0x02, 0xd0, 0x64, 0x1e, 0xe4, 0xb2, 0x07, 0xe0, ++ 0x07, 0x2b, 0x01, 0xd2, 0x5b, 0x1c, 0xdb, 0xb2, 0x00, 0x2d, 0x01, 0xd0, 0x6d, 0x1e, 0xed, 0xb2, ++ 0x69, 0x46, 0x0d, 0x71, 0x00, 0x2a, 0x11, 0xd0, 0x8c, 0x70, 0xcb, 0x70, 0x08, 0xaa, 0x11, 0x7b, ++ 0x6a, 0x46, 0x11, 0x70, 0x08, 0xaa, 0x51, 0x7b, 0x6a, 0x46, 0x51, 0x70, 0x06, 0x22, 0x69, 0x46, ++ 0x03, 0xf0, 0x69, 0xf9, 0xfe, 0xbc, 0x08, 0xbc, 0x04, 0xb0, 0x18, 0x47, 0xcc, 0x70, 0x8b, 0x70, ++ 0xec, 0xe7, 0xfe, 0xb5, 0xd3, 0x1a, 0x2d, 0x4c, 0x2e, 0x4d, 0x5e, 0xb2, 0x01, 0x28, 0x05, 0xd0, ++ 0x02, 0x28, 0x7c, 0xd0, 0x11, 0x46, 0xff, 0xf7, 0xdb, 0xfe, 0xfe, 0xbd, 0x20, 0x68, 0x40, 0x19, ++ 0xc0, 0x8e, 0x6a, 0x46, 0x80, 0x04, 0x40, 0x0f, 0x90, 0x71, 0x20, 0x68, 0x40, 0x19, 0xc0, 0x8e, ++ 0x40, 0x05, 0x40, 0x0f, 0xd0, 0x71, 0x20, 0x68, 0x40, 0x19, 0xc0, 0x8e, 0x80, 0x06, 0x80, 0x0e, ++ 0x10, 0x72, 0x3f, 0x20, 0x50, 0x72, 0x00, 0x29, 0x02, 0xd0, 0x01, 0x29, 0x1d, 0xd1, 0x14, 0xe0, ++ 0x10, 0x89, 0x10, 0x80, 0x01, 0x22, 0x31, 0x46, 0x01, 0xa8, 0x01, 0x9b, 0xff, 0xf7, 0x8e, 0xff, ++ 0x14, 0x48, 0x00, 0x68, 0x80, 0x30, 0x01, 0x7a, 0xc9, 0x06, 0x02, 0xd5, 0x80, 0x7b, 0x80, 0x06, ++ 0x0b, 0xd5, 0x69, 0x46, 0x88, 0x79, 0xc8, 0x71, 0x07, 0xe0, 0x10, 0x89, 0x10, 0x80, 0x00, 0x22, ++ 0x31, 0x46, 0x01, 0xa8, 0x01, 0x9b, 0xff, 0xf7, 0x79, 0xff, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, ++ 0x81, 0x13, 0x81, 0x82, 0x6b, 0x46, 0xda, 0x79, 0x01, 0x23, 0x9b, 0x02, 0xd2, 0x18, 0x23, 0x68, ++ 0x5b, 0x19, 0xda, 0x82, 0x82, 0x8a, 0x09, 0x4a, 0x82, 0x82, 0x23, 0x68, 0x56, 0x1c, 0x5b, 0x19, ++ 0xde, 0x82, 0x0d, 0xe0, 0x90, 0x00, 0x00, 0x20, 0xfe, 0xff, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, ++ 0xd3, 0x8b, 0x00, 0x00, 0x40, 0xa0, 0x01, 0x00, 0x20, 0x20, 0x00, 0x00, 0xff, 0x7f, 0x00, 0x00, ++ 0x83, 0x8a, 0x81, 0x82, 0x6b, 0x46, 0x9b, 0x79, 0xc7, 0x14, 0xdb, 0x19, 0x27, 0x68, 0x7f, 0x19, ++ 0xfb, 0x82, 0x83, 0x8a, 0x82, 0x82, 0x23, 0x68, 0x5b, 0x19, 0xde, 0x82, 0x83, 0x8a, 0x81, 0x82, ++ 0x6b, 0x46, 0x19, 0x7a, 0x23, 0x68, 0xff, 0x31, 0x5b, 0x19, 0xff, 0x31, 0x02, 0x31, 0xd9, 0x82, ++ 0x81, 0x8a, 0x82, 0x82, 0x20, 0x68, 0x40, 0x19, 0xc6, 0x82, 0xfe, 0xbd, 0xff, 0xe7, 0x22, 0x68, ++ 0xfe, 0x48, 0x12, 0x18, 0x12, 0x8f, 0x6d, 0x46, 0x52, 0x06, 0xd2, 0x0f, 0x2a, 0x71, 0x22, 0x68, ++ 0x12, 0x18, 0x12, 0x8f, 0x92, 0x06, 0xd2, 0x0f, 0x6a, 0x71, 0x22, 0x68, 0x12, 0x18, 0x12, 0x8f, ++ 0x92, 0x04, 0x53, 0x0f, 0xab, 0x71, 0x22, 0x68, 0x12, 0x18, 0x12, 0x8f, 0x52, 0x05, 0x52, 0x0f, ++ 0xea, 0x71, 0x25, 0x68, 0x28, 0x18, 0x00, 0x8f, 0x6d, 0x46, 0xc0, 0x06, 0xc0, 0x0e, 0x28, 0x72, ++ 0x1f, 0x27, 0x6f, 0x72, 0x00, 0x25, 0x00, 0x29, 0x02, 0xd0, 0x01, 0x29, 0x44, 0xd1, 0x28, 0xe0, ++ 0xc3, 0x42, 0x04, 0xd1, 0x70, 0x1c, 0x02, 0xd1, 0x01, 0x20, 0x69, 0x46, 0x08, 0x71, 0x6a, 0x46, ++ 0x10, 0x79, 0x40, 0x00, 0x40, 0x42, 0x40, 0x1c, 0x70, 0x43, 0x41, 0xb2, 0x10, 0x89, 0x10, 0x80, ++ 0x01, 0x22, 0x01, 0xa8, 0x01, 0x9b, 0xff, 0xf7, 0xf9, 0xfe, 0x6a, 0x46, 0x91, 0x79, 0x10, 0x7a, ++ 0xc1, 0x42, 0x00, 0xd1, 0x15, 0x71, 0xde, 0x48, 0x00, 0x68, 0x80, 0x30, 0x02, 0x7a, 0xd2, 0x06, ++ 0x02, 0xd5, 0x80, 0x7b, 0x40, 0x06, 0x1f, 0xd5, 0x6a, 0x46, 0xd1, 0x71, 0x10, 0x79, 0x50, 0x71, ++ 0x1a, 0xe0, 0xc2, 0x42, 0x04, 0xd1, 0x70, 0x1c, 0x02, 0xd1, 0x01, 0x20, 0x69, 0x46, 0x48, 0x71, ++ 0x6a, 0x46, 0x50, 0x79, 0x40, 0x00, 0x40, 0x42, 0x40, 0x1c, 0x70, 0x43, 0x41, 0xb2, 0x10, 0x89, ++ 0x10, 0x80, 0x00, 0x22, 0x01, 0xa8, 0x01, 0x9b, 0xff, 0xf7, 0xd0, 0xfe, 0x6a, 0x46, 0xd0, 0x79, ++ 0x11, 0x7a, 0xc8, 0x42, 0x00, 0xd1, 0x55, 0x71, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x82, 0x13, ++ 0x82, 0x82, 0x6e, 0x46, 0xf1, 0x79, 0x05, 0x23, 0x5b, 0x02, 0x25, 0x68, 0xcb, 0x18, 0xc3, 0x49, ++ 0x6d, 0x18, 0xeb, 0x82, 0x83, 0x8a, 0xc3, 0x4b, 0x83, 0x82, 0x26, 0x68, 0x5d, 0x1c, 0x76, 0x18, ++ 0xf5, 0x82, 0x86, 0x8a, 0x82, 0x82, 0x6e, 0x46, 0xb6, 0x79, 0x87, 0x14, 0xf6, 0x19, 0x27, 0x68, ++ 0x7f, 0x18, 0xfe, 0x82, 0x86, 0x8a, 0x83, 0x82, 0x26, 0x68, 0x76, 0x18, 0xf5, 0x82, 0x86, 0x8a, ++ 0x82, 0x82, 0x6e, 0x46, 0x36, 0x7a, 0x2f, 0x11, 0xf6, 0x19, 0x27, 0x68, 0x7f, 0x18, 0xfe, 0x82, ++ 0x86, 0x8a, 0x83, 0x82, 0x26, 0x68, 0x76, 0x18, 0xf5, 0x82, 0x86, 0x8a, 0x82, 0x82, 0x6e, 0x46, ++ 0x36, 0x79, 0x05, 0x27, 0xbf, 0x02, 0xf6, 0x19, 0x27, 0x68, 0x7f, 0x18, 0xfe, 0x82, 0x86, 0x8a, ++ 0x83, 0x82, 0x26, 0x68, 0x76, 0x18, 0xf5, 0x82, 0x86, 0x8a, 0x82, 0x82, 0x6e, 0x46, 0x72, 0x79, ++ 0x0b, 0x26, 0x76, 0x02, 0x92, 0x19, 0x26, 0x68, 0x76, 0x18, 0xf2, 0x82, 0x82, 0x8a, 0x83, 0x82, ++ 0x20, 0x68, 0x40, 0x18, 0xc5, 0x82, 0x40, 0xe7, 0xa3, 0x48, 0x00, 0x68, 0x9f, 0x49, 0x40, 0x18, ++ 0x80, 0x8e, 0x80, 0x06, 0x80, 0x0e, 0x70, 0x47, 0xf3, 0xb5, 0x9d, 0x48, 0x87, 0xb0, 0x00, 0x68, ++ 0x05, 0x90, 0x40, 0x30, 0x04, 0x90, 0xc0, 0x7c, 0x98, 0x4e, 0x01, 0x28, 0x1a, 0xd0, 0x05, 0x98, ++ 0x80, 0x30, 0x01, 0x7a, 0xc9, 0x06, 0x1b, 0xd5, 0x07, 0x99, 0x01, 0x29, 0x02, 0xd0, 0x02, 0x29, ++ 0x03, 0xd0, 0x15, 0xe0, 0x80, 0x7b, 0x80, 0x06, 0x01, 0xe0, 0x80, 0x7b, 0x40, 0x06, 0x00, 0x28, ++ 0x0e, 0xdb, 0x08, 0x98, 0x00, 0x28, 0x05, 0xd0, 0x8f, 0x48, 0x00, 0x68, 0x81, 0x19, 0x2c, 0x20, ++ 0x08, 0x5e, 0x0a, 0xe0, 0x8c, 0x48, 0x00, 0x68, 0x81, 0x19, 0x28, 0x20, 0x08, 0x5e, 0x04, 0xe0, ++ 0x89, 0x48, 0x00, 0x68, 0x81, 0x19, 0x30, 0x20, 0x08, 0x5e, 0x07, 0x99, 0x0e, 0x22, 0xd2, 0x43, ++ 0x0b, 0x00, 0x03, 0xf0, 0x7d, 0xf8, 0x06, 0x6c, 0x04, 0x1b, 0x52, 0x5c, 0x63, 0x6c, 0x08, 0x99, ++ 0x81, 0x4a, 0x00, 0x29, 0x11, 0x68, 0x0d, 0xd0, 0x89, 0x19, 0xc9, 0x8e, 0x09, 0x0a, 0x49, 0x07, ++ 0x12, 0x68, 0x49, 0x0f, 0x92, 0x19, 0xd2, 0x8e, 0x00, 0x24, 0x92, 0x06, 0x92, 0x0e, 0x8f, 0x18, ++ 0x46, 0x25, 0x55, 0xe0, 0x89, 0x19, 0xc9, 0x8e, 0xc9, 0x0a, 0xf0, 0xe7, 0x08, 0x99, 0x00, 0x29, ++ 0x75, 0x49, 0x0a, 0x68, 0x13, 0xd0, 0x92, 0x19, 0x12, 0x8f, 0x52, 0x09, 0xd2, 0x07, 0xd2, 0x0f, ++ 0x0a, 0x68, 0x1b, 0xd0, 0x92, 0x19, 0x12, 0x8f, 0x12, 0x0a, 0x52, 0x07, 0x09, 0x68, 0x52, 0x0f, ++ 0x89, 0x19, 0x09, 0x8f, 0xc9, 0x06, 0xc9, 0x0e, 0x51, 0x18, 0x4f, 0x42, 0x19, 0xe0, 0x92, 0x19, ++ 0x12, 0x8f, 0x92, 0x09, 0xd2, 0x07, 0xd2, 0x0f, 0x0a, 0x68, 0x03, 0xd0, 0x92, 0x19, 0x12, 0x8f, ++ 0xd2, 0x0a, 0xea, 0xe7, 0x92, 0x19, 0x12, 0x8f, 0xd2, 0x0a, 0x02, 0xe0, 0x92, 0x19, 0x12, 0x8f, ++ 0x12, 0x0a, 0x52, 0x07, 0x09, 0x68, 0x52, 0x0f, 0x89, 0x19, 0x09, 0x8f, 0xc9, 0x06, 0xc9, 0x0e, ++ 0x57, 0x18, 0x25, 0x24, 0xe4, 0x43, 0x26, 0x25, 0x1a, 0xe0, 0x5b, 0x49, 0x09, 0x68, 0x89, 0x19, ++ 0x49, 0x8f, 0x1e, 0x24, 0x89, 0x06, 0x8f, 0x16, 0xe4, 0x43, 0x1f, 0x25, 0x10, 0xe0, 0x56, 0x49, ++ 0x09, 0x68, 0x89, 0x19, 0x49, 0x8f, 0x49, 0x05, 0xcf, 0x16, 0x05, 0xe0, 0x52, 0x49, 0x09, 0x68, ++ 0x8b, 0x19, 0x3a, 0x21, 0x59, 0x5e, 0xcf, 0x12, 0x14, 0x46, 0x0f, 0x25, 0x00, 0xe0, 0x00, 0x27, ++ 0x04, 0x99, 0x00, 0x2f, 0x4f, 0x76, 0x02, 0xd0, 0x03, 0xdb, 0x01, 0x21, 0x03, 0xe0, 0x00, 0x21, ++ 0x01, 0xe0, 0x00, 0x21, 0xc9, 0x43, 0x40, 0x1a, 0x00, 0xb2, 0x03, 0x90, 0x04, 0x98, 0x40, 0x7d, ++ 0x00, 0x28, 0x15, 0xd0, 0x00, 0x20, 0xc0, 0x43, 0x00, 0x94, 0x02, 0x90, 0x05, 0x98, 0x01, 0x95, ++ 0x20, 0x23, 0xc3, 0x5e, 0x04, 0x98, 0x18, 0x22, 0x82, 0x56, 0x38, 0x46, 0x03, 0x99, 0xff, 0xf7, ++ 0x32, 0xf9, 0x07, 0x46, 0x3a, 0x48, 0x6c, 0x21, 0x00, 0x68, 0x09, 0x5c, 0x40, 0x30, 0xc1, 0x75, ++ 0x07, 0x98, 0x01, 0x28, 0x0b, 0xd1, 0xa7, 0x42, 0x04, 0xd1, 0x03, 0x99, 0x48, 0x1c, 0x01, 0xda, ++ 0x01, 0x21, 0x00, 0xe0, 0x00, 0x21, 0x32, 0x48, 0x00, 0x68, 0x80, 0x30, 0x41, 0x71, 0x30, 0x48, ++ 0x00, 0x68, 0x40, 0x30, 0x81, 0x7d, 0x01, 0x29, 0x02, 0xd0, 0x00, 0x7d, 0x03, 0x28, 0x06, 0xd1, ++ 0x07, 0x98, 0x01, 0x28, 0x04, 0xd0, 0x02, 0x28, 0x05, 0xd0, 0x03, 0x28, 0x03, 0xd0, 0x96, 0xe0, ++ 0xaf, 0x42, 0x04, 0xd0, 0x93, 0xe0, 0xaf, 0x42, 0x01, 0xd0, 0xa7, 0x42, 0x7e, 0xd1, 0x03, 0x20, ++ 0x00, 0x07, 0x81, 0x8a, 0x01, 0x21, 0xc9, 0x43, 0x81, 0x82, 0x23, 0x4c, 0x01, 0x20, 0x21, 0x68, ++ 0x0d, 0x22, 0x52, 0x03, 0x89, 0x18, 0x48, 0x86, 0x01, 0x46, 0x1c, 0x20, 0x02, 0xf0, 0xda, 0xfe, ++ 0x08, 0x98, 0x00, 0x28, 0x20, 0x68, 0x1e, 0xd0, 0x80, 0x19, 0xc0, 0x8e, 0x21, 0x68, 0x40, 0x05, ++ 0x40, 0x0f, 0x89, 0x19, 0xc9, 0x8e, 0x89, 0x06, 0x89, 0x0e, 0x41, 0x18, 0x20, 0x68, 0x80, 0x19, ++ 0x00, 0x8f, 0x40, 0x09, 0xc0, 0x07, 0xc0, 0x0f, 0x20, 0x68, 0x2f, 0xd0, 0x80, 0x19, 0x00, 0x8f, ++ 0x00, 0x0a, 0x40, 0x07, 0x22, 0x68, 0x40, 0x0f, 0x92, 0x19, 0x12, 0x8f, 0xd2, 0x06, 0xd2, 0x0e, ++ 0x80, 0x18, 0x40, 0x42, 0x2d, 0xe0, 0x80, 0x19, 0xc0, 0x8e, 0x21, 0x68, 0x80, 0x04, 0x40, 0x0f, ++ 0x89, 0x19, 0xc9, 0x8e, 0x89, 0x06, 0x89, 0x0e, 0x41, 0x18, 0x20, 0x68, 0x80, 0x19, 0x00, 0x8f, ++ 0x80, 0x09, 0xc0, 0x07, 0xc0, 0x0f, 0x20, 0x68, 0x0c, 0xd0, 0x07, 0xe0, 0x40, 0xa0, 0x01, 0x00, ++ 0x90, 0x00, 0x00, 0x20, 0xff, 0x7f, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, 0x80, 0x19, 0x00, 0x8f, ++ 0xc0, 0x0a, 0xd6, 0xe7, 0x80, 0x19, 0x00, 0x8f, 0xc0, 0x0a, 0x02, 0xe0, 0x80, 0x19, 0x00, 0x8f, ++ 0x00, 0x0a, 0x40, 0x07, 0x22, 0x68, 0x40, 0x0f, 0x92, 0x19, 0x12, 0x8f, 0xd2, 0x06, 0xd2, 0x0e, ++ 0x80, 0x18, 0x00, 0x06, 0x00, 0x0c, 0x01, 0x43, 0x20, 0x68, 0x80, 0x19, 0x40, 0x8f, 0x03, 0x25, ++ 0x80, 0x06, 0x80, 0x16, 0x00, 0x06, 0x00, 0x0a, 0x01, 0x43, 0x01, 0x91, 0x00, 0x23, 0x2a, 0x46, ++ 0x00, 0x95, 0x12, 0x21, 0x01, 0x20, 0x02, 0xf0, 0xff, 0xfd, 0xff, 0xf7, 0x8d, 0xfe, 0x21, 0x68, ++ 0x00, 0x02, 0xfe, 0x4a, 0x89, 0x18, 0x49, 0x88, 0x09, 0x07, 0x00, 0xe0, 0x0f, 0xe0, 0x09, 0x0f, ++ 0x08, 0x43, 0xfb, 0x49, 0x00, 0x23, 0x09, 0x68, 0x03, 0x22, 0x40, 0x31, 0xc9, 0x7b, 0x00, 0x95, ++ 0x09, 0x04, 0x08, 0x43, 0x01, 0x90, 0x13, 0x21, 0x01, 0x20, 0x02, 0xf0, 0xe5, 0xfd, 0xf4, 0x4c, ++ 0x20, 0x68, 0x40, 0x30, 0xc1, 0x7c, 0x01, 0x29, 0x11, 0xd0, 0x19, 0x23, 0xc3, 0x56, 0x3a, 0x46, ++ 0x08, 0x99, 0x07, 0x98, 0xff, 0xf7, 0x25, 0xfd, 0x20, 0x68, 0x03, 0x99, 0x01, 0x84, 0x40, 0x30, ++ 0x41, 0x7e, 0x01, 0x76, 0x41, 0x7d, 0x49, 0x1c, 0x41, 0x75, 0x09, 0xb0, 0xf0, 0xbd, 0x39, 0x46, ++ 0x07, 0x98, 0xff, 0xf7, 0xfd, 0xfb, 0xef, 0xe7, 0x10, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, ++ 0x8a, 0x13, 0x8a, 0x82, 0xc0, 0x05, 0x17, 0x22, 0xc0, 0x0d, 0x52, 0x02, 0x83, 0x18, 0xe1, 0x4a, ++ 0x14, 0x68, 0xde, 0x48, 0x40, 0x38, 0x24, 0x18, 0xe3, 0x82, 0x8b, 0x8a, 0xde, 0x4b, 0x8b, 0x82, ++ 0x12, 0x68, 0x59, 0x1c, 0x10, 0x18, 0xc1, 0x82, 0x10, 0xbd, 0xfe, 0xb5, 0xd8, 0x48, 0xd7, 0x4f, ++ 0x01, 0x68, 0x3e, 0x23, 0x08, 0x46, 0x40, 0x30, 0xc4, 0x7c, 0xdb, 0x43, 0x3f, 0x22, 0x01, 0x25, ++ 0x40, 0x3f, 0xd4, 0x4e, 0x00, 0x2c, 0x01, 0xd0, 0x01, 0x2c, 0x21, 0xd0, 0x34, 0x68, 0xe7, 0x19, ++ 0x30, 0x24, 0x3c, 0x5f, 0x36, 0x68, 0xd1, 0x4f, 0xf6, 0x19, 0xf6, 0x89, 0x02, 0x95, 0x00, 0x93, ++ 0x01, 0x92, 0x76, 0x06, 0x20, 0x23, 0x18, 0x22, 0x77, 0x16, 0xcb, 0x5e, 0x82, 0x56, 0xc8, 0x4d, ++ 0x21, 0x46, 0x38, 0x46, 0xff, 0xf7, 0x17, 0xf8, 0x06, 0x46, 0x28, 0x68, 0x01, 0x46, 0x40, 0x31, ++ 0x0f, 0x76, 0x04, 0x84, 0x60, 0x30, 0x02, 0x7b, 0xca, 0x75, 0x01, 0x2a, 0x05, 0xd0, 0x10, 0xe0, ++ 0x34, 0x68, 0xe7, 0x19, 0x2c, 0x24, 0x3c, 0x5f, 0xdc, 0xe7, 0x82, 0x7a, 0x06, 0x21, 0x40, 0x20, ++ 0xfe, 0xf7, 0x75, 0xff, 0x28, 0x68, 0x06, 0x21, 0x60, 0x30, 0xc2, 0x7a, 0x40, 0x20, 0xfe, 0xf7, ++ 0x78, 0xff, 0x30, 0x46, 0xff, 0xf7, 0xa0, 0xff, 0x3e, 0x36, 0x28, 0x68, 0x7c, 0x2e, 0x04, 0xd9, ++ 0x40, 0x30, 0xc1, 0x79, 0x02, 0x22, 0x11, 0x43, 0x03, 0xe0, 0x40, 0x30, 0xc1, 0x79, 0xfd, 0x22, ++ 0x11, 0x40, 0xc1, 0x71, 0x29, 0xe5, 0x10, 0xb5, 0xad, 0x4c, 0x4a, 0x21, 0x20, 0x68, 0x09, 0x5c, ++ 0x0a, 0x29, 0x16, 0xd0, 0x80, 0x30, 0x40, 0x7b, 0x80, 0x07, 0x1d, 0xd4, 0x00, 0x20, 0xff, 0xf7, ++ 0x83, 0xff, 0x20, 0x68, 0x40, 0x30, 0xc0, 0x7c, 0x01, 0x28, 0x15, 0xd8, 0xff, 0xf7, 0xfc, 0xf9, ++ 0x10, 0x20, 0xfe, 0xf7, 0x58, 0xff, 0xfc, 0xf7, 0x82, 0xfb, 0x20, 0x68, 0x0a, 0x21, 0x40, 0x30, ++ 0x81, 0x72, 0xfc, 0xf7, 0xc4, 0xfb, 0x00, 0x28, 0x08, 0xd0, 0xff, 0xf7, 0x86, 0xff, 0x20, 0x68, ++ 0x40, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0xee, 0xd0, 0x00, 0x20, 0x10, 0xbd, 0x02, 0x20, 0x10, 0xbd, ++ 0x10, 0xb5, 0x97, 0x4c, 0x20, 0x68, 0x01, 0x46, 0x40, 0x30, 0x82, 0x7a, 0x0e, 0x2a, 0x11, 0xd0, ++ 0x80, 0x31, 0x49, 0x7b, 0x89, 0x07, 0x18, 0xd4, 0xc0, 0x7c, 0x01, 0x28, 0x15, 0xd8, 0xff, 0xf7, ++ 0xd3, 0xf9, 0x10, 0x20, 0xfe, 0xf7, 0x2f, 0xff, 0xfc, 0xf7, 0x59, 0xfb, 0x20, 0x68, 0x0e, 0x21, ++ 0x40, 0x30, 0x81, 0x72, 0xfc, 0xf7, 0x9b, 0xfb, 0x00, 0x28, 0x0c, 0xd0, 0xff, 0xf7, 0x5d, 0xff, ++ 0x20, 0x68, 0x40, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0xee, 0xd0, 0x20, 0x68, 0x2f, 0x21, 0x40, 0x30, ++ 0x81, 0x72, 0x00, 0x20, 0x10, 0xbd, 0x02, 0x20, 0x10, 0xbd, 0x10, 0xb5, 0x1f, 0x28, 0x01, 0xd9, ++ 0x1f, 0x20, 0x03, 0xe0, 0x41, 0xb2, 0x00, 0x29, 0x00, 0xda, 0x00, 0x20, 0xfe, 0xf7, 0x1c, 0xfc, ++ 0x10, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0xfc, 0xf7, 0xd1, 0xfc, 0x03, 0x21, 0x09, 0x07, 0x88, 0x8a, ++ 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0x77, 0x48, 0xe2, 0x06, 0x03, 0x68, 0xd2, 0x0e, 0x0d, 0x24, ++ 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, 0x75, 0x4a, 0x8a, 0x82, 0x75, 0x4b, 0x04, 0x68, ++ 0x6e, 0x4a, 0x40, 0x3a, 0xa4, 0x18, 0x23, 0x84, 0x8b, 0x8a, 0x00, 0x23, 0x8b, 0x82, 0x72, 0x4b, ++ 0x04, 0x68, 0xa4, 0x18, 0x63, 0x84, 0x8b, 0x8a, 0xff, 0x23, 0x8b, 0x82, 0x01, 0x21, 0x00, 0x68, ++ 0x89, 0x02, 0x80, 0x18, 0x81, 0x84, 0x10, 0xbd, 0x10, 0xb5, 0x04, 0x46, 0xfc, 0xf7, 0xa6, 0xfc, ++ 0x03, 0x21, 0x09, 0x07, 0x88, 0x8a, 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0x61, 0x48, 0xe2, 0x06, ++ 0x03, 0x68, 0xd2, 0x0e, 0x0d, 0x24, 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, 0x63, 0x4a, ++ 0x8a, 0x82, 0x09, 0x23, 0x04, 0x68, 0x9b, 0x02, 0x58, 0x4a, 0x40, 0x3a, 0xa4, 0x18, 0x23, 0x84, ++ 0x8b, 0x8a, 0x00, 0x23, 0x8b, 0x82, 0x5c, 0x4b, 0x04, 0x68, 0x40, 0x33, 0xa4, 0x18, 0x63, 0x84, ++ 0x8b, 0x8a, 0xff, 0x23, 0x8b, 0x82, 0x07, 0x21, 0x00, 0x68, 0xc9, 0x02, 0x80, 0x18, 0x81, 0x84, ++ 0x10, 0xbd, 0x70, 0xb5, 0x04, 0x46, 0xfc, 0xf7, 0x79, 0xfc, 0x03, 0x21, 0x09, 0x07, 0x88, 0x8a, ++ 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0x4b, 0x48, 0xe3, 0x06, 0x04, 0x68, 0xdb, 0x0e, 0x0d, 0x22, ++ 0x52, 0x03, 0xa4, 0x18, 0x63, 0x85, 0x8b, 0x8a, 0x47, 0x4b, 0x8b, 0x82, 0x04, 0x68, 0x5b, 0x1c, ++ 0x42, 0x4d, 0x40, 0x3d, 0x64, 0x19, 0x23, 0x84, 0x8b, 0x8a, 0x80, 0x23, 0xdb, 0x43, 0x8b, 0x82, ++ 0x00, 0x68, 0x80, 0x21, 0x80, 0x18, 0x01, 0x84, 0x70, 0xbd, 0x10, 0xb5, 0x3d, 0x4a, 0x10, 0x68, ++ 0x3a, 0x4b, 0x40, 0x3b, 0xc0, 0x18, 0x00, 0x8f, 0x11, 0x68, 0x80, 0x04, 0x40, 0x0f, 0xc9, 0x18, ++ 0x09, 0x8f, 0xc9, 0x06, 0xc9, 0x0e, 0x41, 0x18, 0x10, 0x68, 0xc0, 0x18, 0x00, 0x8f, 0x80, 0x09, ++ 0xc0, 0x07, 0xc0, 0x0f, 0x00, 0xd0, 0x49, 0x42, 0x10, 0x68, 0xc0, 0x18, 0x00, 0x8f, 0x14, 0x68, ++ 0x40, 0x05, 0x40, 0x0f, 0xe4, 0x18, 0x24, 0x8f, 0x12, 0x68, 0xe4, 0x06, 0xe4, 0x0e, 0x00, 0x19, ++ 0xd2, 0x18, 0x12, 0x8f, 0x52, 0x09, 0xd2, 0x07, 0xd2, 0x0f, 0x00, 0xd0, 0x40, 0x42, 0x08, 0x18, ++ 0x40, 0x10, 0x11, 0x38, 0x10, 0xbd, 0xf0, 0xb5, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0x2c, 0x49, ++ 0x81, 0x82, 0x24, 0x4a, 0x81, 0x13, 0x14, 0x68, 0x20, 0x4b, 0x40, 0x3b, 0xe4, 0x18, 0x21, 0x80, ++ 0x81, 0x8a, 0x28, 0x4e, 0x86, 0x82, 0x1e, 0x49, 0x09, 0x68, 0x80, 0x31, 0x0c, 0x7a, 0xe4, 0x06, ++ 0x02, 0xd5, 0x8c, 0x7b, 0xa4, 0x06, 0x01, 0xd5, 0x01, 0x24, 0x00, 0xe0, 0x00, 0x24, 0x01, 0x25, ++ 0x64, 0x00, 0xad, 0x02, 0x17, 0x68, 0x64, 0x19, 0xff, 0x18, 0x7c, 0x80, 0x84, 0x8a, 0x86, 0x82, ++ 0x0c, 0x7a, 0xe4, 0x06, 0x02, 0xd5, 0x89, 0x7b, 0x49, 0x06, 0x01, 0xd5, 0x01, 0x21, 0x00, 0xe0, ++ 0x00, 0x21, 0x49, 0x00, 0x14, 0x68, 0x49, 0x19, 0xe4, 0x18, 0xa1, 0x80, 0x81, 0x8a, 0x15, 0x49, ++ 0x89, 0x1c, 0x81, 0x82, 0x14, 0x68, 0xe4, 0x18, 0xe5, 0x80, 0x84, 0x8a, 0x81, 0x82, 0x14, 0x68, ++ 0xe4, 0x18, 0x25, 0x81, 0x84, 0x8a, 0x81, 0x82, 0x11, 0x68, 0xc9, 0x18, 0x4d, 0x81, 0x81, 0x8a, ++ 0x0d, 0x49, 0x81, 0x82, 0x08, 0x48, 0x11, 0x68, 0xc9, 0x18, 0x17, 0xe0, 0x80, 0xa0, 0x01, 0x00, ++ 0x90, 0x00, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, 0xff, 0x7f, 0x00, 0x00, 0x80, 0xa2, 0x01, 0x00, ++ 0xf3, 0x8f, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, 0x20, 0x20, 0x00, 0x00, 0xf3, 0x8b, 0x00, 0x00, ++ 0xff, 0x3f, 0x00, 0x00, 0xfd, 0x93, 0x00, 0x00, 0xc0, 0xc0, 0x00, 0x00, 0x88, 0x81, 0xf0, 0xbd, ++ 0x70, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0xfb, 0x4a, 0x8a, 0x82, 0x82, 0x02, 0xfb, 0x48, ++ 0x04, 0x68, 0x0d, 0x23, 0x5b, 0x03, 0xe4, 0x18, 0x22, 0x85, 0x8a, 0x8a, 0xf8, 0x4a, 0x8a, 0x82, ++ 0x06, 0x68, 0x00, 0x25, 0xf7, 0x4c, 0x36, 0x19, 0x75, 0x80, 0xf7, 0x4d, 0x2d, 0x68, 0x80, 0x35, ++ 0xad, 0x7b, 0xed, 0x07, 0x0d, 0xd1, 0x8d, 0x8a, 0x8a, 0x82, 0x05, 0x68, 0x52, 0x1c, 0x2c, 0x19, ++ 0x62, 0x80, 0x8a, 0x8a, 0x40, 0x22, 0xd2, 0x43, 0x8a, 0x82, 0x00, 0x68, 0x40, 0x21, 0xc0, 0x18, ++ 0x01, 0x84, 0x70, 0xbd, 0xf0, 0xb5, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0xe6, 0x4a, 0x8a, 0x82, ++ 0x82, 0x02, 0xe6, 0x48, 0x03, 0x68, 0x0d, 0x27, 0x7f, 0x03, 0xdb, 0x19, 0x1a, 0x85, 0x8a, 0x8a, ++ 0xe3, 0x4a, 0x8a, 0x82, 0x05, 0x68, 0x00, 0x24, 0xe2, 0x4b, 0xed, 0x18, 0x6c, 0x80, 0x8d, 0x8a, ++ 0x8a, 0x82, 0x05, 0x68, 0xed, 0x18, 0xac, 0x80, 0x8d, 0x8a, 0x8a, 0x82, 0x05, 0x68, 0xed, 0x18, ++ 0xec, 0x80, 0x8d, 0x8a, 0x8a, 0x82, 0x05, 0x68, 0xed, 0x18, 0x2c, 0x81, 0x8d, 0x8a, 0x8a, 0x82, ++ 0x05, 0x68, 0xed, 0x18, 0x6c, 0x81, 0xd8, 0x4c, 0x24, 0x68, 0x80, 0x34, 0xa5, 0x7b, 0xee, 0x07, ++ 0xd6, 0x4d, 0x04, 0xd1, 0x8e, 0x8a, 0x8a, 0x82, 0x06, 0x68, 0xf6, 0x18, 0x75, 0x80, 0xa6, 0x7b, ++ 0xb6, 0x07, 0x04, 0xd4, 0x8e, 0x8a, 0x8a, 0x82, 0x06, 0x68, 0xf6, 0x18, 0xb5, 0x80, 0xa4, 0x7b, ++ 0x64, 0x07, 0x04, 0xd4, 0x8c, 0x8a, 0x8a, 0x82, 0x02, 0x68, 0xd2, 0x18, 0xd5, 0x80, 0x8a, 0x8a, ++ 0x40, 0x22, 0xd2, 0x43, 0x8a, 0x82, 0x00, 0x68, 0x40, 0x21, 0xc0, 0x19, 0x01, 0x84, 0xf0, 0xbd, ++ 0xfe, 0xb5, 0xc5, 0x4e, 0xc1, 0x4a, 0x30, 0x68, 0xc2, 0x49, 0x04, 0x46, 0x40, 0x30, 0xc3, 0x7c, ++ 0x12, 0x68, 0x01, 0x2b, 0x28, 0xd0, 0x51, 0x18, 0x09, 0x8e, 0x25, 0x46, 0xe1, 0x83, 0x60, 0x35, ++ 0x29, 0x78, 0xa1, 0x84, 0x61, 0x8c, 0x01, 0x22, 0x1f, 0x23, 0x49, 0xb2, 0x01, 0x93, 0x02, 0x92, ++ 0x00, 0x91, 0x18, 0x22, 0x82, 0x56, 0x20, 0x23, 0x1e, 0x21, 0x00, 0x20, 0xe3, 0x5e, 0x61, 0x5e, ++ 0x28, 0x56, 0xfe, 0xf7, 0xd8, 0xfd, 0x31, 0x68, 0xc0, 0xb2, 0x0a, 0x46, 0x60, 0x32, 0x10, 0x70, ++ 0x13, 0x46, 0x20, 0x3a, 0x8d, 0x8c, 0x14, 0x46, 0x15, 0x76, 0x1a, 0x7b, 0xe2, 0x75, 0xca, 0x8b, ++ 0x0a, 0x84, 0xff, 0xf7, 0x3a, 0xfe, 0xdd, 0xe5, 0x51, 0x18, 0x09, 0x8d, 0xd5, 0xe7, 0xfe, 0xb5, ++ 0xa9, 0x4e, 0xa6, 0x4a, 0x31, 0x68, 0xa7, 0x4b, 0x0c, 0x46, 0x40, 0x31, 0xcd, 0x7c, 0x12, 0x68, ++ 0x01, 0x2d, 0x2d, 0xd0, 0xd2, 0x18, 0x12, 0x8e, 0x1f, 0x23, 0x10, 0x18, 0xe0, 0x83, 0x61, 0x22, ++ 0x10, 0x57, 0x20, 0x85, 0x00, 0x22, 0xd2, 0x43, 0x00, 0x25, 0x01, 0x93, 0x02, 0x92, 0x00, 0x95, ++ 0x18, 0x22, 0x8a, 0x56, 0x20, 0x23, 0x1e, 0x21, 0xe3, 0x5e, 0x61, 0x5e, 0xfe, 0xf7, 0xa3, 0xfd, ++ 0x31, 0x68, 0x0a, 0x46, 0x60, 0x32, 0x50, 0x70, 0x13, 0x46, 0x20, 0x3a, 0x0c, 0x8d, 0x17, 0x46, ++ 0x14, 0x76, 0x1a, 0x7b, 0xfa, 0x75, 0xca, 0x8b, 0x0a, 0x84, 0xfc, 0xf7, 0x73, 0xf9, 0x30, 0x68, ++ 0x6a, 0x21, 0x09, 0x5c, 0x00, 0x29, 0x06, 0xd0, 0x01, 0x21, 0x80, 0x30, 0x41, 0x72, 0xa1, 0xe5, ++ 0xd2, 0x18, 0x12, 0x8d, 0xd0, 0xe7, 0x80, 0x30, 0x45, 0x72, 0x9b, 0xe5, 0xfe, 0xb5, 0x87, 0x48, ++ 0x01, 0x68, 0x88, 0x48, 0x40, 0x30, 0x08, 0x18, 0x40, 0x88, 0x87, 0x4c, 0x02, 0x07, 0x20, 0x68, ++ 0x12, 0x0f, 0x07, 0x46, 0x60, 0x37, 0xba, 0x70, 0x82, 0x84, 0x2a, 0x21, 0x41, 0x5e, 0x01, 0x25, ++ 0x0b, 0x1d, 0x08, 0x2b, 0x03, 0xd8, 0x56, 0x23, 0x1b, 0x5c, 0x01, 0x2b, 0x22, 0xd0, 0x00, 0x22, ++ 0xd2, 0x43, 0x0f, 0x23, 0x00, 0x26, 0x01, 0x93, 0x02, 0x92, 0x00, 0x96, 0x2c, 0x23, 0xc3, 0x5e, ++ 0x04, 0x22, 0x02, 0x20, 0xba, 0x56, 0x38, 0x56, 0xfe, 0xf7, 0x5d, 0xfd, 0x22, 0x68, 0xc1, 0xb2, ++ 0x10, 0x46, 0x60, 0x30, 0x81, 0x70, 0x92, 0x8c, 0xd2, 0xb2, 0x02, 0x71, 0x03, 0x7b, 0x01, 0x2b, ++ 0x01, 0xd0, 0x86, 0x71, 0x08, 0xe0, 0x91, 0x42, 0x01, 0xd1, 0x85, 0x71, 0x04, 0xe0, 0x02, 0x21, ++ 0x81, 0x71, 0x01, 0xe0, 0x3a, 0x71, 0xbd, 0x71, 0x20, 0x68, 0x41, 0x8d, 0x81, 0x85, 0x56, 0x21, ++ 0x09, 0x5c, 0x01, 0x29, 0x06, 0xd1, 0x01, 0x46, 0x60, 0x31, 0x8a, 0x79, 0x01, 0x2a, 0x01, 0xd0, ++ 0x02, 0x22, 0x8a, 0x71, 0x03, 0x21, 0x09, 0x07, 0x8a, 0x8a, 0x0f, 0x22, 0xd2, 0x43, 0x8a, 0x82, ++ 0x60, 0x30, 0x81, 0x78, 0x5d, 0x48, 0x02, 0x68, 0x5e, 0x48, 0x40, 0x30, 0x10, 0x18, 0x41, 0x80, ++ 0x40, 0xe5, 0xf8, 0xb5, 0x5c, 0x4c, 0x01, 0x25, 0x20, 0x68, 0x01, 0x46, 0x40, 0x31, 0xcb, 0x7c, ++ 0x02, 0x46, 0x60, 0x32, 0x00, 0x2b, 0x04, 0xd0, 0x01, 0x2b, 0x06, 0xd1, 0x03, 0x78, 0x5b, 0x07, ++ 0x03, 0xd5, 0x8d, 0x23, 0x1b, 0x5c, 0x5b, 0x07, 0x01, 0xd5, 0x15, 0x72, 0x66, 0xe0, 0x00, 0x78, ++ 0x42, 0x07, 0x05, 0x20, 0x00, 0x2a, 0x48, 0x77, 0x03, 0xda, 0xfe, 0xf7, 0x7f, 0xf9, 0x21, 0x68, ++ 0x48, 0x84, 0xfe, 0xf7, 0x83, 0xf9, 0x4c, 0x4a, 0x11, 0x68, 0xc8, 0x84, 0xff, 0xf7, 0x04, 0xfb, ++ 0x12, 0x68, 0x04, 0x46, 0x11, 0x46, 0x60, 0x31, 0x08, 0x70, 0x10, 0x78, 0x40, 0x07, 0x40, 0xd5, ++ 0x13, 0x46, 0x80, 0x33, 0x58, 0x79, 0x00, 0x28, 0x05, 0xd0, 0x00, 0x20, 0x08, 0x56, 0x00, 0x28, ++ 0x01, 0xda, 0x60, 0x1c, 0x1a, 0xe0, 0x26, 0x20, 0x56, 0x8c, 0x10, 0x5e, 0xb4, 0x46, 0x40, 0x4f, ++ 0x86, 0x19, 0x38, 0x8c, 0xb6, 0x46, 0x86, 0x42, 0x08, 0xda, 0x58, 0x7a, 0x00, 0x28, 0x05, 0xd1, ++ 0xff, 0x26, 0x76, 0x36, 0xb4, 0x45, 0x01, 0xd2, 0x1f, 0x2c, 0xea, 0xd3, 0x7e, 0x8c, 0xb6, 0x45, ++ 0x23, 0xdc, 0x58, 0x7a, 0x00, 0x28, 0x20, 0xd1, 0x01, 0xe0, 0x60, 0x1e, 0x08, 0x70, 0x32, 0x4e, ++ 0x08, 0x78, 0xff, 0xf7, 0x42, 0xfd, 0x30, 0x68, 0x02, 0x46, 0x60, 0x30, 0x01, 0x78, 0xa1, 0x42, ++ 0x1b, 0xd0, 0x03, 0x7a, 0x01, 0x2b, 0x18, 0xd0, 0x02, 0x25, 0xa1, 0x42, 0x1a, 0xd9, 0x04, 0x2b, ++ 0x16, 0xd0, 0x40, 0x32, 0x92, 0x7d, 0x01, 0x2a, 0x12, 0xd0, 0x03, 0x22, 0x02, 0x72, 0x08, 0x1b, ++ 0x1a, 0xe0, 0x89, 0x20, 0x80, 0x5c, 0x00, 0x28, 0x04, 0xd0, 0x40, 0x32, 0x52, 0x7f, 0x94, 0x42, ++ 0xdb, 0xd8, 0xdc, 0xe7, 0x1f, 0x2c, 0xbc, 0xd3, 0xd9, 0xe7, 0x05, 0x72, 0x00, 0x20, 0xf8, 0xbd, ++ 0x05, 0x72, 0xec, 0xe7, 0x03, 0x2b, 0x09, 0xd0, 0x40, 0x32, 0x92, 0x7d, 0x01, 0x2a, 0x05, 0xd0, ++ 0x04, 0x22, 0x02, 0x72, 0x60, 0x1a, 0x40, 0x42, 0x40, 0xb2, 0xf8, 0xbd, 0x05, 0x72, 0xf9, 0xe7, ++ 0x10, 0xb5, 0x04, 0x46, 0xfc, 0xf7, 0xea, 0xf9, 0x03, 0x21, 0x09, 0x07, 0x88, 0x8a, 0x1f, 0x20, ++ 0xc0, 0x43, 0x88, 0x82, 0x0d, 0x48, 0xe2, 0x06, 0x03, 0x68, 0xd2, 0x0e, 0x0d, 0x24, 0x64, 0x03, ++ 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, 0x0f, 0x4a, 0x8a, 0x82, 0x09, 0x23, 0x04, 0x68, 0x9b, 0x02, ++ 0x08, 0x4a, 0xa4, 0x18, 0x23, 0x84, 0x8b, 0x8a, 0x00, 0x23, 0x8b, 0x82, 0x0a, 0x49, 0x00, 0x68, ++ 0x80, 0x18, 0x41, 0x84, 0x10, 0xbd, 0x00, 0x00, 0xff, 0x83, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, ++ 0xff, 0x7f, 0x00, 0x00, 0x40, 0xa0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x20, 0x00, 0x80, 0x00, 0x00, ++ 0x00, 0x04, 0x00, 0x20, 0xff, 0x8b, 0x00, 0x00, 0x60, 0x20, 0x00, 0x00, 0xf0, 0xb5, 0x03, 0x21, ++ 0x09, 0x07, 0xff, 0x25, 0x01, 0x26, 0xf7, 0x4a, 0xf7, 0x4b, 0xf8, 0x4c, 0x8f, 0x8a, 0x0d, 0x28, ++ 0x8d, 0x82, 0x09, 0xd8, 0x80, 0x1f, 0x86, 0x40, 0x15, 0x68, 0x30, 0x02, 0xed, 0x18, 0xa8, 0x84, ++ 0x88, 0x8a, 0x8c, 0x82, 0x04, 0x20, 0x08, 0xe0, 0x0e, 0x38, 0x86, 0x40, 0x15, 0x68, 0x30, 0x02, ++ 0xed, 0x18, 0xa8, 0x84, 0x88, 0x8a, 0x8c, 0x82, 0x08, 0x20, 0x11, 0x68, 0xc9, 0x18, 0x08, 0x84, ++ 0xf0, 0xbd, 0xfe, 0xb5, 0xe7, 0x4d, 0x28, 0x68, 0xe7, 0x4e, 0x40, 0x36, 0x80, 0x19, 0x80, 0x88, ++ 0xe7, 0x4f, 0x41, 0x07, 0x3c, 0x68, 0x49, 0x0f, 0x20, 0x46, 0x60, 0x30, 0xc1, 0x70, 0xa1, 0x84, ++ 0x00, 0x23, 0xdb, 0x43, 0x07, 0x22, 0x00, 0x21, 0x02, 0x93, 0x01, 0x92, 0x00, 0x91, 0x2e, 0x23, ++ 0x26, 0x21, 0xe3, 0x5e, 0x05, 0x22, 0x61, 0x5e, 0x82, 0x56, 0x04, 0x46, 0x03, 0x20, 0x20, 0x56, ++ 0xfe, 0xf7, 0x21, 0xfc, 0x3a, 0x68, 0x11, 0x46, 0x60, 0x31, 0xc8, 0x70, 0x90, 0x8c, 0x48, 0x71, ++ 0x08, 0x7b, 0xc8, 0x71, 0xd0, 0x8c, 0xd0, 0x85, 0x03, 0x20, 0x00, 0x07, 0x82, 0x8a, 0x07, 0x22, ++ 0xd2, 0x43, 0x82, 0x82, 0xc8, 0x78, 0x29, 0x68, 0x89, 0x19, 0x88, 0x80, 0x22, 0xe4, 0x70, 0xb5, ++ 0xcf, 0x4c, 0xff, 0x25, 0x20, 0x68, 0x01, 0x46, 0x40, 0x31, 0x8a, 0x7a, 0x17, 0x2a, 0x17, 0xd0, ++ 0x18, 0x2a, 0x22, 0xd0, 0xc9, 0x7c, 0x00, 0x29, 0x23, 0xd1, 0x01, 0x78, 0x49, 0x07, 0x20, 0xd5, ++ 0x60, 0x30, 0x40, 0x7a, 0x00, 0x28, 0x0f, 0xd1, 0x09, 0x20, 0xff, 0xf7, 0x81, 0xfd, 0x20, 0x68, ++ 0x01, 0x22, 0x69, 0x21, 0x0a, 0x54, 0x17, 0x22, 0x4a, 0x21, 0x0a, 0x54, 0x80, 0x30, 0x85, 0x72, ++ 0xfb, 0xf7, 0xe5, 0xff, 0x00, 0x28, 0x12, 0xd0, 0x09, 0x20, 0xff, 0xf7, 0x9b, 0xfd, 0x20, 0x68, ++ 0x18, 0x22, 0x4a, 0x21, 0x0a, 0x54, 0x80, 0x30, 0x85, 0x72, 0xfb, 0xf7, 0xd8, 0xff, 0x00, 0x28, ++ 0x05, 0xd0, 0x20, 0x68, 0x19, 0x21, 0x40, 0x30, 0x81, 0x72, 0x00, 0x20, 0x70, 0xbd, 0x02, 0x20, ++ 0x70, 0xbd, 0x00, 0xb5, 0xb2, 0x49, 0x03, 0x00, 0x09, 0x68, 0x80, 0x31, 0x02, 0xf0, 0x88, 0xfa, ++ 0x06, 0x14, 0x04, 0x07, 0x0a, 0x0d, 0x10, 0x14, 0x88, 0x7b, 0xc0, 0x07, 0x0a, 0xe0, 0x88, 0x7b, ++ 0x80, 0x07, 0x07, 0xe0, 0x88, 0x7b, 0x40, 0x07, 0x04, 0xe0, 0x88, 0x7b, 0x00, 0x07, 0x01, 0xe0, ++ 0x88, 0x7b, 0xc0, 0x06, 0xc0, 0x17, 0x40, 0x1c, 0x00, 0xbd, 0xf8, 0xb5, 0xa4, 0x4c, 0x01, 0x26, ++ 0x20, 0x68, 0x00, 0x25, 0x40, 0x30, 0x80, 0x7a, 0x20, 0x28, 0x28, 0xd0, 0x21, 0x28, 0x76, 0xd0, ++ 0xfe, 0xf7, 0xd2, 0xfd, 0x20, 0x68, 0x01, 0x46, 0x40, 0x30, 0xc2, 0x7c, 0x00, 0x2a, 0x02, 0xd0, ++ 0x01, 0x2a, 0x4f, 0xd0, 0x82, 0xe0, 0x09, 0x78, 0x49, 0x07, 0x7f, 0xd5, 0x86, 0x76, 0xc5, 0x76, ++ 0x20, 0x68, 0x40, 0x30, 0x80, 0x7e, 0xff, 0xf7, 0xc4, 0xff, 0x00, 0x28, 0x1e, 0xd0, 0x20, 0x68, ++ 0x06, 0x21, 0x40, 0x30, 0x80, 0x7e, 0xfe, 0xf7, 0xf8, 0xfe, 0x20, 0x68, 0x40, 0x30, 0xc5, 0x75, ++ 0x45, 0x75, 0xfb, 0xf7, 0x3c, 0xff, 0x20, 0x68, 0x20, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfb, 0xf7, ++ 0x7e, 0xff, 0x00, 0x28, 0x67, 0xd0, 0x20, 0x68, 0x40, 0x30, 0xc1, 0x7e, 0x80, 0x7e, 0xff, 0xf7, ++ 0x83, 0xf9, 0x20, 0x68, 0x40, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0xea, 0xd0, 0x20, 0x68, 0x02, 0x46, ++ 0x80, 0x32, 0x11, 0x7a, 0xc9, 0x06, 0x10, 0xd5, 0x01, 0x46, 0x40, 0x31, 0x1a, 0x23, 0xcb, 0x56, ++ 0x01, 0x2b, 0x02, 0xd1, 0x97, 0x7b, 0xbf, 0x06, 0x04, 0xd5, 0x02, 0x2b, 0x05, 0xd1, 0x92, 0x7b, ++ 0x52, 0x06, 0x02, 0xd4, 0xca, 0x7e, 0x00, 0x2a, 0x0a, 0xd0, 0x01, 0x46, 0x40, 0x31, 0xcd, 0x76, ++ 0x8a, 0x7e, 0x52, 0x1c, 0x8a, 0x76, 0x5a, 0x21, 0x41, 0x56, 0x06, 0x29, 0xb8, 0xdb, 0x35, 0xe0, ++ 0xce, 0x76, 0xf8, 0xe7, 0x09, 0x78, 0x49, 0x07, 0x30, 0xd5, 0x02, 0x21, 0x81, 0x76, 0xc5, 0x76, ++ 0x20, 0x68, 0x40, 0x30, 0x80, 0x7e, 0xff, 0xf7, 0x74, 0xff, 0x00, 0x28, 0x1e, 0xd0, 0x20, 0x68, ++ 0x06, 0x21, 0x40, 0x30, 0x80, 0x7e, 0xfe, 0xf7, 0xa8, 0xfe, 0x20, 0x68, 0x40, 0x30, 0xc5, 0x75, ++ 0x45, 0x75, 0xfb, 0xf7, 0xec, 0xfe, 0x20, 0x68, 0x21, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfb, 0xf7, ++ 0x2e, 0xff, 0x00, 0x28, 0x17, 0xd0, 0x20, 0x68, 0x40, 0x30, 0xc1, 0x7e, 0x80, 0x7e, 0xff, 0xf7, ++ 0x33, 0xf9, 0x20, 0x68, 0x40, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0xea, 0xd0, 0x20, 0x68, 0x40, 0x30, ++ 0x81, 0x7e, 0x89, 0x1c, 0x49, 0xb2, 0x81, 0x76, 0x05, 0x29, 0xd1, 0xdb, 0x20, 0x68, 0x40, 0x30, ++ 0x85, 0x72, 0x00, 0x20, 0xf8, 0xbd, 0x02, 0x20, 0xf8, 0xbd, 0xf8, 0xb5, 0x54, 0x4d, 0x00, 0x24, ++ 0x28, 0x68, 0x02, 0x46, 0x40, 0x30, 0x81, 0x7a, 0x10, 0x29, 0x4d, 0xd0, 0xc1, 0x7c, 0x28, 0x46, ++ 0x00, 0x68, 0x80, 0x30, 0x00, 0x29, 0x02, 0xd0, 0x01, 0x29, 0x77, 0xd0, 0x79, 0xe0, 0x40, 0x7b, ++ 0xc0, 0x07, 0x76, 0xd1, 0xfe, 0xf7, 0x28, 0xfd, 0x28, 0x68, 0x00, 0x78, 0x40, 0x07, 0x06, 0xd4, ++ 0x0c, 0x20, 0xff, 0xf7, 0xa1, 0xfb, 0x28, 0x68, 0x00, 0x78, 0x40, 0x07, 0x2e, 0xd5, 0x28, 0x68, ++ 0x01, 0x46, 0x40, 0x31, 0x8a, 0x7d, 0x01, 0x2a, 0x0d, 0xd0, 0x85, 0x21, 0x09, 0x5c, 0x00, 0x29, ++ 0x02, 0xd0, 0x00, 0x21, 0xc9, 0x43, 0x36, 0xe0, 0xfd, 0xf7, 0xd2, 0xfe, 0x29, 0x68, 0x48, 0x85, ++ 0xff, 0xf7, 0x5c, 0xfd, 0x47, 0xe0, 0xc9, 0x7f, 0x00, 0x29, 0x00, 0xd1, 0x44, 0x85, 0x85, 0x21, ++ 0x09, 0x5c, 0x00, 0x29, 0x03, 0xd0, 0x41, 0x8d, 0x49, 0x1e, 0x41, 0x85, 0x05, 0xe0, 0xfd, 0xf7, ++ 0xbf, 0xfe, 0x29, 0x68, 0x4a, 0x8d, 0x80, 0x18, 0x48, 0x85, 0x28, 0x68, 0x40, 0x30, 0xc1, 0x7f, ++ 0x49, 0x1c, 0xc9, 0xb2, 0xc1, 0x77, 0x08, 0x29, 0x28, 0xd0, 0x2c, 0xe0, 0xfb, 0xf7, 0x77, 0xfe, ++ 0x28, 0x68, 0x10, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfb, 0xf7, 0xb9, 0xfe, 0x00, 0x28, 0x0c, 0xd0, ++ 0x28, 0x68, 0x24, 0x4b, 0x01, 0x46, 0x40, 0x31, 0x8a, 0x7d, 0x23, 0x4e, 0x01, 0x2a, 0x06, 0xd0, ++ 0x19, 0x68, 0x89, 0x19, 0x09, 0x8e, 0x41, 0x85, 0xca, 0xe7, 0x02, 0x20, 0xf8, 0xbd, 0xca, 0x7f, ++ 0x00, 0x2a, 0x00, 0xd1, 0x44, 0x85, 0x47, 0x8d, 0x1b, 0x68, 0x9b, 0x19, 0x1b, 0x8e, 0x52, 0x1c, ++ 0xfb, 0x18, 0x43, 0x85, 0xd0, 0xb2, 0xc8, 0x77, 0x08, 0x28, 0x04, 0xd1, 0xff, 0xf7, 0x16, 0xfd, ++ 0x28, 0x68, 0x40, 0x30, 0xc4, 0x77, 0x28, 0x68, 0x01, 0x78, 0x49, 0x07, 0x0c, 0xd4, 0x60, 0x30, ++ 0x80, 0x79, 0x00, 0x28, 0x97, 0xd0, 0x07, 0xe0, 0x00, 0xe0, 0x02, 0xe0, 0x40, 0x7b, 0xc0, 0x07, ++ 0x08, 0xd0, 0x01, 0x20, 0x60, 0x32, 0x90, 0x71, 0x28, 0x68, 0x33, 0x21, 0x40, 0x30, 0x81, 0x72, ++ 0x00, 0x20, 0xf8, 0xbd, 0xfe, 0xf7, 0xa8, 0xfc, 0x28, 0x68, 0x01, 0x46, 0x40, 0x30, 0x82, 0x7d, ++ 0x01, 0x2a, 0x0f, 0xd0, 0xff, 0xf7, 0x71, 0xfb, 0x29, 0x68, 0x48, 0x85, 0xff, 0xf7, 0xee, 0xfc, ++ 0x1e, 0xe0, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, 0x40, 0xa0, 0x01, 0x00, 0xf3, 0xff, 0x00, 0x00, ++ 0x90, 0x00, 0x00, 0x20, 0xc0, 0x7f, 0x00, 0x28, 0x00, 0xd1, 0x4c, 0x85, 0xff, 0xf7, 0x5d, 0xfb, ++ 0x29, 0x68, 0x4a, 0x8d, 0x80, 0x18, 0x48, 0x85, 0x40, 0x31, 0xc8, 0x7f, 0x40, 0x1c, 0xc0, 0xb2, ++ 0xc8, 0x77, 0x08, 0x28, 0x04, 0xd1, 0xff, 0xf7, 0xd1, 0xfc, 0x28, 0x68, 0x40, 0x30, 0xc4, 0x77, ++ 0x28, 0x68, 0x01, 0x78, 0x49, 0x07, 0xc7, 0xd4, 0x60, 0x30, 0x80, 0x79, 0x00, 0x28, 0xcb, 0xd0, ++ 0xc2, 0xe7, 0x10, 0xb5, 0xfb, 0x4c, 0x20, 0x68, 0x01, 0x46, 0x40, 0x31, 0xca, 0x7c, 0x00, 0x2a, ++ 0x06, 0xd0, 0x01, 0x2a, 0x02, 0xd1, 0x02, 0x78, 0x52, 0x07, 0x01, 0xd4, 0x00, 0x20, 0xc1, 0xe5, ++ 0x89, 0x7a, 0x0f, 0x29, 0x22, 0xd0, 0x80, 0x30, 0x40, 0x7b, 0x80, 0x06, 0x2a, 0xd4, 0xfe, 0xf7, ++ 0x5b, 0xfc, 0x00, 0x20, 0xfc, 0xf7, 0x42, 0xf8, 0x09, 0x20, 0xff, 0xf7, 0xaa, 0xfa, 0x03, 0x20, ++ 0x00, 0x07, 0x81, 0x8a, 0x20, 0x21, 0xc9, 0x43, 0x81, 0x82, 0xeb, 0x49, 0x20, 0x20, 0x09, 0x68, ++ 0xea, 0x4a, 0x89, 0x18, 0x08, 0x84, 0xfb, 0xf7, 0xf4, 0xfd, 0x21, 0x68, 0x60, 0x31, 0x48, 0x70, ++ 0xfb, 0xf7, 0xcd, 0xfd, 0x20, 0x68, 0x0f, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfb, 0xf7, 0x0f, 0xfe, ++ 0x00, 0x28, 0x0c, 0xd0, 0x3c, 0x20, 0xff, 0xf7, 0x4a, 0xfc, 0x20, 0x68, 0x40, 0x30, 0xc0, 0x7d, ++ 0x00, 0x28, 0xed, 0xd0, 0x20, 0x68, 0x32, 0x21, 0x40, 0x30, 0x81, 0x72, 0xc6, 0xe7, 0x02, 0x20, ++ 0x88, 0xe5, 0x10, 0xb5, 0xd7, 0x4c, 0x20, 0x68, 0x01, 0x46, 0x40, 0x31, 0x8a, 0x7a, 0x11, 0x2a, ++ 0x21, 0xd0, 0xc9, 0x7c, 0x00, 0x29, 0x45, 0xd1, 0x88, 0x21, 0x09, 0x5c, 0xc9, 0x09, 0x41, 0xd1, ++ 0x01, 0x78, 0x89, 0x06, 0x89, 0x0f, 0x02, 0x29, 0x3c, 0xd0, 0xfe, 0xf7, 0x15, 0xfc, 0x0c, 0x20, ++ 0xff, 0xf7, 0x4e, 0xfd, 0x20, 0x68, 0x00, 0x21, 0xc1, 0x84, 0x06, 0x21, 0x40, 0x30, 0x41, 0x75, ++ 0x20, 0x68, 0x40, 0x30, 0x40, 0x7d, 0xff, 0xf7, 0x79, 0xfd, 0xfb, 0xf7, 0x90, 0xfd, 0x20, 0x68, ++ 0x11, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfb, 0xf7, 0xd2, 0xfd, 0x00, 0x28, 0x11, 0xd0, 0xc2, 0x49, ++ 0x08, 0x68, 0xc2, 0x4a, 0x80, 0x18, 0x00, 0x8e, 0x00, 0x28, 0x10, 0xd0, 0x20, 0x68, 0x26, 0x23, ++ 0xc3, 0x5e, 0x09, 0x68, 0x8a, 0x18, 0x30, 0x21, 0x51, 0x5e, 0x00, 0x29, 0x03, 0xdd, 0x01, 0x21, ++ 0x03, 0xe0, 0x02, 0x20, 0x46, 0xe5, 0x00, 0x21, 0xc9, 0x43, 0x59, 0x18, 0xc1, 0x84, 0x20, 0x68, ++ 0x40, 0x30, 0x41, 0x7d, 0x49, 0x1c, 0xc9, 0xb2, 0x41, 0x75, 0x16, 0x29, 0xd0, 0xd3, 0xff, 0xf7, ++ 0x70, 0xfd, 0x02, 0xe0, 0x01, 0x21, 0x60, 0x30, 0xc1, 0x71, 0x20, 0x68, 0x31, 0x21, 0x40, 0x30, ++ 0x81, 0x72, 0x00, 0x20, 0x2e, 0xe5, 0xf8, 0xb5, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0xac, 0x49, ++ 0x81, 0x82, 0xa9, 0x4e, 0x01, 0x20, 0x31, 0x68, 0x40, 0x02, 0x0d, 0x27, 0x7f, 0x03, 0xc9, 0x19, ++ 0x48, 0x80, 0x30, 0x68, 0xc0, 0x19, 0x80, 0x8f, 0x01, 0xf0, 0xff, 0xfc, 0x05, 0x46, 0x01, 0xe0, ++ 0x00, 0x2c, 0x08, 0xd0, 0x30, 0x68, 0xc0, 0x19, 0x80, 0x8f, 0x80, 0x09, 0xc0, 0x07, 0xc0, 0x0f, ++ 0x01, 0xd0, 0x01, 0x24, 0x00, 0xe0, 0x00, 0x24, 0x00, 0x2c, 0x05, 0xd0, 0x01, 0xf0, 0xed, 0xfc, ++ 0x40, 0x1b, 0x80, 0xb2, 0x0b, 0x28, 0xeb, 0xd3, 0x30, 0x68, 0xc1, 0x19, 0x0a, 0x20, 0x08, 0x5e, ++ 0x00, 0x2c, 0x03, 0xd0, 0x00, 0x28, 0x01, 0xda, 0x00, 0x24, 0xe4, 0x43, 0x20, 0x46, 0xf8, 0xbd, ++ 0x10, 0xb5, 0x90, 0x48, 0x00, 0x68, 0x80, 0x30, 0x00, 0x7a, 0x80, 0x07, 0x01, 0xd5, 0x00, 0x20, ++ 0xf0, 0xe4, 0xff, 0xf7, 0xc0, 0xff, 0x00, 0x28, 0xfa, 0xd0, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, ++ 0x01, 0x21, 0xc9, 0x43, 0x81, 0x82, 0x88, 0x49, 0x01, 0x20, 0x09, 0x68, 0x0d, 0x22, 0x52, 0x03, ++ 0x89, 0x18, 0x48, 0x86, 0x01, 0x46, 0x17, 0x20, 0x01, 0xf0, 0x3c, 0xff, 0x01, 0x20, 0xd9, 0xe4, ++ 0xf0, 0xb5, 0x80, 0x4c, 0x00, 0x21, 0x20, 0x68, 0x03, 0x25, 0x02, 0x78, 0x2d, 0x07, 0x52, 0x07, ++ 0x7d, 0x4e, 0x0f, 0x46, 0x00, 0x2a, 0x2c, 0xda, 0x58, 0x22, 0x82, 0x56, 0x20, 0x46, 0x00, 0x68, ++ 0xd3, 0x1d, 0x60, 0x30, 0x0e, 0x2b, 0x01, 0xd8, 0x87, 0x70, 0x13, 0xe0, 0x13, 0x46, 0x0f, 0x33, ++ 0x1e, 0x2b, 0x02, 0xd8, 0x10, 0x21, 0x04, 0x22, 0x0b, 0xe0, 0x13, 0x46, 0x17, 0x33, 0x2e, 0x2b, ++ 0x02, 0xd8, 0x20, 0x21, 0x08, 0x22, 0x04, 0xe0, 0x1f, 0x32, 0x3e, 0x2a, 0x02, 0xd8, 0x30, 0x21, ++ 0x0c, 0x22, 0x82, 0x70, 0x01, 0x20, 0xfe, 0xf7, 0xcb, 0xfc, 0xa8, 0x8a, 0x0f, 0x20, 0xc0, 0x43, ++ 0xa8, 0x82, 0x20, 0x68, 0x31, 0x68, 0x60, 0x30, 0x80, 0x78, 0x68, 0x4a, 0x40, 0x32, 0x89, 0x18, ++ 0x48, 0x80, 0x20, 0x68, 0x58, 0x21, 0x41, 0x56, 0x00, 0x29, 0x01, 0xda, 0x65, 0x48, 0x01, 0xe0, ++ 0x03, 0x20, 0x80, 0x03, 0xa9, 0x8a, 0x01, 0x21, 0xa9, 0x82, 0x32, 0x68, 0x41, 0x00, 0x0d, 0x20, ++ 0x40, 0x03, 0x12, 0x18, 0x91, 0x80, 0xa9, 0x8a, 0x5f, 0x49, 0xa9, 0x82, 0x33, 0x68, 0x80, 0x22, ++ 0x1b, 0x18, 0x5a, 0x80, 0xaa, 0x8a, 0xa9, 0x82, 0x31, 0x68, 0x08, 0x18, 0x47, 0x80, 0x00, 0x20, ++ 0xf0, 0xbd, 0x70, 0xb5, 0x53, 0x4c, 0x88, 0x21, 0x20, 0x68, 0x00, 0x25, 0x09, 0x5c, 0x40, 0x30, ++ 0xc9, 0x07, 0x00, 0x29, 0x03, 0xd0, 0x05, 0x76, 0x45, 0x76, 0x00, 0x20, 0x70, 0xbd, 0x81, 0x7a, ++ 0x07, 0x29, 0x01, 0xd0, 0x05, 0x76, 0x45, 0x76, 0xff, 0xf7, 0x3d, 0xff, 0x00, 0x28, 0x28, 0xd0, ++ 0x21, 0x68, 0x40, 0x31, 0x0a, 0x7e, 0x10, 0x18, 0x40, 0xb2, 0x08, 0x76, 0x4a, 0x7e, 0x52, 0x1c, ++ 0x52, 0xb2, 0x4a, 0x76, 0x20, 0x28, 0x09, 0xda, 0x30, 0x2a, 0x07, 0xda, 0xff, 0xf7, 0x80, 0xff, ++ 0x20, 0x68, 0x07, 0x21, 0x40, 0x30, 0x81, 0x72, 0x02, 0x20, 0x70, 0xbd, 0x03, 0x20, 0x00, 0x07, ++ 0x81, 0x8a, 0x01, 0x21, 0xc9, 0x43, 0x81, 0x82, 0x3b, 0x49, 0x01, 0x20, 0x09, 0x68, 0x0d, 0x22, ++ 0x52, 0x03, 0x89, 0x18, 0x48, 0x86, 0x01, 0x46, 0x17, 0x20, 0x01, 0xf0, 0xa3, 0xfe, 0x01, 0x20, ++ 0x70, 0xbd, 0x20, 0x68, 0x40, 0x30, 0xc6, 0xe7, 0x32, 0x48, 0x53, 0x21, 0x00, 0x68, 0x0a, 0x5c, ++ 0xc1, 0x7b, 0xc9, 0x08, 0x00, 0x2a, 0x07, 0xd0, 0x01, 0x29, 0x11, 0xd9, 0x00, 0x7c, 0xc0, 0x08, ++ 0x01, 0x28, 0x0d, 0xd9, 0x00, 0x20, 0x70, 0x47, 0x01, 0x29, 0x09, 0xd9, 0x01, 0x7c, 0xc9, 0x08, ++ 0x01, 0x29, 0x05, 0xd9, 0x41, 0x7b, 0xc9, 0x08, 0x01, 0x29, 0x01, 0xd9, 0x80, 0x7b, 0xee, 0xe7, ++ 0x01, 0x20, 0x70, 0x47, 0xf8, 0xb5, 0x23, 0x4d, 0x0f, 0x23, 0x2a, 0x68, 0x11, 0x46, 0x40, 0x31, ++ 0xcb, 0x56, 0x4b, 0x76, 0x90, 0x7b, 0x54, 0x7b, 0x00, 0x1b, 0x40, 0x10, 0xd0, 0x84, 0x8e, 0x7d, ++ 0x00, 0x24, 0x01, 0x2e, 0x06, 0xd0, 0x01, 0x26, 0x40, 0x05, 0xf6, 0x05, 0x80, 0x19, 0x00, 0x16, ++ 0x18, 0x1a, 0x0d, 0xe0, 0x16, 0x46, 0x80, 0x36, 0xb7, 0x79, 0x07, 0x2f, 0x09, 0xd3, 0xb4, 0x71, ++ 0x0c, 0x28, 0x01, 0xdd, 0x58, 0x1e, 0x03, 0xe0, 0x0c, 0x26, 0xf0, 0x42, 0x01, 0xda, 0x58, 0x1c, ++ 0x48, 0x76, 0x19, 0x20, 0x08, 0x56, 0x18, 0x28, 0x01, 0xda, 0x18, 0x20, 0x02, 0xe0, 0x2c, 0x28, ++ 0x01, 0xdd, 0x2c, 0x20, 0x48, 0x76, 0x19, 0x20, 0x08, 0x56, 0x83, 0x42, 0x30, 0xd0, 0xc3, 0x1a, ++ 0xdb, 0x00, 0xd3, 0x84, 0xc8, 0x73, 0xfb, 0xf7, 0xb7, 0xfe, 0x28, 0x68, 0x26, 0x22, 0x81, 0x7b, ++ 0x82, 0x5e, 0xf8, 0x23, 0x89, 0x18, 0x09, 0xb2, 0x01, 0x85, 0x00, 0x29, 0x0e, 0xda, 0x04, 0x85, ++ 0x0f, 0xe0, 0x00, 0x00, 0x90, 0x00, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, 0x40, 0xa0, 0x01, 0x00, ++ 0xff, 0xf8, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0x7f, 0xff, 0x00, 0x00, 0xf8, 0x29, 0x00, 0xdd, ++ 0x03, 0x85, 0x01, 0x8d, 0x81, 0x73, 0x41, 0x7b, 0x89, 0x1a, 0x09, 0xb2, 0x01, 0x85, 0x00, 0x29, ++ 0x01, 0xda, 0x04, 0x85, 0x02, 0xe0, 0xf8, 0x29, 0x00, 0xdd, 0x03, 0x85, 0x01, 0x8d, 0x41, 0x73, ++ 0x00, 0x20, 0xf8, 0xbd, 0x10, 0xb5, 0xfa, 0x4c, 0x20, 0x68, 0x01, 0x46, 0x40, 0x30, 0x82, 0x7a, ++ 0x12, 0x2a, 0x23, 0xd0, 0xc0, 0x7c, 0x00, 0x28, 0x01, 0xd0, 0x01, 0x28, 0x70, 0xd1, 0x80, 0x31, ++ 0x48, 0x7b, 0x40, 0x06, 0x6c, 0xd4, 0xfe, 0xf7, 0x47, 0xfa, 0xfb, 0xf7, 0xf2, 0xfb, 0x21, 0x68, ++ 0x40, 0x31, 0x08, 0x76, 0x08, 0x7c, 0x08, 0x77, 0x0f, 0x20, 0xfb, 0xf7, 0x84, 0xfd, 0x20, 0x68, ++ 0x00, 0x21, 0x40, 0x30, 0x1d, 0xe0, 0x89, 0x7d, 0x01, 0x29, 0x32, 0xd0, 0xfd, 0xf7, 0xd8, 0xfc, ++ 0xfb, 0xf7, 0xbd, 0xfb, 0x20, 0x68, 0x12, 0x21, 0x40, 0x30, 0x81, 0x72, 0xfb, 0xf7, 0xff, 0xfb, ++ 0x00, 0x28, 0x29, 0xd0, 0x20, 0x68, 0x40, 0x30, 0x81, 0x7d, 0x40, 0x7d, 0x01, 0x29, 0x25, 0xd0, ++ 0xfd, 0xf7, 0x63, 0xfd, 0x20, 0x68, 0x40, 0x30, 0xc1, 0x7d, 0x00, 0x29, 0xe8, 0xd0, 0x41, 0x7d, ++ 0x49, 0x1c, 0x41, 0x75, 0x21, 0x68, 0x40, 0x31, 0xca, 0x7c, 0x48, 0x7d, 0x00, 0x2a, 0x18, 0xd0, ++ 0x02, 0x22, 0x90, 0x42, 0xd7, 0xd3, 0x1c, 0x20, 0x08, 0x56, 0xfb, 0xf7, 0xf7, 0xfd, 0x21, 0x68, ++ 0x58, 0x20, 0x08, 0x56, 0xfb, 0xf7, 0xbe, 0xfb, 0xff, 0xf7, 0x26, 0xff, 0x01, 0x28, 0x0a, 0xd0, ++ 0x26, 0xe0, 0xfd, 0xf7, 0xd9, 0xfc, 0xcb, 0xe7, 0x02, 0x20, 0x98, 0xe5, 0xfd, 0xf7, 0xee, 0xfd, ++ 0xd8, 0xe7, 0x04, 0x22, 0xe5, 0xe7, 0x20, 0x68, 0x80, 0x79, 0x40, 0x06, 0x18, 0xd4, 0x01, 0x21, ++ 0x1b, 0x20, 0x01, 0xf0, 0xaf, 0xfd, 0x20, 0x68, 0x80, 0x30, 0x01, 0x7a, 0x0a, 0x07, 0x01, 0x21, ++ 0x00, 0x2a, 0x0c, 0xdb, 0x03, 0x20, 0x00, 0x07, 0x82, 0x8a, 0xca, 0x1e, 0x82, 0x82, 0xc1, 0x48, ++ 0x00, 0x68, 0x0d, 0x22, 0x52, 0x03, 0x80, 0x18, 0x41, 0x86, 0x01, 0x20, 0x77, 0xe5, 0x01, 0x74, ++ 0x20, 0x68, 0x30, 0x23, 0x01, 0x46, 0x02, 0x46, 0x40, 0x31, 0x8b, 0x72, 0x80, 0x30, 0x84, 0x79, ++ 0x03, 0x46, 0x64, 0x1c, 0x84, 0x71, 0xc8, 0x7c, 0x00, 0x28, 0x0a, 0xd1, 0x10, 0x88, 0x41, 0x07, ++ 0x07, 0xd4, 0x00, 0x06, 0x05, 0xd4, 0x58, 0x7b, 0xc0, 0x06, 0x02, 0xd4, 0xff, 0xf7, 0x02, 0xff, ++ 0x5d, 0xe5, 0x00, 0x20, 0x5b, 0xe5, 0x10, 0xb5, 0x04, 0x46, 0xfb, 0xf7, 0xe7, 0xfc, 0x03, 0x21, ++ 0x09, 0x07, 0x88, 0x8a, 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0xaa, 0x48, 0xe2, 0x06, 0x03, 0x68, ++ 0xd2, 0x0e, 0x0d, 0x24, 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, 0xa6, 0x4a, 0x8a, 0x82, ++ 0xa6, 0x4b, 0x04, 0x68, 0xa6, 0x4a, 0xa4, 0x18, 0x23, 0x84, 0x8b, 0x8a, 0x00, 0x23, 0x8b, 0x82, ++ 0xa4, 0x4b, 0x04, 0x68, 0xa4, 0x18, 0x63, 0x84, 0x8b, 0x8a, 0xff, 0x23, 0x8b, 0x82, 0x01, 0x21, ++ 0x00, 0x68, 0x89, 0x02, 0x80, 0x18, 0x81, 0x84, 0x31, 0xe5, 0x10, 0xb5, 0x04, 0x46, 0xfb, 0xf7, ++ 0xbd, 0xfc, 0x03, 0x21, 0x09, 0x07, 0x88, 0x8a, 0x1f, 0x20, 0xc0, 0x43, 0x88, 0x82, 0x95, 0x48, ++ 0xe2, 0x06, 0x03, 0x68, 0xd2, 0x0e, 0x0d, 0x24, 0x64, 0x03, 0x1b, 0x19, 0x5a, 0x85, 0x8a, 0x8a, ++ 0x91, 0x4a, 0x8a, 0x82, 0x91, 0x4b, 0x04, 0x68, 0x91, 0x4a, 0xa4, 0x18, 0x23, 0x84, 0x8b, 0x8a, ++ 0x00, 0x23, 0x8b, 0x82, 0x90, 0x4b, 0x04, 0x68, 0xa4, 0x18, 0x63, 0x84, 0x8b, 0x8a, 0xff, 0x23, ++ 0x8b, 0x82, 0x01, 0x21, 0x00, 0x68, 0x89, 0x02, 0x80, 0x18, 0x81, 0x84, 0x07, 0xe5, 0x70, 0xb5, ++ 0x83, 0x4c, 0x4d, 0x22, 0x20, 0x68, 0x00, 0x25, 0x11, 0x56, 0x2d, 0x29, 0x2b, 0xd0, 0x2e, 0x29, ++ 0x0e, 0xd0, 0x61, 0x21, 0x09, 0x5c, 0x80, 0x30, 0x41, 0x74, 0x14, 0x20, 0xff, 0xf7, 0x9b, 0xff, ++ 0x20, 0x68, 0x05, 0x84, 0xfb, 0xf7, 0xe3, 0xfa, 0x20, 0x68, 0x2e, 0x21, 0x40, 0x30, 0x41, 0x73, ++ 0xfb, 0xf7, 0x25, 0xfb, 0x00, 0x28, 0x31, 0xd0, 0x00, 0x20, 0xff, 0xf7, 0x60, 0xf9, 0x20, 0x68, ++ 0x01, 0x46, 0x40, 0x30, 0xc2, 0x7d, 0x00, 0x2a, 0xec, 0xd0, 0x60, 0x31, 0x49, 0x78, 0x41, 0x77, ++ 0x14, 0x20, 0xff, 0xf7, 0xaa, 0xff, 0x20, 0x68, 0x05, 0x84, 0xfb, 0xf7, 0xc8, 0xfa, 0x20, 0x68, ++ 0x2d, 0x21, 0x40, 0x30, 0x41, 0x73, 0xfb, 0xf7, 0x0a, 0xfb, 0x00, 0x28, 0x16, 0xd0, 0x00, 0x20, ++ 0xff, 0xf7, 0x45, 0xf9, 0x22, 0x68, 0x11, 0x46, 0x40, 0x31, 0xc8, 0x7d, 0x00, 0x28, 0xec, 0xd0, ++ 0x4d, 0x73, 0x61, 0x24, 0x48, 0x7f, 0xa3, 0x56, 0x98, 0x42, 0x00, 0xdd, 0x18, 0x46, 0x48, 0x77, ++ 0x91, 0x20, 0x10, 0x56, 0xfb, 0xf7, 0xd6, 0xfa, 0x00, 0x20, 0x70, 0xbd, 0x02, 0x20, 0x70, 0xbd, ++ 0xf8, 0xb5, 0x62, 0x48, 0x5a, 0x4c, 0x82, 0x7f, 0x20, 0x68, 0x01, 0x46, 0x40, 0x30, 0x83, 0x7a, ++ 0x23, 0x2b, 0x2c, 0xd0, 0x24, 0x2b, 0x39, 0xd0, 0xc3, 0x7c, 0x00, 0x2b, 0x02, 0xd1, 0x0b, 0x78, ++ 0x5b, 0x07, 0x01, 0xd4, 0x00, 0x20, 0xf8, 0xbd, 0x00, 0x25, 0x0b, 0x46, 0x4d, 0x84, 0x80, 0x33, ++ 0x1e, 0x79, 0x01, 0x2e, 0x00, 0xd0, 0x45, 0x75, 0x5b, 0x79, 0x00, 0x2b, 0x0f, 0xd0, 0x0f, 0x23, ++ 0xc3, 0x56, 0x9d, 0x1a, 0x00, 0x2d, 0x01, 0xdd, 0x5b, 0x1e, 0xc3, 0x73, 0x0f, 0x23, 0xc3, 0x56, ++ 0x9a, 0x1a, 0x01, 0xd5, 0x5b, 0x1c, 0xc3, 0x73, 0x01, 0x20, 0x48, 0x84, 0x53, 0xe0, 0x07, 0x20, ++ 0xc0, 0x43, 0xfb, 0xf7, 0xd3, 0xfc, 0x20, 0x68, 0x23, 0x21, 0x40, 0x30, 0x81, 0x72, 0xff, 0xf7, ++ 0x76, 0xff, 0x02, 0x28, 0xd7, 0xd0, 0x20, 0x68, 0x5d, 0x21, 0x09, 0x5c, 0xc1, 0x84, 0x08, 0x20, ++ 0xfb, 0xf7, 0xc4, 0xfc, 0x20, 0x68, 0x24, 0x21, 0x40, 0x30, 0x81, 0x72, 0xff, 0xf7, 0x67, 0xff, ++ 0x02, 0x28, 0xc8, 0xd0, 0x22, 0x68, 0x00, 0x26, 0x10, 0x46, 0x40, 0x30, 0x41, 0x7f, 0xd3, 0x8c, ++ 0xf6, 0x43, 0xc9, 0x1a, 0x09, 0xb2, 0xd1, 0x84, 0x00, 0x29, 0x10, 0xd0, 0x43, 0x7d, 0x00, 0x2b, ++ 0x31, 0xd0, 0x00, 0x29, 0x01, 0xdb, 0x01, 0x23, 0x00, 0xe0, 0x33, 0x46, 0x1c, 0x25, 0x45, 0x57, ++ 0x00, 0x2d, 0x01, 0xdb, 0x01, 0x25, 0x00, 0xe0, 0x35, 0x46, 0xab, 0x42, 0x23, 0xd0, 0x01, 0x23, ++ 0x53, 0x84, 0x00, 0x29, 0x01, 0xdb, 0x0d, 0x46, 0x00, 0xe0, 0x4d, 0x42, 0x1c, 0x23, 0xc3, 0x56, ++ 0x00, 0x2b, 0x01, 0xdb, 0x1f, 0x46, 0x00, 0xe0, 0x5f, 0x42, 0xbd, 0x42, 0x0a, 0xdd, 0x80, 0x32, ++ 0xd2, 0x78, 0x01, 0x2a, 0x1a, 0xd0, 0x0f, 0x22, 0x82, 0x56, 0x00, 0x2b, 0x00, 0xdb, 0x01, 0x26, ++ 0x92, 0x19, 0xc2, 0x73, 0x01, 0x77, 0x21, 0x68, 0x0f, 0x20, 0x40, 0x31, 0x08, 0x56, 0x18, 0x28, ++ 0x0f, 0xda, 0x18, 0x20, 0x10, 0xe0, 0x80, 0x32, 0xd2, 0x78, 0x01, 0x2a, 0x06, 0xd0, 0x0f, 0x22, ++ 0x82, 0x56, 0x00, 0x29, 0x00, 0xdb, 0x01, 0x26, 0x92, 0x1b, 0xea, 0xe7, 0x0f, 0x22, 0x82, 0x56, ++ 0xe7, 0xe7, 0x2c, 0x28, 0x01, 0xdd, 0x2c, 0x20, 0xc8, 0x73, 0x0f, 0x20, 0x08, 0x56, 0xfb, 0xf7, ++ 0xab, 0xfc, 0x20, 0x68, 0x01, 0x46, 0x40, 0x30, 0x42, 0x7d, 0x03, 0x46, 0x52, 0x1c, 0xd2, 0xb2, ++ 0x42, 0x75, 0x48, 0x8c, 0x01, 0x28, 0x03, 0xd0, 0x10, 0x2a, 0x01, 0xd2, 0x01, 0x20, 0x00, 0xe0, ++ 0x00, 0x20, 0x80, 0x31, 0x08, 0x71, 0x00, 0x20, 0x98, 0x72, 0xfb, 0xf7, 0x4f, 0xfc, 0x59, 0xe7, ++ 0x90, 0x00, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, 0xf3, 0x8f, 0x00, 0x00, 0x0c, 0x30, 0x00, 0x00, ++ 0x40, 0xa0, 0x01, 0x00, 0x60, 0x60, 0x00, 0x00, 0x60, 0x20, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, ++ 0xfe, 0xb5, 0xfe, 0x4e, 0x30, 0x68, 0xff, 0x30, 0x01, 0x30, 0x45, 0x8e, 0x68, 0x46, 0x05, 0x80, ++ 0xac, 0x06, 0x30, 0x68, 0xa4, 0x0e, 0xfa, 0x4f, 0xc0, 0x19, 0x80, 0x88, 0x40, 0x07, 0xc0, 0x0f, ++ 0x0e, 0xd1, 0xe8, 0x0b, 0x0c, 0xd0, 0xb8, 0x05, 0x81, 0x8a, 0x04, 0x21, 0xc9, 0x43, 0x81, 0x82, ++ 0x31, 0x68, 0x04, 0x20, 0xc9, 0x19, 0x88, 0x80, 0x01, 0x21, 0x10, 0x20, 0x01, 0xf0, 0xf2, 0xfb, ++ 0xf0, 0x48, 0x01, 0x68, 0x08, 0x46, 0x80, 0x30, 0xc2, 0x7e, 0xa2, 0x42, 0x1b, 0xd0, 0x00, 0x23, ++ 0x01, 0x22, 0x00, 0x2c, 0x0e, 0xd0, 0x42, 0x31, 0x0d, 0x80, 0x02, 0x76, 0x03, 0x20, 0x00, 0x07, ++ 0x81, 0x8a, 0x83, 0x82, 0x30, 0x68, 0xc0, 0x19, 0x03, 0x80, 0x01, 0x23, 0x00, 0x92, 0x01, 0x94, ++ 0x03, 0x22, 0x04, 0xe0, 0xc2, 0x75, 0x01, 0x93, 0x00, 0x92, 0x01, 0x23, 0x04, 0x22, 0x09, 0x21, ++ 0x01, 0x20, 0x01, 0xf0, 0x59, 0xfb, 0xdf, 0x48, 0x00, 0x68, 0x80, 0x30, 0xc4, 0x76, 0xfe, 0xbd, ++ 0x7c, 0xb5, 0xda, 0x4c, 0x20, 0x68, 0xda, 0x49, 0x40, 0x39, 0x40, 0x18, 0xc0, 0x8c, 0x03, 0x23, ++ 0xc6, 0x07, 0xd8, 0x48, 0x1b, 0x07, 0x00, 0x68, 0x00, 0x21, 0x80, 0x30, 0x00, 0x2e, 0xd6, 0x4a, ++ 0xd3, 0x4d, 0x9e, 0x8a, 0x9a, 0x82, 0x0b, 0xd0, 0x23, 0x68, 0x02, 0x22, 0x5b, 0x19, 0x9a, 0x80, ++ 0x01, 0x22, 0x82, 0x75, 0xc2, 0x75, 0x00, 0x91, 0x01, 0x91, 0x13, 0x46, 0x0b, 0x21, 0x19, 0xe0, ++ 0x22, 0x68, 0x52, 0x19, 0x91, 0x80, 0x22, 0x68, 0x52, 0x19, 0x92, 0x88, 0x52, 0x07, 0xd2, 0x0f, ++ 0x0b, 0xd1, 0x9a, 0x8a, 0x99, 0x82, 0x22, 0x68, 0x52, 0x19, 0x52, 0x88, 0x23, 0x68, 0x52, 0x04, ++ 0x52, 0x0c, 0x5b, 0x19, 0x5a, 0x80, 0x81, 0x75, 0x41, 0x76, 0x00, 0x91, 0x01, 0x23, 0x04, 0x22, ++ 0x01, 0x91, 0x21, 0x21, 0x01, 0x20, 0x01, 0xf0, 0x17, 0xfb, 0x7c, 0xbd, 0x10, 0xb5, 0xbb, 0x48, ++ 0x00, 0x68, 0xbb, 0x49, 0x40, 0x39, 0x40, 0x18, 0x84, 0x8d, 0x60, 0x08, 0xc0, 0x07, 0x01, 0xd0, ++ 0xff, 0xf7, 0xb6, 0xff, 0xe0, 0x07, 0x01, 0xd0, 0xff, 0xf7, 0x6a, 0xff, 0x10, 0xbd, 0x7c, 0xb5, ++ 0xb4, 0x4e, 0x05, 0x46, 0x30, 0x68, 0x01, 0x24, 0x80, 0x30, 0xc0, 0x7d, 0x00, 0x28, 0x08, 0xd1, ++ 0x05, 0x20, 0x01, 0x90, 0x00, 0x23, 0x02, 0x22, 0x15, 0x21, 0x00, 0x94, 0x01, 0x20, 0x01, 0xf0, ++ 0xf3, 0xfa, 0x31, 0x68, 0x00, 0x20, 0x80, 0x31, 0x08, 0x76, 0x03, 0x22, 0xc8, 0x75, 0x12, 0x07, ++ 0x93, 0x8a, 0x90, 0x82, 0xa5, 0x48, 0x00, 0x68, 0xa5, 0x4a, 0x80, 0x18, 0x05, 0x80, 0x88, 0x7e, ++ 0x40, 0x1c, 0xc2, 0xb2, 0x8a, 0x76, 0xe8, 0xb2, 0x01, 0x2a, 0x00, 0x94, 0x01, 0x90, 0x06, 0xd0, ++ 0x00, 0x23, 0x02, 0x22, 0x0a, 0x21, 0x01, 0x20, 0x01, 0xf0, 0xd6, 0xfa, 0x7c, 0xbd, 0x00, 0x23, ++ 0x01, 0x22, 0x20, 0x21, 0xf7, 0xe7, 0x70, 0xb5, 0x98, 0x49, 0x08, 0x68, 0x98, 0x4a, 0x80, 0x18, ++ 0x43, 0x88, 0x01, 0x20, 0xc0, 0x03, 0x03, 0x43, 0x90, 0x05, 0x84, 0x8a, 0x01, 0x24, 0xe4, 0x43, ++ 0x84, 0x82, 0x0d, 0x68, 0x01, 0x24, 0xad, 0x18, 0xac, 0x80, 0x84, 0x8a, 0x00, 0x24, 0x84, 0x82, ++ 0x08, 0x68, 0x80, 0x18, 0x43, 0x80, 0x01, 0x21, 0x0c, 0x20, 0x01, 0xf0, 0x2b, 0xfb, 0x70, 0xbd, ++ 0x0f, 0xb4, 0x10, 0xb5, 0x03, 0x20, 0x00, 0x07, 0x81, 0x8a, 0xff, 0x21, 0x09, 0x02, 0x81, 0x82, ++ 0x6c, 0x46, 0xe1, 0x8e, 0xc9, 0x07, 0x0b, 0x0e, 0xa1, 0x8e, 0xc9, 0x07, 0x49, 0x0e, 0x0b, 0x43, ++ 0x61, 0x8e, 0xc9, 0x07, 0x89, 0x0e, 0x0b, 0x43, 0x21, 0x8e, 0xc9, 0x07, 0xc9, 0x0e, 0x0b, 0x43, ++ 0xe1, 0x8d, 0xc9, 0x07, 0x09, 0x0f, 0x0b, 0x43, 0xa1, 0x8d, 0xc9, 0x07, 0x49, 0x0f, 0x0b, 0x43, ++ 0x61, 0x8d, 0xc9, 0x07, 0x89, 0x0f, 0x0b, 0x43, 0x21, 0x8d, 0xc9, 0x07, 0xc9, 0x0f, 0x0b, 0x43, ++ 0x76, 0x49, 0x0c, 0x68, 0xd1, 0x22, 0x52, 0x02, 0xa4, 0x18, 0xe3, 0x86, 0x83, 0x8a, 0x23, 0x23, ++ 0x9b, 0x02, 0x83, 0x82, 0x6c, 0x46, 0x63, 0x8c, 0x24, 0x8c, 0xdb, 0x07, 0xe4, 0x07, 0x5b, 0x0c, ++ 0xa4, 0x0c, 0x23, 0x43, 0x6c, 0x46, 0xe4, 0x8b, 0xe4, 0x07, 0xe4, 0x0c, 0x23, 0x43, 0x6c, 0x46, ++ 0x64, 0x8b, 0xe4, 0x07, 0xa4, 0x0d, 0x23, 0x43, 0x6c, 0x46, 0x24, 0x8b, 0xe4, 0x07, 0xe4, 0x0d, ++ 0x23, 0x43, 0x6c, 0x46, 0xe4, 0x8a, 0xe4, 0x07, 0x24, 0x0e, 0x23, 0x43, 0x6c, 0x46, 0xa4, 0x8a, ++ 0xe4, 0x07, 0x64, 0x0e, 0x23, 0x43, 0x6c, 0x46, 0x64, 0x8a, 0xe4, 0x07, 0xa4, 0x0e, 0x23, 0x43, ++ 0x6c, 0x46, 0x24, 0x8a, 0xe4, 0x07, 0xe4, 0x0e, 0x23, 0x43, 0x6c, 0x46, 0xe4, 0x89, 0xe4, 0x07, ++ 0x24, 0x0f, 0x23, 0x43, 0x6c, 0x46, 0xa4, 0x89, 0xe4, 0x07, 0x64, 0x0f, 0x23, 0x43, 0x6c, 0x46, ++ 0x64, 0x89, 0xe4, 0x07, 0xa4, 0x0f, 0x23, 0x43, 0x6c, 0x46, 0x24, 0x89, 0xe4, 0x07, 0xe4, 0x0f, ++ 0x23, 0x43, 0x0c, 0x68, 0xa4, 0x18, 0x23, 0x87, 0x83, 0x8a, 0x01, 0x23, 0xdb, 0x03, 0x83, 0x82, ++ 0x10, 0xac, 0xa3, 0x8c, 0x64, 0x8c, 0xdb, 0x07, 0xe4, 0x07, 0x5b, 0x0c, 0xa4, 0x0c, 0x23, 0x43, ++ 0x10, 0xac, 0x24, 0x8c, 0xe4, 0x07, 0xe4, 0x0c, 0x23, 0x43, 0x10, 0xac, 0xe4, 0x8b, 0xe4, 0x07, ++ 0x24, 0x0d, 0x23, 0x43, 0x10, 0xac, 0xa4, 0x8b, 0xe4, 0x07, 0x64, 0x0d, 0x23, 0x43, 0x10, 0xac, ++ 0x64, 0x8b, 0xe4, 0x07, 0xa4, 0x0d, 0x23, 0x43, 0x10, 0xac, 0x24, 0x8b, 0xe4, 0x07, 0xe4, 0x0d, ++ 0x23, 0x43, 0x10, 0xac, 0xe4, 0x8a, 0xe4, 0x07, 0x24, 0x0e, 0x23, 0x43, 0x10, 0xac, 0xa4, 0x8a, ++ 0xe4, 0x07, 0x64, 0x0e, 0x23, 0x43, 0x10, 0xac, 0x64, 0x8a, 0xe4, 0x07, 0xa4, 0x0e, 0x23, 0x43, ++ 0x10, 0xac, 0x24, 0x8a, 0xe4, 0x07, 0xe4, 0x0e, 0x23, 0x43, 0x10, 0xac, 0xe4, 0x89, 0xe4, 0x07, ++ 0x24, 0x0f, 0x23, 0x43, 0x10, 0xac, 0xa4, 0x89, 0xe4, 0x07, 0x64, 0x0f, 0x23, 0x43, 0x10, 0xac, ++ 0x64, 0x89, 0xe4, 0x07, 0xa4, 0x0f, 0x23, 0x43, 0x10, 0xac, 0x24, 0x89, 0xe4, 0x07, 0xe4, 0x0f, ++ 0x23, 0x43, 0x0c, 0x68, 0xa4, 0x18, 0x63, 0x87, 0x83, 0x8a, 0x0f, 0x23, 0xdb, 0x43, 0x83, 0x82, ++ 0x10, 0xac, 0x60, 0x88, 0x23, 0x88, 0xc0, 0x07, 0xdb, 0x07, 0x00, 0x0f, 0x5b, 0x0f, 0x18, 0x43, ++ 0x6c, 0x46, 0xe3, 0x8f, 0x09, 0x68, 0xdb, 0x07, 0x9b, 0x0f, 0x18, 0x43, 0xa3, 0x8f, 0xdb, 0x07, ++ 0xdb, 0x0f, 0x18, 0x43, 0x89, 0x18, 0x88, 0x87, 0x10, 0xbc, 0x08, 0xbc, 0x00, 0x20, 0x04, 0xb0, ++ 0x18, 0x47, 0xff, 0xb5, 0xab, 0xb0, 0x1e, 0x00, 0x15, 0x46, 0x04, 0x46, 0x18, 0xd0, 0x00, 0x27, ++ 0x20, 0x21, 0x15, 0xa8, 0x01, 0xf0, 0xd6, 0xfa, 0x14, 0x21, 0x26, 0xa8, 0x01, 0xf0, 0xd2, 0xfa, ++ 0x00, 0x20, 0x00, 0x90, 0x01, 0x90, 0x02, 0x90, 0x24, 0x21, 0x1d, 0xa8, 0x01, 0xf0, 0xca, 0xfa, ++ 0x00, 0x2f, 0x0a, 0xd0, 0x12, 0x2d, 0x05, 0xdd, 0x06, 0x20, 0xad, 0x1f, 0xe9, 0xb2, 0x06, 0xe0, ++ 0x01, 0x27, 0xe5, 0xe7, 0xe9, 0xb2, 0x00, 0x20, 0x01, 0xe0, 0xe9, 0xb2, 0xf0, 0xb2, 0x2c, 0x9a, ++ 0xc3, 0x07, 0x12, 0x1b, 0x52, 0x1a, 0x12, 0x1a, 0xd5, 0xb2, 0x01, 0x22, 0x00, 0x2b, 0x01, 0xd1, ++ 0x06, 0x28, 0x01, 0xd3, 0x20, 0xab, 0x1a, 0x83, 0x02, 0x28, 0x07, 0xe0, 0x84, 0x00, 0x00, 0x20, ++ 0xc0, 0xa0, 0x01, 0x00, 0x90, 0x00, 0x00, 0x20, 0xfd, 0xff, 0x00, 0x00, 0x01, 0xd3, 0x20, 0xab, ++ 0x1a, 0x84, 0x04, 0x28, 0x04, 0xd3, 0x20, 0xab, 0x9a, 0x84, 0x06, 0x28, 0x00, 0xd3, 0x9a, 0x83, ++ 0xfe, 0x48, 0x20, 0x40, 0x01, 0x28, 0x01, 0xd0, 0x0a, 0x2c, 0x01, 0xdb, 0x10, 0xa8, 0x82, 0x86, ++ 0x02, 0x2c, 0x01, 0xdb, 0x20, 0xa8, 0x82, 0x81, 0x04, 0x2c, 0x01, 0xdb, 0x20, 0xa8, 0xc2, 0x80, ++ 0x06, 0x2c, 0x01, 0xdb, 0x20, 0xa8, 0x02, 0x80, 0x08, 0x2c, 0x04, 0xdb, 0x10, 0xa8, 0x42, 0x87, ++ 0x0a, 0x2c, 0x00, 0xdb, 0x42, 0x85, 0xc8, 0x07, 0x01, 0xd1, 0x08, 0x29, 0x01, 0xd3, 0x10, 0xa8, ++ 0x82, 0x82, 0x02, 0x29, 0x01, 0xd3, 0x10, 0xa8, 0x82, 0x83, 0x04, 0x29, 0x01, 0xd3, 0x10, 0xa8, ++ 0x02, 0x84, 0x06, 0x29, 0x04, 0xd3, 0x10, 0xa8, 0x82, 0x84, 0x08, 0x29, 0x00, 0xd3, 0x02, 0x83, ++ 0x10, 0xa8, 0x44, 0x8d, 0x00, 0x2c, 0x1f, 0xd1, 0xc8, 0x07, 0x01, 0xd0, 0x08, 0x29, 0x19, 0xd2, ++ 0x12, 0x29, 0x17, 0xd2, 0x10, 0xa8, 0x40, 0x8f, 0x01, 0x28, 0x01, 0xd1, 0x0a, 0x29, 0x11, 0xd2, ++ 0x20, 0xa8, 0x00, 0x88, 0x01, 0x28, 0x01, 0xd1, 0x0c, 0x29, 0x0b, 0xd2, 0x20, 0xa8, 0xc0, 0x88, ++ 0x01, 0x28, 0x01, 0xd1, 0x0e, 0x29, 0x05, 0xd2, 0x20, 0xa8, 0x80, 0x89, 0x01, 0x28, 0x03, 0xd1, ++ 0x10, 0x29, 0x01, 0xd3, 0x10, 0xa8, 0x82, 0x85, 0x10, 0xab, 0x58, 0x8f, 0x03, 0x90, 0x00, 0x28, ++ 0x02, 0xd1, 0x0a, 0x29, 0x00, 0xd3, 0x9a, 0x87, 0x20, 0xa8, 0x00, 0x88, 0x84, 0x46, 0x00, 0x28, ++ 0x03, 0xd1, 0x0c, 0x29, 0x01, 0xd3, 0x20, 0xa8, 0x42, 0x80, 0x20, 0xa8, 0xc7, 0x88, 0x00, 0x2f, ++ 0x02, 0xd1, 0x0e, 0x29, 0x00, 0xd3, 0x02, 0x81, 0x86, 0x89, 0x00, 0x2e, 0x02, 0xd1, 0x10, 0x29, ++ 0x00, 0xd3, 0xc2, 0x81, 0x9b, 0x8e, 0x00, 0x2b, 0x15, 0xd1, 0x12, 0x29, 0x11, 0xd2, 0x03, 0x98, ++ 0x01, 0x28, 0x01, 0xd1, 0x0a, 0x29, 0x0c, 0xd2, 0x60, 0x46, 0x01, 0x28, 0x01, 0xd1, 0x0c, 0x29, ++ 0x07, 0xd2, 0x01, 0x2f, 0x01, 0xd1, 0x0e, 0x29, 0x03, 0xd2, 0x01, 0x2e, 0x03, 0xd1, 0x10, 0x29, ++ 0x01, 0xd3, 0x10, 0xa8, 0xc2, 0x86, 0x00, 0x2d, 0x7e, 0xd0, 0x6d, 0x1e, 0xe8, 0xb2, 0xc1, 0x07, ++ 0x01, 0xd0, 0x69, 0x46, 0x0a, 0x80, 0x40, 0x08, 0xf6, 0xd0, 0xc1, 0x07, 0x05, 0xd0, 0x40, 0x1e, ++ 0x69, 0x46, 0x00, 0x06, 0x4a, 0x80, 0x00, 0x0e, 0xee, 0xd0, 0x69, 0x46, 0x89, 0x88, 0x00, 0x29, ++ 0x05, 0xd1, 0x80, 0x1e, 0x69, 0x46, 0x00, 0x06, 0x8a, 0x80, 0x00, 0x0e, 0xe4, 0xd0, 0x69, 0x46, ++ 0xc9, 0x88, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, 0x69, 0x46, 0x00, 0x06, 0xca, 0x80, 0x00, 0x0e, ++ 0xda, 0xd0, 0x69, 0x46, 0x49, 0x88, 0x00, 0x29, 0x6f, 0xd1, 0x20, 0xa9, 0xc9, 0x8b, 0x00, 0x29, ++ 0x0d, 0xd1, 0x20, 0xa9, 0x89, 0x8b, 0x00, 0x29, 0x09, 0xd1, 0x69, 0x46, 0x4a, 0x80, 0x80, 0x1e, ++ 0x20, 0xa9, 0x00, 0x06, 0xca, 0x83, 0x00, 0x0e, 0xc6, 0xd0, 0x00, 0x2a, 0x5d, 0xd1, 0x20, 0xa9, ++ 0x49, 0x8b, 0x00, 0x29, 0x0d, 0xd1, 0x20, 0xa9, 0x09, 0x8b, 0x00, 0x29, 0x09, 0xd1, 0x69, 0x46, ++ 0x4a, 0x80, 0x80, 0x1e, 0x20, 0xa9, 0x00, 0x06, 0x4a, 0x83, 0x00, 0x0e, 0xb4, 0xd0, 0x00, 0x2a, ++ 0x4b, 0xd1, 0x10, 0xa9, 0x49, 0x8b, 0x00, 0x29, 0x0d, 0xd1, 0x10, 0xa9, 0x09, 0x8b, 0x00, 0x29, ++ 0x09, 0xd1, 0x69, 0x46, 0x4a, 0x80, 0x80, 0x1e, 0x10, 0xa9, 0x00, 0x06, 0x4a, 0x83, 0x00, 0x0e, ++ 0xa2, 0xd0, 0x00, 0x2a, 0x39, 0xd1, 0x10, 0xa9, 0xc9, 0x8a, 0x00, 0x29, 0x0d, 0xd1, 0x10, 0xa9, ++ 0x89, 0x8a, 0x00, 0x29, 0x09, 0xd1, 0x69, 0x46, 0x4a, 0x80, 0x80, 0x1e, 0x10, 0xa9, 0x00, 0x06, ++ 0xca, 0x82, 0x00, 0x0e, 0x90, 0xd0, 0x00, 0x2a, 0x27, 0xd1, 0x10, 0xa9, 0x09, 0x8f, 0x00, 0x29, ++ 0x11, 0xd1, 0x00, 0x2b, 0x0f, 0xd1, 0x10, 0xa9, 0xc9, 0x8e, 0x00, 0x29, 0x0b, 0xd1, 0x69, 0x46, ++ 0x4a, 0x80, 0x10, 0xa9, 0x0a, 0x87, 0x00, 0xe0, 0x1e, 0xe1, 0x80, 0x1e, 0x00, 0x06, 0x00, 0x0e, ++ 0x8a, 0xd0, 0x00, 0x2a, 0x11, 0xd1, 0x10, 0xa9, 0xc9, 0x8d, 0x00, 0x29, 0x0d, 0xd1, 0x00, 0x2c, ++ 0x0b, 0xd1, 0x10, 0xa9, 0x89, 0x8d, 0x00, 0x29, 0x07, 0xd1, 0x69, 0x46, 0x4a, 0x80, 0x80, 0x1e, ++ 0x10, 0xa9, 0x00, 0x06, 0xca, 0x85, 0x00, 0x0e, 0x8a, 0xd0, 0x20, 0xa9, 0xc9, 0x8c, 0x00, 0x29, ++ 0x09, 0xd1, 0x20, 0xa9, 0x89, 0x8c, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, 0x20, 0xa9, 0x00, 0x06, ++ 0xca, 0x84, 0x00, 0x0e, 0x90, 0xd0, 0x20, 0xa9, 0x49, 0x8c, 0x00, 0x29, 0x09, 0xd1, 0x20, 0xa9, ++ 0x09, 0x8c, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, 0x20, 0xa9, 0x00, 0x06, 0x4a, 0x84, 0x00, 0x0e, ++ 0x94, 0xd0, 0x10, 0xa9, 0xc9, 0x8c, 0x00, 0x29, 0x09, 0xd1, 0x10, 0xa9, 0x89, 0x8c, 0x00, 0x29, ++ 0x05, 0xd1, 0x80, 0x1e, 0x10, 0xa9, 0x00, 0x06, 0xca, 0x84, 0x00, 0x0e, 0x86, 0xd0, 0x10, 0xa9, ++ 0x49, 0x8c, 0x00, 0x29, 0x09, 0xd1, 0x10, 0xa9, 0x09, 0x8c, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, ++ 0x10, 0xa9, 0x00, 0x06, 0x4a, 0x84, 0x00, 0x0e, 0x8a, 0xd0, 0x10, 0xa9, 0xc9, 0x8b, 0x00, 0x29, ++ 0x09, 0xd1, 0x10, 0xa9, 0x89, 0x8b, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, 0x10, 0xa9, 0x00, 0x06, ++ 0xca, 0x83, 0x00, 0x0e, 0x8e, 0xd0, 0x20, 0xa9, 0x09, 0x8a, 0x00, 0x29, 0x0b, 0xd1, 0x00, 0x2e, ++ 0x09, 0xd1, 0x20, 0xa9, 0xc9, 0x89, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, 0x20, 0xa9, 0x00, 0x06, ++ 0x0a, 0x82, 0x00, 0x0e, 0x94, 0xd0, 0x20, 0xa9, 0x49, 0x89, 0x00, 0x29, 0x0b, 0xd1, 0x00, 0x2f, ++ 0x09, 0xd1, 0x20, 0xa9, 0x09, 0x89, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, 0x20, 0xa9, 0x00, 0x06, ++ 0x4a, 0x81, 0x00, 0x0e, 0x84, 0xd0, 0x20, 0xa9, 0x89, 0x88, 0x00, 0x29, 0x0c, 0xd1, 0x61, 0x46, ++ 0x00, 0x29, 0x09, 0xd1, 0x20, 0xa9, 0x49, 0x88, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, 0x20, 0xa9, ++ 0x00, 0x06, 0x8a, 0x80, 0x00, 0x0e, 0x87, 0xd0, 0x10, 0xa9, 0xc9, 0x8f, 0x00, 0x29, 0x0c, 0xd1, ++ 0x03, 0x99, 0x00, 0x29, 0x09, 0xd1, 0x10, 0xa9, 0x89, 0x8f, 0x00, 0x29, 0x05, 0xd1, 0x80, 0x1e, ++ 0x10, 0xa9, 0x00, 0x06, 0xca, 0x87, 0x00, 0x0e, 0x7e, 0xd0, 0x20, 0xa9, 0xc9, 0x8b, 0x00, 0x29, ++ 0x3a, 0xd1, 0x20, 0xa9, 0x89, 0x8b, 0x00, 0x29, 0x36, 0xd1, 0x20, 0xad, 0x6d, 0x8b, 0x00, 0x2d, ++ 0x0e, 0xd1, 0x20, 0xad, 0x2d, 0x8b, 0x00, 0x2d, 0x0a, 0xd1, 0x20, 0xad, 0x80, 0x1e, 0xea, 0x83, ++ 0x00, 0x06, 0x6a, 0x83, 0x00, 0x0e, 0x67, 0xd0, 0x00, 0x2a, 0x25, 0xd1, 0x00, 0x29, 0x23, 0xd1, ++ 0x10, 0xad, 0x6d, 0x8b, 0x00, 0x2d, 0x0f, 0xd1, 0x10, 0xad, 0x2d, 0x8b, 0x00, 0x2d, 0x0b, 0xd1, ++ 0x20, 0xad, 0xea, 0x83, 0x80, 0x1e, 0x10, 0xad, 0x00, 0x06, 0x6a, 0x83, 0x00, 0x0e, 0x53, 0xd0, ++ 0x00, 0x2a, 0x11, 0xd1, 0x00, 0x29, 0x0f, 0xd1, 0x10, 0xa9, 0xc9, 0x8a, 0x00, 0x29, 0x0b, 0xd1, ++ 0x10, 0xa9, 0x89, 0x8a, 0x00, 0x29, 0x07, 0xd1, 0x20, 0xa9, 0xca, 0x83, 0x80, 0x1e, 0x10, 0xa9, ++ 0x00, 0x06, 0xca, 0x82, 0x00, 0x0e, 0x3f, 0xd0, 0x20, 0xa9, 0x49, 0x8b, 0x00, 0x29, 0x2a, 0xd1, ++ 0x20, 0xa9, 0x09, 0x8b, 0x00, 0x29, 0x26, 0xd1, 0x10, 0xad, 0x6d, 0x8b, 0x00, 0x2d, 0x12, 0xd1, ++ 0x10, 0xad, 0x2d, 0x8b, 0x00, 0x2d, 0x0e, 0xd1, 0x20, 0xad, 0x01, 0xe0, 0x01, 0x00, 0x00, 0x80, ++ 0x6a, 0x83, 0x80, 0x1e, 0x10, 0xad, 0x00, 0x06, 0x6a, 0x83, 0x00, 0x0e, 0x24, 0xd0, 0x00, 0x2a, ++ 0x11, 0xd1, 0x00, 0x29, 0x0f, 0xd1, 0x10, 0xa9, 0xc9, 0x8a, 0x00, 0x29, 0x0b, 0xd1, 0x10, 0xa9, ++ 0x89, 0x8a, 0x00, 0x29, 0x07, 0xd1, 0x20, 0xa9, 0x4a, 0x83, 0x80, 0x1e, 0x10, 0xa9, 0x00, 0x06, ++ 0xca, 0x82, 0x00, 0x0e, 0x10, 0xd0, 0x10, 0xa9, 0x49, 0x8b, 0x00, 0x29, 0x14, 0xd1, 0x10, 0xa9, ++ 0x09, 0x8b, 0x00, 0x29, 0x10, 0xd1, 0x10, 0xa9, 0xc9, 0x8a, 0x00, 0x29, 0x0c, 0xd1, 0x10, 0xa9, ++ 0x89, 0x8a, 0x00, 0x29, 0x08, 0xd1, 0x00, 0xe0, 0x84, 0xe0, 0x10, 0xa9, 0x80, 0x1e, 0x4a, 0x83, ++ 0x00, 0x06, 0xca, 0x82, 0x00, 0x0e, 0x7d, 0xd0, 0x20, 0xa9, 0xc9, 0x8b, 0x00, 0x29, 0x2b, 0xd1, ++ 0x20, 0xa9, 0x89, 0x8b, 0x00, 0x29, 0x27, 0xd1, 0x10, 0xad, 0x2d, 0x8f, 0x00, 0x2d, 0x11, 0xd1, ++ 0x00, 0x2b, 0x0f, 0xd1, 0x10, 0xad, 0xed, 0x8e, 0x00, 0x2d, 0x0b, 0xd1, 0x20, 0xad, 0xea, 0x83, ++ 0x80, 0x1e, 0x10, 0xad, 0x00, 0x06, 0x2a, 0x87, 0x00, 0x0e, 0x63, 0xd0, 0x00, 0x2a, 0x13, 0xd1, ++ 0x00, 0x29, 0x11, 0xd1, 0x10, 0xa9, 0xc9, 0x8d, 0x00, 0x29, 0x0d, 0xd1, 0x00, 0x2c, 0x0b, 0xd1, ++ 0x10, 0xa9, 0x89, 0x8d, 0x00, 0x29, 0x07, 0xd1, 0x20, 0xa9, 0xca, 0x83, 0x80, 0x1e, 0x10, 0xa9, ++ 0x00, 0x06, 0xca, 0x85, 0x00, 0x0e, 0x4d, 0xd0, 0x20, 0xa9, 0x49, 0x8b, 0x00, 0x29, 0x2b, 0xd1, ++ 0x20, 0xa9, 0x09, 0x8b, 0x00, 0x29, 0x27, 0xd1, 0x10, 0xad, 0x2d, 0x8f, 0x00, 0x2d, 0x11, 0xd1, ++ 0x00, 0x2b, 0x0f, 0xd1, 0x10, 0xad, 0xed, 0x8e, 0x00, 0x2d, 0x0b, 0xd1, 0x20, 0xad, 0x6a, 0x83, ++ 0x80, 0x1e, 0x10, 0xad, 0x00, 0x06, 0x2a, 0x87, 0x00, 0x0e, 0x33, 0xd0, 0x00, 0x2a, 0x13, 0xd1, ++ 0x00, 0x29, 0x11, 0xd1, 0x10, 0xa9, 0xc9, 0x8d, 0x00, 0x29, 0x0d, 0xd1, 0x00, 0x2c, 0x0b, 0xd1, ++ 0x10, 0xa9, 0x89, 0x8d, 0x00, 0x29, 0x07, 0xd1, 0x20, 0xa9, 0x4a, 0x83, 0x80, 0x1e, 0x10, 0xa9, ++ 0x00, 0x06, 0xca, 0x85, 0x00, 0x0e, 0x74, 0xd0, 0x10, 0xa9, 0x49, 0x8b, 0x00, 0x29, 0x2b, 0xd1, ++ 0x10, 0xa9, 0x09, 0x8b, 0x00, 0x29, 0x27, 0xd1, 0x10, 0xad, 0x2d, 0x8f, 0x00, 0x2d, 0x10, 0xd1, ++ 0x00, 0x2b, 0x0e, 0xd1, 0x10, 0xad, 0xed, 0x8e, 0x00, 0x2d, 0x0a, 0xd1, 0x10, 0xad, 0x80, 0x1e, ++ 0x6a, 0x83, 0x00, 0x06, 0x2a, 0x87, 0x00, 0x0e, 0x5b, 0xd0, 0x00, 0x2a, 0x14, 0xd1, 0x00, 0x29, ++ 0x12, 0xd1, 0x00, 0xe0, 0x55, 0xe0, 0x10, 0xa9, 0xc9, 0x8d, 0x00, 0x29, 0x0c, 0xd1, 0x00, 0x2c, ++ 0x0a, 0xd1, 0x10, 0xa9, 0x89, 0x8d, 0x00, 0x29, 0x06, 0xd1, 0x10, 0xa9, 0x80, 0x1e, 0x4a, 0x83, ++ 0x00, 0x06, 0xca, 0x85, 0x00, 0x0e, 0x44, 0xd0, 0x10, 0xa9, 0xc9, 0x8a, 0x00, 0x29, 0x29, 0xd1, ++ 0x10, 0xa9, 0x89, 0x8a, 0x00, 0x29, 0x25, 0xd1, 0x10, 0xad, 0x2d, 0x8f, 0x00, 0x2d, 0x10, 0xd1, ++ 0x00, 0x2b, 0x0e, 0xd1, 0x10, 0xad, 0xed, 0x8e, 0x00, 0x2d, 0x0a, 0xd1, 0x10, 0xad, 0x80, 0x1e, ++ 0xea, 0x82, 0x00, 0x06, 0x2a, 0x87, 0x00, 0x0e, 0x2b, 0xd0, 0x00, 0x2a, 0x12, 0xd1, 0x00, 0x29, ++ 0x10, 0xd1, 0x10, 0xa9, 0xc9, 0x8d, 0x00, 0x29, 0x0c, 0xd1, 0x00, 0x2c, 0x0a, 0xd1, 0x10, 0xa9, ++ 0x89, 0x8d, 0x00, 0x29, 0x06, 0xd1, 0x10, 0xa9, 0x80, 0x1e, 0xca, 0x82, 0x00, 0x06, 0xca, 0x85, ++ 0x00, 0x0e, 0x16, 0xd0, 0x10, 0xa8, 0x00, 0x8f, 0x00, 0x28, 0x12, 0xd1, 0x00, 0x2b, 0x10, 0xd1, ++ 0x10, 0xa8, 0xc0, 0x8e, 0x00, 0x28, 0x0c, 0xd1, 0x10, 0xa8, 0xc0, 0x8d, 0x00, 0x28, 0x08, 0xd1, ++ 0x00, 0x2c, 0x06, 0xd1, 0x10, 0xa8, 0x80, 0x8d, 0x00, 0x28, 0x02, 0xd1, 0x10, 0xa8, 0x02, 0x87, ++ 0xc2, 0x85, 0x22, 0x22, 0x1d, 0xa9, 0x0c, 0xa8, 0xf9, 0xf7, 0x1c, 0xfc, 0x6b, 0x46, 0x07, 0xcb, ++ 0x09, 0xab, 0x07, 0xc3, 0x14, 0x22, 0x26, 0xa9, 0x04, 0xa8, 0xf9, 0xf7, 0x13, 0xfc, 0x19, 0xac, ++ 0x0f, 0xcc, 0x6c, 0x46, 0x0f, 0xc4, 0x15, 0xac, 0x0f, 0xcc, 0xff, 0xf7, 0xb9, 0xfb, 0x2f, 0xb0, ++ 0xf0, 0xbd, 0xf8, 0xb5, 0x03, 0x24, 0x24, 0x07, 0xa5, 0x8a, 0xca, 0x4d, 0xa5, 0x82, 0x06, 0x07, ++ 0x36, 0x0f, 0xd5, 0x06, 0xed, 0x0c, 0x2e, 0x43, 0xc7, 0x4d, 0x2f, 0x68, 0xc7, 0x4d, 0x7f, 0x19, ++ 0x3e, 0x81, 0xa6, 0x8a, 0x3f, 0x26, 0xf6, 0x43, 0xa6, 0x82, 0xc3, 0x4f, 0x8e, 0x06, 0x3f, 0x68, ++ 0xb6, 0x0e, 0x7d, 0x19, 0x6e, 0x81, 0xa5, 0x8a, 0xc1, 0x4d, 0xa5, 0x82, 0x00, 0x2b, 0x05, 0xd0, ++ 0x00, 0x24, 0x65, 0x03, 0x00, 0x28, 0x03, 0xdd, 0x01, 0x24, 0x02, 0xe0, 0x01, 0x24, 0xf8, 0xe7, ++ 0x00, 0x24, 0x24, 0x03, 0x25, 0x43, 0x00, 0x2a, 0x01, 0xdd, 0x01, 0x24, 0x00, 0xe0, 0x00, 0x24, ++ 0xe4, 0x02, 0x25, 0x43, 0x00, 0x2b, 0x01, 0xdd, 0x01, 0x24, 0x00, 0xe0, 0x00, 0x24, 0xa4, 0x02, ++ 0x25, 0x43, 0xb1, 0x4c, 0x26, 0x68, 0xb1, 0x4f, 0x80, 0x37, 0xf6, 0x19, 0x75, 0x81, 0x03, 0x25, ++ 0x2d, 0x07, 0xae, 0x8a, 0x0f, 0x26, 0xf6, 0x43, 0xae, 0x82, 0x1d, 0x07, 0x24, 0x68, 0x2d, 0x0f, ++ 0xd1, 0x26, 0x76, 0x02, 0xa4, 0x19, 0x25, 0x84, 0xff, 0xf7, 0x4b, 0xfc, 0xf8, 0xbd, 0xfe, 0xb5, ++ 0x00, 0x20, 0x69, 0x46, 0x08, 0x81, 0xa4, 0x48, 0x01, 0x68, 0xa4, 0x4a, 0x40, 0x3a, 0x89, 0x18, ++ 0x49, 0x8d, 0x00, 0x68, 0xff, 0x30, 0x01, 0x30, 0x00, 0x8e, 0x69, 0x46, 0x08, 0x80, 0x00, 0x20, ++ 0x0d, 0x88, 0x84, 0x46, 0xa8, 0x04, 0x0c, 0x27, 0x30, 0x26, 0x00, 0x28, 0x0a, 0xda, 0x00, 0x20, ++ 0x02, 0x46, 0x3c, 0x21, 0x63, 0x46, 0xff, 0xf7, 0x94, 0xff, 0xb7, 0x43, 0x10, 0x37, 0xb8, 0x08, ++ 0x80, 0x00, 0x10, 0xe0, 0xe8, 0x04, 0x12, 0xd5, 0x96, 0x4b, 0x17, 0x20, 0x18, 0x22, 0x16, 0x21, ++ 0x18, 0x56, 0x9a, 0x56, 0x59, 0x56, 0x63, 0x46, 0xff, 0xf7, 0x83, 0xff, 0x04, 0x20, 0xb0, 0x43, ++ 0x10, 0x30, 0x80, 0x08, 0x80, 0x00, 0x69, 0x46, 0x40, 0x1c, 0x08, 0x81, 0xfe, 0xe0, 0xa8, 0x06, ++ 0xfc, 0xd0, 0x89, 0x4a, 0x10, 0x68, 0x89, 0x4b, 0xc0, 0x18, 0x40, 0x89, 0x81, 0x06, 0x10, 0x68, ++ 0x89, 0x0e, 0xc0, 0x18, 0x00, 0x89, 0x12, 0x68, 0x00, 0x07, 0x00, 0x0f, 0xd2, 0x18, 0x12, 0x89, ++ 0x2b, 0x07, 0xd2, 0x04, 0xd2, 0x0e, 0x00, 0x24, 0x9b, 0x0f, 0x01, 0x2b, 0x02, 0xd0, 0x02, 0x2b, ++ 0x18, 0xd0, 0x31, 0xe0, 0x49, 0x1c, 0x21, 0x29, 0x07, 0xdb, 0x3c, 0x29, 0x03, 0xdc, 0x43, 0x18, ++ 0x9b, 0x18, 0x3c, 0x2b, 0x01, 0xdd, 0x49, 0x1e, 0x17, 0xe0, 0x01, 0x24, 0x4b, 0x1c, 0x21, 0x2b, ++ 0x06, 0xdb, 0x3c, 0x2b, 0x1e, 0xdc, 0x43, 0x18, 0x9b, 0x18, 0x5b, 0x1c, 0x3c, 0x2b, 0x19, 0xdc, ++ 0x04, 0x27, 0x17, 0xe0, 0x08, 0x27, 0x49, 0x1e, 0x3c, 0x29, 0x08, 0xdc, 0x21, 0x29, 0x03, 0xdb, ++ 0x0b, 0x1a, 0x9b, 0x1a, 0x06, 0x2b, 0x02, 0xda, 0x49, 0x1c, 0x49, 0xb2, 0x0a, 0xe0, 0x01, 0x24, ++ 0x4b, 0x1e, 0x3c, 0x2b, 0xec, 0xdc, 0x21, 0x2b, 0x04, 0xdb, 0x0b, 0x1a, 0x9b, 0x1a, 0x5b, 0x1e, ++ 0x06, 0x2b, 0xe5, 0xda, 0x6b, 0x46, 0x1f, 0x81, 0xab, 0x06, 0x9b, 0x0f, 0x01, 0x2b, 0x02, 0xd0, ++ 0x02, 0x2b, 0x1a, 0xd0, 0x47, 0xe0, 0x52, 0x1e, 0x18, 0x2a, 0x07, 0xdc, 0x00, 0x2a, 0x05, 0xda, ++ 0x6f, 0x46, 0x3b, 0x89, 0x33, 0x43, 0x3b, 0x81, 0x52, 0x1c, 0x3c, 0xe0, 0x01, 0x24, 0x53, 0x1e, ++ 0x18, 0x2b, 0x05, 0xdc, 0x00, 0x2b, 0x03, 0xda, 0x6f, 0x46, 0x3b, 0x89, 0x33, 0x43, 0x31, 0xe0, ++ 0x6f, 0x46, 0x3b, 0x89, 0xb3, 0x43, 0x10, 0x33, 0x2c, 0xe0, 0x52, 0x1c, 0x13, 0xd4, 0x18, 0x2a, ++ 0x0a, 0xdc, 0x43, 0x18, 0x9b, 0x18, 0x3c, 0x2b, 0x06, 0xdc, 0x0b, 0x1a, 0x9b, 0x1a, 0x06, 0x2b, ++ 0x02, 0xdb, 0x83, 0x18, 0x18, 0x2b, 0x06, 0xdd, 0x6f, 0x46, 0x3b, 0x89, 0xb3, 0x43, 0x20, 0x33, ++ 0x3b, 0x81, 0x52, 0x1e, 0x17, 0xe0, 0x01, 0x24, 0x53, 0x1c, 0xe1, 0xd4, 0x18, 0x2b, 0x0d, 0xdc, ++ 0x43, 0x18, 0x9b, 0x18, 0x5b, 0x1c, 0x3c, 0x2b, 0x08, 0xdc, 0x0b, 0x1a, 0x9b, 0x1a, 0x5b, 0x1e, ++ 0x06, 0x2b, 0x03, 0xdb, 0x83, 0x18, 0x5b, 0x1c, 0x18, 0x2b, 0xd1, 0xdd, 0x6f, 0x46, 0x3b, 0x89, ++ 0xb3, 0x43, 0x20, 0x33, 0x3b, 0x81, 0xab, 0x07, 0x9b, 0x0f, 0x01, 0x2b, 0x02, 0xd0, 0x02, 0x2b, ++ 0x1d, 0xd0, 0x4c, 0xe0, 0x03, 0x26, 0x40, 0x1e, 0x0a, 0x28, 0x07, 0xdc, 0x00, 0x28, 0x05, 0xda, ++ 0x6f, 0x46, 0x3b, 0x89, 0x33, 0x43, 0x3b, 0x81, 0x40, 0x1c, 0x40, 0xe0, 0x01, 0x24, 0x43, 0x1e, ++ 0x0a, 0x2b, 0x06, 0xdc, 0x00, 0x2b, 0x04, 0xda, 0x6f, 0x46, 0x3b, 0x89, 0x33, 0x43, 0x3b, 0x81, ++ 0x35, 0xe0, 0x6e, 0x46, 0x33, 0x89, 0x9b, 0x08, 0x9b, 0x00, 0x5b, 0x1c, 0x2e, 0xe0, 0x40, 0x1c, ++ 0x14, 0xd4, 0x0a, 0x28, 0x0a, 0xdc, 0x43, 0x18, 0x9b, 0x18, 0x3c, 0x2b, 0x06, 0xdc, 0x0b, 0x1a, ++ 0x9b, 0x1a, 0x06, 0x2b, 0x02, 0xdb, 0x83, 0x18, 0x18, 0x2b, 0x07, 0xdd, 0x6e, 0x46, 0x33, 0x89, ++ 0x9b, 0x08, 0x9b, 0x00, 0x9b, 0x1c, 0x33, 0x81, 0x40, 0x1e, 0x18, 0xe0, 0x01, 0x24, 0x43, 0x1c, ++ 0xdf, 0xd4, 0x0a, 0x2b, 0x0d, 0xdc, 0x43, 0x18, 0x9b, 0x18, 0x5b, 0x1c, 0x3c, 0x2b, 0x08, 0xdc, ++ 0x0b, 0x1a, 0x9b, 0x1a, 0x5b, 0x1e, 0x06, 0x2b, 0x03, 0xdb, 0x83, 0x18, 0x5b, 0x1c, 0x18, 0x2b, ++ 0xcf, 0xdd, 0x6e, 0x46, 0x33, 0x89, 0x9b, 0x08, 0x9b, 0x00, 0x9b, 0x1c, 0x33, 0x81, 0x63, 0x46, ++ 0xff, 0xf7, 0x87, 0xfe, 0x00, 0x2c, 0x09, 0xd0, 0xa9, 0x06, 0x89, 0x0e, 0x01, 0x20, 0x01, 0x91, ++ 0x03, 0x46, 0x04, 0x22, 0x00, 0x90, 0x1f, 0x21, 0x00, 0xf0, 0xe6, 0xfc, 0x0a, 0x4a, 0x10, 0x68, ++ 0x0a, 0x4b, 0xc0, 0x18, 0x80, 0x89, 0xc1, 0x03, 0x68, 0x46, 0x00, 0x89, 0x40, 0x04, 0x40, 0x0c, ++ 0x08, 0x43, 0x99, 0x05, 0x8c, 0x8a, 0x00, 0x24, 0x8c, 0x82, 0x11, 0x68, 0xc9, 0x18, 0x48, 0x80, ++ 0xfe, 0xbd, 0x00, 0x00, 0xf0, 0xe0, 0x00, 0x00, 0x84, 0x00, 0x00, 0x20, 0xc0, 0xa0, 0x01, 0x00, ++ 0xff, 0xc3, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, 0xf0, 0xb5, 0xf9, 0x4a, 0x3e, 0x23, 0x11, 0x88, ++ 0x00, 0x25, 0x99, 0x43, 0xf4, 0x4c, 0xf5, 0x4e, 0x03, 0x00, 0x00, 0xf0, 0x09, 0xfe, 0x09, 0x06, ++ 0x37, 0x68, 0x99, 0xca, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0x00, 0x03, 0x20, 0x00, 0x07, 0x83, 0x8a, ++ 0x3f, 0x23, 0x9b, 0x02, 0x83, 0x82, 0xef, 0x4f, 0x48, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x3b, 0x86, ++ 0x83, 0x8a, 0x83, 0x13, 0x83, 0x82, 0xeb, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0xdd, 0x85, 0x83, 0x8a, ++ 0xe9, 0x4b, 0x83, 0x82, 0xe7, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x9d, 0x85, 0x83, 0x8a, 0x06, 0x23, ++ 0xdb, 0x43, 0x83, 0x82, 0xe3, 0x4f, 0x04, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x7b, 0x86, 0x83, 0x8a, ++ 0x86, 0x82, 0xe0, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x5d, 0x86, 0x83, 0x8a, 0x86, 0x82, 0xdd, 0x4b, ++ 0x01, 0x20, 0x1b, 0x68, 0x1b, 0x19, 0x58, 0x86, 0x2e, 0x31, 0x8c, 0xe1, 0x03, 0x20, 0x00, 0x07, ++ 0x83, 0x8a, 0x3f, 0x23, 0x9b, 0x02, 0x83, 0x82, 0xd6, 0x4f, 0x28, 0x23, 0x3f, 0x68, 0x3f, 0x19, ++ 0x3b, 0x86, 0x83, 0x8a, 0x83, 0x13, 0x83, 0x82, 0xd2, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0xdd, 0x85, ++ 0x83, 0x8a, 0xd1, 0x4b, 0x83, 0x82, 0xcf, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x9d, 0x85, 0x83, 0x8a, ++ 0x06, 0x23, 0xdb, 0x43, 0x83, 0x82, 0xcb, 0x4f, 0x04, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x7b, 0x86, ++ 0x83, 0x8a, 0x86, 0x82, 0xc7, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x5d, 0x86, 0x83, 0x8a, 0x86, 0x82, ++ 0xc4, 0x48, 0x01, 0x23, 0x00, 0x68, 0x00, 0x19, 0x43, 0x86, 0x89, 0x1d, 0x5b, 0xe1, 0x03, 0x20, ++ 0x00, 0x07, 0x83, 0x8a, 0x3f, 0x23, 0x9b, 0x02, 0x83, 0x82, 0xbe, 0x4f, 0x2a, 0x23, 0x3f, 0x68, ++ 0x3f, 0x19, 0x3b, 0x86, 0x83, 0x8a, 0x83, 0x13, 0x83, 0x82, 0xba, 0x4b, 0x1b, 0x68, 0x1b, 0x19, ++ 0xdd, 0x85, 0x83, 0x8a, 0xb8, 0x4b, 0x83, 0x82, 0xb6, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x9d, 0x85, ++ 0x83, 0x8a, 0x06, 0x23, 0xdb, 0x43, 0x83, 0x82, 0xb2, 0x4f, 0x04, 0x23, 0x3f, 0x68, 0x3f, 0x19, ++ 0x7b, 0x86, 0x83, 0x8a, 0x86, 0x82, 0xaf, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x5d, 0x86, 0x83, 0x8a, ++ 0x86, 0x82, 0xac, 0x4b, 0x01, 0x20, 0x1b, 0x68, 0x1b, 0x19, 0x58, 0x86, 0x08, 0x31, 0x2a, 0xe1, ++ 0x03, 0x20, 0x00, 0x07, 0x83, 0x8a, 0x3f, 0x23, 0x9b, 0x02, 0x83, 0x82, 0xa5, 0x4f, 0x34, 0x23, ++ 0x3f, 0x68, 0x3f, 0x19, 0x3b, 0x86, 0x83, 0x8a, 0x83, 0x13, 0x83, 0x82, 0xa1, 0x4b, 0x1b, 0x68, ++ 0x1b, 0x19, 0xdd, 0x85, 0x83, 0x8a, 0xa0, 0x4b, 0x83, 0x82, 0x9e, 0x4b, 0x1b, 0x68, 0x1b, 0x19, ++ 0x9d, 0x85, 0x83, 0x8a, 0x06, 0x23, 0xdb, 0x43, 0x83, 0x82, 0x9a, 0x4f, 0x04, 0x23, 0x3f, 0x68, ++ 0x3f, 0x19, 0x7b, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x96, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x5d, 0x86, ++ 0x83, 0x8a, 0x86, 0x82, 0x93, 0x4b, 0x01, 0x20, 0x1b, 0x68, 0x1b, 0x19, 0x58, 0x86, 0x16, 0x31, ++ 0xf9, 0xe0, 0x03, 0x20, 0x00, 0x07, 0x83, 0x8a, 0x3f, 0x23, 0x9b, 0x02, 0x83, 0x82, 0x8d, 0x4f, ++ 0x3c, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x3b, 0x86, 0x83, 0x8a, 0x83, 0x13, 0x83, 0x82, 0x89, 0x4b, ++ 0x1b, 0x68, 0x1b, 0x19, 0xdd, 0x85, 0x83, 0x8a, 0x87, 0x4b, 0x83, 0x82, 0x85, 0x4b, 0x1b, 0x68, ++ 0x1b, 0x19, 0x9d, 0x85, 0x83, 0x8a, 0x06, 0x23, 0xdb, 0x43, 0x83, 0x82, 0x81, 0x4f, 0x04, 0x23, ++ 0x3f, 0x68, 0x3f, 0x19, 0x7b, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x7e, 0x4b, 0x1b, 0x68, 0x1b, 0x19, ++ 0x5d, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x7b, 0x4b, 0x01, 0x20, 0x1b, 0x68, 0x1b, 0x19, 0x04, 0xe0, ++ 0xca, 0xe0, 0x98, 0xe0, 0x66, 0xe0, 0x34, 0xe0, 0x02, 0xe0, 0x58, 0x86, 0x20, 0x31, 0xc2, 0xe0, ++ 0x03, 0x20, 0x00, 0x07, 0x83, 0x8a, 0x3f, 0x23, 0x9b, 0x02, 0x83, 0x82, 0x71, 0x4f, 0x40, 0x23, ++ 0x3f, 0x68, 0x3f, 0x19, 0x3b, 0x86, 0x83, 0x8a, 0x83, 0x13, 0x83, 0x82, 0x6d, 0x4b, 0x1b, 0x68, ++ 0x1b, 0x19, 0xdd, 0x85, 0x83, 0x8a, 0x6c, 0x4b, 0x83, 0x82, 0x6a, 0x4b, 0x1b, 0x68, 0x1b, 0x19, ++ 0x9d, 0x85, 0x83, 0x8a, 0x06, 0x23, 0xdb, 0x43, 0x83, 0x82, 0x66, 0x4f, 0x04, 0x23, 0x3f, 0x68, ++ 0x3f, 0x19, 0x7b, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x62, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x5d, 0x86, ++ 0x83, 0x8a, 0x86, 0x82, 0x5f, 0x4b, 0x01, 0x20, 0x1b, 0x68, 0x1b, 0x19, 0x58, 0x86, 0x24, 0x31, ++ 0x91, 0xe0, 0x03, 0x20, 0x00, 0x07, 0x83, 0x8a, 0x3f, 0x23, 0x9b, 0x02, 0x83, 0x82, 0x59, 0x4f, ++ 0x42, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x3b, 0x86, 0x83, 0x8a, 0x83, 0x13, 0x83, 0x82, 0x55, 0x4b, ++ 0x1b, 0x68, 0x1b, 0x19, 0xdd, 0x85, 0x83, 0x8a, 0x53, 0x4b, 0x83, 0x82, 0x51, 0x4b, 0x1b, 0x68, ++ 0x1b, 0x19, 0x9d, 0x85, 0x83, 0x8a, 0x06, 0x23, 0xdb, 0x43, 0x83, 0x82, 0x4d, 0x4f, 0x04, 0x23, ++ 0x3f, 0x68, 0x3f, 0x19, 0x7b, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x4a, 0x4b, 0x1b, 0x68, 0x1b, 0x19, ++ 0x5d, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x47, 0x4b, 0x01, 0x20, 0x1b, 0x68, 0x1b, 0x19, 0x58, 0x86, ++ 0x26, 0x31, 0x60, 0xe0, 0x03, 0x20, 0x00, 0x07, 0x83, 0x8a, 0x3f, 0x23, 0x9b, 0x02, 0x83, 0x82, ++ 0x40, 0x4f, 0x46, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x3b, 0x86, 0x83, 0x8a, 0x83, 0x13, 0x83, 0x82, ++ 0x3c, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0xdd, 0x85, 0x83, 0x8a, 0x3b, 0x4b, 0x83, 0x82, 0x39, 0x4b, ++ 0x1b, 0x68, 0x1b, 0x19, 0x9d, 0x85, 0x83, 0x8a, 0x06, 0x23, 0xdb, 0x43, 0x83, 0x82, 0x35, 0x4f, ++ 0x04, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x7b, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x31, 0x4b, 0x1b, 0x68, ++ 0x1b, 0x19, 0x5d, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x2e, 0x4b, 0x01, 0x20, 0x1b, 0x68, 0x1b, 0x19, ++ 0x58, 0x86, 0x2c, 0x31, 0x2f, 0xe0, 0x03, 0x20, 0x00, 0x07, 0x83, 0x8a, 0x3f, 0x23, 0x9b, 0x02, ++ 0x83, 0x82, 0x28, 0x4f, 0x50, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x3b, 0x86, 0x83, 0x8a, 0x83, 0x13, ++ 0x83, 0x82, 0x24, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0xdd, 0x85, 0x83, 0x8a, 0x22, 0x4b, 0x83, 0x82, ++ 0x20, 0x4b, 0x1b, 0x68, 0x1b, 0x19, 0x9d, 0x85, 0x83, 0x8a, 0x06, 0x23, 0xdb, 0x43, 0x83, 0x82, ++ 0x1c, 0x4f, 0x04, 0x23, 0x3f, 0x68, 0x3f, 0x19, 0x7b, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x19, 0x4b, ++ 0x1b, 0x68, 0x1b, 0x19, 0x5d, 0x86, 0x83, 0x8a, 0x86, 0x82, 0x16, 0x4b, 0x01, 0x20, 0x1b, 0x68, ++ 0x1b, 0x19, 0x58, 0x86, 0x38, 0x31, 0x11, 0x80, 0xf0, 0xbd, 0x00, 0xb5, 0x03, 0x00, 0x00, 0xf0, ++ 0x3f, 0xfc, 0x2b, 0x17, 0x29, 0x29, 0x29, 0x29, 0x17, 0x29, 0x17, 0x29, 0x29, 0x29, 0x19, 0x2d, ++ 0x2b, 0x29, 0x29, 0x29, 0x29, 0x25, 0x25, 0x25, 0x25, 0x19, 0x19, 0x17, 0x17, 0x17, 0x17, 0x17, ++ 0x27, 0x17, 0x17, 0x27, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x17, 0x29, 0x29, 0x29, 0x17, 0x00, ++ 0x06, 0x20, 0x14, 0xe0, 0x03, 0x20, 0x12, 0xe0, 0x40, 0xa1, 0x01, 0x00, 0xfe, 0xff, 0x00, 0x00, ++ 0x00, 0x04, 0x00, 0x20, 0x84, 0x00, 0x00, 0x20, 0xff, 0x0f, 0x00, 0x00, 0x02, 0x20, 0x06, 0xe0, ++ 0x07, 0x20, 0x04, 0xe0, 0x08, 0x20, 0x02, 0xe0, 0x05, 0x20, 0x00, 0xe0, 0x04, 0x20, 0xff, 0xf7, ++ 0xfb, 0xfd, 0x00, 0xbd, 0xf0, 0xb5, 0x4d, 0x48, 0x00, 0x21, 0x00, 0x68, 0x4c, 0x4a, 0x80, 0x18, ++ 0x02, 0x8a, 0x8c, 0x27, 0xd3, 0x05, 0xde, 0x0f, 0xd0, 0xb2, 0x93, 0x05, 0x52, 0x05, 0xd5, 0x0f, ++ 0x48, 0x4a, 0xdb, 0x0f, 0x12, 0x68, 0xdb, 0x01, 0x14, 0x88, 0xbc, 0x43, 0x1c, 0x43, 0x14, 0x80, ++ 0x0d, 0x28, 0x26, 0xd0, 0x0a, 0xdc, 0x03, 0x00, 0x00, 0xf0, 0xf2, 0xfb, 0x0d, 0x29, 0x2b, 0x2b, ++ 0x2b, 0x2b, 0x29, 0x27, 0x2c, 0x27, 0x27, 0x27, 0x23, 0x23, 0x2c, 0x00, 0x36, 0x28, 0x1e, 0xd0, ++ 0x0e, 0xdc, 0x11, 0x28, 0x15, 0xd0, 0x06, 0xdc, 0x0e, 0x28, 0x12, 0xd0, 0x0f, 0x28, 0x10, 0xd0, ++ 0x10, 0x28, 0x17, 0xd1, 0x0d, 0xe0, 0x31, 0x28, 0x0b, 0xd0, 0x35, 0x28, 0x12, 0xd1, 0x0e, 0xe0, ++ 0x07, 0x46, 0x37, 0x3f, 0x3b, 0x00, 0x00, 0xf0, 0xd3, 0xfb, 0x05, 0x0a, 0x06, 0x06, 0x06, 0x06, ++ 0x0d, 0x00, 0x01, 0x21, 0x06, 0xe0, 0x03, 0x21, 0x04, 0xe0, 0x04, 0x21, 0x02, 0xe0, 0x08, 0x21, ++ 0x00, 0xe0, 0x09, 0x21, 0x1b, 0x28, 0x23, 0xd0, 0x17, 0x28, 0x21, 0xd0, 0x15, 0x28, 0x1f, 0xd0, ++ 0x13, 0x28, 0x1d, 0xd0, 0x11, 0x28, 0x1b, 0xd0, 0x19, 0x28, 0x19, 0xd0, 0x1a, 0x28, 0x17, 0xd0, ++ 0x16, 0x28, 0x15, 0xd0, 0x14, 0x28, 0x13, 0xd0, 0x12, 0x28, 0x11, 0xd0, 0x1c, 0x28, 0x0f, 0xd0, ++ 0x1e, 0x28, 0x0d, 0xd0, 0x1f, 0x28, 0x0b, 0xd0, 0x21, 0x28, 0x09, 0xd0, 0x22, 0x28, 0x07, 0xd0, ++ 0x24, 0x28, 0x05, 0xd0, 0x28, 0x28, 0x03, 0xd0, 0x29, 0x28, 0x01, 0xd0, 0x2a, 0x28, 0x02, 0xd1, ++ 0x04, 0x20, 0x04, 0x43, 0x14, 0x80, 0x03, 0x20, 0x00, 0x07, 0x82, 0x8a, 0x0f, 0x22, 0xd2, 0x43, ++ 0x82, 0x82, 0x12, 0x4a, 0x14, 0x68, 0x14, 0x4b, 0xe4, 0x18, 0x21, 0x80, 0x81, 0x8a, 0x13, 0x49, ++ 0x81, 0x82, 0x14, 0x68, 0x49, 0x1c, 0xe3, 0x18, 0x19, 0x80, 0x81, 0x8a, 0x10, 0x49, 0x81, 0x82, ++ 0x14, 0x68, 0x73, 0x00, 0x0d, 0x26, 0x76, 0x03, 0xa4, 0x19, 0x23, 0x84, 0x83, 0x8a, 0x81, 0x82, ++ 0x10, 0x68, 0x69, 0x00, 0xff, 0x30, 0x01, 0x30, 0x81, 0x85, 0xf0, 0xbd, 0x03, 0x48, 0x00, 0x68, ++ 0x05, 0x49, 0xc0, 0x31, 0x40, 0x18, 0x40, 0x8e, 0xc0, 0xb2, 0x2e, 0xe7, 0x84, 0x00, 0x00, 0x20, ++ 0xc0, 0xa2, 0x01, 0x00, 0x90, 0x00, 0x00, 0x20, 0x00, 0xa1, 0x01, 0x00, 0xff, 0x7f, 0x00, 0x00, ++ 0xfd, 0xff, 0x00, 0x00, 0x31, 0x48, 0x00, 0x79, 0xc0, 0x07, 0xc0, 0x0f, 0x70, 0x47, 0x2f, 0x48, ++ 0x01, 0x78, 0x8f, 0x22, 0x11, 0x40, 0x01, 0x70, 0x01, 0x79, 0x01, 0x78, 0x01, 0x22, 0x11, 0x43, ++ 0x01, 0x70, 0x70, 0x47, 0x29, 0x48, 0x80, 0x68, 0x70, 0x47, 0x28, 0x48, 0x00, 0x89, 0x80, 0xb2, ++ 0x70, 0x47, 0x70, 0x47, 0x03, 0x20, 0x00, 0x07, 0x00, 0x8a, 0x80, 0x05, 0x80, 0x0d, 0x70, 0x47, ++ 0x23, 0x49, 0x09, 0x68, 0x80, 0x31, 0x89, 0x7c, 0x09, 0x07, 0x09, 0x0e, 0x8a, 0x00, 0x1f, 0x49, ++ 0x40, 0x31, 0x51, 0x18, 0x88, 0x60, 0x08, 0x78, 0x8f, 0x22, 0x10, 0x40, 0x10, 0x30, 0x08, 0x70, ++ 0x08, 0x78, 0x01, 0x22, 0x10, 0x43, 0x08, 0x70, 0x70, 0x47, 0x19, 0x48, 0x00, 0x68, 0x80, 0x30, ++ 0x80, 0x7c, 0x00, 0x07, 0x00, 0x0e, 0x81, 0x00, 0x14, 0x48, 0x40, 0x30, 0x08, 0x18, 0x01, 0x78, ++ 0x02, 0x22, 0x11, 0x43, 0x01, 0x70, 0x70, 0x47, 0x11, 0x48, 0x10, 0x49, 0x00, 0x68, 0x40, 0x31, ++ 0x80, 0x30, 0x80, 0x7c, 0x00, 0x07, 0x00, 0x0e, 0x80, 0x00, 0x40, 0x18, 0xc0, 0x68, 0x70, 0x47, ++ 0x0b, 0x48, 0x0a, 0x49, 0x00, 0x68, 0x40, 0x31, 0x80, 0x30, 0x80, 0x7c, 0x00, 0x07, 0x00, 0x0e, ++ 0x80, 0x00, 0x40, 0x18, 0x00, 0x79, 0xc0, 0x07, 0xc0, 0x0f, 0x70, 0x47, 0x03, 0x21, 0x09, 0x07, ++ 0x08, 0x60, 0x08, 0x7b, 0x01, 0x22, 0x10, 0x43, 0x08, 0x73, 0x70, 0x47, 0xc0, 0x00, 0x00, 0x30, ++ 0x90, 0x00, 0x00, 0x20, 0x10, 0xb5, 0x72, 0xb6, 0x56, 0x49, 0xc8, 0x69, 0xff, 0x22, 0x12, 0x04, ++ 0x90, 0x43, 0x01, 0x22, 0x92, 0x05, 0x10, 0x43, 0xc8, 0x61, 0x54, 0x48, 0x52, 0x49, 0x41, 0x60, ++ 0x81, 0x60, 0x00, 0x20, 0x52, 0x4a, 0x01, 0x21, 0xc4, 0x06, 0xe4, 0x0e, 0x0b, 0x46, 0xa3, 0x40, ++ 0x44, 0x09, 0xa4, 0x00, 0xa4, 0x18, 0x23, 0x60, 0x40, 0x1c, 0x40, 0xb2, 0x0c, 0x28, 0xf3, 0xdb, ++ 0x4c, 0x4a, 0x04, 0x20, 0xc4, 0x06, 0xe4, 0x0e, 0x0b, 0x46, 0xa3, 0x40, 0x44, 0x09, 0xa4, 0x00, ++ 0xa4, 0x18, 0x23, 0x60, 0x40, 0x1c, 0x40, 0xb2, 0x0c, 0x28, 0xf3, 0xdb, 0x62, 0xb6, 0x10, 0xbd, ++ 0xfe, 0xb5, 0x45, 0x4c, 0x21, 0x68, 0x00, 0x91, 0x44, 0x4d, 0x45, 0x4f, 0x2e, 0x68, 0x39, 0x68, ++ 0x01, 0x91, 0x01, 0x02, 0x43, 0x4a, 0x80, 0x07, 0x89, 0x18, 0x29, 0x60, 0x21, 0x68, 0xfa, 0x12, ++ 0x91, 0x43, 0x40, 0x0b, 0x01, 0x43, 0x21, 0x60, 0xff, 0xf7, 0x51, 0xfb, 0x00, 0x98, 0x20, 0x60, ++ 0x2e, 0x60, 0x01, 0x98, 0x38, 0x60, 0xfe, 0xbd, 0xfe, 0xb5, 0x37, 0x4c, 0x21, 0x68, 0x00, 0x91, ++ 0x36, 0x4d, 0x37, 0x4f, 0x2e, 0x68, 0x39, 0x68, 0x01, 0x91, 0x01, 0x02, 0x35, 0x4a, 0x80, 0x07, ++ 0x89, 0x18, 0x29, 0x60, 0x21, 0x68, 0xfa, 0x12, 0x91, 0x43, 0x40, 0x0b, 0x01, 0x43, 0x21, 0x60, ++ 0xfe, 0xf7, 0x3c, 0xfe, 0x00, 0x98, 0x20, 0x60, 0x2e, 0x60, 0x01, 0x98, 0x38, 0x60, 0xfe, 0xbd, ++ 0x10, 0xb5, 0x00, 0x22, 0x11, 0x46, 0x01, 0x98, 0x00, 0xf0, 0xc0, 0xf8, 0x10, 0xbd, 0x10, 0xb5, ++ 0x00, 0x22, 0x11, 0x46, 0x01, 0x98, 0x00, 0xf0, 0xb9, 0xf8, 0x10, 0xbd, 0x10, 0xb5, 0x00, 0x22, ++ 0x11, 0x46, 0x01, 0x98, 0x00, 0xf0, 0xb2, 0xf8, 0x10, 0xbd, 0x10, 0xb5, 0x00, 0x22, 0x11, 0x46, ++ 0x01, 0x98, 0x00, 0xf0, 0xab, 0xf8, 0x10, 0xbd, 0x10, 0xb5, 0x00, 0x22, 0x11, 0x46, 0x01, 0x98, ++ 0x00, 0xf0, 0xa4, 0xf8, 0x10, 0xbd, 0x10, 0xb5, 0x00, 0x22, 0x11, 0x46, 0x01, 0x98, 0x00, 0xf0, ++ 0x9d, 0xf8, 0x10, 0xbd, 0x18, 0x48, 0x40, 0x7e, 0x9a, 0xe7, 0x17, 0x48, 0x80, 0x7e, 0x97, 0xe7, ++ 0x15, 0x48, 0xc0, 0x7e, 0x94, 0xe7, 0x14, 0x48, 0x00, 0x7f, 0x91, 0xe7, 0x12, 0x48, 0x40, 0x7e, ++ 0xaa, 0xe7, 0x11, 0x48, 0x80, 0x7e, 0xa7, 0xe7, 0x0f, 0x48, 0xc0, 0x7e, 0xa4, 0xe7, 0x0e, 0x48, ++ 0x00, 0x7f, 0xa1, 0xe7, 0x10, 0xb5, 0x00, 0x22, 0x11, 0x46, 0x01, 0x98, 0x00, 0xf0, 0x7e, 0xf8, ++ 0x10, 0xbd, 0x00, 0x00, 0x04, 0xed, 0x00, 0xe0, 0x80, 0x80, 0x80, 0x80, 0x00, 0xe4, 0x00, 0xe0, ++ 0x80, 0xe2, 0x00, 0xe0, 0x00, 0xe1, 0x00, 0xe0, 0x84, 0x00, 0x00, 0x20, 0x90, 0x00, 0x00, 0x20, ++ 0x14, 0x00, 0x00, 0x30, 0x00, 0x05, 0x00, 0x20, 0x00, 0x04, 0x00, 0x20, 0x10, 0xb5, 0xff, 0x21, ++ 0x01, 0x31, 0x2b, 0x48, 0x00, 0xf0, 0xf6, 0xf9, 0x10, 0xbd, 0xc1, 0x08, 0x10, 0xb5, 0x09, 0x1d, ++ 0x1f, 0x28, 0x13, 0xd8, 0x72, 0xb6, 0x27, 0x4a, 0x25, 0x4b, 0x12, 0x68, 0x80, 0x32, 0x92, 0x7c, ++ 0x92, 0x01, 0x9c, 0x5c, 0x01, 0x2c, 0x00, 0xd1, 0x09, 0x1d, 0xd2, 0x18, 0x44, 0x07, 0x53, 0x5c, ++ 0x64, 0x0f, 0x01, 0x20, 0xa0, 0x40, 0x03, 0x43, 0x53, 0x54, 0x62, 0xb6, 0x10, 0xbd, 0xf0, 0xb5, ++ 0x1c, 0x49, 0x1b, 0x4e, 0x0b, 0x68, 0x80, 0x33, 0x99, 0x7c, 0x89, 0x01, 0x8d, 0x19, 0xa9, 0x78, ++ 0xff, 0x29, 0x2c, 0xd0, 0x6a, 0x78, 0xfe, 0x29, 0x04, 0xd0, 0x8f, 0x1a, 0x91, 0x42, 0x03, 0xd8, ++ 0x0d, 0x24, 0x02, 0xe0, 0x02, 0x24, 0x02, 0xe0, 0x00, 0x24, 0x3c, 0x19, 0x64, 0x1e, 0x24, 0x06, ++ 0x24, 0x0e, 0x1c, 0xd0, 0x01, 0x2c, 0x00, 0xd1, 0xa0, 0x1e, 0x94, 0x00, 0x2c, 0x19, 0x52, 0x1c, ++ 0xe0, 0x60, 0xd0, 0xb2, 0x0d, 0x28, 0x00, 0xd3, 0x00, 0x20, 0x9a, 0x7c, 0x92, 0x01, 0x92, 0x19, ++ 0x50, 0x70, 0xfe, 0x29, 0x0b, 0xd1, 0x99, 0x7c, 0x89, 0x01, 0x8a, 0x19, 0xd1, 0x78, 0x81, 0x42, ++ 0x05, 0xd1, 0x49, 0x1c, 0xc8, 0xb2, 0x0d, 0x28, 0x00, 0xd3, 0x00, 0x20, 0xd0, 0x70, 0xf0, 0xbd, ++ 0x00, 0x09, 0x00, 0x20, 0x90, 0x00, 0x00, 0x20, 0x10, 0xb5, 0x20, 0x21, 0x37, 0x48, 0x00, 0xf0, ++ 0x99, 0xf9, 0x20, 0x21, 0x36, 0x48, 0x00, 0xf0, 0x95, 0xf9, 0x10, 0xbd, 0x72, 0xb6, 0xbf, 0xf3, ++ 0x40, 0x8f, 0x34, 0x4b, 0x20, 0x25, 0x1c, 0x7c, 0x2c, 0x43, 0x1c, 0x74, 0xef, 0xf3, 0x05, 0x83, ++ 0x2e, 0x4c, 0x9b, 0x06, 0x9b, 0x0e, 0x25, 0x78, 0x23, 0x70, 0x00, 0x2d, 0x09, 0xd1, 0xa3, 0x70, ++ 0xa0, 0x60, 0xef, 0xf3, 0x08, 0x80, 0xe0, 0x60, 0xef, 0xf3, 0x09, 0x80, 0xe2, 0x61, 0xa1, 0x61, ++ 0x20, 0x61, 0x01, 0x20, 0x10, 0x2b, 0x06, 0xd3, 0x02, 0x46, 0x10, 0x3b, 0x61, 0x69, 0x9a, 0x40, ++ 0x11, 0x43, 0x61, 0x61, 0x04, 0xe0, 0x02, 0x46, 0x61, 0x68, 0x9a, 0x40, 0x11, 0x43, 0x61, 0x60, ++ 0x00, 0x21, 0x61, 0x70, 0xbf, 0xf3, 0x40, 0x8f, 0x62, 0xb6, 0xe1, 0x78, 0x01, 0x43, 0xe1, 0x70, ++ 0xfe, 0xe7, 0xf0, 0xb5, 0x05, 0x9d, 0x72, 0xb6, 0xbf, 0xf3, 0x40, 0x8f, 0x19, 0x4c, 0x40, 0x27, ++ 0x26, 0x7c, 0x3e, 0x43, 0x26, 0x74, 0x16, 0x4c, 0x26, 0x78, 0x20, 0x70, 0x00, 0x2e, 0x09, 0xd1, ++ 0xa0, 0x70, 0xa1, 0x60, 0xef, 0xf3, 0x08, 0x81, 0xe1, 0x60, 0xef, 0xf3, 0x09, 0x81, 0xe5, 0x61, ++ 0xa3, 0x61, 0x21, 0x61, 0x01, 0x21, 0x20, 0x28, 0x06, 0xd3, 0x0d, 0x46, 0x20, 0x38, 0x63, 0x69, ++ 0x85, 0x40, 0x2b, 0x43, 0x63, 0x61, 0x04, 0xe0, 0x0b, 0x46, 0x65, 0x68, 0x83, 0x40, 0x1d, 0x43, ++ 0x65, 0x60, 0x00, 0x20, 0x60, 0x70, 0xbf, 0xf3, 0x40, 0x8f, 0x62, 0xb6, 0x00, 0x2a, 0x03, 0xd0, ++ 0xe0, 0x78, 0x08, 0x43, 0xe0, 0x70, 0xfe, 0xe7, 0xf0, 0xbd, 0x00, 0x00, 0x24, 0x04, 0x00, 0x20, ++ 0x44, 0x04, 0x00, 0x20, 0x00, 0x04, 0x00, 0x20, 0xf0, 0xb5, 0x4c, 0x4d, 0x0a, 0x21, 0x69, 0x5e, ++ 0x00, 0x22, 0x4b, 0x4e, 0x4b, 0x4b, 0x4c, 0x4f, 0x0a, 0xe0, 0xb4, 0x5c, 0x5c, 0x54, 0x40, 0x1e, ++ 0x52, 0x1c, 0x49, 0x1e, 0x09, 0xb2, 0xc0, 0xb2, 0xd2, 0xb2, 0x00, 0x29, 0x00, 0xda, 0x39, 0x46, ++ 0x00, 0x28, 0xf2, 0xd1, 0x69, 0x81, 0xf0, 0xbd, 0xff, 0xb5, 0x81, 0xb0, 0x05, 0x46, 0x04, 0x98, ++ 0x0b, 0x9e, 0x00, 0x28, 0x00, 0xd1, 0x72, 0xb6, 0x3c, 0x49, 0x48, 0x7b, 0xff, 0x28, 0x02, 0xd1, ++ 0x4b, 0x89, 0x08, 0x2b, 0x01, 0xd3, 0x01, 0x24, 0x00, 0xe0, 0x00, 0x24, 0x02, 0x9b, 0x5b, 0x1e, ++ 0x2f, 0x2b, 0x52, 0xd2, 0x00, 0x2c, 0x50, 0xd0, 0x34, 0x49, 0x49, 0x7d, 0x00, 0x29, 0x4c, 0xd1, ++ 0x01, 0x2d, 0x02, 0xd0, 0x00, 0x2d, 0x03, 0xd0, 0x04, 0xe0, 0x34, 0x48, 0x00, 0x68, 0x40, 0x79, ++ 0x90, 0x42, 0x42, 0xd3, 0xff, 0xf7, 0xce, 0xfd, 0x07, 0x46, 0x01, 0x0c, 0x30, 0x48, 0x00, 0x68, ++ 0x00, 0x0c, 0x08, 0x1a, 0x00, 0x04, 0x00, 0x0c, 0x12, 0xd0, 0x29, 0x49, 0xff, 0x22, 0x8a, 0x70, ++ 0x02, 0x0a, 0x4a, 0x70, 0x08, 0x70, 0x03, 0x20, 0xff, 0xf7, 0xae, 0xff, 0x23, 0x48, 0x41, 0x7b, ++ 0xff, 0x29, 0x04, 0xd1, 0x40, 0x89, 0x08, 0x28, 0x01, 0xd2, 0x00, 0x24, 0x00, 0xe0, 0x01, 0x24, ++ 0x23, 0x48, 0x00, 0x2c, 0x07, 0x60, 0x20, 0xd0, 0x01, 0x2d, 0x24, 0xd0, 0x00, 0x2d, 0x27, 0xd0, ++ 0x08, 0x24, 0x0a, 0x98, 0x00, 0x28, 0x08, 0xd0, 0x19, 0x48, 0x31, 0x0a, 0x06, 0x70, 0x41, 0x70, ++ 0x31, 0x0c, 0x81, 0x70, 0x0a, 0x98, 0xff, 0xf7, 0x8f, 0xff, 0x0a, 0x98, 0x14, 0x49, 0x00, 0x1d, ++ 0x40, 0x01, 0x20, 0x43, 0xc8, 0x70, 0x16, 0x48, 0x00, 0x88, 0x02, 0x0a, 0x8a, 0x70, 0x48, 0x70, ++ 0x02, 0x98, 0x08, 0x70, 0x04, 0x20, 0xff, 0xf7, 0x7f, 0xff, 0x04, 0x98, 0x00, 0x28, 0x00, 0xd1, ++ 0x62, 0xb6, 0x05, 0xb0, 0xf0, 0xbd, 0x0d, 0x48, 0x00, 0x68, 0x80, 0x30, 0x84, 0x7c, 0xd8, 0xe7, ++ 0x0f, 0x24, 0xd6, 0xe7, 0x1c, 0xb5, 0x0a, 0x46, 0x00, 0x21, 0x00, 0x91, 0x0b, 0x46, 0x01, 0x91, ++ 0x01, 0x46, 0x01, 0x20, 0xff, 0xf7, 0x80, 0xff, 0x1c, 0xbd, 0x00, 0x00, 0x00, 0x04, 0x00, 0x20, ++ 0x8c, 0x00, 0x00, 0x20, 0x00, 0x01, 0x00, 0x20, 0xff, 0x02, 0x00, 0x00, 0x90, 0x00, 0x00, 0x20, ++ 0x88, 0x00, 0x00, 0x20, 0x30, 0xb5, 0x0e, 0x49, 0x00, 0x20, 0x09, 0x78, 0x0b, 0x4d, 0x4c, 0x1e, ++ 0x11, 0xe0, 0x02, 0x02, 0x52, 0x19, 0x80, 0x32, 0x90, 0x74, 0x00, 0x28, 0x05, 0xd0, 0x43, 0x1e, ++ 0x13, 0x75, 0xa0, 0x42, 0x03, 0xd1, 0x00, 0x23, 0x02, 0xe0, 0x23, 0x46, 0xf8, 0xe7, 0x43, 0x1c, ++ 0x40, 0x1c, 0xd3, 0x74, 0xc0, 0xb2, 0x88, 0x42, 0xeb, 0xd3, 0x30, 0xbd, 0x00, 0x05, 0x00, 0x20, ++ 0x80, 0x00, 0x00, 0x20, 0x70, 0x47, 0xf8, 0xb5, 0x04, 0x2a, 0x2c, 0xd3, 0x83, 0x07, 0x12, 0xd0, ++ 0x0b, 0x78, 0x49, 0x1c, 0x03, 0x70, 0x40, 0x1c, 0x52, 0x1e, 0x83, 0x07, 0x0b, 0xd0, 0x0b, 0x78, ++ 0x49, 0x1c, 0x03, 0x70, 0x40, 0x1c, 0x52, 0x1e, 0x83, 0x07, 0x04, 0xd0, 0x0b, 0x78, 0x49, 0x1c, ++ 0x03, 0x70, 0x40, 0x1c, 0x52, 0x1e, 0x8b, 0x07, 0x9b, 0x0f, 0x05, 0xd0, 0xc9, 0x1a, 0xdf, 0x00, ++ 0x20, 0x23, 0xde, 0x1b, 0x08, 0xc9, 0x0a, 0xe0, 0xf8, 0xf7, 0xcc, 0xfc, 0xf8, 0xbd, 0x1d, 0x46, ++ 0x08, 0xc9, 0xfd, 0x40, 0x1c, 0x46, 0xb4, 0x40, 0x2c, 0x43, 0x10, 0xc0, 0x12, 0x1f, 0x04, 0x2a, ++ 0xf5, 0xd2, 0xf3, 0x08, 0xc9, 0x1a, 0x52, 0x1e, 0xf0, 0xd4, 0x0b, 0x78, 0x49, 0x1c, 0x03, 0x70, ++ 0x40, 0x1c, 0x52, 0x1e, 0xea, 0xd4, 0x0b, 0x78, 0x49, 0x1c, 0x03, 0x70, 0x40, 0x1c, 0x01, 0x2a, ++ 0xe4, 0xd4, 0x09, 0x78, 0x01, 0x70, 0xf8, 0xbd, 0x01, 0xe0, 0x04, 0xc0, 0x09, 0x1f, 0x04, 0x29, ++ 0xfb, 0xd2, 0x8b, 0x07, 0x01, 0xd5, 0x02, 0x80, 0x80, 0x1c, 0xc9, 0x07, 0x00, 0xd0, 0x02, 0x70, ++ 0x70, 0x47, 0x00, 0x29, 0x0b, 0xd0, 0xc3, 0x07, 0x02, 0xd0, 0x02, 0x70, 0x40, 0x1c, 0x49, 0x1e, ++ 0x02, 0x29, 0x04, 0xd3, 0x83, 0x07, 0x02, 0xd5, 0x02, 0x80, 0x80, 0x1c, 0x89, 0x1e, 0xe3, 0xe7, ++ 0x00, 0x22, 0xee, 0xe7, 0x00, 0x22, 0xdf, 0xe7, 0x03, 0x78, 0xc2, 0x78, 0x19, 0x46, 0x43, 0x78, ++ 0x12, 0x06, 0x1b, 0x02, 0x19, 0x43, 0x83, 0x78, 0xc0, 0x78, 0x1b, 0x04, 0x19, 0x43, 0x11, 0x43, ++ 0x09, 0x02, 0x09, 0x0a, 0x00, 0x06, 0x08, 0x43, 0x70, 0x47, 0x70, 0x47, 0x75, 0x46, 0x00, 0xf0, ++ 0x23, 0xf8, 0xae, 0x46, 0x05, 0x00, 0x69, 0x46, 0x53, 0x46, 0xc0, 0x08, 0xc0, 0x00, 0x85, 0x46, ++ 0x18, 0xb0, 0x20, 0xb5, 0xf8, 0xf7, 0x9e, 0xfc, 0x60, 0xbc, 0x00, 0x27, 0x49, 0x08, 0xb6, 0x46, ++ 0x00, 0x26, 0xc0, 0xc5, 0xc0, 0xc5, 0xc0, 0xc5, 0xc0, 0xc5, 0xc0, 0xc5, 0xc0, 0xc5, 0xc0, 0xc5, ++ 0xc0, 0xc5, 0x40, 0x3d, 0x49, 0x00, 0x8d, 0x46, 0x70, 0x47, 0x04, 0x46, 0xc0, 0x46, 0xc0, 0x46, ++ 0x20, 0x46, 0xf8, 0xf7, 0x50, 0xfc, 0x00, 0x00, 0x00, 0x48, 0x70, 0x47, 0x94, 0x00, 0x00, 0x20, ++ 0x30, 0xb4, 0x74, 0x46, 0x64, 0x1e, 0x25, 0x78, 0x64, 0x1c, 0xab, 0x42, 0x00, 0xd2, 0x1d, 0x46, ++ 0x63, 0x5d, 0x5b, 0x00, 0xe3, 0x18, 0x30, 0xbc, 0x18, 0x47, 0x19, 0x19, 0x19, 0x19, 0x19, 0x19, ++ 0x19, 0x19, 0x19, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x19, 0x19, 0x19, 0x19, 0x1a, 0x22, ++ 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x30, ++ 0x31, 0x31, 0x32, 0x32, 0x21, 0x10, 0x42, 0x20, 0x84, 0x40, 0x08, 0x81, 0x31, 0x12, 0x62, 0x24, ++ 0xc4, 0x48, 0x88, 0x91, 0x00, 0x00, 0x0a, 0x00, 0x15, 0x00, 0x1f, 0x00, 0x29, 0x00, 0x34, 0x00, ++ 0x3e, 0x00, 0x49, 0x00, 0x53, 0x00, 0x5d, 0x00, 0x68, 0x00, 0x72, 0x00, 0x7c, 0x00, 0x87, 0x00, ++ 0x91, 0x00, 0x9b, 0x00, 0xa6, 0x00, 0xb0, 0x00, 0xba, 0x00, 0xc5, 0x00, 0xcf, 0x00, 0xda, 0x00, ++ 0xe4, 0x00, 0xee, 0x00, 0xf9, 0x00, 0x03, 0x01, 0x0d, 0x01, 0x18, 0x01, 0x22, 0x01, 0x2c, 0x01, ++ 0x37, 0x01, 0x41, 0x01, 0x00, 0x00, 0x11, 0x00, 0x23, 0x00, 0x34, 0x00, 0x46, 0x00, 0x57, 0x00, ++ 0x69, 0x00, 0x7a, 0x00, 0x8c, 0x00, 0x9d, 0x00, 0xaf, 0x00, 0xc0, 0x00, 0xd2, 0x00, 0xe3, 0x00, ++ 0xf5, 0x00, 0x06, 0x01, 0x18, 0x01, 0x29, 0x01, 0x3b, 0x01, 0x4c, 0x01, 0x5d, 0x01, 0x6f, 0x01, ++ 0x80, 0x01, 0x92, 0x01, 0xa3, 0x01, 0xb5, 0x01, 0xc6, 0x01, 0xd8, 0x01, 0xe9, 0x01, 0xfb, 0x01, ++ 0x0c, 0x02, 0x1e, 0x02, 0x74, 0x7a, 0x00, 0x00, 0x80, 0x00, 0x00, 0x20, 0x14, 0x00, 0x00, 0x00, ++ 0xc4, 0x01, 0x00, 0x00, 0x88, 0x7a, 0x00, 0x00, 0x94, 0x00, 0x00, 0x20, 0x6c, 0x09, 0x00, 0x00, ++ 0xe0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ++ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/pm.h b/drivers/net/ethernet/broadcom/pm.h +--- a/drivers/net/ethernet/broadcom/pm.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/pm.h 2018-05-30 15:50:51.032753168 +0800 +@@ -0,0 +1,96 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++#ifndef _PM_H ++#define _PM_H ++ ++ ++#define pmLoopbackMac 0 ++#define pmLoopbackPhy 1 ++ ++struct iproc_pm_stats { ++ u64 rx_frames;//XLMIB_GRxPkt ++ u64 rx_frame_good;//XLMIB_GRxPOK ++ u64 rx_bytes;//XLMIB_GRxByt ++ u64 rx_frame_64;//XLMIB_GRx64 ++ u64 rx_frame_127;//XLMIB_GRx127 ++ u64 rx_frame_255;//XLMIB_GRx255 ++ u64 rx_frame_511;//XLMIB_GRx511 ++ u64 rx_frame_1023;//XLMIB_GRx1023 ++ u64 rx_frame_1518;//XLMIB_GRx1518 ++ u64 rx_frame_1522;//XLMIB_GRx1522 ++ u64 rx_frame_jumbo;//XLMIB_GRx2047 + XLMIB_GRx4095 + XLMIB_GRx9216+ XLMIB_GRx16383 ++ u64 rx_frame_unicast;//XLMIB_GRxUCA ++ u64 rx_frame_multicast;//XLMIB_GRxMCA ++ u64 rx_frame_broadcast;//XLMIB_GRxBCA ++ u64 rx_frame_control;//XLMIB_GRxCF ++ u64 rx_frame_pause;//XLMIB_GRxPF ++ u64 rx_frame_jabber;//XLMIB_GRxJBR ++ u64 rx_frame_fragment;//XLMIB_GRxFRG ++ u64 rx_frame_vlan;//XLMIB_GRxVLN ++ u64 rx_frame_dvlan;//XLMIB_GRxDVLN ++ u64 rx_frame_fcs_error;//XLMIB_GRxFCS ++ u64 rx_frame_unsupport;//XLMIB_GRxUO ++ u64 rx_frame_wrong_sa;//XLMIB_GRxWSA ++ u64 rx_frame_align_err;//XLMIB_GRxALN ++ u64 rx_frame_length_err;//XLMIB_GRxFLR ++ u64 rx_frame_oversize;//XLMIB_GRxOVR ++ u64 rx_frame_mtu_err;//XLMIB_GRxMTUE ++ u64 rx_frame_truncated_err;//XLMIB_GRxTRFU ++ u64 rx_frame_undersize;//XLMIB_GRxUND ++ u64 tx_frames;//XLMIB_GTxPkt ++ u64 tx_frame_good;//XLMIB_GTxPOK ++ u64 tx_bytes;//XLMIB_GTxBYT ++ u64 tx_frame_64;//XLMIB_GTx64 ++ u64 tx_frame_127;//XLMIB_GTx127 ++ u64 tx_frame_255;//XLMIB_GTx255 ++ u64 tx_frame_511;//XLMIB_GTx511 ++ u64 tx_frame_1023;//XLMIB_GTx1023 ++ u64 tx_frame_1518;//XLMIB_GTx1518 ++ u64 tx_frame_1522;//XLMIB_GTx1522 ++ u64 tx_frame_jumbo;//XLMIB_GTx2047 + XLMIB_GTx4095 + XLMIB_GTx9216 + XLMIB_GTx16383 ++ u64 tx_frame_unicast;//XLMIB_GTxUCA ++ u64 tx_frame_multicast;//XLMIB_GTxMCA ++ u64 tx_frame_broadcast;//XLMIB_GTxBCA ++ u64 tx_frame_control;//XLMIB_GTxCF ++ u64 tx_frame_pause;//XLMIB_GTxPF ++ u64 tx_frame_jabber;//XLMIB_GTxJBR ++ u64 tx_frame_fragment;//XLMIB_GTxFRG ++ u64 tx_frame_vlan;//XLMIB_GTxVLN ++ u64 tx_frame_dvlan;//XLMIB_GTxDVLN ++ u64 tx_frame_fcs_error;//XLMIB_GTxFCS ++ u64 tx_frame_oversize;//XLMIB_GTxOVR ++ u64 tx_frame_error;//XLMIB_GTxErr ++ u64 tx_frame_fifo_underrun;//XLMIB_GTxUFL ++ u64 tx_frame_collision;//XLMIB_GTxNCL ++}; ++ ++struct iproc_pm_ops { ++ int (*port_enable)(int port, int enable); ++ int (*port_speed)(int port, int speed); ++ int (*port_loopback)(int port, int lb_type, int lb_en); ++ int (*port_mac_addr)(int port, u8 *mac); ++ int (*port_stats)(int port, struct iproc_pm_stats *stats); ++ int (*port_stats_clear)(int port); ++}; ++ ++extern int pm4x10_pm_init(struct iproc_pm_ops *pm_ops, u8 lane_idx); ++extern int pm4x10_pm_deinit(struct iproc_pm_ops *pm_ops); ++ ++extern int pm4x10_pm_xlport_port_config(int port, int enable); ++extern int pm4x10_xlport_speed_set(int port, int speed); ++extern int pm4x10_xlport_loopback_set(int port, int lb_type, int lb_en); ++extern int pm4x10_xlport_mac_addr_set(int port, u8 *mac); ++extern int pm4x10_xlport_stats_get(int port, struct iproc_pm_stats *stats); ++extern int pm4x10_xlport_mib_reset(int port); ++ ++#endif /* _PM_H */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/ethernet/broadcom/pm4x10.c b/drivers/net/ethernet/broadcom/pm4x10.c +--- a/drivers/net/ethernet/broadcom/pm4x10.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/ethernet/broadcom/pm4x10.c 2018-05-31 16:19:28.761893937 +0800 +@@ -0,0 +1,1175 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include "pm.h" ++#include "merlin16_ucode.h" ++ ++#define JUMBO_MAXSZ 0x3fe8 ++ ++#define debug(fmt, args...) do {} while (0) ++ ++ ++#define PM_CORE_ADDR(port) ((1 << (port + 1)) + 1) ++ ++#define PM_PMD_X1_CTL_REG(port) (0x00009010 | (PM_CORE_ADDR(port) << 19)) ++#define PM_PMD_X4_CTL_REG(port) (0x0000c010 | (PM_CORE_ADDR(port) << 19)) ++#define PM_CKRST_LN_CLK_RST_N_PWRDWN_CTL_REG(port) (0x0001d0b1 | (PM_CORE_ADDR(port) << 19)) ++#define PM_DIG_TOP_USER_CTL0_REG(port) (0x0001d104 | (PM_CORE_ADDR(port) << 19)) ++#define PM_TXFIR_MISC_CTL1_REG(port) (0x0001d139 | (PM_CORE_ADDR(port) << 19)) ++ ++#define TSC_OPERATION_WRITE 0x1 ++#define TSC_OPERATION_READ 0x0 ++ ++ ++/* S-channel address */ ++/* Per port registers */ ++#define XLMIB_GRx64(port) (0x00000000 + port) ++#define XLMIB_GRx127(port) (0x00000100 + port) ++#define XLMIB_GRx255(port) (0x00000200 + port) ++#define XLMIB_GRx511(port) (0x00000300 + port) ++#define XLMIB_GRx1023(port) (0x00000400 + port) ++#define XLMIB_GRx1518(port) (0x00000500 + port) ++#define XLMIB_GRx1522(port) (0x00000600 + port) ++#define XLMIB_GRx2047(port) (0x00000700 + port) ++#define XLMIB_GRx4095(port) (0x00000800 + port) ++#define XLMIB_GRx9216(port) (0x00000900 + port) ++#define XLMIB_GRx16383(port) (0x00000a00 + port) ++#define XLMIB_GRxPkt(port) (0x00000b00 + port) ++#define XLMIB_GRxUCA(port) (0x00000c00 + port) ++#define XLMIB_GRxMCA(port) (0x00000d00 + port) ++#define XLMIB_GRxBCA(port) (0x00000e00 + port) ++#define XLMIB_GRxFCS(port) (0x00000f00 + port) ++#define XLMIB_GRxCF(port) (0x00001000 + port) ++#define XLMIB_GRxPF(port) (0x00001100 + port) ++#define XLMIB_GRxUO(port) (0x00001300 + port) ++#define XLMIB_GRxWSA(port) (0x00001500 + port) ++#define XLMIB_GRxALN(port) (0x00001600 + port) ++#define XLMIB_GRxFLR(port) (0x00001700 + port) ++#define XLMIB_GRxOVR(port) (0x00001a00 + port) ++#define XLMIB_GRxJBR(port) (0x00001b00 + port) ++#define XLMIB_GRxMTUE(port) (0x00001c00 + port) ++#define XLMIB_GRxVLN(port) (0x00001f00 + port) ++#define XLMIB_GRxDVLN(port) (0x00002000 + port) ++#define XLMIB_GRxTRFU(port) (0x00002100 + port) ++#define XLMIB_GRxPOK(port) (0x00002200 + port) ++#define XLMIB_GRxUND(port) (0x00003400 + port) ++#define XLMIB_GRxFRG(port) (0x00003500 + port) ++#define XLMIB_GRxByt(port) (0x00003d00 + port) ++#define XLMIB_GTx64(port) (0x00004000 + port) ++#define XLMIB_GTx127(port) (0x00004100 + port) ++#define XLMIB_GTx255(port) (0x00004200 + port) ++#define XLMIB_GTx511(port) (0x00004300 + port) ++#define XLMIB_GTx1023(port) (0x00004400 + port) ++#define XLMIB_GTx1518(port) (0x00004500 + port) ++#define XLMIB_GTx1522(port) (0x00004600 + port) ++#define XLMIB_GTx2047(port) (0x00004700 + port) ++#define XLMIB_GTx4095(port) (0x00004800 + port) ++#define XLMIB_GTx9216(port) (0x00004900 + port) ++#define XLMIB_GTx16383(port) (0x00004a00 + port) ++#define XLMIB_GTxPOK(port) (0x00004b00 + port) ++#define XLMIB_GTxPkt(port) (0x00004c00 + port) ++#define XLMIB_GTxUCA(port) (0x00004d00 + port) ++#define XLMIB_GTxMCA(port) (0x00004e00 + port) ++#define XLMIB_GTxBCA(port) (0x00004f00 + port) ++#define XLMIB_GTxPF(port) (0x00005000 + port) ++#define XLMIB_GTxJBR(port) (0x00005200 + port) ++#define XLMIB_GTxFCS(port) (0x00005300 + port) ++#define XLMIB_GTxCF(port) (0x00005400 + port) ++#define XLMIB_GTxOVR(port) (0x00005500 + port) ++#define XLMIB_GTxFRG(port) (0x00005c00 + port) ++#define XLMIB_GTxErr(port) (0x00005d00 + port) ++#define XLMIB_GTxVLN(port) (0x00005e00 + port) ++#define XLMIB_GTxDVLN(port) (0x00005f00 + port) ++#define XLMIB_GTxUFL(port) (0x00006100 + port) ++#define XLMIB_GTxNCL(port) (0x00006e00 + port) ++#define XLMIB_GTxBYT(port) (0x00006f00 + port) ++ ++#define XLPORT_CONFIG(port) (0x00020000 + port) ++#define XLMAC_CTRL(port) (0x00060000 + port) ++#define XLMAC_CTRL__SW_LINK_STATUS 12 ++#define XLMAC_CTRL__XGMII_IPG_CHECK_DISABLE 11 ++#define XLMAC_CTRL__SOFT_RESET 6 ++#define XLMAC_CTRL__LOCAL_LPBK 2 ++#define XLMAC_CTRL__RX_EN 1 ++#define XLMAC_CTRL__TX_EN 0 ++#define XLMAC_MODE(port) (0x00060100 + port) ++#define XLMAC_MODE_OFFSET 0x1 ++#define XLMAC_MODE__SPEED_MODE_L 6 ++#define XLMAC_MODE__SPEED_MODE_R 4 ++#define XLMAC_MODE__SPEED_MODE_WIDTH 3 ++#define SPEED_MODE_LINK_10M 0x0 ++#define SPEED_MODE_LINK_100M 0x1 ++#define SPEED_MODE_LINK_1G 0x2 ++#define SPEED_MODE_LINK_2G5 0x3 ++#define SPEED_MODE_LINK_10G_PLUS 0x4 ++#define XLMAC_MODE__SPEED_MODE_RESETVALUE 0x4 ++#define XLMAC_MODE__NO_SOP_FOR_CRC_HG 3 ++#define XLMAC_MODE__NO_SOP_FOR_CRC_HG_WIDTH 1 ++#define XLMAC_MODE__NO_SOP_FOR_CRC_HG_RESETVALUE 0x0 ++#define XLMAC_MODE__HDR_MODE_L 2 ++#define XLMAC_MODE__HDR_MODE_R 0 ++#define XLMAC_MODE__HDR_MODE_WIDTH 3 ++#define HDR_MODE_IEEE 0x0 ++#define HDR_MODE_HG_PLUS 0x1 ++#define HDR_MODE_HG_2 0x2 ++#define HDR_MODE_SOP_ONLY_IEEE 0x5 ++#define XLMAC_TX_CTRL(port) (0x00060400 + port) ++#define XLMAC_TX_CTRL__AVERAGE_IPG_R 12 ++#define XLMAC_TX_CTRL__PAD_EN 4 ++#define XLMAC_TX_CTRL__CRC_MODE_R 0 ++#define CRC_MODE_APPEND 0x0 ++#define CRC_MODE_KEEP 0x1 ++#define CRC_MODE_REPLACE 0x2 ++#define CRC_MODE_PER_PKT_MODE 0x3 ++#define XLMAC_TX_MAC_SA(port) (0x00060500 + port) ++#define XLMAC_RX_MAX_SIZE(port) (0x00060800 + port) ++#define XLMAC_RX_MAX_SIZE__RX_MAX_SIZE_L 13 ++#define XLMAC_RX_MAX_SIZE__RX_MAX_SIZE_R 0 ++#define XLMAC_RX_MAX_SIZE__RX_MAX_SIZE_WIDTH 14 ++#define XLMAC_RX_CTRL(port) (0x00060600 + port) ++#define XLMAC_RX_CTRL__STRIP_CRC 2 ++#define XLMAC_RX_LSS_CTRL(port) (0x00060a00 + port) ++#define XLMAC_RX_LSS_CTRL__DROP_TX_DATA_ON_LINK_INTERRUPT 6 ++#define XLMAC_RX_LSS_CTRL__DROP_TX_DATA_ON_REMOTE_FAULT 5 ++#define XLMAC_RX_LSS_CTRL__DROP_TX_DATA_ON_LOCAL_FAULT 4 ++#define XLMAC_RX_LSS_CTRL__REMOTE_FAULT_DISABLE 1 ++#define XLMAC_RX_LSS_CTRL__LOCAL_FAULT_DISABLE 0 ++#define XLMAC_PAUSE_CTRL(port) (0x00060d00 + port) ++#define XLMAC_PAUSE_CTRL__RX_PAUSE_EN 18 ++#define XLMAC_PAUSE_CTRL__TX_PAUSE_EN 17 ++#define XLMAC_PFC_CTRL(port) (0x00060e00 + port) ++#define XLMAC_PFC_CTRL__PFC_REFRESH_EN 32 ++/* General type registers */ ++#define XLPORT_MODE_REG (0x02020a00) ++#define XLPORT_MODE_REG__RESET_MASK 0x3f ++#define XLPORT_MODE_REG__XPORT0_CORE_PORT_MODE_L 5 ++#define XLPORT_MODE_REG__XPORT0_CORE_PORT_MODE_R 3 ++#define XLPORT_MODE_REG__XPORT0_CORE_PORT_MODE_WIDTH 3 ++#define XPORT0_CORE_PORT_MODE_QUAD 0x0 ++#define XPORT0_CORE_PORT_MODE_TRI_012 0x1 ++#define XPORT0_CORE_PORT_MODE_TRI_023 0x2 ++#define XPORT0_CORE_PORT_MODE_DUAL 0x3 ++#define XPORT0_CORE_PORT_MODE_SINGLE 0x4 ++#define XLPORT_MODE_REG__XPORT0_PHY_PORT_MODE_L 2 ++#define XLPORT_MODE_REG__XPORT0_PHY_PORT_MODE_R 0 ++#define XLPORT_MODE_REG__XPORT0_PHY_PORT_MODE_WIDTH 3 ++#define XPORT0_PHY_PORT_MODE_QUAD 0x0 ++#define XPORT0_PHY_PORT_MODE_TRI_012 0x1 ++#define XPORT0_PHY_PORT_MODE_TRI_023 0x2 ++#define XPORT0_PHY_PORT_MODE_DUAL 0x3 ++#define XPORT0_PHY_PORT_MODE_SINGLE 0x4 ++#define XLPORT_ENABLE_REG (0x02020b00) ++#define XLPORT_ENABLE_REG__PORT3 3 ++#define XLPORT_ENABLE_REG__PORT2 2 ++#define XLPORT_ENABLE_REG__PORT1 1 ++#define XLPORT_ENABLE_REG__PORT0 0 ++#define XLPORT_MAC_CONTROL (0x02021000) ++#define XLPORT_MAC_CONTROL__RX_DUAL_CYCLE_TDM_EN 5 ++#define XLPORT_MAC_CONTROL__RX_NON_LINEAR_QUAD_TDM_EN 3 ++#define XLPORT_MAC_CONTROL__RX_FLEX_TDM_ENABLE 2 ++#define XLPORT_MAC_CONTROL__XMAC0_BYPASS_OSTS 1 ++#define XLPORT_MAC_CONTROL__XMAC0_RESET 0 ++#define XLPORT_XGXS0_CTRL_REG (0x02021400) ++#define XLPORT_XGXS0_CTRL_REG__RefSel 8 ++#define XLPORT_XGXS0_CTRL_REG__RefCMOS 7 ++#define XLPORT_XGXS0_CTRL_REG__Pwrdwn_CML_LC 6 ++#define XLPORT_XGXS0_CTRL_REG__Pwrdwn_CML 5 ++#define XLPORT_XGXS0_CTRL_REG__IDDQ 4 ++#define XLPORT_XGXS0_CTRL_REG__PWRDWN 3 ++#define XLPORT_XGXS0_CTRL_REG__Refin_EN 2 ++#define XLPORT_XGXS0_CTRL_REG__RSTB_HW 0 ++#define XLPORT_WC_UCMEM_CTRL (0x02021900) ++#define XLPORT_WC_UCMEM_CTRL__ACCESS_MODE 0 ++#define XLPORT_MIB_RESET (0x02022400) ++#define XLPORT_MIB_RESET__CLR_CNT_L 3 ++#define XLPORT_MIB_RESET__CLR_CNT_R 0 ++#define XLPORT_INTR_STATUS (0x02022900) ++#define XLPORT_INTR_ENABLE (0x02022a00) ++#define XLPORT_SOFT_RESET (0x02020c00) ++#define XLPORT_SOFT_RESET__PORT3 3 ++#define XLPORT_SOFT_RESET__PORT2 2 ++#define XLPORT_SOFT_RESET__PORT1 1 ++#define XLPORT_SOFT_RESET__PORT0 0 ++#define XLPORT_POWER_SAVE (0x02020d00) ++#define XLPORT_POWER_SAVE__XPORT_CORE0 0 ++ ++#define XLPORT_PORT_FIELD(reg, port) reg##__PORT##port ++#define XLPORT_PORT_FIELD_SET(_r, _p, _v) { \ ++ if (_p == 0) val |= (1 << _r##__PORT0); \ ++ else if (_p == 1) val |= (1 << _r##__PORT1); \ ++ else if (_p == 2) val |= (1 << _r##__PORT2); \ ++ else if (_p == 3) val |= (1 << _r##__PORT3); \ ++} ++ ++#define XLPORT_PORT_FIELD_CLEAR(_r, _p, _v) { \ ++ if (_p == 0) val &= ~(1 << _r##__PORT0); \ ++ else if (_p == 1) val &= ~(1 << _r##__PORT1); \ ++ else if (_p == 2) val &= ~(1 << _r##__PORT2); \ ++ else if (_p == 3) val &= ~(1 << _r##__PORT3); \ ++} ++ ++static u32 pm4x10_enabled = 0; ++ ++static inline void ++xlmac_reg64_write(u32 addr, u64 val) ++{ ++ iproc_cmic_schan_reg64_write(CMIC_BLOCK_TYPE_APM, addr, val); ++} ++ ++static inline u64 ++xlmac_reg64_read(u32 addr) ++{ ++ return iproc_cmic_schan_reg64_read(CMIC_BLOCK_TYPE_APM, addr); ++} ++ ++static inline void ++xlport_reg32_write(u32 addr, u32 val) ++{ ++ iproc_cmic_schan_reg32_write(CMIC_BLOCK_TYPE_APM, addr, val); ++} ++ ++static inline u32 ++xlport_reg32_read(u32 addr) ++{ ++ return iproc_cmic_schan_reg32_read(CMIC_BLOCK_TYPE_APM, addr); ++} ++ ++ ++/* MDIO address for each lane in this PM */ ++static u32 lane_mdio_addr[4] = { 3, 4, 5, 6 }; ++ ++static inline void ++pm_phy_sbus_write(u32 lane, u32 addr, u32 val, u32 mask, u32 shift) ++{ ++ u32 device, mem_data[4]; ++ ++ /* TSC register address (indirect access) */ ++ if ((addr == 0x0002) || (addr == 0x0003) || ((addr <= 0xc340) && (addr >= 0x9000))) ++ device = 0; /* PCS (TSC) */ ++ else ++ device = 1; /* PMA/PMD (Physical Media Device or called serdes(merlin)) */ ++ ++ mem_data[0] = (device << 27) | (lane_mdio_addr[lane] << 19) | (lane << 16) | addr; ++ mem_data[1] = ((val << shift) << 16) | /* data */ ++ (~(mask << shift) & 0xffff); /* mask */ ++ mem_data[2] = TSC_OPERATION_WRITE; ++ mem_data[3] = 0; ++ iproc_cmic_schan_ucmem_write(CMIC_BLOCK_TYPE_APM, mem_data); ++ } ++ ++static inline u32 ++pm_phy_sbus_read(u32 lane, u32 addr, u32 *val) ++{ ++ u32 device, mem_data[4]; ++ ++ /* TSC register address (indirect access) */ ++ if ((addr == 0x0002) || (addr == 0x0003) || ((addr <= 0xc340) && (addr >= 0x9000))) ++ device = 0; /* PCS (TSC) */ ++ else ++ device = 1; /* PMA/PMD (Physical Media Device or called serdes(merlin)) */ ++ ++ mem_data[0] = (device << 27) | (lane_mdio_addr[lane] << 19) | (lane << 16) | addr; ++ mem_data[1] = 0; ++ mem_data[2] = TSC_OPERATION_READ; ++ mem_data[3] = 0; ++ iproc_cmic_schan_ucmem_write(CMIC_BLOCK_TYPE_APM, mem_data); ++ *val = iproc_cmic_schan_ucmem_read(CMIC_BLOCK_TYPE_APM, mem_data); ++ return 0; ++} ++ ++ ++static void cmpw(u8 readonly, u32 addr, u32 val) ++{ ++ u8 i; ++ ++ if (readonly) ++ { ++ //printk("(read only) Reg addr = 0x%x, current = 0x%x, expect = 0x%x\n", reg_addr, get_val, reg_data_val); ++ } else ++ { ++ //printk("(write) Reg addr = 0x%x, current = 0x%x, expect = 0x%x\n", reg_addr, get_val, reg_data_val); ++ for (i=0; i<4; ++i) /* per lane */ ++ if ((i % 2) == 0) ++ pm_phy_sbus_write(i, addr, val, 0xffff, 0); ++ } ++} ++ ++static inline u32 ++pm_phy_configure(int port) ++{ ++ cmpw(0, 0x0002, 0x600d); cmpw(0, 0x0003, 0x8770); cmpw(0, 0x000d, 0x0000); cmpw(0, 0x000e, 0x0000); ++ cmpw(0, 0x0096, 0x0000); cmpw(0, 0x0097, 0x0000); cmpw(0, 0x0098, 0x0000); cmpw(0, 0x0099, 0x0000); ++ cmpw(0, 0x009a, 0x0000); cmpw(0, 0x009b, 0x0000); cmpw(0, 0x9000, 0x6000); cmpw(0, 0x9001, 0x00aa); ++ cmpw(0, 0x9003, 0xe4e4); cmpw(0, 0x9004, 0x0083); cmpw(0, 0x9005, 0x0000); cmpw(0, 0x9007, 0x0000); ++ cmpw(0, 0x9008, 0x0000); cmpw(0, 0x9009, 0x0000); cmpw(0, 0x900a, 0xf800); cmpw(0, 0x900e, 0x0312); ++ cmpw(0, 0x9010, 0x0003); cmpw(0, 0x9011, 0x0000); cmpw(1, 0x9012, 0x0002); cmpw(1, 0x9013, 0x0002); ++ cmpw(0, 0x9014, 0x0000); cmpw(0, 0x9030, 0x0000); cmpw(0, 0x9031, 0x0028); cmpw(0, 0x9032, 0x0000); ++ cmpw(0, 0x9033, 0x0000); cmpw(0, 0x9034, 0x0000); cmpw(0, 0x9035, 0x0000); cmpw(0, 0x9037, 0x0000); ++ cmpw(0, 0x9038, 0x0000); cmpw(0, 0x9039, 0x0000); cmpw(0, 0x903a, 0x0000); cmpw(0, 0x903b, 0x0000); ++ cmpw(0, 0x903c, 0x0000); cmpw(0, 0x903d, 0x0000); cmpw(0, 0x903e, 0x0000); cmpw(0, 0x9040, 0x0000); ++ cmpw(0, 0x9041, 0x0000); cmpw(0, 0x9042, 0x0000); cmpw(0, 0x9043, 0x0000); cmpw(0, 0x9044, 0x0000); ++ cmpw(0, 0x9045, 0x0000); cmpw(0, 0x9050, 0x0000); cmpw(0, 0x9051, 0x0000); cmpw(0, 0x9052, 0x0000); ++ cmpw(0, 0x9053, 0x0000); cmpw(0, 0x9054, 0x0000); cmpw(0, 0x9055, 0x0000); cmpw(0, 0x9056, 0x0000); ++ cmpw(0, 0x9057, 0x0000); cmpw(0, 0x9058, 0x0000); cmpw(0, 0x9059, 0x0000); cmpw(0, 0x905a, 0x0000); ++ cmpw(0, 0x9060, 0x0000); cmpw(0, 0x9061, 0x0000); cmpw(0, 0x9062, 0x0000); cmpw(1, 0x90b1, 0x0000); ++ cmpw(0, 0x90b3, 0x0000); cmpw(0, 0x90b4, 0x001d); cmpw(0, 0x90b5, 0xffff); cmpw(0, 0x9123, 0x3fff); ++ cmpw(0, 0x9130, 0x7690); cmpw(0, 0x9131, 0xc4f0); cmpw(0, 0x9132, 0xe647); cmpw(0, 0x9140, 0x0000); ++ cmpw(0, 0x9141, 0x0000); cmpw(0, 0x9142, 0x0000); cmpw(0, 0x9220, 0x0101); cmpw(0, 0x9221, 0x6140); ++ cmpw(0, 0x9222, 0xeea7); cmpw(0, 0x9230, 0x4010); cmpw(0, 0x9231, 0x0400); cmpw(0, 0x9232, 0x0041); ++ cmpw(0, 0x9233, 0x8090); cmpw(0, 0x9234, 0xa0b0); cmpw(0, 0x9235, 0xc0d0); cmpw(0, 0x9236, 0xe070); ++ cmpw(0, 0x9237, 0x0001); cmpw(0, 0x9238, 0xf0f0); cmpw(0, 0x9239, 0xf0f0); cmpw(0, 0x923a, 0xf0f0); ++ cmpw(0, 0x923b, 0xf0f0); cmpw(0, 0x923c, 0x0003); cmpw(0, 0x9240, 0x0000); cmpw(0, 0x9241, 0x0000); ++ cmpw(0, 0x9242, 0x0000); cmpw(0, 0x9243, 0x0000); cmpw(0, 0x9244, 0x0000); cmpw(0, 0x9245, 0x0000); ++ cmpw(0, 0x9246, 0x0000); cmpw(0, 0x9247, 0x0000); cmpw(0, 0x9248, 0x0000); cmpw(0, 0x9251, 0x029a); ++ cmpw(0, 0x9252, 0x0000); cmpw(0, 0x9253, 0x10ed); cmpw(0, 0x9254, 0x0000); cmpw(0, 0x9255, 0x14d4); ++ cmpw(0, 0x9256, 0x029a); cmpw(0, 0x9257, 0x8382); cmpw(0, 0x9258, 0x0bb8); cmpw(0, 0x9259, 0x0a6a); ++ cmpw(0, 0x925a, 0x029a); cmpw(0, 0x925b, 0x0a6a); cmpw(0, 0x925c, 0x029a); cmpw(0, 0x925d, 0x3b5f); ++ cmpw(0, 0x925e, 0x006b); cmpw(0, 0x9260, 0x0000); cmpw(0, 0x9261, 0x0000); cmpw(0, 0x9262, 0x00ff); ++ cmpw(0, 0x9263, 0x0002); cmpw(0, 0x9264, 0x0000); cmpw(0, 0x9270, 0xff00); cmpw(0, 0x9272, 0x0000); ++ cmpw(0, 0x9273, 0x0000); cmpw(0, 0x9274, 0x0400); cmpw(0, 0x9275, 0x0000); cmpw(0, 0x9276, 0x0000); ++ cmpw(0, 0x9277, 0x0000); cmpw(0, 0x9278, 0x0000); cmpw(0, 0x9279, 0x0000); cmpw(0, 0x927a, 0x0000); ++ cmpw(0, 0x9280, 0xff00); cmpw(0, 0x9282, 0x0000); cmpw(0, 0x9283, 0x0000); cmpw(0, 0x9284, 0x0400); ++ cmpw(0, 0x9285, 0x0000); cmpw(0, 0x9286, 0x0000); cmpw(0, 0x9287, 0x0000); cmpw(0, 0x9288, 0x0000); ++ cmpw(0, 0x9289, 0x0000); cmpw(0, 0x928a, 0x0000); cmpw(0, 0x9290, 0xff00); cmpw(0, 0x9292, 0x0000); ++ cmpw(0, 0x9293, 0x0000); cmpw(0, 0x9294, 0x0400); cmpw(0, 0x9295, 0x0000); cmpw(0, 0x9296, 0x0000); ++ cmpw(0, 0x9297, 0x0000); cmpw(0, 0x9298, 0x0000); cmpw(0, 0x9299, 0x0000); cmpw(0, 0x929a, 0x0000); ++ cmpw(0, 0x92a0, 0xff00); cmpw(0, 0x92a2, 0x0000); cmpw(0, 0x92a3, 0x0000); cmpw(0, 0x92a4, 0x0400); ++ cmpw(0, 0x92a5, 0x0000); cmpw(0, 0x92a6, 0x0000); cmpw(0, 0x92a7, 0x0000); cmpw(0, 0x92a8, 0x0000); ++ cmpw(0, 0x92a9, 0x0000); cmpw(0, 0x92aa, 0x0000); cmpw(0, 0xa000, 0xfffc); cmpw(0, 0xa001, 0x8030); ++ cmpw(0, 0xa002, 0x0070); cmpw(0, 0xa003, 0x0064); cmpw(1, 0xa011, 0x0812); cmpw(0, 0xa020, 0x0000); ++ cmpw(0, 0xa021, 0x0000); cmpw(0, 0xa022, 0x0000); cmpw(0, 0xa023, 0x1400); cmpw(0, 0xa024, 0x030f); ++ cmpw(0, 0xa031, 0x0000); cmpw(0, 0xa032, 0x0000); cmpw(0, 0xa080, 0x0000); cmpw(0, 0xa081, 0x0000); ++ cmpw(0, 0xa085, 0x0000); cmpw(0, 0xa086, 0x8000); cmpw(0, 0xc010, 0xc003); cmpw(0, 0xc011, 0x0000); ++ cmpw(1, 0xc012, 0x000e); cmpw(0, 0xc013, 0x000c); cmpw(0, 0xc014, 0x0000); cmpw(0, 0xc018, 0x0000); ++ cmpw(0, 0xc019, 0x0000); cmpw(0, 0xc040, 0x0000); cmpw(0, 0xc041, 0x0000); cmpw(0, 0xc042, 0x0000); ++ cmpw(0, 0xc043, 0x0000); ++ //cmpw(0, 0xc050, 0x0135); /* speed = 10M */ ++ //cmpw(0, 0xc050, 0x0136); /* speed = 100M */ ++ cmpw(0, 0xc050, 0x0137); /* speed = 1000M */ ++ //cmpw(0, 0xc050, 0x011c); /* speed = 10G */ ++ cmpw(1, 0xc051, 0x0000); cmpw(0, 0xc052, 0x0000); cmpw(1, 0xc054, 0xef62); cmpw(0, 0xc055, 0x0000); ++ cmpw(0, 0xc058, 0x0000); cmpw(0, 0xc060, 0x0000); cmpw(0, 0xc061, 0x0000); cmpw(0, 0xc070, 0x1c00); ++ cmpw(0, 0xc072, 0x0e05); cmpw(0, 0xc073, 0x0830); cmpw(0, 0xc074, 0x0010); cmpw(0, 0xc075, 0x0021); ++ cmpw(0, 0xc076, 0x0000); cmpw(0, 0xc077, 0x0040); cmpw(0, 0xc078, 0x0004); cmpw(0, 0xc079, 0x0000); ++ cmpw(0, 0xc07a, 0x0000); cmpw(0, 0xc100, 0x0000); cmpw(0, 0xc101, 0x0000); cmpw(0, 0xc102, 0x0000); ++ cmpw(0, 0xc103, 0x0000); cmpw(0, 0xc104, 0x0000); cmpw(0, 0xc105, 0x0000); cmpw(0, 0xc111, 0x0000); ++ cmpw(0, 0xc112, 0x01b4); cmpw(0, 0xc113, 0x01cb); cmpw(0, 0xc114, 0x0000); cmpw(1, 0xc120, 0x4811); ++ cmpw(1, 0xc121, 0x0084); cmpw(0, 0xc130, 0x0000); cmpw(0, 0xc131, 0x2000); cmpw(0, 0xc132, 0x442c); ++ cmpw(0, 0xc133, 0x0000); cmpw(0, 0xc134, 0x0870); cmpw(0, 0xc135, 0x0000); cmpw(0, 0xc136, 0x0000); ++ cmpw(0, 0xc137, 0x0001); cmpw(0, 0xc139, 0x0000); cmpw(0, 0xc13d, 0x14a0); cmpw(0, 0xc140, 0x0000); ++ cmpw(0, 0xc141, 0x0000); cmpw(0, 0xc142, 0x0000); cmpw(0, 0xc143, 0x0000); cmpw(0, 0xc144, 0x0000); ++ cmpw(0, 0xc145, 0x0000); cmpw(0, 0xc146, 0x0000); cmpw(0, 0xc147, 0x0000); cmpw(0, 0xc148, 0x0000); ++ cmpw(0, 0xc149, 0x0000); cmpw(0, 0xc14a, 0x0000); cmpw(0, 0xc14b, 0x0000); cmpw(0, 0xc14c, 0x0000); ++ cmpw(0, 0xc14d, 0x0000); cmpw(0, 0xc14e, 0x0000); cmpw(0, 0xc152, 0x0000); cmpw(0, 0xc153, 0x0000); ++ cmpw(0, 0xc154, 0x0000); cmpw(0, 0xc155, 0x0000); cmpw(0, 0xc156, 0x0000); cmpw(0, 0xc157, 0x0000); ++ cmpw(0, 0xc158, 0x0000); cmpw(0, 0xc159, 0x0000); cmpw(0, 0xc15a, 0x0000); cmpw(0, 0xc15b, 0x0000); ++ cmpw(0, 0xc15c, 0x0000); cmpw(0, 0xc161, 0x0000); cmpw(0, 0xc162, 0x0000); cmpw(0, 0xc163, 0x0000); ++ cmpw(0, 0xc170, 0x0000); cmpw(0, 0xc171, 0x0000); cmpw(0, 0xc172, 0x0000); cmpw(0, 0xc173, 0x0000); ++ cmpw(0, 0xc174, 0x0000); cmpw(0, 0xc175, 0x0000); cmpw(0, 0xc176, 0x0000); cmpw(0, 0xc177, 0x0000); ++ cmpw(0, 0xc178, 0x0000); cmpw(0, 0xc179, 0x0000); cmpw(0, 0xc17a, 0x0000); cmpw(0, 0xc17b, 0x0000); ++ cmpw(0, 0xc17c, 0x0000); cmpw(0, 0xc17d, 0x0000); cmpw(0, 0xc180, 0x0000); cmpw(0, 0xc181, 0x0056); ++ cmpw(0, 0xc182, 0x0005); cmpw(0, 0xc183, 0x2000); cmpw(0, 0xc184, 0x0001); cmpw(0, 0xc185, 0x02a1); ++ cmpw(0, 0xc186, 0x0168); cmpw(0, 0xc187, 0x0000); cmpw(0, 0xc188, 0x0000); cmpw(0, 0xc190, 0x0000); ++ cmpw(0, 0xc191, 0x0000); cmpw(0, 0xc192, 0x0000); cmpw(0, 0xc193, 0x0000); cmpw(0, 0xc194, 0x0000); ++ cmpw(0, 0xc195, 0x0000); cmpw(0, 0xc196, 0x0000); cmpw(0, 0xc197, 0x0000); cmpw(0, 0xc198, 0x0000); ++ cmpw(0, 0xc199, 0x0000); cmpw(0, 0xc19a, 0x0000); cmpw(0, 0xc1a0, 0x0000); cmpw(0, 0xc1a1, 0x0000); ++ cmpw(0, 0xc1a2, 0x0000); cmpw(0, 0xc1a3, 0x0000); cmpw(0, 0xc1a4, 0x0000); cmpw(0, 0xc1a5, 0x0000); ++ cmpw(0, 0xc1a6, 0x0000); cmpw(0, 0xc1a7, 0x0000); cmpw(0, 0xc1a8, 0x0000); cmpw(0, 0xc1a9, 0x0000); ++ cmpw(0, 0xc1aa, 0x0000); cmpw(0, 0xc1ab, 0x0030); cmpw(0, 0xc1ac, 0x0000); cmpw(0, 0xc1ad, 0x0001); ++ cmpw(0, 0xc1ae, 0x0000); cmpw(0, 0xc253, 0x4000); cmpw(0, 0xc30a, 0x0000); cmpw(0, 0xc30b, 0x0000); ++ cmpw(0, 0xc330, 0x0002); cmpw(0, 0xc340, 0x0011); cmpw(0, 0xd001, 0x0205); cmpw(0, 0xd002, 0x0690); ++ cmpw(0, 0xd003, 0x00f0); cmpw(0, 0xd004, 0x2401); cmpw(1, 0xd005, 0xf07c); cmpw(1, 0xd006, 0x0002); ++ cmpw(1, 0xd007, 0x6969); cmpw(1, 0xd008, 0x3414); cmpw(1, 0xd009, 0x5878); cmpw(1, 0xd00a, 0x00e0); ++ cmpw(0, 0xd00b, 0x0060); cmpw(0, 0xd00d, 0x0805); cmpw(0, 0xd00e, 0x0000); cmpw(0, 0xd010, 0x0028); ++ cmpw(0, 0xd011, 0x0200); cmpw(0, 0xd012, 0x0087); cmpw(0, 0xd013, 0x1c1e); cmpw(0, 0xd014, 0x35ad); ++ cmpw(0, 0xd015, 0x35af); cmpw(0, 0xd016, 0x340d); cmpw(0, 0xd017, 0x0000); cmpw(0, 0xd018, 0x0011); ++ cmpw(0, 0xd019, 0x0000); cmpw(1, 0xd01a, 0x0004); cmpw(1, 0xd01b, 0x0dff); cmpw(1, 0xd01c, 0x0000); ++ cmpw(1, 0xd01d, 0x0000); cmpw(1, 0xd01e, 0x0880); cmpw(0, 0xd020, 0x0000); cmpw(0, 0xd021, 0x0000); ++ cmpw(0, 0xd022, 0x0000); cmpw(0, 0xd023, 0x0000); cmpw(0, 0xd024, 0x0000); cmpw(0, 0xd025, 0x0000); ++ cmpw(0, 0xd026, 0x0000); cmpw(0, 0xd027, 0x8400); cmpw(0, 0xd029, 0x0000); cmpw(0, 0xd02a, 0x0000); ++ cmpw(0, 0xd02b, 0x2e02); cmpw(0, 0xd02c, 0x0000); cmpw(0, 0xd02d, 0x0000); cmpw(0, 0xd02e, 0xc400); ++ cmpw(0, 0xd030, 0xa404); cmpw(0, 0xd031, 0x2060); cmpw(0, 0xd032, 0x0100); cmpw(0, 0xd033, 0x0000); ++ cmpw(1, 0xd034, 0xfff0); cmpw(1, 0xd035, 0x00d0); cmpw(1, 0xd036, 0xfffa); cmpw(1, 0xd037, 0x0096); ++ cmpw(1, 0xd038, 0x000b); cmpw(1, 0xd039, 0x0108); cmpw(1, 0xd03a, 0x2118); cmpw(1, 0xd03b, 0x0000); ++ cmpw(1, 0xd03c, 0x0000); cmpw(1, 0xd03d, 0x0000); cmpw(1, 0xd03e, 0x009f); cmpw(0, 0xd040, 0x00b8); ++ cmpw(0, 0xd041, 0x0000); cmpw(0, 0xd042, 0x0001); cmpw(0, 0xd050, 0x0004); cmpw(0, 0xd051, 0x0052); ++ cmpw(0, 0xd052, 0x0310); cmpw(0, 0xd053, 0x0000); cmpw(0, 0xd054, 0x0000); cmpw(0, 0xd055, 0x0000); ++ cmpw(0, 0xd056, 0x0000); cmpw(0, 0xd060, 0x0000); cmpw(0, 0xd061, 0x0000); cmpw(0, 0xd062, 0x0000); ++ cmpw(0, 0xd063, 0x0004); cmpw(0, 0xd064, 0x0a00); cmpw(0, 0xd065, 0x0032); cmpw(1, 0xd066, 0x0002); ++ cmpw(0, 0xd067, 0x03f5); cmpw(0, 0xd070, 0x0000); cmpw(0, 0xd071, 0x0000); cmpw(0, 0xd072, 0x0000); ++ cmpw(0, 0xd073, 0x3100); cmpw(0, 0xd074, 0x0004); cmpw(0, 0xd075, 0x0004); cmpw(0, 0xd078, 0x0000); ++ cmpw(0, 0xd079, 0x0000); cmpw(0, 0xd07a, 0x0000); cmpw(0, 0xd07b, 0x0000); cmpw(0, 0xd07c, 0x0000); ++ cmpw(1, 0xd07d, 0x0002); ++ //cmpw(0, 0xd080, 0x8008); /* speed = 10M */ ++ //cmpw(0, 0xd080, 0x8008); /* speed = 100M */ ++ cmpw(0, 0xd080, 0x8008); /* speed = 1000M */ ++ //cmpw(0, 0xd080, 0x8000); /* speed = 10G */ ++ cmpw(0, 0xd081, 0x0001); cmpw(0, 0xd083, 0x0000); cmpw(0, 0xd085, 0x0000); cmpw(0, 0xd086, 0x0000); ++ cmpw(1, 0xd089, 0x0000); cmpw(0, 0xd08a, 0x0000); cmpw(1, 0xd08b, 0x0000); cmpw(1, 0xd08c, 0x0000); ++ cmpw(0, 0xd08e, 0x0001); cmpw(0, 0xd090, 0x1c40); cmpw(0, 0xd091, 0x1048); cmpw(0, 0xd092, 0x7e92); ++ cmpw(0, 0xd093, 0x288f); cmpw(0, 0xd094, 0x0820); cmpw(0, 0xd095, 0x07a0); cmpw(0, 0xd096, 0x14f8); ++ cmpw(0, 0xd097, 0x0121); cmpw(0, 0xd098, 0x0000); cmpw(0, 0xd099, 0x0088); cmpw(0, 0xd0a0, 0x2800); ++ cmpw(0, 0xd0a1, 0x0744); cmpw(0, 0xd0a2, 0x5250); cmpw(0, 0xd0a3, 0x1556); cmpw(0, 0xd0a4, 0x0000); ++ cmpw(0, 0xd0a5, 0x2800); cmpw(0, 0xd0a6, 0x0001); cmpw(0, 0xd0a7, 0x0aa0); cmpw(0, 0xd0a8, 0x0000); ++ cmpw(0, 0xd0a9, 0x0000); cmpw(0, 0xd0aa, 0x0088); cmpw(0, 0xd0b0, 0x2480); cmpw(0, 0xd0b1, 0x0007); ++ cmpw(0, 0xd0b2, 0x0080); cmpw(0, 0xd0b3, 0x460e); cmpw(0, 0xd0b4, 0x0501); cmpw(0, 0xd0b5, 0x1405); ++ cmpw(0, 0xd0b6, 0x0000); cmpw(0, 0xd0b7, 0x0000); cmpw(0, 0xd0b8, 0x4442); cmpw(0, 0xd0b9, 0x5285); ++ cmpw(0, 0xd0ba, 0x0015); cmpw(0, 0xd0be, 0x0000); cmpw(0, 0xd0bf, 0x0001); cmpw(0, 0xd0c0, 0x5229); ++ cmpw(0, 0xd0c1, 0x0008); cmpw(0, 0xd0c2, 0xfd29); cmpw(1, 0xd0c8, 0x0333); cmpw(1, 0xd0c9, 0x0303); ++ cmpw(1, 0xd0ca, 0x0000); cmpw(1, 0xd0cb, 0x0001); cmpw(1, 0xd0cc, 0x0009); cmpw(0, 0xd0d0, 0x0602); ++ cmpw(0, 0xd0d1, 0x002a); cmpw(0, 0xd0d2, 0x000e); cmpw(0, 0xd0d3, 0x0000); cmpw(0, 0xd0d4, 0x0000); ++ cmpw(0, 0xd0d5, 0x0000); cmpw(0, 0xd0d6, 0x0000); cmpw(0, 0xd0d7, 0x0000); cmpw(0, 0xd0d8, 0x0002); ++ cmpw(0, 0xd0d9, 0x0000); cmpw(0, 0xd0da, 0x8000); cmpw(0, 0xd0db, 0x0000); cmpw(0, 0xd0dc, 0x0000); ++ cmpw(0, 0xd0e0, 0x0000); cmpw(0, 0xd0e1, 0x000a); cmpw(0, 0xd0e2, 0x0002); cmpw(0, 0xd0e3, 0x0000); ++ cmpw(0, 0xd0e8, 0x0002); cmpw(0, 0xd0f0, 0x0363); cmpw(0, 0xd0f1, 0x0001); cmpw(0, 0xd0f2, 0x0000); ++ cmpw(0, 0xd0f3, 0x0000); cmpw(0, 0xd0f4, 0xa271); cmpw(0, 0xd0f5, 0x0000); cmpw(0, 0xd0f6, 0x0000); ++ cmpw(0, 0xd0f7, 0x8604); cmpw(1, 0xd0f8, 0x0000); cmpw(1, 0xd0f9, 0x001c); cmpw(1, 0xd0fa, 0x403c); ++ cmpw(0, 0xd0fe, 0x0000); cmpw(0, 0xd100, 0xff00); cmpw(0, 0xd101, 0xff00); cmpw(0, 0xd102, 0xff00); ++ cmpw(0, 0xd103, 0xff00); cmpw(0, 0xd104, 0xff00); cmpw(0, 0xd105, 0xff00); cmpw(0, 0xd106, 0xff00); ++ cmpw(0, 0xd107, 0xff00); cmpw(0, 0xd108, 0xff00); cmpw(0, 0xd109, 0xff00); cmpw(0, 0xd10a, 0xff00); ++ cmpw(0, 0xd10b, 0xff00); cmpw(0, 0xd10c, 0xff00); cmpw(0, 0xd10d, 0xff00); cmpw(0, 0xd10e, 0xff00); ++ cmpw(0, 0xd110, 0x0000); cmpw(0, 0xd111, 0x0020); cmpw(1, 0xd112, 0x0000); cmpw(0, 0xd113, 0xc140); ++ cmpw(0, 0xd11b, 0x00aa); cmpw(0, 0xd11c, 0x4155); cmpw(0, 0xd11d, 0x4914); cmpw(0, 0xd11e, 0x000f); ++ cmpw(0, 0xd120, 0x1ffa); cmpw(0, 0xd121, 0xfff0); cmpw(0, 0xd122, 0x0fff); cmpw(0, 0xd123, 0x1007); ++ cmpw(0, 0xd124, 0x8240); cmpw(0, 0xd125, 0x8160); cmpw(0, 0xd126, 0x0000); cmpw(1, 0xd128, 0x4f52); ++ cmpw(1, 0xd129, 0x1fdb); cmpw(1, 0xd12a, 0xbffd); cmpw(1, 0xd12b, 0xfff3); cmpw(1, 0xd12c, 0xfff3); ++ cmpw(1, 0xd12d, 0x23ff); cmpw(1, 0xd12e, 0x5288); cmpw(0, 0xd130, 0x01f4); cmpw(0, 0xd131, 0x00c8); ++ cmpw(1, 0xd141, 0x003f); cmpw(1, 0xd142, 0x0003); cmpw(1, 0xd143, 0x0000); cmpw(1, 0xd144, 0x003f); ++ cmpw(1, 0xd145, 0x0003); cmpw(1, 0xd146, 0x0000); cmpw(1, 0xd147, 0x0010); cmpw(0, 0xd150, 0x0000); ++ cmpw(0, 0xd151, 0x0101); cmpw(0, 0xd152, 0x0202); cmpw(0, 0xd153, 0x0303); cmpw(0, 0xd161, 0x0000); ++ cmpw(0, 0xd162, 0x0000); cmpw(0, 0xd163, 0x0000); cmpw(0, 0xd164, 0x0003); cmpw(0, 0xd167, 0x0000); ++ cmpw(0, 0xd168, 0x041c); cmpw(1, 0xd16c, 0x0000); cmpw(0, 0xd171, 0x0000); cmpw(0, 0xd172, 0x0000); ++ cmpw(0, 0xd174, 0x0003); cmpw(0, 0xd177, 0x0000); cmpw(1, 0xd17c, 0x0000); cmpw(0, 0xd17d, 0x0001); ++ cmpw(0, 0xd180, 0x8000); cmpw(0, 0xd181, 0x0001); cmpw(0, 0xd183, 0x0000); cmpw(1, 0xd185, 0x0000); ++ cmpw(0, 0xd186, 0x0000); cmpw(1, 0xd189, 0x0000); cmpw(1, 0xd18a, 0x0000); cmpw(1, 0xd18b, 0x0000); ++ cmpw(1, 0xd18c, 0x0000); cmpw(0, 0xd18e, 0x0001); cmpw(0, 0xd190, 0x8000); cmpw(0, 0xd191, 0x0001); ++ cmpw(0, 0xd193, 0x0000); cmpw(1, 0xd195, 0x0000); cmpw(0, 0xd196, 0x0000); cmpw(1, 0xd199, 0x0000); ++ cmpw(0, 0xd19a, 0x0000); cmpw(1, 0xd19b, 0x0000); cmpw(1, 0xd19c, 0x0000); cmpw(0, 0xd19e, 0x0001); ++ cmpw(0, 0xd200, 0x0003); cmpw(0, 0xd201, 0x000b); cmpw(0, 0xd202, 0x0011); cmpw(0, 0xd200, 0x0003); ++ cmpw(1, 0xd203, 0x0001); cmpw(0, 0xd204, 0x0800); cmpw(0, 0xd205, 0x2000); cmpw(0, 0xd206, 0x0200); ++ cmpw(0, 0xd207, 0x0000); cmpw(0, 0xd208, 0x0800); cmpw(0, 0xd209, 0x2000); cmpw(1, 0xd20a, 0x0200); ++ cmpw(1, 0xd20b, 0x0000); cmpw(0, 0xd20c, 0x0000); cmpw(0, 0xd20d, 0x0000); cmpw(0, 0xd20e, 0x0000); ++ cmpw(1, 0xd210, 0x02ec); cmpw(0, 0xd211, 0x0000); cmpw(0, 0xd212, 0x0000); cmpw(1, 0xd213, 0x0000); ++ cmpw(1, 0xd214, 0x0000); cmpw(0, 0xd215, 0x0000); cmpw(0, 0xd216, 0x0007); cmpw(1, 0xd217, 0x0000); ++ cmpw(1, 0xd218, 0x0802); cmpw(1, 0xd219, 0x0802); cmpw(1, 0xd21a, 0x7a90); cmpw(0, 0xd21b, 0x0000); ++ cmpw(0, 0xd220, 0x0000); cmpw(0, 0xd221, 0x0000); cmpw(1, 0xd222, 0x0000); cmpw(1, 0xd223, 0x0018); ++ cmpw(0, 0xd224, 0x0000); cmpw(0, 0xd225, 0x8401); cmpw(0, 0xd226, 0x0000); cmpw(1, 0xd227, 0x0000); ++ cmpw(0, 0xd228, 0x0101); cmpw(0, 0xd229, 0x0000); cmpw(1, 0xd22a, 0x0007); cmpw(0, 0xffdc, 0x001f); ++ cmpw(0, 0xffdd, 0x404d); cmpw(0, 0xffde, 0x0000); cmpw(0, 0xffdf, 0x0000); ++} ++ ++ ++static inline u32 ++pm_ucode_download(u8 *ucode_image, u16 ucode_len) ++{ ++ u32 get_val; ++ u8 i, wrdata_lsb; ++ u16 wrdata_lsw, ucode_len_padded, count = 0; ++ ++ /* Check array pointer */ ++ if (ucode_image == (u8 *)NULL) { ++ printk("uCode Image is empty !!\n"); ++ return -1; ++ } ++ ++ /* Check ucode size */ ++ if (ucode_len > (32768)) { /* 16 x 2048 */ ++ printk("Can't fit all of the firmware into the device load table(max = 16 x 2048 bytes) \n"); ++ return -1; ++ } ++ ++ //[1] EFUN(wrc_micro_master_clk_en(0x1)); /* Enable clock to microcontroller subsystem */ ++ /* [0xd200] Write to Clock control register 0 to enable micro core clock (m0) */ ++ pm_phy_sbus_write(0, 0xd200, 0x0001, 0x0001, 0); ++ ++ //[2] EFUN(wrc_micro_master_rstb(0x1)); /* De-assert reset to microcontroller sybsystem */ ++ /* [0xd201] Write to Reset control registers 0 to make micro_master_rstb = 1 */ ++ pm_phy_sbus_write(0, 0xd201, 0x0001, 0x0001, 0); ++ ++ //[3] EFUN(wrc_micro_master_rstb(0x0)); /* Assert reset to microcontroller sybsystem - Toggling reset */ ++ /* [0xd201] Write to Reset control registers 0 to make micro_master_rstb = 0 */ ++ pm_phy_sbus_write(0, 0xd201, 0x0000, 0x0001, 0); ++ ++ //[4] EFUN(wrc_micro_master_rstb(0x1)); /* De-assert reset to microcontroller sybsystem */ ++ /* [0xd201] Write to Reset control registers 0 to make micro_master_rstb = 1 */ ++ pm_phy_sbus_write(0, 0xd201, 0x0001, 0x0001, 0); ++ ++ //[5] EFUN(wrc_micro_ra_init(0x1)); /* Set initialization command to initialize code RAM */ ++ /* [0xd202] Write to rmi to ahb control register 0 to initialize code RAMs */ ++ pm_phy_sbus_write(0, 0xd202, 0x0001, 0x0003, 8); ++ ++ //[6] EFUN(merlin16_INTERNAL_poll_micro_ra_initdone(sa__, 250)); /* Poll for micro_ra_initdone = 1 to indicate initialization done */ ++ /* [0xd203] Read from ahb status register 0 to make sure all are done */ ++ for (i=0; i<100; ++i) ++ { ++ pm_phy_sbus_read(0, 0xd203, &get_val); ++ if (get_val == 0x1) /* code/data RAM initialization process is complete */ ++ break; ++ udelay(2500); ++ } ++ if (i == 100) ++ { ++ printk("code/data RAM initialization process is timeout !!\n"); ++ return -1; ++ } ++ ++ //[7] EFUN(wrc_micro_ra_init(0x0)); /* Clear initialization command */ ++ /* [0xd202] Write to rmi to ahb control register 0 to clear intialize code/data RAM command */ ++ pm_phy_sbus_write(0, 0xd202, 0x0000, 0x0003, 8); ++ ++ ucode_len_padded = ((ucode_len + 3) & 0xFFFC); /* Aligning ucode size to 4-byte boundary */ ++ ++ /* Code to Load microcode */ ++ //[8] EFUN(wrc_micro_autoinc_wraddr_en(0x1)); /* To auto increment RAM write address */ ++ /* [0xd202] Write to rmi to ahb control register 0 to make Automatic increment write address enable */ ++ pm_phy_sbus_write(0, 0xd202, 0x0001, 0x0001, 12); ++ ++ //[9] EFUN(wrc_micro_ra_wrdatasize(0x1)); /* Select 16bit transfers */ ++ /* [0xd202] Write to rmi to ahb control register 0 to select write data size = 16 bits */ ++ pm_phy_sbus_write(0, 0xd202, 0x0001, 0x0003, 0); ++ ++ //[10] EFUN(wrc_micro_ra_wraddr_msw(0x0)); /* Upper 16bits of start address of Program RAM where the ucode is to be loaded */ ++ /* [0xd205] Write to rmi to ahb write address MSW (bits 31:16) register with 0 */ ++ pm_phy_sbus_write(0, 0xd205, 0x0000, 0xffff, 0); ++ ++ //[11] EFUN(wrc_micro_ra_wraddr_lsw(0x0)); /* Lower 16bits of start address of Program RAM where the ucode is to be loaded */ ++ /* [0xd206] Write to rmi to ahb write data LSW (bits 15:0) register with 0 (starting address = 0x0) */ ++ pm_phy_sbus_write(0, 0xd206, 0x0000, 0xffff, 0); ++ ++ do { /* ucode_image loaded 16bits at a time */ ++ /* wrdata_lsb read from ucode_image; zero padded to 4byte boundary */ ++ wrdata_lsb = (count < ucode_len) ? ucode_image[count] : 0x0; ++ count++; ++ /* wrdata_msb read from ucode_image; zero padded to 4byte boundary */ ++ wrdata_lsw = (count < ucode_len) ? ucode_image[count] : 0x0; ++ count++; ++ /* 16bit wrdata_lsw formed from 8bit msb and lsb values read from ucode_image */ ++ wrdata_lsw = ((wrdata_lsw << 8) | wrdata_lsb); ++ ++ //[12] EFUN(wrc_micro_ra_wrdata_lsw(wrdata_lsw)); /* Program RAM lower 16bits write data */ ++ /* [0xd206] Write to rmi to ahb write data LSW (bits 15:0) register with data */ ++ pm_phy_sbus_write(0, 0xd206, wrdata_lsw, 0xffff, 0); ++ } while (count < ucode_len_padded); /* Loop repeated till entire image loaded (upto the 4byte boundary) */ ++ ++ //[13] EFUN(wrc_micro_ra_wrdatasize(0x2)); /* Select 32bit transfers as default */ ++ /* [0xd202] Write to rmi to ahb control register 0 to Select 32bit transfers as default */ ++ pm_phy_sbus_write(0, 0xd202, 0x0002, 0x0003, 0); ++ ++ //[14] EFUN(wrc_micro_core_clk_en(0x1)); /* Enable clock to M0 core */ ++ /* [0xd200] Write to Clock control register 0 to enable micro core clock enable (m0) */ ++ pm_phy_sbus_write(0, 0xd200, 0x0001, 0x0001, 1); ++ ++ return 0; ++} ++ ++static int __xlmac_credit_reset(int port) ++{ ++ return 0; ++} ++ ++static void __xlmac_enable_set(int port, bool enable) ++{ ++ u64 ctrl, octrl; ++ int soft_reset; ++ ++ ctrl = xlmac_reg64_read(XLMAC_CTRL(port)); ++ octrl = ctrl; ++ /* Don't disable TX since it stops egress and hangs if CPU sends */ ++ ctrl |= (1 << XLMAC_CTRL__TX_EN); ++ ctrl &= ~(1 << XLMAC_CTRL__RX_EN); ++ if (enable) { ++ ctrl |= (1 << XLMAC_CTRL__RX_EN); ++ } ++ ++ if (ctrl == octrl) { ++ /* SDK-49952 fix soluition : ++ * >> to avoid the unexpected early return to prevent this problem. ++ * 1. Problem occurred for disabling process only. ++ * 2. To comply origianl designing senario, XLMAC_CTRLr.SOFT_RESETf is ++ * used to early check to see if this port is at disabled state ++ * already. ++ */ ++ soft_reset = ctrl & (1 << XLMAC_CTRL__SOFT_RESET); ++ if ((enable) || (!enable && soft_reset)){ ++ return; ++ } ++ } ++ ++ ctrl |= (1 << XLMAC_CTRL__SOFT_RESET); ++ if (enable) { ++ /* Reset EP credit before de-assert SOFT_RESET */ ++ __xlmac_credit_reset(port); ++ /* Deassert SOFT_RESET */ ++ ctrl &= ~(1 << XLMAC_CTRL__SOFT_RESET); ++ } ++ ++ xlmac_reg64_write(XLMAC_CTRL(port), ctrl); ++} ++ ++static int __xlmac_enable_get(int port) ++{ ++ u64 ctrl; ++ int tx_en, rx_en; ++ ++ ctrl = xlmac_reg64_read(XLMAC_CTRL(port)); ++ tx_en = ctrl & (1 << XLMAC_CTRL__TX_EN); ++ rx_en = ctrl & (1 << XLMAC_CTRL__RX_EN); ++ ++ return (tx_en && rx_en); ++} ++ ++static int __xlmac_speed_set(int port, int speed) ++{ ++ u64 speed_cfg, val64; ++ int enable; ++ ++ //pm_phy_sbus_write(port, 0xd080, 0x8008, 0x8008, 0); /* CKRST_CTRL_OSR_MODE_CONTROL */ ++ ++ if (speed == 1000) { ++ speed_cfg = SPEED_MODE_LINK_1G; ++ pm_phy_sbus_write(port, 0xc050, 0x0037, 0x01ff, 0); /* SC_X4_CONTROL_CONTROL */ ++ } else if (speed == 100) { ++ speed_cfg = SPEED_MODE_LINK_100M; ++ pm_phy_sbus_write(port, 0xc050, 0x0036, 0x01ff, 0); /* SC_X4_CONTROL_CONTROL */ ++ } else if (speed == 10) { ++ speed_cfg = SPEED_MODE_LINK_10M; ++ pm_phy_sbus_write(port, 0xc050, 0x0035, 0x01ff, 0); /* SC_X4_CONTROL_CONTROL */ ++ } else { ++ printk("%s: Invalid xlport speed(%d)!\n", __func__, speed); ++ return -1; ++ } ++ ++ pm_phy_sbus_write(port, 0xc050, 0x0000, 0x0001, 8); /* SC_X4_CONTROL_CONTROL */ ++ pm_phy_sbus_write(port, 0xc050, 0x0001, 0x0001, 8); /* SC_X4_CONTROL_CONTROL */ ++ ++ enable = __xlmac_enable_get(port); ++ /* disable before updating the speed */ ++ if (enable) { ++ __xlmac_enable_set(port, 0); ++ } ++ ++ /* Update the speed */ ++ val64 = xlmac_reg64_read(XLMAC_MODE(port)); ++ val64 &= ~(0x70); ++ val64 |= speed_cfg << XLMAC_MODE__SPEED_MODE_R; ++ xlmac_reg64_write(XLMAC_MODE(port), val64); ++ debug("%s XLMAC_MODE = 0x%llx\n", __func__, xlmac_reg64_read(XLMAC_MODE(port))); ++ ++ if (enable) { ++ __xlmac_enable_set(port, 1); ++ } ++ return 0; ++} ++ ++static int __xlmac_rx_max_size_set(int port, int value) ++{ ++ u64 val64; ++ u64 mask64; ++ ++ val64 = xlmac_reg64_read(XLMAC_RX_MAX_SIZE(port)); ++ mask64 = (1 << XLMAC_RX_MAX_SIZE__RX_MAX_SIZE_WIDTH) - 1; ++ val64 &= ~(mask64 << XLMAC_RX_MAX_SIZE__RX_MAX_SIZE_R); ++ val64 |= value << XLMAC_RX_MAX_SIZE__RX_MAX_SIZE_R; ++ xlmac_reg64_write(XLMAC_RX_MAX_SIZE(port), val64); ++ ++ return 0; ++} ++ ++static int __xlmac_tx_mac_addr_set(int port, u8 *mac) ++{ ++ u64 val64; ++ ++ /* set our local address */ ++ debug("GMAC: %02x:%02x:%02x:%02x:%02x:%02x\n", ++ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); ++ ++ val64 = (u64)htonl(*(u32 *)&mac[2]); ++ val64 |= ((u64)htons(*(u32 *)mac) << 32); ++ xlmac_reg64_write(XLMAC_TX_MAC_SA(port), val64); ++ ++ debug("%s XLMAC_TX_MAC_SA = 0x%llx\n", __func__, xlmac_reg64_read(XLMAC_TX_MAC_SA(port))); ++ return 0; ++} ++ ++static int __xlmac_init(int port) ++{ ++ u64 val64; ++ ++ /* Disable Tx/Rx, assume that MAC is stable (or out of reset) */ ++ val64 = xlmac_reg64_read(XLMAC_CTRL(port)); ++ val64 &= ~(1 << XLMAC_CTRL__XGMII_IPG_CHECK_DISABLE); ++ val64 &= ~(1 << XLMAC_CTRL__RX_EN); ++ val64 &= ~(1 << XLMAC_CTRL__TX_EN); ++ xlmac_reg64_write(XLMAC_CTRL(port), val64); ++ ++ /* XLMAC_RX_CTRL */ ++ val64 = xlmac_reg64_read(XLMAC_RX_CTRL(port)); ++ val64 &= ~(1 << XLMAC_RX_CTRL__STRIP_CRC); ++ xlmac_reg64_write(XLMAC_RX_CTRL(port), val64); ++ ++ /* XLMAC_TX_CTRL */ ++ val64 = xlmac_reg64_read(XLMAC_TX_CTRL(port)); ++ val64 &= ~(0x3 << XLMAC_TX_CTRL__CRC_MODE_R); ++ val64 |= (CRC_MODE_REPLACE << XLMAC_TX_CTRL__CRC_MODE_R); ++ val64 |= (1 << XLMAC_TX_CTRL__PAD_EN); ++ xlmac_reg64_write(XLMAC_TX_CTRL(port), val64); ++ ++ /* PAUSE */ ++ val64 = xlmac_reg64_read(XLMAC_PAUSE_CTRL(port)); ++ val64 |= 1 << XLMAC_PAUSE_CTRL__RX_PAUSE_EN; ++ val64 |= 1 << XLMAC_PAUSE_CTRL__TX_PAUSE_EN; ++ xlmac_reg64_write(XLMAC_PAUSE_CTRL(port), val64); ++ ++ /* PFC */ ++ val64 = xlmac_reg64_read(XLMAC_PFC_CTRL(port)); ++ val64 |= ((u64)1 << XLMAC_PFC_CTRL__PFC_REFRESH_EN); ++ xlmac_reg64_write(XLMAC_PFC_CTRL(port), val64); ++ ++ /* Set jumbo max size (8000 byte payload) */ ++ __xlmac_rx_max_size_set(port, JUMBO_MAXSZ); ++ ++ /* XLMAC_RX_LSS_CTRL */ ++ val64 = xlmac_reg64_read(XLMAC_RX_LSS_CTRL(port)); ++ val64 |= 1 << XLMAC_RX_LSS_CTRL__DROP_TX_DATA_ON_LINK_INTERRUPT; ++ val64 |= 1 << XLMAC_RX_LSS_CTRL__DROP_TX_DATA_ON_REMOTE_FAULT; ++ val64 |= 1 << XLMAC_RX_LSS_CTRL__DROP_TX_DATA_ON_LOCAL_FAULT; ++ xlmac_reg64_write(XLMAC_RX_LSS_CTRL(port), val64); ++ ++ /* Disable loopback and bring XLMAC out of reset */ ++ val64 = xlmac_reg64_read(XLMAC_CTRL(port)); ++ val64 &= ~(1 << XLMAC_CTRL__SOFT_RESET);; ++ val64 &= ~(1 << XLMAC_CTRL__LOCAL_LPBK); ++ val64 |= 1 << XLMAC_CTRL__RX_EN; ++ val64 |= 1 << XLMAC_CTRL__TX_EN; ++ xlmac_reg64_write(XLMAC_CTRL(port), val64); ++ ++ return 0; ++} ++ ++static int __tsc_reset(int in_reset) ++{ ++ u32 val; ++ ++ val = xlport_reg32_read(XLPORT_XGXS0_CTRL_REG); ++ if (in_reset) { ++ //val &= ~(7 << XLPORT_XGXS0_CTRL_REG__RefSel); ++ val |= (1 << XLPORT_XGXS0_CTRL_REG__IDDQ); ++ //val &= ~(1 << XLPORT_XGXS0_CTRL_REG__Refin_EN); ++ val |= 1 << XLPORT_XGXS0_CTRL_REG__PWRDWN; ++ val &= ~(1 << XLPORT_XGXS0_CTRL_REG__RSTB_HW); ++ } else { ++ //val |= (5 << XLPORT_XGXS0_CTRL_REG__RefSel); ++ val &= ~(1 << XLPORT_XGXS0_CTRL_REG__IDDQ); ++ //val |= (1 << XLPORT_XGXS0_CTRL_REG__Refin_EN); ++ val &= ~(1 << XLPORT_XGXS0_CTRL_REG__PWRDWN); ++ //val &= ~(0 << XLPORT_XGXS0_CTRL_REG__RSTB_HW); ++ val |= (1 << XLPORT_XGXS0_CTRL_REG__RSTB_HW); ++ } ++ xlport_reg32_write(XLPORT_XGXS0_CTRL_REG, val); ++ ++ ++/* if (!in_reset) ++ { ++ msleep(1); ++ val |= (1 << XLPORT_XGXS0_CTRL_REG__RSTB_HW); ++ xlport_reg32_write(XLPORT_XGXS0_CTRL_REG, val); ++ } */ ++ msleep(1); ++ return 0; ++} ++ ++static void pm4x10_tsc_config(int port) ++{ ++#ifdef CONFIG_IPROC_EMULATION ++ printf("skip %s... in emulation\n", __func__); ++#else ++ u32 val; ++ int i; ++ ++ /* Global PMD reset controls */ ++ pm_phy_sbus_write(port, 0x9010, 0x0000, 0xffff, 0); ++ udelay(10); ++ pm_phy_sbus_write(port, 0x9010, 0x0003, 0xffff, 0); ++ udelay(10); ++ ++ /* PMD lane reset controls */ ++ for (i=0; i<4; ++i) ++ { ++ pm_phy_sbus_write(i, 0xc010, 0x0000, 0xc003, 0); ++ udelay(10); ++ pm_phy_sbus_write(i, 0xc010, 0xc003, 0xc003, 0); ++ } ++ /* set refclk_sel = 156.25 MHz */ ++ pm_phy_sbus_write(port, 0x9000, 0x0003, 0x0007, 13); ++ /* set heartbeat_count_1us = 0x271 */ ++ pm_phy_sbus_write(port, 0xd0f4, 0x0271, 0x03ff, 0); ++#endif ++ return 0; ++} ++ ++/***************************************************************************** ++*****************************************************************************/ ++static void pm4x10_xlport_mac_enable(int port) ++{ ++ __xlmac_enable_set(port, 1); ++} ++ ++static void pm4x10_xlport_mac_disable(int port) ++{ ++ __xlmac_enable_set(port, 0); ++} ++ ++//static int pm4x10_xlport_speed_set(int port, int speed) ++int pm4x10_xlport_speed_set(int port, int speed) ++{ ++ return __xlmac_speed_set(port, speed); ++} ++ ++//static int pm4x10_xlport_mac_addr_set(int port, u8 *mac) ++int pm4x10_xlport_mac_addr_set(int port, u8 *mac) ++{ ++ return __xlmac_tx_mac_addr_set(port, mac); ++} ++ ++static int pm4x10_xlport_max_packet_size_set(int port, int value) ++{ ++ return __xlmac_rx_max_size_set(port, value); ++} ++ ++//static int pm4x10_xlport_loopback_set(int port, int lb_type, int lb_en) ++int pm4x10_xlport_loopback_set(int port, int lb_type, int lb_en) ++{ ++ u64 val64; ++ u32 val32; ++//printk(" (%s) enter.....port = %d, lb_type = %d, lb_en = %d\n", __func__, port, lb_type, lb_en); ++ ++ switch(lb_type) { ++ case pmLoopbackMac: ++ val64 = xlmac_reg64_read(XLMAC_CTRL(port)); ++ val64 &= ~(1 << XLMAC_CTRL__LOCAL_LPBK); ++ if (lb_en) { ++ printk("(%s) MAC port = %d, lb_en = %d\n", __func__, port, lb_en); ++ val64 |= (1 << XLMAC_CTRL__LOCAL_LPBK); ++ } ++ xlmac_reg64_write(XLMAC_CTRL(port), val64); ++ break; ++ ++ case pmLoopbackPhy: ++ if (lb_en) { ++ printk("(%s) PHY port = %d, lb_en = %d\n", __func__, port, lb_en); ++ pm_phy_sbus_write(port*2, 0x9009, (1 << port*2), 0x000f, 4); /* MAIN0_LOOPBACK_CONTROL */ ++ pm_phy_sbus_write(port*2, 0xc014, 0x0043, 0x0043, 0); /* PMD_X4_OVERRIDE */ ++ pm_phy_sbus_write(port*2, 0xc010, 0x0001, 0x0001, 8); /* PMD_X4_CONTROL */ ++ } else { ++ pm_phy_sbus_write(port*2, 0x9009, 0x0000, 0x000f, 4); /* MAIN0_LOOPBACK_CONTROL */ ++ pm_phy_sbus_write(port*2, 0xc014, 0x0000, 0x0043, 0); /* PMD_X4_OVERRIDE */ ++ pm_phy_sbus_write(port*2, 0xc010, 0x0000, 0x0001, 8); /* PMD_X4_CONTROL */ ++ } ++ break; ++ ++ default: ++ break; ++ } ++ return 0; ++} ++ ++//static int pm4x10_xlport_stats_get(int port, struct iproc_pm_stats *stats) ++int pm4x10_xlport_stats_get(int port, struct iproc_pm_stats *stats) ++{ ++ stats->rx_frames = xlmac_reg64_read(XLMIB_GRxPkt(port)); ++ stats->rx_frame_good = xlmac_reg64_read(XLMIB_GRxPOK(port)); ++ stats->rx_bytes = xlmac_reg64_read(XLMIB_GRxByt(port)); ++ stats->rx_frame_64 = xlmac_reg64_read(XLMIB_GRx64(port)); ++ stats->rx_frame_127 = xlmac_reg64_read(XLMIB_GRx127(port)); ++ stats->rx_frame_255 = xlmac_reg64_read(XLMIB_GRx255(port)); ++ stats->rx_frame_511 = xlmac_reg64_read(XLMIB_GRx511(port)); ++ stats->rx_frame_1023 = xlmac_reg64_read(XLMIB_GRx1023(port)); ++ stats->rx_frame_1518 = xlmac_reg64_read(XLMIB_GRx1518(port)); ++ stats->rx_frame_1522 = xlmac_reg64_read(XLMIB_GRx1522(port)); ++ stats->rx_frame_jumbo = xlmac_reg64_read(XLMIB_GRx2047(port)) + ++ xlmac_reg64_read(XLMIB_GRx4095(port)) + ++ xlmac_reg64_read(XLMIB_GRx9216(port)) + ++ xlmac_reg64_read(XLMIB_GRx16383(port)); ++ stats->rx_frame_unicast = xlmac_reg64_read(XLMIB_GRxUCA(port)); ++ stats->rx_frame_multicast = xlmac_reg64_read(XLMIB_GRxMCA(port)); ++ stats->rx_frame_broadcast = xlmac_reg64_read(XLMIB_GRxBCA(port)); ++ stats->rx_frame_control = xlmac_reg64_read(XLMIB_GRxCF(port)); ++ stats->rx_frame_pause = xlmac_reg64_read(XLMIB_GRxPF(port)); ++ stats->rx_frame_jabber = xlmac_reg64_read(XLMIB_GRxJBR(port)); ++ stats->rx_frame_fragment = xlmac_reg64_read(XLMIB_GRxFRG(port)); ++ stats->rx_frame_vlan = xlmac_reg64_read(XLMIB_GRxVLN(port)); ++ stats->rx_frame_dvlan = xlmac_reg64_read(XLMIB_GRxDVLN(port)); ++ stats->rx_frame_fcs_error = xlmac_reg64_read(XLMIB_GRxFCS(port)); ++ stats->rx_frame_unsupport = xlmac_reg64_read(XLMIB_GRxUO(port)); ++ stats->rx_frame_wrong_sa = xlmac_reg64_read(XLMIB_GRxWSA(port)); ++ stats->rx_frame_align_err = xlmac_reg64_read(XLMIB_GRxALN(port)); ++ stats->rx_frame_length_err = xlmac_reg64_read(XLMIB_GRxFLR(port)); ++ stats->rx_frame_oversize = xlmac_reg64_read(XLMIB_GRxOVR(port)); ++ stats->rx_frame_mtu_err = xlmac_reg64_read(XLMIB_GRxMTUE(port)); ++ stats->rx_frame_truncated_err = xlmac_reg64_read(XLMIB_GRxTRFU(port)); ++ stats->rx_frame_undersize = xlmac_reg64_read(XLMIB_GRxUND(port)); ++ stats->tx_frames = xlmac_reg64_read(XLMIB_GTxPkt(port)); ++ stats->tx_frame_good = xlmac_reg64_read(XLMIB_GTxPOK(port)); ++ stats->tx_bytes = xlmac_reg64_read(XLMIB_GTxBYT(port)); ++ stats->tx_frame_64 = xlmac_reg64_read(XLMIB_GTx64(port)); ++ stats->tx_frame_127 = xlmac_reg64_read(XLMIB_GTx127(port)); ++ stats->tx_frame_255 = xlmac_reg64_read(XLMIB_GTx255(port)); ++ stats->tx_frame_511 = xlmac_reg64_read(XLMIB_GTx511(port)); ++ stats->tx_frame_1023 = xlmac_reg64_read(XLMIB_GTx1023(port)); ++ stats->tx_frame_1518 = xlmac_reg64_read(XLMIB_GTx1518(port)); ++ stats->tx_frame_1522 = xlmac_reg64_read(XLMIB_GTx1522(port)); ++ stats->tx_frame_jumbo = xlmac_reg64_read(XLMIB_GTx2047(port)) + ++ xlmac_reg64_read(XLMIB_GTx4095(port)) + ++ xlmac_reg64_read(XLMIB_GTx9216(port)) + ++ xlmac_reg64_read(XLMIB_GTx16383(port)); ++ stats->tx_frame_unicast = xlmac_reg64_read(XLMIB_GTxUCA(port)); ++ stats->tx_frame_multicast = xlmac_reg64_read(XLMIB_GTxMCA(port)); ++ stats->tx_frame_broadcast = xlmac_reg64_read(XLMIB_GTxBCA(port)); ++ stats->tx_frame_control = xlmac_reg64_read(XLMIB_GTxCF(port)); ++ stats->tx_frame_pause = xlmac_reg64_read(XLMIB_GTxPF(port)); ++ stats->tx_frame_jabber = xlmac_reg64_read(XLMIB_GTxJBR(port)); ++ stats->tx_frame_fragment = xlmac_reg64_read(XLMIB_GTxFRG(port)); ++ stats->tx_frame_vlan = xlmac_reg64_read(XLMIB_GTxVLN(port)); ++ stats->tx_frame_dvlan = xlmac_reg64_read(XLMIB_GTxDVLN(port)); ++ stats->tx_frame_fcs_error = xlmac_reg64_read(XLMIB_GTxFCS(port)); ++ stats->tx_frame_oversize = xlmac_reg64_read(XLMIB_GTxOVR(port)); ++ stats->tx_frame_error = xlmac_reg64_read(XLMIB_GTxErr(port)); ++ stats->tx_frame_fifo_underrun = xlmac_reg64_read(XLMIB_GTxUFL(port)); ++ stats->tx_frame_collision = xlmac_reg64_read(XLMIB_GTxNCL(port)); ++ ++ return 0; ++} ++ ++//static int pm4x10_xlport_mib_reset(int port) ++int pm4x10_xlport_mib_reset(int port) ++{ ++ u32 val; ++ ++ /* MIB reset */ ++ val = xlport_reg32_read(XLPORT_MIB_RESET); ++ val |= (1 << port) << XLPORT_MIB_RESET__CLR_CNT_R; ++ xlport_reg32_write(XLPORT_MIB_RESET, val); ++ ++ val &= ~((1 << port) << XLPORT_MIB_RESET__CLR_CNT_R); ++ xlport_reg32_write(XLPORT_MIB_RESET, val); ++ ++ return 0; ++} ++ ++//static int pm4x10_pm_xlport_port_config(int port, int enable) ++int pm4x10_pm_xlport_port_config(int port, int enable) ++{ ++ u32 val; ++ ++ if (enable) { ++ /* Soft reset */ ++ val = xlport_reg32_read(XLPORT_SOFT_RESET); ++ XLPORT_PORT_FIELD_SET(XLPORT_SOFT_RESET, port, val); ++ xlport_reg32_write(XLPORT_SOFT_RESET, val); ++ ++ XLPORT_PORT_FIELD_CLEAR(XLPORT_SOFT_RESET, port, val); ++ xlport_reg32_write(XLPORT_SOFT_RESET, val); ++ ++ /* Port enable */ ++ val = xlport_reg32_read(XLPORT_ENABLE_REG); ++ XLPORT_PORT_FIELD_SET(XLPORT_ENABLE_REG, port, val); ++ xlport_reg32_write(XLPORT_ENABLE_REG, val); ++ ++ /* Init MAC */ ++ __xlmac_init(port); ++ ++#if 0 //FIXME ++ /* LSS */ ++ val = xlport_reg32_read(XLPORT_FAULT_LINK_STATUS(port)); ++ val |= 1 << XLPORT_FAULT_LINK_STATUS__REMOTE_FAULT; ++ val |= 1 << XLPORT_FAULT_LINK_STATUS__LOCAL_FAULT; ++ xlport_reg32_write(XLPORT_FAULT_LINK_STATUS(port), val); ++#endif /* 0 */ ++ ++ /* MIB reset */ ++ val = xlport_reg32_read(XLPORT_MIB_RESET); ++ val |= (1 << port) << XLPORT_MIB_RESET__CLR_CNT_R; ++ xlport_reg32_write(XLPORT_MIB_RESET, val); ++ ++ val &= ~((1 << port) << XLPORT_MIB_RESET__CLR_CNT_R); ++ xlport_reg32_write(XLPORT_MIB_RESET, val); ++ } else { ++ /* Port disable */ ++ val = xlport_reg32_read(XLPORT_ENABLE_REG); ++ XLPORT_PORT_FIELD_CLEAR(XLPORT_ENABLE_REG, port, val); ++ xlport_reg32_write(XLPORT_ENABLE_REG, val); ++ ++ /* Soft reset */ ++ val = xlport_reg32_read(XLPORT_SOFT_RESET); ++ XLPORT_PORT_FIELD_CLEAR(XLPORT_SOFT_RESET, port, val); ++ xlport_reg32_write(XLPORT_SOFT_RESET, val); ++ } ++ ++ return 0; ++} ++ ++static int pm4x10_pm_disable(void) ++{ ++ u32 val; ++ ++ /* Put MAC in reset */ ++ val = xlport_reg32_read(XLPORT_MAC_CONTROL); ++ val |= 1 << XLPORT_MAC_CONTROL__XMAC0_RESET; ++ xlport_reg32_write(XLPORT_MAC_CONTROL, val); ++ ++ /* Put Serdes in reset*/ ++ __tsc_reset(1); ++ ++ return 0; ++} ++ ++static int pm4x10_pm_enable(void) ++{ ++ u32 val; ++ u32 mask; ++ ++ /* Power Save */ ++ val = xlport_reg32_read(XLPORT_POWER_SAVE); ++ val &= ~(1 << XLPORT_POWER_SAVE__XPORT_CORE0); ++ xlport_reg32_write(XLPORT_POWER_SAVE, val); ++ ++ /* Port configuration */ ++ val = xlport_reg32_read(XLPORT_MODE_REG); ++ mask = (1 << XLPORT_MODE_REG__XPORT0_CORE_PORT_MODE_WIDTH) - 1; ++ val &= ~(mask << XLPORT_MODE_REG__XPORT0_CORE_PORT_MODE_R); ++ val |= (XPORT0_CORE_PORT_MODE_QUAD << XLPORT_MODE_REG__XPORT0_CORE_PORT_MODE_R); ++ mask = (1 << XLPORT_MODE_REG__XPORT0_PHY_PORT_MODE_WIDTH) - 1; ++ val &= ~(mask << XLPORT_MODE_REG__XPORT0_PHY_PORT_MODE_R); ++ val |= (XPORT0_CORE_PORT_MODE_QUAD << XLPORT_MODE_REG__XPORT0_PHY_PORT_MODE_R); ++ xlport_reg32_write(XLPORT_MODE_REG, val); ++ ++ /* Get Serdes OOR */ ++ __tsc_reset(1); ++ __tsc_reset(0); ++ ++ /* Bring MAC OOR */ ++ val = xlport_reg32_read(XLPORT_MAC_CONTROL); ++ val &= ~(1 << XLPORT_MAC_CONTROL__XMAC0_RESET); ++ xlport_reg32_write(XLPORT_MAC_CONTROL, val); ++ ++ return 0; ++} ++ ++int pm4x10_pm_init(struct iproc_pm_ops *pm_ops, u8 land_idx) ++{ ++#if 0 ++ pm_ops = kmalloc(sizeof(struct iproc_pm_ops), GFP_KERNEL); ++ if (!pm_ops) { ++ return -ENOMEM; ++ } ++ pm_ops->port_enable= pm4x10_pm_xlport_port_config; ++ pm_ops->port_speed = pm4x10_xlport_speed_set; ++ pm_ops->port_loopback = pm4x10_xlport_loopback_set; ++ pm_ops->port_mac_addr = pm4x10_xlport_mac_addr_set; ++ pm_ops->port_stats = pm4x10_xlport_stats_get; ++ pm_ops->port_stats_clear = pm4x10_xlport_mib_reset; ++#endif ++ ++#if 0 ++ if (!pm4x10_enabled) /* check initialize for first time */ ++#else ++ if (pm4x10_enabled == 0x100) /* don't do it now */ ++#endif ++ { ++ /* configure TSC registers before download ucode */ ++ pm4x10_tsc_config(land_idx); ++ ++ /* ucode download */ ++ pm_ucode_download(merlin16_ucode, merlin16_ucode_len); ++ ++ /* Configure TSC/merlin16 registers */ ++ pm_phy_configure(land_idx); ++ ++ /* Enable PM4x10 */ ++ pm4x10_pm_enable(); ++ pm4x10_enabled++; ++ } ++ ++ return 0; ++} ++ ++int pm4x10_pm_deinit(struct iproc_pm_ops *pm_ops) ++{ ++#if 0 ++ kfree(pm_ops); ++ pm_ops = NULL; ++#endif ++ pm4x10_enabled--; ++ if (!pm4x10_enabled) { ++ pm4x10_pm_disable(); ++ } ++ ++ return 0; ++} ++ ++#if 0 ++static void pm4x10_xlport_config(int port) ++{ ++ u32 val; ++ u64 val64; ++ ++ /* xlport_mac_config */ ++ val = xlport_reg32_read(XLPORT_ENABLE_REG); ++ val |= ((1 << XLPORT_ENABLE_REG__PORT0) | (1 << XLPORT_ENABLE_REG__PORT2)); ++ xlport_reg32_write(XLPORT_ENABLE_REG, val); ++ debug("%s XLPORT_ENABLE_REG = 0x%x\n", __func__, xlport_reg32_read(XLPORT_ENABLE_REG)); ++ ++ val = xlport_reg32_read(XLPORT_MAC_CONTROL); ++ val &= ~(1 << XLPORT_MAC_CONTROL__XMAC0_RESET); ++ xlport_reg32_write(XLPORT_MAC_CONTROL, val); ++ ++ /* xlport_intr_enable ? */ ++ ++ /* Resetting MIB counter */ ++ xlport_reg32_write(XLPORT_MIB_RESET, 0xf); ++ /* FIXME : delay? */ ++ /* udelay(10); */ ++ xlport_reg32_write(XLPORT_MIB_RESET, 0x0); ++ ++ /* Ethernet mode, 1G */ ++ val64 = xlmac_reg64_read(XLMAC_MODE(port)); ++ val64 &= ~(0x70); ++ val64 |= SPEED_MODE_LINK_1G << XLMAC_MODE__SPEED_MODE_R; ++ xlmac_reg64_write(XLMAC_MODE(port), val64); ++ debug("%s XLMAC_MODE = 0x%llx\n", __func__, xlmac_reg64_read(XLMAC_MODE(port))); ++ ++ val64 = xlmac_reg64_read(XLMAC_RX_CTRL(port)); ++ val64 &= ~(1 << XLMAC_RX_CTRL__STRIP_CRC); ++ xlmac_reg64_write(XLMAC_RX_CTRL(port), val64); ++ debug("%s XLMAC_RX_CTRL = 0x%llx\n", __func__, xlmac_reg64_read(XLMAC_RX_CTRL(port))); ++ ++ val64 = xlmac_reg64_read(XLMAC_TX_CTRL(port)); ++ val64 &= ~(0x3 << XLMAC_TX_CTRL__CRC_MODE_R); ++ val64 |= (CRC_MODE_REPLACE << XLMAC_TX_CTRL__CRC_MODE_R); ++ val64 |= (1 << XLMAC_TX_CTRL__PAD_EN); ++ xlmac_reg64_write(XLMAC_TX_CTRL(port), val64); ++ debug("%s XLMAC_TX_CTRL = 0x%llx\n", __func__, xlmac_reg64_read(XLMAC_TX_CTRL(port))); ++ ++#if 0 ++ val64 = xlmac_reg64_read(XLMAC_CTRL(port)); ++ val64 &= ~(1 << XLMAC_CTRL__SOFT_RESET); ++ val64 |= ((1 << XLMAC_CTRL__RX_EN) | (1 << XLMAC_CTRL__TX_EN)); ++ xlmac_reg64_write(XLMAC_CTRL(port), val64); ++ debug("%s XLMAC_CTRL = 0x%llx\n", __func__, xlmac_reg64_read(XLMAC_CTRL(port))); ++#endif ++} ++#endif /* 0 */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/Kconfig b/drivers/net/phy/Kconfig +--- a/drivers/net/phy/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/net/phy/Kconfig 2018-05-10 11:31:32.077402284 +0800 +@@ -198,6 +198,14 @@ config LED_TRIGGER_PHY + Mbps or Gbps + + ++config MDIO_XGS_IPROC ++ tristate "Broadcom XGS iProc MDIO bus controller" ++ depends on ARCH_XGS_IPROC || COMPILE_TEST ++ depends on HAS_IOMEM && OF_MDIO ++ help ++ This module provides a driver for the MDIO busses found in the ++ Broadcom XGS iProc SoC's. ++ + comment "MII PHY device drivers" + + config SFP +@@ -262,6 +270,12 @@ config BROADCOM_PHY + Currently supports the BCM5411, BCM5421, BCM5461, BCM54616S, BCM5464, + BCM5481, BCM54810 and BCM5482 PHYs. + ++config XGS_IPROC_SERDES ++ tristate "Broadcom XGS iProc SERDES" ++ depends on MDIO_XGS_IPROC ++ ---help--- ++ Supports HX4/KT2/GH2 SERDES. ++ + config CICADA_PHY + tristate "Cicada PHYs" + ---help--- +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/Makefile b/drivers/net/phy/Makefile +--- a/drivers/net/phy/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/net/phy/Makefile 2018-05-10 11:31:32.081402288 +0800 +@@ -38,6 +38,7 @@ obj-$(CONFIG_MDIO_OCTEON) += mdio-octeon + obj-$(CONFIG_MDIO_SUN4I) += mdio-sun4i.o + obj-$(CONFIG_MDIO_THUNDER) += mdio-thunder.o + obj-$(CONFIG_MDIO_XGENE) += mdio-xgene.o ++obj-$(CONFIG_MDIO_XGS_IPROC) += mdio-xgs-iproc-cmicx.o mdio-xgs-iproc-cmicd.o mdio-xgs-iproc-cc.o + + obj-$(CONFIG_SFP) += sfp.o + sfp-obj-$(CONFIG_SFP) += sfp-bus.o +@@ -52,6 +53,7 @@ obj-$(CONFIG_BCM87XX_PHY) += bcm87xx.o + obj-$(CONFIG_BCM_CYGNUS_PHY) += bcm-cygnus.o + obj-$(CONFIG_BCM_NET_PHYLIB) += bcm-phy-lib.o + obj-$(CONFIG_BROADCOM_PHY) += broadcom.o ++obj-$(CONFIG_XGS_IPROC_SERDES) += xgs-iproc-serdes.o + obj-$(CONFIG_CICADA_PHY) += cicada.o + obj-$(CONFIG_CORTINA_PHY) += cortina.o + obj-$(CONFIG_DAVICOM_PHY) += davicom.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/mdio-xgs-iproc-cc.c b/drivers/net/phy/mdio-xgs-iproc-cc.c +--- a/drivers/net/phy/mdio-xgs-iproc-cc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/phy/mdio-xgs-iproc-cc.c 2018-05-10 11:31:32.085402292 +0800 +@@ -0,0 +1,492 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include "mdio-xgs-iproc.h" ++ ++#define MGMT_CTL_REG 0x000 ++#define MGMT_CTL__BYP_SHIFT 10 ++#define MGMT_CTL__BYP_WIDTH 1 ++#define MGMT_CTL__BYP_MASK ((1 << MGMT_CTL__BYP_WIDTH) - 1) ++#define MGMT_CTL__EXT_SHIFT 9 ++#define MGMT_CTL__EXT_WIDTH 1 ++#define MGMT_CTL__EXT_MASK ((1 << MGMT_CTL__EXT_WIDTH) - 1) ++#define MGMT_CTL__BSY_SHIFT 8 ++#define MGMT_CTL__BSY_WIDTH 1 ++#define MGMT_CTL__BSY_MASK ((1 << MGMT_CTL__BSY_WIDTH) - 1) ++#define MGMT_CTL__PRE_SHIFT 7 ++#define MGMT_CTL__PRE_WIDTH 1 ++#define MGMT_CTL__PRE_MASK ((1 << MGMT_CTL__BSY_WIDTH) - 1) ++#define MGMT_CTL__MDCDIV_SHIFT 0 ++#define MGMT_CTL__MDCDIV_WIDTH 7 ++#define MGMT_CTL__MDCDIV_MASK ((1 << MGMT_CTL__MDCDIV_WIDTH) - 1) ++ ++#define MGMT_CMD_DATA_REG 0x004 ++#define MGMT_CMD_DATA__SB_SHIFT 30 ++#define MGMT_CMD_DATA__SB_WIDTH 2 ++#define MGMT_CMD_DATA__SB_MASK ((1 << MGMT_CMD_DATA__SB_WIDTH) - 1) ++#define MGMT_CMD_DATA__OP_SHIFT 28 ++#define MGMT_CMD_DATA__OP_WIDTH 2 ++#define MGMT_CMD_DATA__OP_MASK ((1 << MGMT_CMD_DATA__OP_WIDTH) - 1) ++#define MGMT_CMD_DATA__PA_SHIFT 23 ++#define MGMT_CMD_DATA__PA_WIDTH 5 ++#define MGMT_CMD_DATA__PA_MASK ((1 << MGMT_CMD_DATA__PA_WIDTH) - 1) ++#define MGMT_CMD_DATA__RA_SHIFT 18 ++#define MGMT_CMD_DATA__RA_WIDTH 5 ++#define MGMT_CMD_DATA__RA_MASK ((1 << MGMT_CMD_DATA__RA_WIDTH) - 1) ++#define MGMT_CMD_DATA__TA_SHIFT 16 ++#define MGMT_CMD_DATA__TA_WIDTH 2 ++#define MGMT_CMD_DATA__TA_MASK ((1 << MGMT_CMD_DATA__TA_WIDTH) - 1) ++#define MGMT_CMD_DATA__DATA_SHIFT 0 ++#define MGMT_CMD_DATA__DATA_WIDTH 16 ++#define MGMT_CMD_DATA__DATA_MASK ((1 << MGMT_CMD_DATA__DATA_WIDTH) - 1) ++ ++#define MII_OP_HALT_USEC 10 ++ ++struct cc_mii_cmd { ++ int bus_id; ++ int ext_sel; ++ int phy_id; ++ int regnum; ++ u16 op_mode; ++ u16 val; ++}; ++ ++static struct iproc_mdio_ctrl *cc_mdio_ctrl = NULL; ++ ++/* ++ * For HX4/KT2, the mdio bus is shared with iProc mdio and CMICd mdio ++ * controllers. By default the mdio bus is released to CMICd for SDK to run. ++ * Set kernel argument mdio_bus_release to 0 if ethtool test is required. ++ */ ++static bool mdio_bus_release = true; ++static int __init set_mdio_bus_release(char *str) ++{ ++ return strtobool(str, &mdio_bus_release); ++} ++__setup("mdio_bus_release=", set_mdio_bus_release); ++ ++ ++/* HX4/KT2 need to release mdio bus from iProc to cmicd */ ++bool xgs_mdio_bus_release(void) ++{ ++ if (of_machine_is_compatible("brcm,helix4") || ++ of_machine_is_compatible("brcm,katana2")) ++ return mdio_bus_release; ++ else ++ return 0; ++} ++ ++/* HX4/KT2/SB2 needs to enable iProc mdio bus access, default is cimcd access */ ++static void xgs_iproc_mdio_enable(struct iproc_mdio_ctrl *ctrl, int enable) ++{ ++ void __iomem *iproc_mdio_enable_reg = NULL; ++ u32 iproc_mdio_sel; ++ u32 tmp; ++ ++ if (!ctrl->iproc_mdio_enable_reg) ++ return; ++ ++ iproc_mdio_enable_reg = ctrl->iproc_mdio_enable_reg; ++ iproc_mdio_sel = ctrl->iproc_mdio_sel_bit; ++ ++ tmp = readl(iproc_mdio_enable_reg); ++ ++ if (enable) ++ tmp |= (1 << iproc_mdio_sel); ++ else ++ tmp &= ~(1 << iproc_mdio_sel); ++ ++ writel(tmp, iproc_mdio_enable_reg); ++} ++ ++static inline u32 cc_mii_reg_read(struct iproc_mdio_ctrl *cc_mii, u32 reg) ++{ ++ return readl(cc_mii->base + reg); ++} ++ ++static inline void cc_mii_reg_write(struct iproc_mdio_ctrl *cc_mii, ++ u32 reg, u32 data) ++{ ++ writel(data, cc_mii->base + reg); ++} ++ ++static int cc_mii_busy(struct iproc_mdio_ctrl *cc_mii, int to_usec) ++{ ++ do { ++ if(!GET_REG_FIELD(cc_mii_reg_read(cc_mii, MGMT_CTL_REG), ++ MGMT_CTL__BSY_SHIFT, MGMT_CTL__BSY_MASK)) ++ return 0; ++ ++ udelay(MII_OP_HALT_USEC); ++ to_usec -= MII_OP_HALT_USEC; ++ } while (to_usec > 0); ++ ++ return 1; ++} ++ ++static int do_cc_mii_op(struct iproc_mdio_ctrl *cc_mii, struct cc_mii_cmd *cmd) ++{ ++ u32 cmd_data = 0; ++ u32 mgt_ctrl; ++ u32 op_mode = cmd->op_mode; ++ unsigned long flags; ++ int ret = 0; ++ ++ if (MII_OP_MODE_WRITE == op_mode) { ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__OP_SHIFT, ++ MGMT_CMD_DATA__OP_MASK, 1); ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__DATA_SHIFT, ++ MGMT_CMD_DATA__DATA_MASK, cmd->val); ++ } ++ else if (MII_OP_MODE_READ == op_mode) { ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__OP_SHIFT, ++ MGMT_CMD_DATA__OP_MASK, 2); ++ } ++ else { ++ pr_err("%s : invalid op code %d\n", __func__, op_mode); ++ return -EINVAL; ++ } ++ ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__PA_SHIFT, ++ MGMT_CMD_DATA__PA_MASK, cmd->phy_id); ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__RA_SHIFT, ++ MGMT_CMD_DATA__RA_MASK, cmd->regnum); ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__TA_SHIFT, ++ MGMT_CMD_DATA__TA_MASK, 2); ++ ISET_REG_FIELD(cmd_data, MGMT_CMD_DATA__SB_SHIFT, ++ MGMT_CMD_DATA__SB_MASK, 1); ++ ++ spin_lock_irqsave(&cc_mii->lock, flags); ++ ++ if (cc_mii_busy(cc_mii, MII_OP_MAX_HALT_USEC)) { ++ ret = -EBUSY; ++ pr_err("%s : bus busy (1)\n", __func__); ++ goto err_exit_unlock; ++ } ++ ++ mgt_ctrl = cc_mii_reg_read(cc_mii, MGMT_CTL_REG); ++ if (cmd->ext_sel != GET_REG_FIELD(mgt_ctrl, MGMT_CTL__EXT_SHIFT, ++ MGMT_CTL__EXT_MASK)) { ++ SET_REG_FIELD(mgt_ctrl, MGMT_CTL__EXT_SHIFT, ++ MGMT_CTL__EXT_MASK, cmd->ext_sel); ++ cc_mii_reg_write(cc_mii, MGMT_CTL_REG, mgt_ctrl); ++ } ++ ++ cc_mii_reg_write(cc_mii, MGMT_CMD_DATA_REG, cmd_data); ++ ++ if (cc_mii_busy(cc_mii, MII_OP_MAX_HALT_USEC)) { ++ ret = -EBUSY; ++ pr_err("%s : bus busy (2)\n", __func__); ++ goto err_exit_unlock; ++ } ++ ++ if (MII_OP_MODE_READ == cmd->op_mode) { ++ ret = GET_REG_FIELD(cc_mii_reg_read(cc_mii, MGMT_CMD_DATA_REG), ++ MGMT_CMD_DATA__DATA_SHIFT, MGMT_CMD_DATA__DATA_MASK); ++ } ++ ++ spin_unlock_irqrestore(&cc_mii->lock, flags); ++ ++ return ret; ++ ++err_exit_unlock: ++ spin_unlock_irqrestore(&cc_mii->lock, flags); ++ return ret; ++} ++ ++static int cc_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum) ++{ ++ struct iproc_mdiobus_private *bus_priv = bus->priv; ++ struct iproc_mdiobus_data *bus_data = bus_priv->bus_data; ++ struct cc_mii_cmd cmd = {0}; ++ int ret; ++ ++ xgs_iproc_mdio_enable(bus_priv->hw_ctrl, 1); ++ ++ cmd.bus_id = bus_data->phybus_num; ++ if (IPROC_MDIOBUS_TYPE_EXTERNAL == bus_data->phybus_type) ++ cmd.ext_sel = 1; ++ cmd.phy_id = phy_id; ++ cmd.regnum = regnum; ++ cmd.op_mode = MII_OP_MODE_READ; ++ ++ ret = do_cc_mii_op(bus_priv->hw_ctrl, &cmd); ++ ++ xgs_iproc_mdio_enable(bus_priv->hw_ctrl, 0); ++ ++ return ret; ++} ++ ++static int cc_mdiobus_write(struct mii_bus *bus, int phy_id, ++ int regnum, u16 val) ++{ ++ struct iproc_mdiobus_private *bus_priv = bus->priv; ++ struct iproc_mdiobus_data *bus_data = bus_priv->bus_data; ++ struct cc_mii_cmd cmd = {0}; ++ int ret; ++ ++ xgs_iproc_mdio_enable(bus_priv->hw_ctrl, 1); ++ ++ cmd.bus_id = bus_data->phybus_num; ++ ++ if (IPROC_MDIOBUS_TYPE_EXTERNAL == bus_data->phybus_type) ++ cmd.ext_sel = 1; ++ ++ cmd.phy_id = phy_id; ++ cmd.regnum = regnum; ++ cmd.op_mode = MII_OP_MODE_WRITE; ++ cmd.val = val; ++ ++ ret = do_cc_mii_op(bus_priv->hw_ctrl, &cmd); ++ ++ xgs_iproc_mdio_enable(bus_priv->hw_ctrl, 0); ++ ++ return ret; ++} ++ ++static struct iproc_mdio_ctrl * cc_mdio_res_alloc(void) ++{ ++ if (!cc_mdio_ctrl) { ++ cc_mdio_ctrl = kzalloc(sizeof(*cc_mdio_ctrl), GFP_KERNEL); ++ if (!cc_mdio_ctrl) ++ return NULL; ++ ++ spin_lock_init(&cc_mdio_ctrl->lock); ++ cc_mdio_ctrl->ref_cnt = 1; ++ } ++ else ++ cc_mdio_ctrl->ref_cnt++; ++ ++ return cc_mdio_ctrl; ++} ++ ++static void cc_mdio_res_free(struct iproc_mdio_ctrl *ctrl) ++{ ++ if (ctrl) { ++ ctrl->ref_cnt--; ++ if (ctrl->ref_cnt == 0) { ++ iounmap(ctrl->base); ++ kfree(ctrl); ++ cc_mdio_ctrl = NULL; ++ } ++ } ++} ++ ++static void cc_mii_init(struct iproc_mdio_ctrl *cc_mii, u32 mdio_clk_rate) ++{ ++ u32 val = 0; ++ ++ if(cc_mii->ref_cnt == 1) { ++ /* Set preamble enabled */ ++ ISET_REG_FIELD(val, MGMT_CTL__PRE_SHIFT, MGMT_CTL__PRE_MASK, 1); ++ /* Set the MII clock to 1 MHz */ ++ ISET_REG_FIELD(val, MGMT_CTL__MDCDIV_SHIFT, MGMT_CTL__MDCDIV_MASK, ++ mdio_clk_rate/(1000000)); ++ cc_mii_reg_write(cc_mii, MGMT_CTL_REG, val); ++ } ++} ++ ++static int cc_mdiobus_probe(struct platform_device *pdev) ++{ ++ struct mii_bus *mii_bus; ++ struct device_node *dn = pdev->dev.of_node; ++ struct resource *res; ++ struct iproc_mdiobus_private *bus_priv; ++ struct iproc_mdiobus_data *bus_data; ++ struct iproc_mdio_ctrl *cc_ctrl; ++ u32 mdio_clk_rate; ++ const char *mdio_bus_type; ++ struct clk *clk=NULL; ++ int ret; ++ ++ /* hw_ctrl is shared */ ++ if (cc_mdio_ctrl) ++ goto hw_ctrl_allocated; ++ ++ cc_ctrl = cc_mdio_res_alloc(); ++ if (!cc_ctrl) { ++ dev_err(&pdev->dev, "CC mdio resource alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_exit; ++ } ++ ++ cc_ctrl->base = (void *)of_iomap(dn, 0); ++ if (!cc_ctrl->base) { ++ dev_err(&pdev->dev, "cc mdio register base map error\n"); ++ ret = -ENXIO; ++ goto err_ctrl_free; ++ } ++ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, ++ "iproc-mdio-enable"); ++ if (res) { ++ cc_ctrl->iproc_mdio_enable_reg = ++ devm_ioremap_resource(&pdev->dev, res); ++ if (IS_ERR(cc_ctrl->iproc_mdio_enable_reg)) { ++ ret = PTR_ERR(cc_ctrl->iproc_mdio_enable_reg); ++ goto err_ctrl_free; ++ } ++ } ++ ++ if (cc_ctrl->iproc_mdio_enable_reg) { ++ if (of_property_read_u32(dn, "iproc-mdio-sel-bit", ++ &cc_ctrl->iproc_mdio_sel_bit)) { ++ dev_err(&pdev->dev, "No mdio bus select bit!\n"); ++ ret = -EINVAL; ++ goto err_ctrl_free; ++ } ++ } ++ ++hw_ctrl_allocated: ++ cc_ctrl = cc_mdio_ctrl; ++ ++ clk = of_clk_get(dn, 0); ++ if (clk) { ++ mdio_clk_rate = clk_get_rate(clk) / 2; ++ } else { ++ dev_warn(&pdev->dev, "No CC MDIO clock available in DT, \ ++ use default clock rate: 50MHz\n"); ++ mdio_clk_rate = 50000000; ++ } ++ ++ cc_mii_init(cc_ctrl, mdio_clk_rate); ++ ++ /* If no property available, use default: "internal" */ ++ if (of_property_read_string(dn, "bus-type", &mdio_bus_type)) ++ mdio_bus_type = "internal"; ++ ++ bus_data = devm_kzalloc(&pdev->dev, sizeof(*bus_data), GFP_KERNEL); ++ if (!bus_data) { ++ dev_err(&pdev->dev, "iProc MDIO bus data alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_bus_data_free; ++ } ++ ++ bus_priv = devm_kzalloc(&pdev->dev, sizeof(*bus_priv), GFP_KERNEL); ++ if (!bus_priv) { ++ dev_err(&pdev->dev, "iProc MDIO private data alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_bus_priv_free; ++ } ++ ++ if (!strcmp(mdio_bus_type, "internal")) ++ bus_data->phybus_type = IPROC_MDIOBUS_TYPE_INTERNAL; ++ else ++ bus_data->phybus_type = IPROC_MDIOBUS_TYPE_EXTERNAL; ++ ++ bus_priv->bus_data = bus_data; ++ bus_priv->hw_ctrl = cc_ctrl; ++ ++ mii_bus = mdiobus_alloc(); ++ if (!mii_bus) { ++ dev_err(&pdev->dev, "mdiobus alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_ctrl_free; ++ } ++ ++ mii_bus->name = "iproc_cc_mdiobus"; ++ snprintf(mii_bus->id, MII_BUS_ID_SIZE, "%s-%s", "cc mdio", ++ bus_data->phybus_type? "external":"internal"); ++ mii_bus->parent = &pdev->dev; ++ mii_bus->read = cc_mdiobus_read; ++ mii_bus->write = cc_mdiobus_write; ++ mii_bus->priv = bus_priv; ++ ++ ret = of_mdiobus_register(mii_bus, dn); ++ if (ret) { ++ dev_err(&pdev->dev, "mdiobus register failed\n"); ++ goto err_bus_free; ++ } ++ ++ platform_set_drvdata(pdev, mii_bus); ++ ++ return 0; ++ ++err_bus_free: ++ mdiobus_free(mii_bus); ++err_bus_priv_free: ++ kfree(bus_priv); ++err_bus_data_free: ++ kfree(bus_data); ++err_ctrl_free: ++ cc_mdio_res_free(cc_ctrl); ++err_exit: ++ return ret; ++} ++ ++static int cc_mdiobus_remove(struct platform_device *pdev) ++{ ++ struct mii_bus *mii_bus = platform_get_drvdata(pdev); ++ struct iproc_mdiobus_private *bus_priv; ++ ++ if (mii_bus) { ++ bus_priv = mii_bus->priv; ++ ++ mdiobus_unregister(mii_bus); ++ if (bus_priv) ++ cc_mdio_res_free(bus_priv->hw_ctrl); ++ mdiobus_free(mii_bus); ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id cc_mdio_dt_ids[] = { ++ { .compatible = "brcm,iproc-ccb-mdio"}, ++ { .compatible = "brcm,iproc-ccg-mdio"}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, cc_mdio_dt_ids); ++ ++ ++static struct platform_driver iproc_cc_mdiobus_driver = ++{ ++ .driver = { ++ .name = "iproc_cc_mdio", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(cc_mdio_dt_ids), ++ }, ++ .probe = cc_mdiobus_probe, ++ .remove = cc_mdiobus_remove, ++}; ++ ++static int __init cc_mdio_init(void) ++{ ++ return platform_driver_register(&iproc_cc_mdiobus_driver); ++} ++ ++static void __exit cc_mdio_exit(void) ++{ ++ platform_driver_unregister(&iproc_cc_mdiobus_driver); ++} ++ ++//module_init(cc_mdio_init); ++subsys_initcall(cc_mdio_init); ++module_exit(cc_mdio_exit); ++ ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_DESCRIPTION("iProc CC mdio driver"); ++MODULE_LICENSE("GPL"); ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/mdio-xgs-iproc-cmicd.c b/drivers/net/phy/mdio-xgs-iproc-cmicd.c +--- a/drivers/net/phy/mdio-xgs-iproc-cmicd.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/phy/mdio-xgs-iproc-cmicd.c 2018-05-10 11:31:32.085402292 +0800 +@@ -0,0 +1,457 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mdio-xgs-iproc.h" ++ ++/* CMICD MDIO */ ++#define CMIC_MIIM_PARAM_OFFSET 0x080 ++#define CMIC_MIIM_PARAM_MIIM_CYCLE_R 29 ++#define CMIC_MIIM_PARAM_MIIM_CYCLE_W 3 ++#define CMIC_MIIM_PARAM_INTERNAL_SEL 25 ++#define CMIC_MIIM_PARAM_INTERNAL_SEL_W 1 ++#define CMIC_MIIM_PARAM_BUS_ID_R 22 ++#define CMIC_MIIM_PARAM_BUS_ID_W 3 ++#define CMIC_MIIM_PARAM_C45_SEL 21 ++#define CMIC_MIIM_PARAM_C45_SEL_W 1 ++#define CMIC_MIIM_PARAM_PHY_ID_R 16 ++#define CMIC_MIIM_PARAM_PHY_ID_W 5 ++#define CMIC_MIIM_PARAM_PHY_DATA_R 0 ++#define CMIC_MIIM_PARAM_PHY_DATA_W 16 ++ ++#define CMIC_MIIM_READ_DATA_OFFSET 0x084 ++#define CMIC_MIIM_READ_DATA_DATA_R 0 ++#define CMIC_MIIM_READ_DATA_DATA_W 16 ++ ++#define CMIC_MIIM_ADDR_OFFSET 0x088 ++#define CMIC_MIIM_ADDR_C45_DTYPE_R 16 ++#define CMIC_MIIM_ADDR_C45_DTYPE_W 5 ++#define CMIC_MIIM_ADDR_C45_REGADR_R 0 ++#define CMIC_MIIM_ADDR_C45_REGADR_W 16 ++#define CMIC_MIIM_ADDR_C22_REGADR_R 0 ++#define CMIC_MIIM_ADDR_C22_REGADR_W 5 ++ ++#define CMIC_MIIM_CTRL_OFFSET 0x08c ++#define CMIC_MIIM_CTRL_RD_START 1 ++#define CMIC_MIIM_CTRL_RD_START_W 1 ++#define CMIC_MIIM_CTRL_WR_START 0 ++#define CMIC_MIIM_CTRL_WR_START_W 1 ++ ++#define CMIC_MIIM_STAT_OFFSET 0x090 ++#define CMIC_MIIM_STAT_OPN_DONE 0 ++#define CMIC_MIIM_STAT_OPN_DONE_W 1 ++ ++#define CMIC_COMMON_UC0_PIO_ENDIANESS 0x1F0 ++ ++#define MIIM_PARAM_REG CMIC_MIIM_PARAM_OFFSET ++#define MIIM_PARAM_MIIM_CYCLE_SHIFT CMIC_MIIM_PARAM_MIIM_CYCLE_R ++#define MIIM_PARAM_MIIM_CYCLE_MASK ((1 << CMIC_MIIM_PARAM_MIIM_CYCLE_W)-1) ++#define MIIM_PARAM_INTERNAL_SEL_SHIFT CMIC_MIIM_PARAM_INTERNAL_SEL ++#define MIIM_PARAM_INTERNAL_SEL_MASK ((1<base + reg); ++#if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) ++ if (readl(cmic_mdio->base + CMIC_COMMON_UC0_PIO_ENDIANESS) != 0) ++ /* CMICD is in big-endian mode */ ++ value = swab32(value); ++#endif ++ return value; ++} ++ ++static inline void cmicd_miim_reg_write(struct iproc_mdio_ctrl *cmic_mdio, ++ u32 reg, u32 data) ++{ ++ u32 value = data; ++#if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) ++ if (readl(cmic_mdio->base + CMIC_COMMON_UC0_PIO_ENDIANESS) != 0) ++ /* CMICD is in big-endian mode */ ++ value = swab32(data); ++#endif ++ writel(value, cmic_mdio->base + reg); ++} ++ ++static inline void cmicd_miim_set_op_read(u32 *data, u32 set) ++{ ++ SET_REG_FIELD(*data, MIIM_CTRL_RD_START_SHIFT, ++ MIIM_CTRL_RD_START_MASK, set); ++} ++ ++static inline void cmicd_miim_set_op_write(u32 *data, u32 set) ++{ ++ SET_REG_FIELD(*data, MIIM_CTRL_WR_START_SHIFT, ++ MIIM_CTRL_WR_START_MASK, set); ++} ++ ++static int do_cmicd_miim_op(struct iproc_mdio_ctrl *cmic_mdio, u32 op, ++ u32 param, u32 addr) ++{ ++ u32 val, op_done; ++ unsigned long flags; ++ int ret = 0; ++ int usec = MII_OP_MAX_HALT_USEC; ++ ++ if (op >= MII_OP_MODE_MAX) { ++ pr_err("%s : invalid op code %d\n", __func__, op); ++ return -EINVAL; ++ } ++ ++ spin_lock_irqsave(&cmic_mdio->lock, flags); ++ ++ cmicd_miim_reg_write(cmic_mdio, MIIM_PARAM_REG, param); ++ cmicd_miim_reg_write(cmic_mdio, MIIM_ADDRESS_REG, addr); ++ val = cmicd_miim_reg_read(cmic_mdio, MIIM_CTRL_REG); ++ if(op == MII_OP_MODE_READ) ++ cmicd_miim_set_op_read(&val, 1); ++ else ++ cmicd_miim_set_op_write(&val, 1); ++ cmicd_miim_reg_write(cmic_mdio, MIIM_CTRL_REG, val); ++ ++ do { ++ op_done = GET_REG_FIELD( ++ cmicd_miim_reg_read(cmic_mdio, MIIM_STAT_REG), ++ MIIM_STAT_OPN_DONE_SHIFT, ++ MIIM_STAT_OPN_DONE_MASK); ++ if (op_done) ++ break; ++ ++ udelay(1); ++ } while (usec-- > 0); ++ ++ if (op_done) { ++ if(op == MII_OP_MODE_READ) ++ ret = cmicd_miim_reg_read(cmic_mdio, MIIM_READ_DATA_REG); ++ } else { ++ ret = -ETIME; ++ } ++ ++ val = cmicd_miim_reg_read(cmic_mdio, MIIM_CTRL_REG); ++ if(op == MII_OP_MODE_READ) ++ cmicd_miim_set_op_read(&val, 0); ++ else ++ cmicd_miim_set_op_write(&val, 0); ++ cmicd_miim_reg_write(cmic_mdio, MIIM_CTRL_REG, val); ++ ++ spin_unlock_irqrestore(&cmic_mdio->lock, flags); ++ ++ return ret; ++} ++ ++ ++static int cmicd_miim_op(struct iproc_mdio_ctrl *cmic_mdio, ++ struct cmicd_miim_cmd *cmd) ++{ ++ u32 miim_param =0, miim_addr = 0; ++ ++ ISET_REG_FIELD(miim_param, MIIM_PARAM_BUS_ID_SHIFT, ++ MIIM_PARAM_BUS_ID_MASK, cmd->bus_id); ++ ++ if (cmd->int_sel) ++ ISET_REG_FIELD(miim_param, MIIM_PARAM_INTERNAL_SEL_SHIFT, ++ MIIM_PARAM_INTERNAL_SEL_MASK, 1); ++ ++ ISET_REG_FIELD(miim_param, MIIM_PARAM_PHY_ID_SHIFT, ++ MIIM_PARAM_PHY_ID_MASK, cmd->phy_id); ++ ++ if (cmd->op_mode == MII_OP_MODE_WRITE) ++ ISET_REG_FIELD(miim_param, MIIM_PARAM_PHY_DATA_SHIFT, ++ MIIM_PARAM_PHY_DATA_MASK, cmd->val); ++ ++ if (cmd->c45_sel) { ++ ISET_REG_FIELD(miim_param, MIIM_PARAM_C45_SEL_SHIFT, ++ MIIM_PARAM_C45_SEL_MASK, 1); ++ ISET_REG_FIELD(miim_addr, MIIM_ADDR_C45_REGADR_SHIFT, ++ MIIM_ADDR_C45_REGADR_MASK, cmd->regnum); ++ ISET_REG_FIELD(miim_addr, MIIM_ADDR_C45_DTYPE_SHIFT, ++ MIIM_ADDR_C45_REGADR_MASK, cmd->regnum >> 16); ++ } ++ else { ++ ISET_REG_FIELD(miim_addr, MIIM_ADDR_C22_REGADR_SHIFT, ++ MIIM_ADDR_C22_REGADR_MASK, cmd->regnum); ++ } ++ ++ return do_cmicd_miim_op(cmic_mdio, cmd->op_mode, miim_param, miim_addr); ++} ++ ++ ++static int cmicd_mdiobus_read(struct mii_bus *bus, int phy_id, int regnum) ++{ ++ struct iproc_mdiobus_private *bus_priv = bus->priv; ++ struct iproc_mdiobus_data *bus_data = bus_priv->bus_data; ++ struct cmicd_miim_cmd cmd = {0}; ++ ++ cmd.bus_id = bus_data->phybus_num; ++ if (IPROC_MDIOBUS_TYPE_INTERNAL == bus_data->phybus_type) ++ cmd.int_sel = 1; ++ cmd.phy_id = phy_id; ++ cmd.regnum = regnum; ++ ++ if (regnum & MII_ADDR_C45) ++ cmd.c45_sel = 1; ++ ++ cmd.op_mode = MII_OP_MODE_READ; ++ ++ return cmicd_miim_op(bus_priv->hw_ctrl, &cmd); ++} ++ ++static int cmicd_mdiobus_write(struct mii_bus *bus, int phy_id, ++ int regnum, u16 val) ++{ ++ struct iproc_mdiobus_private *bus_priv = bus->priv; ++ struct iproc_mdiobus_data *bus_data = bus_priv->bus_data; ++ struct cmicd_miim_cmd cmd = {0}; ++ ++ cmd.bus_id = bus_data->phybus_num; ++ if (IPROC_MDIOBUS_TYPE_INTERNAL == bus_data->phybus_type) ++ cmd.int_sel = 1; ++ cmd.phy_id = phy_id; ++ cmd.regnum = regnum; ++ cmd.val = val; ++ ++ if (regnum & MII_ADDR_C45) ++ cmd.c45_sel = 1; ++ ++ cmd.op_mode = MII_OP_MODE_WRITE; ++ ++ return cmicd_miim_op(bus_priv->hw_ctrl, &cmd); ++} ++ ++static struct iproc_mdio_ctrl * cmicd_mdio_res_alloc(void) ++{ ++ if (!cmic_common) { ++ cmic_common = kzalloc(sizeof(*cmic_common), GFP_KERNEL); ++ if (!cmic_common) ++ return NULL; ++ spin_lock_init(&cmic_common->lock); ++ cmic_common->ref_cnt = 1; ++ } ++ else ++ cmic_common->ref_cnt++; ++ ++ return cmic_common; ++} ++ ++static void cmicd_mdio_res_free(struct iproc_mdio_ctrl *ctrl) ++{ ++ if (ctrl) { ++ ctrl->ref_cnt--; ++ if (ctrl->ref_cnt == 0) { ++ iounmap(ctrl->base); ++ kfree(ctrl); ++ cmic_common = NULL; ++ } ++ } ++} ++ ++static int cmicd_mdiobus_probe(struct platform_device *pdev) ++{ ++ struct mii_bus *mii_bus; ++ struct device_node *dn = pdev->dev.of_node; ++ struct iproc_mdiobus_private *bus_priv; ++ struct iproc_mdiobus_data *bus_data; ++ struct iproc_mdio_ctrl *cmicd_ctrl; ++ u32 mdio_bus_id; ++ const char *mdio_bus_type; ++ int ret; ++ ++ cmicd_ctrl = cmicd_mdio_res_alloc(); ++ if (!cmicd_ctrl) { ++ dev_err(&pdev->dev, "cmicd mdio resource alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_exit; ++ } ++ ++ /* Get register base address for the first mdio node only */ ++ if (!cmicd_ctrl->base) ++ cmicd_ctrl->base = of_iomap(dn, 0); ++ if (!cmicd_ctrl->base) { ++ dev_err(&pdev->dev, "cmicd mdio register base map error\n"); ++ ret = -ENXIO; ++ goto err_ctrl_free; ++ } ++ ++ /* If no property available, use default: 2 */ ++ if (of_property_read_u32(dn, "#bus-id", &mdio_bus_id)) ++ mdio_bus_id = 2; ++ ++ /* If no property available, use default: "external" */ ++ if (of_property_read_string(dn, "bus-type", &mdio_bus_type)) ++ mdio_bus_type = "external"; ++ ++ bus_data = devm_kzalloc(&pdev->dev, sizeof(*bus_data), GFP_KERNEL); ++ if (!bus_data) { ++ dev_err(&pdev->dev, "iProc MDIO bus data alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_bus_data_free; ++ } ++ ++ bus_priv = devm_kzalloc(&pdev->dev, sizeof(*bus_priv), GFP_KERNEL); ++ if (!bus_priv) { ++ dev_err(&pdev->dev, "iProc MDIO private data alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_bus_priv_free; ++ } ++ ++ bus_data->phybus_num = mdio_bus_id; ++ if (!strcmp(mdio_bus_type, "internal")) ++ bus_data->phybus_type = IPROC_MDIOBUS_TYPE_INTERNAL; ++ else ++ bus_data->phybus_type = IPROC_MDIOBUS_TYPE_EXTERNAL; ++ ++ bus_priv->bus_data = bus_data; ++ bus_priv->hw_ctrl = cmicd_ctrl; ++ ++ mii_bus = mdiobus_alloc(); ++ if (!mii_bus) { ++ dev_err(&pdev->dev, "mdiobus_alloc failed\n"); ++ ret = -ENOMEM; ++ goto err_ctrl_free; ++ } ++ ++ mii_bus->name = "iproc_cmicd_mdiobus"; ++ snprintf(mii_bus->id, MII_BUS_ID_SIZE, "%s-%d-%d", "cmicd mdio", ++ mdio_bus_id, bus_data->phybus_type? 1:0); ++ mii_bus->parent = &pdev->dev; ++ mii_bus->read = cmicd_mdiobus_read; ++ mii_bus->write = cmicd_mdiobus_write; ++ mii_bus->priv = bus_priv; ++ ++ ret = of_mdiobus_register(mii_bus, dn); ++ if (ret) { ++ dev_err(&pdev->dev, "mdiobus register failed\n"); ++ goto err_bus_free; ++ } ++ ++ platform_set_drvdata(pdev, mii_bus); ++ ++ return 0; ++ ++err_bus_free: ++ mdiobus_free(mii_bus); ++err_bus_priv_free: ++ kfree(bus_priv); ++err_bus_data_free: ++ kfree(bus_data); ++err_ctrl_free: ++ cmicd_mdio_res_free(cmicd_ctrl); ++err_exit: ++ return ret; ++} ++ ++static int cmicd_mdiobus_remove(struct platform_device *pdev) ++{ ++ struct mii_bus *mii_bus = platform_get_drvdata(pdev); ++ struct iproc_mdiobus_private *bus_priv; ++ ++ if (mii_bus) { ++ bus_priv = mii_bus->priv; ++ ++ mdiobus_unregister(mii_bus); ++ if (bus_priv) ++ cmicd_mdio_res_free(bus_priv->hw_ctrl); ++ mdiobus_free(mii_bus); ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id cmicd_mdio_dt_ids[] = { ++ { .compatible = "brcm,iproc-cmicd-mdio"}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, cmicd_mdio_dt_ids); ++ ++static struct platform_driver iproc_cmicd_mdiobus_driver = ++{ ++ .driver = { ++ .name = "iproc_cmicd_mdio", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(cmicd_mdio_dt_ids), ++ }, ++ .probe = cmicd_mdiobus_probe, ++ .remove = cmicd_mdiobus_remove, ++}; ++ ++static int __init cmicd_mdio_init(void) ++{ ++ return platform_driver_register(&iproc_cmicd_mdiobus_driver); ++} ++ ++static void __exit cmicd_mdio_exit(void) ++{ ++ platform_driver_unregister(&iproc_cmicd_mdiobus_driver); ++} ++ ++//module_init(cmicd_mdio_init); ++subsys_initcall(cmicd_mdio_init); ++module_exit(cmicd_mdio_exit); ++ ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_DESCRIPTION("iProc CMICd mdio driver"); ++MODULE_LICENSE("GPL"); ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/mdio-xgs-iproc-cmicx.c b/drivers/net/phy/mdio-xgs-iproc-cmicx.c +--- a/drivers/net/phy/mdio-xgs-iproc-cmicx.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/phy/mdio-xgs-iproc-cmicx.c 2018-05-30 15:50:51.032753168 +0800 +@@ -0,0 +1,543 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "mdio-xgs-iproc.h" ++ ++#define MIIM_CH0_CONTROL_REG 0x000 ++#define MIIM_CH1_CONTROL_REG 0x010 ++#define MIIM_CH2_CONTROL_REG 0x020 ++#define MIIM_CH3_CONTROL_REG 0x030 ++#define MIIM_CONTROL__START_SHIFT 0 ++#define MIIM_CONTROL__START_WIDTH 1 ++#define MIIM_CONTROL__START_MASK ((1 << MIIM_CONTROL__START_WIDTH) - 1) ++#define MIIM_CH0_PARAMS_REG 0x004 ++#define MIIM_CH1_PARAMS_REG 0x014 ++#define MIIM_CH2_PARAMS_REG 0x024 ++#define MIIM_CH3_PARAMS_REG 0x034 ++#define MIIM_PARAMS__RING_MAP_SHIFT 20 ++#define MIIM_PARAMS__RING_MAP_WIDTH 12 ++#define MIIM_PARAMS__RING_MAP_MASK ((1 << MIIM_PARAMS__RING_MAP_WIDTH) - 1) ++#define MIIM_PARAMS__MDIO_OP_TYPE_SHIFT 17 ++#define MIIM_PARAMS__MDIO_OP_TYPE_WIDTH 3 ++#define MIIM_PARAMS__MDIO_OP_TYPE_MASK ((1 << MIIM_PARAMS__MDIO_OP_TYPE_WIDTH) - 1) ++#define CLAUSE_22_WRITE_OP_MODE 0x0 ++#define CLAUSE_22_READ_OP_MODE 0x1 ++#define CLAUSE_45_WRITE_OP_MODE 0x5 ++#define CLAUSE_45_READ_OP_MODE 0x6 ++#define MIIM_PARAMS__SEL_INT_PHY_SHIFT 16 ++#define MIIM_PARAMS__SEL_INT_PHY_WIDTH 1 ++#define MIIM_PARAMS__SEL_INT_PHY_MASK ((1 << MIIM_PARAMS__SEL_INT_PHY_WIDTH) - 1) ++#define MIIM_PARAMS__PHY_WR_DATA_SHIFT 0 ++#define MIIM_PARAMS__PHY_WR_DATA_WIDTH 16 ++#define MIIM_PARAMS__PHY_WR_DATA_MASK ((1 << MIIM_PARAMS__PHY_WR_DATA_WIDTH) - 1) ++#define MIIM_CH0_ADDRESS_REG 0x008 ++#define MIIM_CH1_ADDRESS_REG 0x018 ++#define MIIM_CH2_ADDRESS_REG 0x028 ++#define MIIM_CH3_ADDRESS_REG 0x038 ++#define MIIM_ADDRESS__C45_REGADDR_SHIFT 16 ++#define MIIM_ADDRESS__C45_REGADDR_WIDTH 16 ++#define MIIM_ADDRESS__C45_REGADDR_MASK ((1 << MIIM_ADDRESS__C45_REGADDR_WIDTH) - 1) ++#define MIIM_ADDRESS__C22_REGADDR_C45_DTYPE_SHIFT 11 ++#define MIIM_ADDRESS__C22_REGADDR_C45_DTYPE_WIDTH 5 ++#define MIIM_ADDRESS__C22_REGADDR_C45_DTYPE_MASK ((1 << MIIM_ADDRESS__C22_REGADDR_C45_DTYPE_WIDTH) - 1) ++#define MIIM_ADDRESS__PHY_ID_SHIFT 6 ++#define MIIM_ADDRESS__PHY_ID_WIDTH 5 ++#define MIIM_ADDRESS__PHY_ID_MASK ((1 << MIIM_ADDRESS__PHY_ID_WIDTH) - 1) ++#define MIIM_CH0_STATUS_REG 0x00c ++#define MIIM_CH1_STATUS_REG 0x01c ++#define MIIM_CH2_STATUS_REG 0x02c ++#define MIIM_CH3_STATUS_REG 0x03c ++#define MIIM_STATUS__DONE_SHIFT 18 ++#define MIIM_STATUS__DONE_WIDTH 1 ++#define MIIM_STATUS__DONE_MASK ((1 << MIIM_STATUS__DONE_WIDTH) - 1) ++#define MIIM_STATUS__ERROR_SHIFT 17 ++#define MIIM_STATUS__ERROR_WIDTH 1 ++#define MIIM_STATUS__ERROR_MASK ((1 << MIIM_STATUS__ERROR_WIDTH) - 1) ++#define MIIM_STATUS__ACTIVE_SHIFT 16 ++#define MIIM_STATUS__ACTIVE_WIDTH 1 ++#define MIIM_STATUS__ACTIVE_MASK ((1 << MIIM_STATUS__ACTIVE_WIDTH) - 1) ++#define MIIM_STATUS__PHY_RD_DATA_SHIFT 0 ++#define MIIM_STATUS__PHY_RD_DATA_WIDTH 16 ++#define MIIM_STATUS__PHY_RD_DATA_MASK ((1 << MIIM_STATUS__PHY_RD_DATA_WIDTH) - 1) ++#define MIIM_RING0_CONTROL_REG 0x0f0 ++#define MIIM_RING1_CONTROL_REG 0x0f4 ++#define MIIM_RING2_CONTROL_REG 0x0f8 ++#define MIIM_RING3_CONTROL_REG 0x0fc ++#define MIIM_RING4_CONTROL_REG 0x100 ++#define MIIM_RING5_CONTROL_REG 0x104 ++#define MIIM_RING6_CONTROL_REG 0x108 ++#define MIIM_RING7_CONTROL_REG 0x10c ++#define MIIM_RING8_CONTROL_REG 0x110 ++#define MIIM_RING9_CONTROL_REG 0x114 ++#define MIIM_RING10_CONTROL_REG 0x118 ++#define MIIM_RING11_CONTROL_REG 0x11c ++#define MIIM_RING_CTRL__MDC_MODE_SHIFT 26 ++#define MIIM_RING_CTRL__MDC_MODE_WIDTH 1 ++#define MIIM_RING_CTRL__MDC_MODE_MASK ((1 << MIIM_RING_CTRL__MDC_MODE_WIDTH) - 1) ++#define MIIM_RING_CTRL__PREAMBLE_SHIFT 24 ++#define MIIM_RING_CTRL__PREAMBLE_WIDTH 2 ++#define MIIM_RING_CTRL__PREAMBLE_MASK ((1 << MIIM_RING_CTRL__PREAMBLE_WIDTH) - 1) ++#define MIIM_RING_CTRL__MDIO_OUT_DELAY_SHIFT 16 ++#define MIIM_RING_CTRL__MDIO_OUT_DELAY_WIDTH 8 ++#define MIIM_RING_CTRL__MDIO_OUT_DELAY_MASK ((1 << MIIM_RING_CTRL__MDIO_OUT_DELAY_WIDTH) - 1) ++#define MIIM_RING_CTRL__CLOCK_DIVIDER_EXT_SHIFT 8 ++#define MIIM_RING_CTRL__CLOCK_DIVIDER_EXT_WIDTH 8 ++#define MIIM_RING_CTRL__CLOCK_DIVIDER_EXT_MASK ((1 << MIIM_RING_CTRL__CLOCK_DIVIDER_EXT_WIDTH) - 1) ++#define MIIM_RING_CTRL__CLOCK_DIVIDER_INT_SHIFT 0 ++#define MIIM_RING_CTRL__CLOCK_DIVIDER_INT_WIDTH 8 ++#define MIIM_RING_CTRL__CLOCK_DIVIDER_INT_MASK ((1 << MIIM_RING_CTRL__CLOCK_DIVIDER_INT_WIDTH) - 1) ++#define MIIM_COMMON_CONTROL_REG 0x140 ++#define MIIM_COMM_CTRL__EXT_MDIO_MSTR_CNTRL_SHIFT 0 ++#define MIIM_COMM_CTRL__EXT_MDIO_MSTR_CNTRL_WIDTH 1 ++#define MIIM_COMM_CTRL__EXT_MDIO_MSTR_CNTRL_MASK ((1 << MIIM_COMM_CTRL__EXT_MDIO_MSTR_CNTRL_WIDTH) - 1) ++ ++#define MIIM_MAX_RINGS 12 ++ ++struct cmicx_miim_cmd { ++ u32 bus_id; ++ u32 int_sel; ++ u32 phy_id; ++ u32 reg_num; ++ u32 c45_sel; ++ u16 op_mode; ++ u16 phy_data; ++}; ++ ++static inline u32 cmicx_miim_read(struct iproc_mdio_ctrl *mdio_ctrl, u32 reg) ++{ ++ return readl(mdio_ctrl->base + reg); ++} ++ ++static inline void cmicx_miim_write(struct iproc_mdio_ctrl *mdio_ctrl, ++ u32 reg, u32 data) ++{ ++ writel(data, mdio_ctrl->base + reg); ++} ++ ++static int cmicx_miim_init(struct iproc_mdio_ctrl *mdio_ctrl) ++{ ++ u32 val; ++ u32 mstr_ctrl; ++ ++ /* Give MDIO control to IPROC */ ++ val = cmicx_miim_read(mdio_ctrl, MIIM_COMMON_CONTROL_REG); ++ mstr_ctrl = GET_REG_FIELD(val, MIIM_COMM_CTRL__EXT_MDIO_MSTR_CNTRL_SHIFT, ++ MIIM_COMM_CTRL__EXT_MDIO_MSTR_CNTRL_MASK); ++ if (!mstr_ctrl) { ++ ISET_REG_FIELD(val, MIIM_COMM_CTRL__EXT_MDIO_MSTR_CNTRL_SHIFT, ++ MIIM_COMM_CTRL__EXT_MDIO_MSTR_CNTRL_MASK, 1); ++ cmicx_miim_write(mdio_ctrl, MIIM_COMMON_CONTROL_REG, val); ++ } ++ return 0; ++} ++ ++static int cmicx_miim_ring_init(struct iproc_mdio_ctrl *mdio_ctrl, u32 ring_idx, ++ int int_divider, int ext_divider, int out_delay) ++{ ++ u32 ring_ctrl_reg[] = { MIIM_RING0_CONTROL_REG, ++ MIIM_RING1_CONTROL_REG, ++ MIIM_RING2_CONTROL_REG, ++ MIIM_RING3_CONTROL_REG, ++ MIIM_RING4_CONTROL_REG, ++ MIIM_RING5_CONTROL_REG, ++ MIIM_RING6_CONTROL_REG, ++ MIIM_RING7_CONTROL_REG, ++ MIIM_RING8_CONTROL_REG, ++ MIIM_RING9_CONTROL_REG, ++ MIIM_RING10_CONTROL_REG, ++ MIIM_RING11_CONTROL_REG }; ++ u32 val; ++ ++ if (ring_idx >= MIIM_MAX_RINGS) { ++ return -EINVAL; ++ } ++ ++ val = cmicx_miim_read(mdio_ctrl, ring_ctrl_reg[ring_idx]); ++ if (int_divider != -1) { ++ ISET_REG_FIELD(val, MIIM_RING_CTRL__CLOCK_DIVIDER_INT_SHIFT, ++ MIIM_RING_CTRL__CLOCK_DIVIDER_INT_MASK, int_divider); ++ } ++ if (ext_divider != -1) { ++ ISET_REG_FIELD(val, MIIM_RING_CTRL__CLOCK_DIVIDER_EXT_SHIFT, ++ MIIM_RING_CTRL__CLOCK_DIVIDER_EXT_MASK, ext_divider); ++ } ++ if (out_delay != -1) { ++ ISET_REG_FIELD(val, MIIM_RING_CTRL__MDIO_OUT_DELAY_SHIFT, ++ MIIM_RING_CTRL__MDIO_OUT_DELAY_MASK, out_delay); ++ } ++ cmicx_miim_write(mdio_ctrl, ring_ctrl_reg[ring_idx], val); ++ ++ return 0; ++} ++ ++static int cmicx_miim_operation(struct iproc_mdio_ctrl *mdio_ctrl, ++ struct cmicx_miim_cmd *miim_cmd) ++{ ++ unsigned long flags; ++ u32 is_done, is_error; ++ u32 optype = 0; ++ u32 val; ++ int usec = MII_OP_MAX_HALT_USEC; ++ int ret = 0,bus_id = miim_cmd->bus_id; ++ ++ spin_lock_irqsave(&mdio_ctrl->lock, flags); ++ ++ /* prepare transaction data */ ++ //val = cmicx_miim_read(mdio_ctrl, (MIIM_CH0_ADDRESS_REG + 0x10 * bus_id)); ++ val = 0; ++ ISET_REG_FIELD(val, MIIM_ADDRESS__PHY_ID_SHIFT, ++ MIIM_ADDRESS__PHY_ID_MASK, miim_cmd->phy_id); ++ if (miim_cmd->c45_sel) { ++ ISET_REG_FIELD(val, MIIM_ADDRESS__C45_REGADDR_SHIFT, ++ MIIM_ADDRESS__C45_REGADDR_MASK, miim_cmd->reg_num); ++ ISET_REG_FIELD(val, MIIM_ADDRESS__C22_REGADDR_C45_DTYPE_SHIFT, ++ MIIM_ADDRESS__C22_REGADDR_C45_DTYPE_MASK, (miim_cmd->reg_num >> 16)); ++ } else { ++ ISET_REG_FIELD(val, MIIM_ADDRESS__C22_REGADDR_C45_DTYPE_SHIFT, ++ MIIM_ADDRESS__C22_REGADDR_C45_DTYPE_MASK, miim_cmd->reg_num); ++ } ++ //cmicx_miim_write(mdio_ctrl, MIIM_CH1_ADDRESS_REG, val); ++ cmicx_miim_write(mdio_ctrl, (MIIM_CH0_ADDRESS_REG + 0x10 * bus_id), val); ++ ++ /* _SOC_IF_ERR_EXIT(READ_MIIM_CH0_PARAMSr(unit, ®_val)); */ ++ //val = cmicx_miim_read(mdio_ctrl, (MIIM_CH0_PARAMS_REG + 0x10 * bus_id)); ++ val = 0; ++ ISET_REG_FIELD(val, MIIM_PARAMS__PHY_WR_DATA_SHIFT, ++ MIIM_PARAMS__PHY_WR_DATA_MASK, miim_cmd->phy_data); ++ ISET_REG_FIELD(val, MIIM_PARAMS__SEL_INT_PHY_SHIFT, ++ MIIM_PARAMS__SEL_INT_PHY_MASK, miim_cmd->int_sel); ++ ISET_REG_FIELD(val, MIIM_PARAMS__RING_MAP_SHIFT, ++ MIIM_PARAMS__RING_MAP_MASK, (1 << miim_cmd->bus_id)); ++ if (miim_cmd->c45_sel) { ++ optype = CLAUSE_45_READ_OP_MODE; ++ if (miim_cmd->op_mode == MII_OP_MODE_WRITE) { ++ optype = CLAUSE_45_WRITE_OP_MODE; ++ } ++ } else { ++ optype = CLAUSE_22_READ_OP_MODE; ++ if (miim_cmd->op_mode == MII_OP_MODE_WRITE) { ++ optype = CLAUSE_22_WRITE_OP_MODE; ++ } ++ } ++ ISET_REG_FIELD(val, MIIM_PARAMS__MDIO_OP_TYPE_SHIFT, ++ MIIM_PARAMS__MDIO_OP_TYPE_MASK, optype); ++ //cmicx_miim_write(mdio_ctrl, MIIM_CH1_PARAMS_REG, val); ++ cmicx_miim_write(mdio_ctrl, (MIIM_CH0_PARAMS_REG + 0x10 * bus_id), val); ++ ++ /* start transaction */ ++ val = 0; ++ ISET_REG_FIELD(val, MIIM_CONTROL__START_SHIFT, ++ MIIM_CONTROL__START_MASK, 0x1); ++ //cmicx_miim_write(mdio_ctrl, MIIM_CH1_CONTROL_REG, val); ++ cmicx_miim_write(mdio_ctrl, (MIIM_CH0_CONTROL_REG + 0x10 * bus_id), val); ++ ++ /* poll for DONE bit */ ++ do { ++ //val = cmicx_miim_read(mdio_ctrl, MIIM_CH1_STATUS_REG); ++ val = cmicx_miim_read(mdio_ctrl, (MIIM_CH0_STATUS_REG + 0x10 * bus_id)); ++ is_done = GET_REG_FIELD(val, MIIM_STATUS__DONE_SHIFT, MIIM_STATUS__DONE_MASK); ++ if (is_done) { ++ break; /* MIIM operation is done */ ++ } ++ ++ udelay(1); ++ } while (usec-- > 0); ++ ++ /* check for transaction error */ ++ //val = cmicx_miim_read(mdio_ctrl, MIIM_CH1_STATUS_REG); ++ val = cmicx_miim_read(mdio_ctrl, (MIIM_CH0_STATUS_REG + 0x10 * bus_id)); ++ is_error = GET_REG_FIELD(val, MIIM_STATUS__ERROR_SHIFT, MIIM_STATUS__ERROR_MASK); ++ if (is_error) { ++ printk(KERN_ERR "%s : mdio execution error.\n", __func__); ++ ret = -EIO; ++ goto exit; ++ } ++ ++ /* in case of read - get data */ ++ if (miim_cmd->op_mode == MII_OP_MODE_READ) { ++ miim_cmd->phy_data = GET_REG_FIELD(val, MIIM_STATUS__PHY_RD_DATA_SHIFT, ++ MIIM_STATUS__PHY_RD_DATA_MASK); ++ } ++ ++exit: ++ /* cleanup */ ++ //cmicx_miim_write(mdio_ctrl, MIIM_CH1_CONTROL_REG, 0); ++ cmicx_miim_write(mdio_ctrl, (MIIM_CH0_CONTROL_REG + 0x10 * bus_id), 0); ++ spin_unlock_irqrestore(&mdio_ctrl->lock, flags); ++ ++ return ret; ++} ++ ++static int cmicx_mdiobus_read(struct mii_bus *bus, int phy_id, int reg_num) ++{ ++ struct iproc_mdiobus_private *mdio_bus_priv = bus->priv; ++ struct iproc_mdiobus_data *mdio_bus_data = mdio_bus_priv->bus_data; ++ struct cmicx_miim_cmd miim_cmd = { 0 }; ++ int ret = 0; ++ ++ if (IPROC_MDIOBUS_TYPE_INTERNAL == mdio_bus_data->phybus_type) { ++ miim_cmd.int_sel = 1; ++ } ++ if (reg_num & MII_ADDR_C45) { ++ miim_cmd.c45_sel = 1; ++ } ++ miim_cmd.bus_id = mdio_bus_data->phybus_num; ++ miim_cmd.phy_id = phy_id; ++ miim_cmd.reg_num = reg_num; ++ miim_cmd.op_mode = MII_OP_MODE_READ; ++ miim_cmd.phy_data = 0; ++ ++ ret = cmicx_miim_operation(mdio_bus_priv->hw_ctrl, &miim_cmd); ++ if (ret == 0) { ++ return miim_cmd.phy_data; ++ } ++ return ret; ++} ++ ++static int cmicx_mdiobus_write(struct mii_bus *bus, int phy_id, ++ int reg_num, u16 val) ++{ ++ struct iproc_mdiobus_private *mdio_bus_priv = bus->priv; ++ struct iproc_mdiobus_data *mdio_bus_data = mdio_bus_priv->bus_data; ++ struct cmicx_miim_cmd miim_cmd = {0}; ++ ++ if (IPROC_MDIOBUS_TYPE_INTERNAL == mdio_bus_data->phybus_type) { ++ miim_cmd.int_sel = 1; ++ } ++ if (reg_num & MII_ADDR_C45) { ++ miim_cmd.c45_sel = 1; ++ } ++ miim_cmd.bus_id = mdio_bus_data->phybus_num; ++ miim_cmd.phy_id = phy_id; ++ miim_cmd.reg_num = reg_num; ++ miim_cmd.op_mode = MII_OP_MODE_WRITE; ++ miim_cmd.phy_data = val; ++ ++ return cmicx_miim_operation(mdio_bus_priv->hw_ctrl, &miim_cmd); ++} ++ ++/************************************************************************************* ++**************************************************************************************/ ++static int cmicx_mdiobus_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *dn = pdev->dev.of_node; ++ struct mii_bus *mii_bus = NULL; ++ struct iproc_mdiobus_private *mdio_bus_priv = NULL; ++ struct iproc_mdiobus_data *mdio_bus_data = NULL; ++ struct iproc_mdio_ctrl *mdio_ctrl = NULL; ++ u32 mdio_bus_id; ++ int clock_divider, out_delay; ++ int divider_int = -1, divider_ext = -1; ++ const char *mdio_bus_type; ++ int ret; ++ ++ mdio_ctrl = devm_kzalloc(dev, sizeof(*mdio_ctrl), GFP_KERNEL); ++ if (!mdio_ctrl) { ++ dev_err(dev, "cmicx mdio resource allocated failed\n"); ++ return -ENOMEM; ++ } ++ ++ spin_lock_init(&mdio_ctrl->lock); ++ ++ /* Get register base address */ ++ mdio_ctrl->base = of_iomap(dn, 0); ++ if (!mdio_ctrl->base) { ++ dev_err(dev, "cmicx mdio register base map error\n"); ++ ret = -ENXIO; ++ goto err; ++ } ++ ++ /* If no property available, use default: 2 */ ++ if (of_property_read_u32(dn, "#bus-id", &mdio_bus_id)) { ++ mdio_bus_id = 2; ++ } ++ ++ /* If no property available, use default: "external" */ ++ if (of_property_read_string(dn, "bus-type", &mdio_bus_type)) { ++ mdio_bus_type = "external"; ++ } ++ ++ /* If no property available, use default: -1 */ ++ if (of_property_read_u32(dn, "#divider", &clock_divider)) { ++ clock_divider = -1; ++ } ++ ++ /* If no property available, use default: -1 */ ++ if (of_property_read_u32(dn, "#delay", &out_delay)) { ++ out_delay = -1; ++ } ++ ++ mdio_bus_data = devm_kzalloc(dev, sizeof(*mdio_bus_data), GFP_KERNEL); ++ if (!mdio_bus_data) { ++ dev_err(dev, "iProc MDIO bus data allocated failed\n"); ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ mdio_bus_data->phybus_num = mdio_bus_id; ++ if (!strcmp(mdio_bus_type, "internal")) { ++ mdio_bus_data->phybus_type = IPROC_MDIOBUS_TYPE_INTERNAL; ++ divider_int = clock_divider; ++ } else { ++ mdio_bus_data->phybus_type = IPROC_MDIOBUS_TYPE_EXTERNAL; ++ divider_ext = clock_divider; ++ } ++ ++ mdio_bus_priv = devm_kzalloc(dev, sizeof(*mdio_bus_priv), GFP_KERNEL); ++ if (!mdio_bus_priv) { ++ dev_err(dev, "iProc MDIO private data allocated failed\n"); ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ mdio_bus_priv->bus_data = mdio_bus_data; ++ mdio_bus_priv->hw_ctrl = mdio_ctrl; ++ ++ ret = cmicx_miim_init(mdio_ctrl); ++ if (ret) { ++ dev_err(dev, "cmicx init failed\n"); ++ goto err; ++ } ++ ++ ret = cmicx_miim_ring_init(mdio_ctrl, mdio_bus_id, ++ divider_int, divider_ext, out_delay); ++ if (ret) { ++ dev_err(dev, "cmicx init ring failed\n"); ++ goto err; ++ } ++ ++ mii_bus = mdiobus_alloc(); ++ if (!mii_bus) { ++ dev_err(dev, "MII bus memory allocated failed\n"); ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ mii_bus->name = "iproc_cmicx_mdiobus"; ++ snprintf(mii_bus->id, MII_BUS_ID_SIZE, "%s-%d-%d", "cmicx mdio", mdio_bus_id, ++ (mdio_bus_data->phybus_type == IPROC_MDIOBUS_TYPE_EXTERNAL) ? 1 : 0); ++ mii_bus->parent = dev; ++ mii_bus->read = cmicx_mdiobus_read; ++ mii_bus->write = cmicx_mdiobus_write; ++ mii_bus->priv = mdio_bus_priv; ++ ++ ret = of_mdiobus_register(mii_bus, dn); ++ if (ret) { ++ dev_err(dev, "mdiobus register failed\n"); ++ goto err; ++ } ++ ++ platform_set_drvdata(pdev, mii_bus); ++ ++ return 0; ++ ++err: ++ if (mii_bus) { ++ mdiobus_free(mii_bus); ++ } ++ if (mdio_bus_priv) { ++ devm_kfree(dev, mdio_bus_priv); ++ } ++ if (mdio_bus_data) { ++ devm_kfree(dev, mdio_bus_data); ++ } ++ if (mdio_ctrl->base) { ++ iounmap(mdio_ctrl->base); ++ } ++ if (mdio_ctrl) { ++ devm_kfree(dev, mdio_ctrl); ++ } ++ ++ return ret; ++} ++ ++static int cmicx_mdiobus_remove(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct mii_bus *mii_bus = platform_get_drvdata(pdev); ++ struct iproc_mdiobus_private *mdio_bus_priv; ++ struct iproc_mdiobus_data *mdio_bus_data; ++ struct iproc_mdio_ctrl *mdio_ctrl; ++ ++ if (mii_bus) { ++ mdio_bus_priv = mii_bus->priv; ++ mdio_bus_data = mdio_bus_priv->bus_data; ++ mdio_ctrl = mdio_bus_priv->hw_ctrl; ++ ++ mdiobus_unregister(mii_bus); ++ mdiobus_free(mii_bus); ++ ++ if (mdio_bus_priv) { ++ if (mdio_ctrl) { ++ if (mdio_ctrl->base) { ++ iounmap(mdio_ctrl->base); ++ } ++ devm_kfree(dev, mdio_ctrl); ++ } ++ if (mdio_bus_data) { ++ devm_kfree(dev, mdio_bus_data); ++ } ++ devm_kfree(dev, mdio_bus_priv); ++ } ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id cmicx_mdio_dt_ids[] = { ++ { .compatible = "brcm,iproc-cmicx-mdio"}, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, cmicx_mdio_dt_ids); ++ ++static struct platform_driver iproc_cmicx_mdiobus_driver = ++{ ++ .driver = { ++ .name = "iproc_cmicx_mdio", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(cmicx_mdio_dt_ids), ++ }, ++ .probe = cmicx_mdiobus_probe, ++ .remove = cmicx_mdiobus_remove, ++}; ++ ++static int __init cmicx_mdio_init(void) ++{ ++ return platform_driver_register(&iproc_cmicx_mdiobus_driver); ++} ++ ++static void __exit cmicx_mdio_exit(void) ++{ ++ platform_driver_unregister(&iproc_cmicx_mdiobus_driver); ++} ++ ++subsys_initcall(cmicx_mdio_init); ++module_exit(cmicx_mdio_exit); ++ ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_DESCRIPTION("iProc CMICx mdio driver"); ++MODULE_LICENSE("GPL"); ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/mdio-xgs-iproc.h b/drivers/net/phy/mdio-xgs-iproc.h +--- a/drivers/net/phy/mdio-xgs-iproc.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/phy/mdio-xgs-iproc.h 2018-05-10 11:31:32.085402292 +0800 +@@ -0,0 +1,55 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ */ ++ ++ ++#ifndef _XGS_IPROC_MDIO_H_ ++#define _XGS_IPROC_MDIO_H_ ++ ++enum { ++ MII_OP_MODE_READ, ++ MII_OP_MODE_WRITE, ++ MII_OP_MODE_MAX ++}; ++ ++/* iProc General Interface for mdio bus support */ ++struct iproc_mdiobus_data { ++ /* required for cmicd mdio controller supports several buses */ ++ u32 phybus_num; ++ u32 phybus_type; ++}; ++ ++/* ++ * struct iproc_mdio_ctrl ++ * @base: base address of cmic_common ++ * @iproc_mdio_enable_reg: register addr of mdio bus enable ++ * @iproc_mdio_sel_bit: bit position in register for enabling mdio bus access ++ * @lock: spin lock protecting io access ++ */ ++struct iproc_mdio_ctrl { ++ void __iomem *base; ++ void __iomem *iproc_mdio_enable_reg; ++ u32 iproc_mdio_sel_bit; ++ spinlock_t lock; ++ int ref_cnt; ++}; ++ ++struct iproc_mdiobus_private { ++ struct iproc_mdiobus_data *bus_data; ++ struct iproc_mdio_ctrl *hw_ctrl; ++}; ++ ++#define SET_REG_FIELD(reg_value, fshift, fmask, fvalue) \ ++ (reg_value) = ((reg_value) & ~((fmask) << (fshift))) | \ ++ (((fvalue) & (fmask)) << (fshift)) ++#define ISET_REG_FIELD(reg_value, fshift, fmask, fvalue) \ ++ (reg_value) = (reg_value) | (((fvalue) & (fmask)) << (fshift)) ++#define GET_REG_FIELD(reg_value, fshift, fmask) \ ++ (((reg_value) & ((fmask) << (fshift))) >> (fshift)) ++ ++#define MII_OP_MAX_HALT_USEC 500 ++ ++#define IPROC_MDIOBUS_TYPE_INTERNAL 0 ++#define IPROC_MDIOBUS_TYPE_EXTERNAL 1 ++ ++#endif /* _XGS_IPROC_MDIO_H_ */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c +--- a/drivers/net/phy/phy.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/net/phy/phy.c 2018-05-10 11:31:32.085402292 +0800 +@@ -42,6 +42,11 @@ + case PHY_##_state: \ + return __stringify(_state); \ + ++#if IS_ENABLED(CONFIG_MDIO_XGS_IPROC) ++#define MAX_IPROC_PHY_ADDR 4 ++extern bool xgs_mdio_bus_release(void); ++#endif ++ + static const char *phy_state_to_str(enum phy_state st) + { + switch (st) { +@@ -889,6 +894,9 @@ void phy_state_machine(struct work_struc + enum phy_state old_state; + int err = 0; + int old_link; ++#if IS_ENABLED(CONFIG_MDIO_XGS_IPROC) ++ static u32 schedule_cnt[MAX_IPROC_PHY_ADDR]= {0}; ++#endif + + mutex_lock(&phydev->lock); + +@@ -1078,9 +1086,32 @@ void phy_state_machine(struct work_struc + * PHY, if PHY_IGNORE_INTERRUPT is set, then we will be moving + * between states from phy_mac_interrupt() + */ ++#if IS_ENABLED(CONFIG_MDIO_XGS_IPROC) ++ if (phydev->irq == PHY_POLL) { ++ /* Re-schedule PHY state machine change if mdio_bus_release=0 */ ++ if (!xgs_mdio_bus_release()) { ++ queue_delayed_work(system_power_efficient_wq, ++ &phydev->state_queue, PHY_STATE_TIME * HZ); ++ } ++ /* If mdio_bus_release=1, stop re-schedule of PHY state machine ++ * change after 5 * PHY_STATE_TIME seconds for HX4/KT2 ++ * which shares the mdio bus between iProc and CMICd. ++ */ ++ else { ++ schedule_cnt[phydev->mdio.addr] += 1; ++ if (schedule_cnt[phydev->mdio.addr] > 5) { ++ schedule_cnt[phydev->mdio.addr] = 0; ++ return; ++ } ++ queue_delayed_work(system_power_efficient_wq, ++ &phydev->state_queue, PHY_STATE_TIME * HZ); ++ } ++ } ++#else + if (phydev->irq == PHY_POLL) + queue_delayed_work(system_power_efficient_wq, &phydev->state_queue, + PHY_STATE_TIME * HZ); ++#endif + } + + /** +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/xgs-iproc-serdes.c b/drivers/net/phy/xgs-iproc-serdes.c +--- a/drivers/net/phy/xgs-iproc-serdes.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/phy/xgs-iproc-serdes.c 2018-05-10 11:31:32.089402296 +0800 +@@ -0,0 +1,644 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include "xgs_iproc_serdes_def.h" ++ ++/* the SERDES PHY ID for HX4/KT2/SB2/GH2/WH2 is the same */ ++#define PHY_ID_XGS_AMAC_SERDES 0x0143bff0 ++ ++#define SERDES_ID_HX4_AMAC 0x828f4e00 ++#define SERDES_ID_KT2_AMAC 0x42814fc0 ++/* The amac serdes id (id0,id1) of SB2/GH2/WH2 is the same */ ++#define SERDES_ID_SB2_AMAC 0x02cf1a00 ++#define SERDES_ID_GH2_AMAC 0x02cf1a00 /* apply to WH2 */ ++/* When ID is the same, use id2 for further identification */ ++#define SERDES_ID2_HX4_AMAC 0x000f ++#define SERDES_ID2_KT2_AMAC 0x03ff ++#define SERDES_ID2_SB2_AMAC 0x8007 ++#define SERDES_ID2_GH2_AMAC 0x800f /* apply to WH2 */ ++ ++#define PHY_REG_BLK_ADDR 0x001f ++#define PHY_REG_AER_BLK 0xffd0 ++#define PHY_REG_AER_OFFSET 0x001e ++#define PHY_REG_BLK_ADDR_MASK 0x7ff0 ++#define PHY_REG_ADDR_MASK 0xf ++#define PHY_REG_ADDR_32_MASK 0x8000 ++ ++#define PHY_AER_REG_ADDR_AER(_addr) (((_addr) >> XGXS16G_SERDES_LANE_SHIFT) \ ++ & 0xFFFF) ++#define PHY_REG_ADDR_BLK(_addr) ((_addr) & PHY_REG_BLK_ADDR_MASK) ++#define PHY_REG_ADDR_REGAD(_addr) (((_addr & PHY_REG_ADDR_32_MASK) >> 11) \ ++ | (_addr & PHY_REG_ADDR_MASK)) ++ ++//#define BCMDBG ++//#define BCMDBG_ERR ++#ifdef BCMDBG ++#define SERDES_ERROR(args) pr_err args ++#define SERDES_TRACE(args) pr_info args ++#elif defined(BCMDBG_ERR) ++#define SERDES_ERROR(args) pr_err args ++#define SERDES_TRACE(args) ++#else ++#define SERDES_ERROR(args) ++#define SERDES_TRACE(args) ++#endif /* BCMDBG */ ++ ++/* For pcie/usb serdes and phy write */ ++void xgs_phy_wr_reg(struct phy_device *phydev, u32 regnum, u16 data) ++{ ++ u16 phy_reg_blk=0; ++ u32 phy_reg_addr=0; ++ ++ phy_reg_blk = regnum & PHY_REG_BLK_ADDR_MASK; ++ phy_reg_addr = regnum & PHY_REG_ADDR_MASK; ++ phy_reg_addr |= (regnum & PHY_REG_ADDR_32_MASK) ? 0x10 : 0x0; ++ ++ phy_write(phydev, PHY_REG_BLK_ADDR, phy_reg_blk); ++ phy_write(phydev, phy_reg_addr, data); ++} ++ ++/* For pcie/usb serdes and phy read */ ++u16 xgs_phy_rd_reg(struct phy_device *phydev, u32 regnum) ++{ ++ u16 phy_reg_blk=0; ++ u32 phy_reg_addr=0; ++ int data; ++ ++ phy_reg_blk = regnum & PHY_REG_BLK_ADDR_MASK; ++ phy_reg_addr = regnum & PHY_REG_ADDR_MASK; ++ phy_reg_addr |= (regnum & PHY_REG_ADDR_32_MASK) ? 0x10 : 0x0; ++ ++ phy_write(phydev, PHY_REG_BLK_ADDR, phy_reg_blk); ++ data = phy_read(phydev, phy_reg_addr); ++ ++ return (u16)data; ++} ++ ++/* for SB2 USB PHY write */ ++void xgs_sb2_usb_phy_wr_reg(struct phy_device *phydev, u32 regnum, u16 data) ++{ ++ u16 phy_reg_blk=0; ++ u32 phy_reg_addr=0; ++ ++ phy_reg_blk = regnum & 0xfff0; ++ phy_reg_addr = regnum & 0xf; ++ ++ phy_write(phydev, PHY_REG_BLK_ADDR, phy_reg_blk); ++ phy_write(phydev, phy_reg_addr, data); ++} ++ ++/* for SB2 USB PHY read */ ++u16 xgs_sb2_usb_phy_rd_reg(struct phy_device *phydev, u32 regnum) ++{ ++ u16 phy_reg_blk=0; ++ u32 phy_reg_addr=0; ++ int data; ++ ++ phy_reg_blk = regnum & 0xfff0; ++ phy_reg_addr = regnum & 0xf; ++ ++ phy_write(phydev, PHY_REG_BLK_ADDR, phy_reg_blk); ++ data = phy_read(phydev, phy_reg_addr); ++ ++ return (u16)data; ++} ++ ++/* SB2/GH2/WH2 amac serdes supports AER */ ++static u16 xgs_serdes_rd_reg(struct phy_device *phydev, u32 regnum) ++{ ++ int data; ++ u16 phy_reg_blk=0; ++ u32 phy_reg_addr=0; ++ u32 phy_reg_aer=0; ++ ++ phy_reg_aer = PHY_AER_REG_ADDR_AER(regnum); ++ phy_reg_blk = PHY_REG_ADDR_BLK(regnum); ++ phy_reg_addr = PHY_REG_ADDR_REGAD(regnum); ++ ++ if (phy_reg_aer) { ++ phy_write(phydev, PHY_REG_BLK_ADDR, PHY_REG_AER_BLK); ++ phy_write(phydev, PHY_REG_AER_OFFSET, phy_reg_aer); ++ } ++ ++ phy_write(phydev, PHY_REG_BLK_ADDR, phy_reg_blk); ++ data = phy_read(phydev, phy_reg_addr); ++ ++ if (phy_reg_aer) { ++ phy_write(phydev, PHY_REG_BLK_ADDR, PHY_REG_AER_BLK); ++ phy_write(phydev, PHY_REG_AER_OFFSET, 0x0); ++ } ++ ++ return (u16)data; ++} ++ ++static void xgs_serdes_wr_reg(struct phy_device *phydev, u32 regnum, u16 data) ++{ ++ u16 phy_reg_blk=0; ++ u32 phy_reg_addr=0; ++ u32 phy_reg_aer=0; ++ ++ phy_reg_aer = PHY_AER_REG_ADDR_AER(regnum); ++ phy_reg_blk = PHY_REG_ADDR_BLK(regnum); ++ phy_reg_addr = PHY_REG_ADDR_REGAD(regnum); ++ ++ if (phy_reg_aer) { ++ phy_write(phydev, PHY_REG_BLK_ADDR, PHY_REG_AER_BLK); ++ phy_write(phydev, PHY_REG_AER_OFFSET, phy_reg_aer); ++ } ++ ++ phy_write(phydev, PHY_REG_BLK_ADDR, phy_reg_blk); ++ phy_write(phydev, phy_reg_addr, data); ++ ++ if (phy_reg_aer) { ++ phy_write(phydev, PHY_REG_BLK_ADDR, PHY_REG_AER_BLK); ++ phy_write(phydev, PHY_REG_AER_OFFSET, 0x0); ++ } ++} ++ ++static u32 serdes_get_id(struct phy_device *phy_dev) ++{ ++ u16 serdes_id0, serdes_id1; ++ u32 serdes_id; ++ struct phy_device *phydev = phy_dev; ++ ++ serdes_id0 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID0r); ++ serdes_id1 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID1r); ++ serdes_id = (serdes_id0 << 16) | serdes_id1; ++ ++ return serdes_id; ++} ++ ++void xgs_serdes_set_lane(struct phy_device *phy_dev, u32 lane) ++{ ++ xgs_serdes_info_t *serdes_info; ++ ++ serdes_info = devm_kzalloc(&phy_dev->mdio.dev, sizeof(*serdes_info), ++ GFP_KERNEL); ++ if (!serdes_info) { ++ dev_err(&phy_dev->mdio.dev, "Fail to allocate xgs_serdes_info\n"); ++ return; ++ } ++ ++ serdes_info->lane = lane; ++ phy_dev->priv = serdes_info; ++} ++ ++static inline u32 xgs_serdes_get_lane(struct phy_device *phy_dev) ++{ ++ xgs_serdes_info_t *lane_info = (xgs_serdes_info_t *) phy_dev->priv; ++ ++ return lane_info->lane; ++} ++ ++bool xgs_serdes_hx4_amac(struct phy_device *phy_dev) ++{ ++ return (serdes_get_id(phy_dev) == SERDES_ID_HX4_AMAC); ++} ++ ++bool xgs_serdes_kt2_amac(struct phy_device *phy_dev) ++{ ++ return (serdes_get_id(phy_dev) == SERDES_ID_KT2_AMAC); ++} ++ ++/* Needed for HX4/KT2/GH2/WH2, WH2 has the same ID as GH2 */ ++static void xgs_serdes_reset_core(struct phy_device *phy_dev) ++{ ++ u16 data16; ++ u32 serdes_id; ++ u16 serdes_id2; ++ static u32 serdes_core_reset = 0; ++ struct phy_device *phydev = phy_dev; ++ ++ if (phydev->phy_id != PHY_ID_XGS_AMAC_SERDES) ++ return; ++ ++ /* Only reset once */ ++ if (serdes_core_reset) ++ return; ++ ++ serdes_id = serdes_get_id(phydev); ++ serdes_id2 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID2r); ++ SERDES_TRACE(("-----SERDESID2: 0x%x\n", serdes_id2)); ++ ++ if (!((serdes_id == SERDES_ID_HX4_AMAC) || ++ (serdes_id == SERDES_ID_KT2_AMAC) || ++ (serdes_id == SERDES_ID_GH2_AMAC))) ++ return; ++ ++ /* GH2/WH2 specific code */ ++ if (serdes_id == SERDES_ID_GH2_AMAC) { ++ if (serdes_id2 != SERDES_ID2_GH2_AMAC) ++ return; ++ ++ /* Disable pll start sequencer */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr); ++ data16 &= ~XGXSBLK0_CONTROL_PLL_SEQUENCER_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr, data16); ++ serdes_core_reset = 1; ++ return; ++ } ++ ++ /* The following is HX4/KT2 related */ ++ /* unlock lane */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_WC40_DIGITAL4_MISC3r); ++ data16 &= ~(DIGITAL4_MISC3_LANEDISABLE_MASK); ++ xgs_serdes_wr_reg(phydev, XGXS16G_WC40_DIGITAL4_MISC3r, data16); ++ ++ /* Reset the core */ ++ /* Stop PLL Sequencer and configure the core into correct mode */ ++ data16 = (XGXSBLK0_XGXSCONTROL_MODE_10G_IndLane << ++ XGXSBLK0_XGXSCONTROL_MODE_10G_SHIFT) | ++ XGXSBLK0_XGXSCONTROL_HSTL_MASK | ++ XGXSBLK0_XGXSCONTROL_CDET_EN_MASK | ++ XGXSBLK0_XGXSCONTROL_EDEN_MASK | ++ XGXSBLK0_XGXSCONTROL_AFRST_EN_MASK | ++ XGXSBLK0_XGXSCONTROL_TXCKO_DIV_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr, data16); ++ ++ /* ++ * Disable IEEE block select auto-detect. ++ * The driver will select desired block as necessary. ++ * By default, the driver keeps the XAUI block in IEEE address space. ++ */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_XGXSBLK0_MISCCONTROL1r); ++ data16 &= ~(XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_MASK | ++ XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_MASK); ++ if (!XGXS16G_2p5G_ID(serdes_id2) && (serdes_id == SERDES_ID_HX4_AMAC)) ++ data16 |= XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_XGXSBLK0_MISCCONTROL1r, data16); ++ ++ /* disable in-band MDIO. PHY-443 */ ++ data16 = xgs_serdes_rd_reg(phydev, 0x8111); ++ /* rx_inBandMdio_rst */ ++ data16 |= 1 << 3; ++ xgs_serdes_wr_reg(phydev, 0x8111, data16); ++ ++ serdes_core_reset = 1; ++} ++ ++static void xgs_serdes_reset(struct phy_device *phy_dev) ++{ ++ u16 ctrl; ++ struct phy_device *phydev = phy_dev; ++ u32 serdes_id; ++ u16 serdes_id2; ++ u32 aer = 0; ++ u32 aer_blk_reg = 0; ++ ++ if (phydev->phy_id != PHY_ID_XGS_AMAC_SERDES) ++ return; ++ ++ serdes_id = serdes_get_id(phydev); ++ serdes_id2 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID2r); ++ ++ /* AER required for GH2/WH2 serdes */ ++ if ((serdes_id == SERDES_ID_GH2_AMAC) && ++ (serdes_id2 == SERDES_ID2_GH2_AMAC)) ++ aer = xgs_serdes_get_lane(phy_dev) << XGXS16G_SERDES_LANE_SHIFT; ++ ++ /* de-assert reset */ ++ aer_blk_reg = aer | XGXS16G_IEEE0BLK_IEEECONTROL0r; ++ ctrl = xgs_serdes_rd_reg(phydev, aer_blk_reg); ++ ctrl |= IEEE0BLK_IEEECONTROL0_RST_HW_MASK; ++ xgs_serdes_wr_reg(phydev, aer_blk_reg, ctrl); ++ udelay(100); ++ ++ /* check if out of reset */ ++ if (xgs_serdes_rd_reg(phydev, aer_blk_reg) & ++ IEEE0BLK_IEEECONTROL0_RST_HW_MASK) ++ SERDES_ERROR(("amac serdes reset not completed.\n")); ++} ++ ++static void xgs_serdes_init(struct phy_device *phy_dev) ++{ ++ u16 data16; ++ u32 serdes_id; ++ u16 serdes_id2; ++ u32 __maybe_unused aer_blk_reg, aer; ++ struct phy_device *phydev = phy_dev; ++ ++#ifdef BCMDBG ++ u16 tmp0, tmp1; ++ tmp0 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID0r); ++ tmp1 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID1r); ++ SERDES_TRACE(("-----SERDESID0: 0x%x; SERDESID1: 0x%x\n", tmp0, tmp1)); ++ ++ tmp0 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID2r); ++ tmp1 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID3r); ++ SERDES_TRACE(("-----SERDESID2: 0x%x;SERDESID3: 0x%x\n", tmp0, tmp1)); ++#endif /* BCMDBG */ ++ ++ SERDES_TRACE(("%s: phyaddr %d\n",__FUNCTION__, phydev->mdio.addr)); ++ ++ if (phydev->phy_id != PHY_ID_XGS_AMAC_SERDES) ++ return; ++ ++ serdes_id = serdes_get_id(phydev); ++ serdes_id2 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID2r); ++ ++ if ((serdes_id == SERDES_ID_SB2_AMAC) && ++ (serdes_id2 == SERDES_ID2_SB2_AMAC)) { ++ /* Auto Negotiation 10M/100M/1G ¡V SGMII Slave */ ++ /* Disable pll start sequencer */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr); ++ data16 &= ~XGXSBLK0_CONTROL_PLL_SEQUENCER_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr, data16); ++ ++ /* Set SGMII slave mode */ ++ xgs_serdes_wr_reg(phydev, XGXS16G_SERDESDIGITAL_CONTROL1000X1r, ++ SERDESDIGITAL_CONTROL1000X1_SLAVE_MODE); ++ ++ /* Enable AN 10M/100M/1G */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_IEEE0BLK_IEEECONTROL0r); ++ data16 |= IEEE0BLK_IEEECONTROL0_ENABLE_AN_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_IEEE0BLK_IEEECONTROL0r, data16); ++ ++ /* Enable pll start sequencer */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr); ++ data16 |= XGXSBLK0_CONTROL_PLL_SEQUENCER_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr, data16); ++ } else if ((serdes_id == SERDES_ID_GH2_AMAC) && ++ (serdes_id2 == SERDES_ID2_GH2_AMAC)) { ++ aer = xgs_serdes_get_lane(phydev) << XGXS16G_SERDES_LANE_SHIFT; ++ ++ /* Disable IEEE block select auto-detect */ ++ data16 = 0; ++ aer_blk_reg = (aer | XGXS16G_XGXSBLK0_MISCCONTROL1r); ++ xgs_serdes_wr_reg(phydev, aer_blk_reg, data16); ++ ++ /* Disable lmtcal (broadcast to all lanes) */ ++ data16 = 0x83f8; ++ aer_blk_reg = (aer | XGXS16G_RX3_CONTROL2r); ++ xgs_serdes_wr_reg(phydev, aer_blk_reg, data16); ++ ++ /* Set SGMII slave mode */ ++ aer_blk_reg = (aer | XGXS16G_SERDESDIGITAL_CONTROL1000X1r); ++ xgs_serdes_wr_reg(phydev, aer_blk_reg, ++ SERDESDIGITAL_CONTROL1000X1_SLAVE_MODE); ++ ++ /* Enable AN 10M/100M/1G */ ++ aer_blk_reg = (aer | XGXS16G_IEEE0BLK_IEEECONTROL0r); ++ data16 = xgs_serdes_rd_reg(phydev, aer_blk_reg); ++ data16 |= IEEE0BLK_IEEECONTROL0_ENABLE_AN_MASK; ++ xgs_serdes_wr_reg(phydev, aer_blk_reg, data16); ++ } else if ((serdes_id == SERDES_ID_HX4_AMAC) || ++ (serdes_id == SERDES_ID_KT2_AMAC)) { ++ /* unlock lane */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_WC40_DIGITAL4_MISC3r); ++ data16 &= ~(DIGITAL4_MISC3_LANEDISABLE_MASK); ++ xgs_serdes_wr_reg(phydev, XGXS16G_WC40_DIGITAL4_MISC3r, data16); ++ ++ /* disable CL73 BAM */ ++ data16 = xgs_serdes_rd_reg(phydev, ++ XGXS16G_CL73_USERB0_CL73_BAMCTRL1r); ++ data16 &= ~(CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_MASK); ++ xgs_serdes_wr_reg(phydev, XGXS16G_CL73_USERB0_CL73_BAMCTRL1r, ++ data16); ++ ++ /* Set Local Advertising Configuration */ ++ data16 = MII_ANA_C37_FD | MII_ANA_C37_PAUSE | ++ MII_ANA_C37_ASYM_PAUSE; ++ xgs_serdes_wr_reg(phydev, XGXS16G_COMBO_IEEE0_AUTONEGADVr, data16); ++ ++ /* Disable BAM in Independent Lane mode. Over 1G AN not supported */ ++ data16 = 0; ++ xgs_serdes_wr_reg(phydev, XGXS16G_BAM_NEXTPAGE_MP5_NEXTPAGECTRLr, ++ data16); ++ xgs_serdes_wr_reg(phydev, XGXS16G_BAM_NEXTPAGE_UD_FIELDr, data16); ++ ++ data16 = SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_MASK | ++ SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_MASK; ++ /* Set SGMII mode */ ++ xgs_serdes_wr_reg(phydev, XGXS16G_SERDESDIGITAL_CONTROL1000X1r, ++ data16); ++ ++ /* Set autoneg */ ++ data16 = IEEE0BLK_IEEECONTROL0_ENABLE_AN_MASK | ++ IEEE0BLK_IEEECONTROL0_RESTART_AN_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_COMBO_IEEE0_MIICNTLr, data16); ++ ++ /* Disable 10G parallel detect */ ++ data16 = 0; ++ xgs_serdes_wr_reg(phydev, XGXS16G_AN73_PDET_PARDET10GCONTROLr, ++ data16); ++ ++ /* Disable BAM mode and Teton mode */ ++ xgs_serdes_wr_reg(phydev, XGXS16G_BAM_NEXTPAGE_MP5_NEXTPAGECTRLr, ++ data16); ++ ++ /* Enable lanes */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_XGXSBLK1_LANECTRL0r); ++ data16 |= XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_MASK | ++ XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_XGXSBLK1_LANECTRL0r, data16); ++ ++ /* Set elasticity fifo size to 13.5k to support 12k jumbo pkt size*/ ++ data16 = xgs_serdes_rd_reg(phydev, ++ XGXS16G_SERDESDIGITAL_CONTROL1000X3r); ++ data16 &= SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_MASK; ++ data16 |= (1 << 2); ++ xgs_serdes_wr_reg(phydev, XGXS16G_SERDESDIGITAL_CONTROL1000X3r, ++ data16); ++ ++ /* Enable LPI passthru' for native mode EEE */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_REMOTEPHY_MISC5r); ++ data16 |= XGXS16G_REMOTEPHY_MISC5_LPI_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_REMOTEPHY_MISC5r, data16); ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_XGXSBLK7_EEECONTROLr); ++ data16 |= 0x0007; ++ xgs_serdes_wr_reg(phydev, XGXS16G_XGXSBLK7_EEECONTROLr, data16); ++ } ++} ++ ++/* Needed for HX4/KT2/GH2/WH2 */ ++static void xgs_serdes_start_pll(struct phy_device *phy_dev) ++{ ++ u16 data16; ++ u32 serdes_id; ++ u16 serdes_id2; ++ u32 count = 100; ++ struct phy_device *phydev = phy_dev; ++ static u32 serdes_pll_started = 0; ++ ++ if (phydev->phy_id != PHY_ID_XGS_AMAC_SERDES) ++ return; ++ ++ /* PLL started or not */ ++ if (serdes_pll_started) ++ return; ++ ++ serdes_id = serdes_get_id(phydev); ++ serdes_id2 = xgs_serdes_rd_reg(phydev, XGXS16G_SERDESID_SERDESID2r); ++ ++ if (!((serdes_id == SERDES_ID_HX4_AMAC) || ++ (serdes_id == SERDES_ID_KT2_AMAC) || ++ (serdes_id == SERDES_ID_GH2_AMAC))) ++ return; ++ ++ /* Change PLL calibration threshold to 0xc for GH2/WH2*/ ++ if ((serdes_id == SERDES_ID_GH2_AMAC) && ++ (serdes_id2 == SERDES_ID2_GH2_AMAC)) { ++ data16 = 0xc << XGXS16G_PLL2_CTRL_CAL_TH_SHIFT; ++ xgs_serdes_wr_reg(phydev, XGXS16G_PLL2_CTRL1r, data16); ++ } ++ ++ /* Start PLL Sequencer and wait for PLL to lock */ ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr); ++ data16 |= XGXSBLK0_XGXSCONTROL_START_SEQUENCER_MASK; ++ xgs_serdes_wr_reg(phydev, XGXS16G_XGXSBLK0_XGXSCONTROLr, data16); ++ ++ /* wait for PLL to lock */ ++ while (count--) { ++ data16 = xgs_serdes_rd_reg(phydev, XGXS16G_XGXSBLK0_XGXSSTATUSr); ++ if (data16 & XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_MASK) ++ break; ++ udelay(10); ++ } ++ if (!count) ++ SERDES_ERROR(("amac serdes TXPLL did not lock\n")); ++ else ++ serdes_pll_started = 1; ++} ++ ++static int xgs_serdes_config_init(struct phy_device *phydev) ++{ ++ xgs_serdes_reset_core(phydev); ++ xgs_serdes_reset(phydev); ++ xgs_serdes_init(phydev); ++ xgs_serdes_start_pll(phydev); ++ ++ return 0; ++} ++ ++/* ++ * REGADDR: 0x8304 ++ * DESC: 1000X status 1 register ++ * SGMII_MODE 1 = sgmii mode0 = fiber mode (1000-X) ++ * LINK_STATUS 1 = link is up0 = link is down ++ * DUPLEX_STATUS 1 = full-duplex0 = half-duplex ++ * SPEED_STATUS 11 = 2.5G10 = gigabit01 = 100 mbps00 = 10 mbps ++ */ ++static int xgs_serdes_read_status(struct phy_device *phydev) ++{ ++ u16 link_stat; ++ u32 serdes_lane; ++ u32 reg; ++ ++ serdes_lane = xgs_serdes_get_lane(phydev); ++ reg = (serdes_lane << XGXS16G_SERDES_LANE_SHIFT) | ++ XGXS16G_SERDESDIGITAL_STATUS1000X1r; ++ link_stat = xgs_serdes_rd_reg(phydev, reg); ++ ++ if (link_stat & 0x2) ++ phydev->link = 1; ++ else ++ phydev->link = 0; ++ ++ if (link_stat & 0x4) ++ phydev->duplex = 1; ++ else ++ phydev->duplex = 0; ++ ++ phydev->pause = 0; ++ phydev->asym_pause = 0; ++/* ++ link_stat >>= 3; ++ link_stat &= 0x3; ++*/ ++ link_stat >>= SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_SHIFT; ++ link_stat &= ((1 << SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_BITS) - 1); ++ switch(link_stat) { ++ case 0: ++ phydev->speed = SPEED_10; ++ break; ++ case 1: ++ phydev->speed = SPEED_100; ++ break; ++ case 2: ++ phydev->speed = SPEED_1000; ++ break; ++ case 3: ++ phydev->speed = SPEED_2500; ++ break; ++ }; ++ ++ return 0; ++} ++ ++static int xgs_serdes_config_aneg(struct phy_device *phydev) ++{ ++ u32 serdes_lane; ++ u32 reg; ++ u16 data16; ++ ++ if (AUTONEG_ENABLE != phydev->autoneg) ++ return 0; ++ ++ serdes_lane = xgs_serdes_get_lane(phydev); ++ ++ /* Enable AN 10M/100M/1G */ ++ reg = (serdes_lane << XGXS16G_SERDES_LANE_SHIFT) | ++ XGXS16G_IEEE0BLK_IEEECONTROL0r; ++ data16 = xgs_serdes_rd_reg(phydev, reg); ++ //data16 |= IEEE0BLK_IEEECONTROL0_ENABLE_AN_MASK; ++ data16 |= IEEE0BLK_IEEECONTROL0_RESTART_AN_MASK; ++ xgs_serdes_wr_reg(phydev, reg, data16); ++ ++ return 0; ++} ++ ++static int xgs_serdes_aneg_done(struct phy_device *phydev) ++{ ++ u16 link_stat; ++ u32 serdes_lane; ++ u32 reg; ++ ++ serdes_lane = xgs_serdes_get_lane(phydev); ++ reg = (serdes_lane << XGXS16G_SERDES_LANE_SHIFT) | ++ XGXS16G_SERDESDIGITAL_STATUS1000X2r; ++ link_stat = xgs_serdes_rd_reg(phydev, reg); ++ if (link_stat & XGXS16G_SERDES_ANEG_MASK) ++ return 1; ++ ++ return 0; ++} ++ ++static struct mdio_device_id __maybe_unused xgs_serdes_tbl[] = { ++ { PHY_ID_XGS_AMAC_SERDES, 0xfffffff0 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(mdio, xgs_serdes_tbl); ++ ++static struct phy_driver xgs_serdes_drivers[] = { ++ { ++ .phy_id = PHY_ID_XGS_AMAC_SERDES, ++ .phy_id_mask = 0xfffffff0, ++ .name = "Broadcom XGS AMAC SERDES", ++ .config_init = xgs_serdes_config_init, ++ .read_status = xgs_serdes_read_status, ++ .config_aneg = xgs_serdes_config_aneg, ++ .aneg_done = xgs_serdes_aneg_done, ++ } ++}; ++ ++module_phy_driver(xgs_serdes_drivers); ++ ++MODULE_AUTHOR("Broadcom Corporation"); ++MODULE_DESCRIPTION("XGS iProc AMAC serdes driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/net/phy/xgs_iproc_serdes_def.h b/drivers/net/phy/xgs_iproc_serdes_def.h +--- a/drivers/net/phy/xgs_iproc_serdes_def.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/net/phy/xgs_iproc_serdes_def.h 2018-05-10 11:31:32.089402296 +0800 +@@ -0,0 +1,339 @@ ++/* ++ * Copyright (C) 2013, Broadcom Corporation. All Rights Reserved. ++ * ++ * Permission to use, copy, modify, and/or distribute this software for any ++ * purpose with or without fee is hereby granted, provided that the above ++ * copyright notice and this permission notice appear in all copies. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES ++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF ++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY ++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES ++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION ++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN ++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ++ * ++ * These are serdes defines ++ * ++ */ ++ ++#ifndef _PHY_XGXS16G_H_ ++#define _PHY_XGXS16G_H_ ++ ++/* macros */ ++ ++/* Macros ONLY used after initialization */ ++#define XGXS16G_2p5G_ID(id2) ((id2 & 0xff) == 0xf) ++ ++/****************************************************************************/ ++/***** Starting below is auto-generated register macros from RDB files *****/ ++/****************************************************************************/ ++ ++/**************************************************************************** ++ * Core Enums. ++ ***************************************************************************/ ++ ++#define XGXS16G_IEEE0BLK_IEEECONTROL0r 0x00000000 ++#define XGXS16G_XGXSBLK0_XGXSCONTROLr 0x00008000 ++#define XGXS16G_XGXSBLK0_XGXSSTATUSr 0x00008001 ++#define XGXS16G_XGXSBLK0_MMDSELECTr 0x0000800d ++#define XGXS16G_XGXSBLK0_MISCCONTROL1r 0x0000800e ++#define XGXS16G_XGXSBLK1_LANECTRL0r 0x00008015 ++#define XGXS16G_XGXSBLK1_LANECTRL1r 0x00008016 ++#define XGXS16G_XGXSBLK1_LANECTRL3r 0x00008018 ++#define XGXS16G_TX0_TX_ACONTROL0r 0x00008061 ++#define XGXS16G_RX0_RX_CONTROLr 0x000080b1 ++#define XGXS16G_AN73_PDET_PARDET10GCONTROLr 0x00008131 ++#define XGXS16G_XGXSBLK7_EEECONTROLr 0x00008150 ++#define XGXS16G_TX_LN_SWAP1r 0x00008169 ++#define XGXS16G_SERDESDIGITAL_CONTROL1000X1r 0x00008300 ++#define XGXS16G_SERDESDIGITAL_CONTROL1000X2r 0x00008301 ++#define XGXS16G_SERDESDIGITAL_CONTROL1000X3r 0x00008302 ++#define XGXS16G_SERDESDIGITAL_STATUS1000X1r 0x00008304 ++#define XGXS16G_SERDESDIGITAL_MISC1r 0x00008308 ++#define XGXS16G_SERDESID_SERDESID0r 0x00008310 ++#define XGXS16G_SERDESID_SERDESID1r 0x00008311 ++#define XGXS16G_SERDESID_SERDESID2r 0x00008312 ++#define XGXS16G_SERDESID_SERDESID3r 0x00008313 ++#define XGXS16G_REMOTEPHY_MISC3r 0x0000833c ++#define XGXS16G_REMOTEPHY_MISC5r 0x0000833e ++#define XGXS16G_BAM_NEXTPAGE_MP5_NEXTPAGECTRLr 0x00008350 ++#define XGXS16G_BAM_NEXTPAGE_UD_FIELDr 0x00008357 ++#define XGXS16G_COMBO_IEEE0_MIICNTLr 0x0000ffe0 ++#define XGXS16G_COMBO_IEEE0_AUTONEGADVr 0x0000ffe4 ++#define XGXS16G_WC40_DIGITAL4_MISC3r 0x0000833c ++ ++/* Digital4 :: Misc3 :: laneDisable [06:06] */ ++#define DIGITAL4_MISC3_LANEDISABLE_MASK 0x0040 ++#define DIGITAL4_MISC3_LANEDISABLE_ALIGN 0 ++#define DIGITAL4_MISC3_LANEDISABLE_BITS 1 ++#define DIGITAL4_MISC3_LANEDISABLE_SHIFT 6 ++ ++ ++/**************************************************************************** ++ * XGXS16G_IEEE_ieee0Blk ++ ***************************************************************************/ ++/**************************************************************************** ++ * ieee0Blk :: ieeeControl0 ++ ***************************************************************************/ ++/* ieee0Blk :: ieeeControl0 :: rst_hw [15:15] */ ++#define IEEE0BLK_IEEECONTROL0_RST_HW_MASK 0x8000 ++#define IEEE0BLK_IEEECONTROL0_RST_HW_ALIGN 0 ++#define IEEE0BLK_IEEECONTROL0_RST_HW_BITS 1 ++#define IEEE0BLK_IEEECONTROL0_RST_HW_SHIFT 15 ++ ++/* ieee0Blk :: ieeeControl0 :: gloopback [14:14] */ ++#define IEEE0BLK_IEEECONTROL0_GLOOPBACK_MASK 0x4000 ++#define IEEE0BLK_IEEECONTROL0_GLOOPBACK_ALIGN 0 ++#define IEEE0BLK_IEEECONTROL0_GLOOPBACK_BITS 1 ++#define IEEE0BLK_IEEECONTROL0_GLOOPBACK_SHIFT 14 ++ ++ ++/**************************************************************************** ++ * XGXS16G_USER_XgxsBlk0 ++ ***************************************************************************/ ++/**************************************************************************** ++ * XgxsBlk0 :: xgxsControl ++ ***************************************************************************/ ++/* XgxsBlk0 :: xgxsControl :: start_sequencer [13:13] */ ++#define XGXSBLK0_XGXSCONTROL_START_SEQUENCER_MASK 0x2000 ++#define XGXSBLK0_XGXSCONTROL_START_SEQUENCER_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_START_SEQUENCER_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_START_SEQUENCER_SHIFT 13 ++ ++/* XgxsBlk0 :: xgxsControl :: mode_10g [11:08] */ ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_MASK 0x0f00 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_BITS 4 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_SHIFT 8 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_XGXS 0 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_XGXS_noCC 1 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_IndLane 6 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_XGXS_noLss 8 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_XGXS_noLss_noCC 9 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_protBypass 10 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_protBypass_noDsk 11 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_ComboCoreMode 12 ++#define XGXSBLK0_XGXSCONTROL_MODE_10G_ClocksOff 15 ++ ++/* XgxsBlk0 :: xgxsControl :: hstl [05:05] */ ++#define XGXSBLK0_XGXSCONTROL_HSTL_MASK 0x0020 ++#define XGXSBLK0_XGXSCONTROL_HSTL_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_HSTL_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_HSTL_SHIFT 5 ++ ++/* XgxsBlk0 :: xgxsControl :: cdet_en [03:03] */ ++#define XGXSBLK0_XGXSCONTROL_CDET_EN_MASK 0x0008 ++#define XGXSBLK0_XGXSCONTROL_CDET_EN_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_CDET_EN_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_CDET_EN_SHIFT 3 ++ ++/* XgxsBlk0 :: xgxsControl :: eden [02:02] */ ++#define XGXSBLK0_XGXSCONTROL_EDEN_MASK 0x0004 ++#define XGXSBLK0_XGXSCONTROL_EDEN_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_EDEN_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_EDEN_SHIFT 2 ++ ++/* XgxsBlk0 :: xgxsControl :: afrst_en [01:01] */ ++#define XGXSBLK0_XGXSCONTROL_AFRST_EN_MASK 0x0002 ++#define XGXSBLK0_XGXSCONTROL_AFRST_EN_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_AFRST_EN_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_AFRST_EN_SHIFT 1 ++ ++/* XgxsBlk0 :: xgxsControl :: txcko_div [00:00] */ ++#define XGXSBLK0_XGXSCONTROL_TXCKO_DIV_MASK 0x0001 ++#define XGXSBLK0_XGXSCONTROL_TXCKO_DIV_ALIGN 0 ++#define XGXSBLK0_XGXSCONTROL_TXCKO_DIV_BITS 1 ++#define XGXSBLK0_XGXSCONTROL_TXCKO_DIV_SHIFT 0 ++ ++ ++/**************************************************************************** ++ * XgxsBlk0 :: xgxsStatus ++ ***************************************************************************/ ++/* XgxsBlk0 :: xgxsStatus :: txpll_lock [11:11] */ ++#define XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_MASK 0x0800 ++#define XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_ALIGN 0 ++#define XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_BITS 1 ++#define XGXSBLK0_XGXSSTATUS_TXPLL_LOCK_SHIFT 11 ++ ++ ++/**************************************************************************** ++ * XgxsBlk0 :: miscControl1 ++ ***************************************************************************/ ++/* XgxsBlk0 :: miscControl1 :: PCS_dev_en_override [10:10] */ ++#define XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_MASK 0x0400 ++#define XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_ALIGN 0 ++#define XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_BITS 1 ++#define XGXSBLK0_MISCCONTROL1_PCS_DEV_EN_OVERRIDE_SHIFT 10 ++ ++/* XgxsBlk0 :: miscControl1 :: PMD_dev_en_override [09:09] */ ++#define XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_MASK 0x0200 ++#define XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_ALIGN 0 ++#define XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_BITS 1 ++#define XGXSBLK0_MISCCONTROL1_PMD_DEV_EN_OVERRIDE_SHIFT 9 ++ ++/* XgxsBlk0 :: miscControl1 :: ieee_blksel_autodet [01:01] */ ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_MASK 0x0002 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_ALIGN 0 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_BITS 1 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_AUTODET_SHIFT 1 ++ ++/* XgxsBlk0 :: miscControl1 :: ieee_blksel_val [00:00] */ ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_MASK 0x0001 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_ALIGN 0 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_BITS 1 ++#define XGXSBLK0_MISCCONTROL1_IEEE_BLKSEL_VAL_SHIFT 0 ++ ++ ++/**************************************************************************** ++ * XGXS16G_USER_XgxsBlk1 ++ ***************************************************************************/ ++/**************************************************************************** ++ * XgxsBlk1 :: laneCtrl0 ++ ***************************************************************************/ ++/* XgxsBlk1 :: laneCtrl0 :: cl36_pcs_en_rx [07:04] */ ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_MASK 0x00f0 ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_ALIGN 0 ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_BITS 4 ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_RX_SHIFT 4 ++ ++/* XgxsBlk1 :: laneCtrl0 :: cl36_pcs_en_tx [03:00] */ ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_MASK 0x000f ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_ALIGN 0 ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_BITS 4 ++#define XGXSBLK1_LANECTRL0_CL36_PCS_EN_TX_SHIFT 0 ++ ++ ++/**************************************************************************** ++ * XGXS16G_USER_TX0 ++ ***************************************************************************/ ++/**************************************************************************** ++ * TX0 :: Tx_AControl0 ++ ***************************************************************************/ ++/* TX0 :: Tx_AControl0 :: txpol_flip [05:05] */ ++#define TX0_TX_ACONTROL0_TXPOL_FLIP_MASK 0x0020 ++#define TX0_TX_ACONTROL0_TXPOL_FLIP_ALIGN 0 ++#define TX0_TX_ACONTROL0_TXPOL_FLIP_BITS 1 ++#define TX0_TX_ACONTROL0_TXPOL_FLIP_SHIFT 5 ++ ++ ++/**************************************************************************** ++ * XGXS16G_USER_dsc_2_0 ++ ***************************************************************************/ ++/**************************************************************************** ++ * dsc_2_0 :: dsc_ctrl0 ++ ***************************************************************************/ ++/* dsc_2_0 :: dsc_ctrl0 :: rxSeqStart [15:15] */ ++#define DSC_2_0_DSC_CTRL0_RXSEQSTART_MASK 0x8000 ++#define DSC_2_0_DSC_CTRL0_RXSEQSTART_ALIGN 0 ++#define DSC_2_0_DSC_CTRL0_RXSEQSTART_BITS 1 ++#define DSC_2_0_DSC_CTRL0_RXSEQSTART_SHIFT 15 ++ ++ ++/**************************************************************************** ++ * XGXS16G_USER_SerdesDigital ++ ***************************************************************************/ ++/**************************************************************************** ++ * SerdesDigital :: Control1000X1 ++ ***************************************************************************/ ++/* SerdesDigital :: Control1000X1 :: crc_checker_disable [07:07] */ ++#define SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_MASK 0x0080 ++#define SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_ALIGN 0 ++#define SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_BITS 1 ++#define SERDESDIGITAL_CONTROL1000X1_CRC_CHECKER_DISABLE_SHIFT 7 ++ ++/* SerdesDigital :: Control1000X1 :: disable_pll_pwrdwn [06:06] */ ++#define SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_MASK 0x0040 ++#define SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_ALIGN 0 ++#define SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_BITS 1 ++#define SERDESDIGITAL_CONTROL1000X1_DISABLE_PLL_PWRDWN_SHIFT 6 ++ ++/* SerdesDigital :: Control1000X1 :: fiber_mode_1000X [00:00] */ ++#define SERDESDIGITAL_CONTROL1000X1_FIBER_MODE_1000X_MASK 0x0001 ++#define SERDESDIGITAL_CONTROL1000X1_FIBER_MODE_1000X_ALIGN 0 ++#define SERDESDIGITAL_CONTROL1000X1_FIBER_MODE_1000X_BITS 1 ++#define SERDESDIGITAL_CONTROL1000X1_FIBER_MODE_1000X_SHIFT 0 ++ ++/**************************************************************************** ++ * SerdesDigital :: Control1000X3 ++ ***************************************************************************/ ++/* SerdesDigital :: Control1000X3 :: fifo_elasicity_tx_rx [02:01] */ ++#define SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_MASK 0x0006 ++#define SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_ALIGN 0 ++#define SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_BITS 2 ++#define SERDESDIGITAL_CONTROL1000X3_FIFO_ELASICITY_TX_RX_SHIFT 1 ++ ++/* SerdesDigital :: Control1000X3 :: tx_fifo_rst [00:00] */ ++#define SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_MASK 0x0001 ++#define SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_ALIGN 0 ++#define SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_BITS 1 ++#define SERDESDIGITAL_CONTROL1000X3_TX_FIFO_RST_SHIFT 0 ++ ++/**************************************************************************** ++ * SerdesDigital :: Status1000X1 ++ ***************************************************************************/ ++/* SerdesDigital :: Status1000X1 :: speed_status [04:03] */ ++#define SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_MASK 0x0018 ++#define SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_ALIGN 0 ++#define SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_BITS 2 ++#define SERDESDIGITAL_STATUS1000X1_SPEED_STATUS_SHIFT 3 ++ ++/**************************************************************************** ++ * SerdesDigital :: Misc1 ++ ***************************************************************************/ ++/* SerdesDigital :: Misc1 :: refclk_sel [15:13] */ ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_MASK 0xe000 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_ALIGN 0 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_BITS 3 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_SHIFT 13 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_25MHz 0 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_100MHz 1 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_125MHz 2 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_156p25MHz 3 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_187p5MHz 4 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_161p25Mhz 5 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_50Mhz 6 ++#define SERDESDIGITAL_MISC1_REFCLK_SEL_clk_106p25Mhz 7 ++ ++/* SerdesDigital :: Misc1 :: force_speed_sel [04:04] */ ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_MASK 0x0010 ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_ALIGN 0 ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_BITS 1 ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_SEL_SHIFT 4 ++ ++/* SerdesDigital :: Misc1 :: force_speed [03:00] */ ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_MASK 0x000f ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_ALIGN 0 ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_BITS 4 ++#define SERDESDIGITAL_MISC1_FORCE_SPEED_SHIFT 0 ++ ++ ++/**************************************************************************** ++ * CL73_UserB0 :: CL73_BAMCtrl1 ++ ***************************************************************************/ ++/* CL73_UserB0 :: CL73_BAMCtrl1 :: CL73_bamEn [15:15] */ ++#define CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_MASK 0x8000 ++#define CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_ALIGN 0 ++#define CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_BITS 1 ++#define CL73_USERB0_CL73_BAMCTRL1_CL73_BAMEN_SHIFT 15 ++ ++/* Definitions required in addition to the above auto-generated */ ++#define XGXS16G_REMOTEPHY_MISC5_LPI_MASK 0xc000 ++#define IEEE0BLK_IEEECONTROL0_ENABLE_AN_MASK BIT(12) ++#define IEEE0BLK_IEEECONTROL0_RESTART_AN_MASK BIT(9) ++#define XGXSBLK0_CONTROL_PLL_SEQUENCER_MASK BIT(13) ++#define SERDESDIGITAL_CONTROL1000X1_SLAVE_MODE BIT(8) ++#define XGXS16G_PLL2_CTRL1r 0x00008081 ++#define XGXS16G_SERDESDIGITAL_STATUS1000X2r 0x00008305 ++#define XGXS16G_CL73_USERB0_CL73_BAMCTRL1r 0x00008372 ++#define XGXS16G_RX3_CONTROL2r 0x00008482 ++#define XGXS16G_PLL2_CTRL_CAL_TH_SHIFT 7 ++#define XGXS16G_SERDES_LANE_SHIFT 16 ++#define XGXS16G_SERDES_ANEG_MASK BIT(4) ++#define MII_ANA_C37_PAUSE BIT(7) ++#define MII_ANA_C37_ASYM_PAUSE BIT(8) ++#define MII_ANA_C37_FD BIT(5) ++ ++#endif /* _PHY_XGXS16G_H_ */ ++ ++/* End of File */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig +--- a/drivers/pci/host/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/pci/host/Kconfig 2018-05-10 11:31:32.457402700 +0800 +@@ -99,6 +99,15 @@ config PCI_VERSATILE + bool "ARM Versatile PB PCI controller" + depends on ARCH_VERSATILE + ++config PCIE_XGS_IPROC ++ bool "Broadcom XGS iProc PCIe controller" ++ select PCI_DOMAINS ++ depends on ARCH_XGS_IPROC ++ default n ++ help ++ This enables the XGS iProc PCIe core controller support for Broadcom's ++ iProc family of SoCs. ++ + config PCIE_IPROC + tristate + select PCI_DOMAINS +@@ -129,7 +138,7 @@ config PCIE_IPROC_BCMA + + config PCIE_IPROC_MSI + bool "Broadcom iProc PCIe MSI support" +- depends on PCIE_IPROC_PLATFORM || PCIE_IPROC_BCMA ++ depends on PCIE_IPROC_PLATFORM || PCIE_IPROC_BCMA || PCIE_XGS_IPROC + depends on PCI_MSI_IRQ_DOMAIN + default ARCH_BCM_IPROC + help +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile +--- a/drivers/pci/host/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/pci/host/Makefile 2018-05-10 11:31:32.457402700 +0800 +@@ -16,6 +16,7 @@ obj-$(CONFIG_PCIE_IPROC) += pcie-iproc.o + obj-$(CONFIG_PCIE_IPROC_MSI) += pcie-iproc-msi.o + obj-$(CONFIG_PCIE_IPROC_PLATFORM) += pcie-iproc-platform.o + obj-$(CONFIG_PCIE_IPROC_BCMA) += pcie-iproc-bcma.o ++obj-$(CONFIG_PCIE_XGS_IPROC) += pcie-xgs-iproc.o + obj-$(CONFIG_PCIE_ALTERA) += pcie-altera.o + obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o + obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/pci/host/pcie-iproc.h b/drivers/pci/host/pcie-iproc.h +--- a/drivers/pci/host/pcie-iproc.h 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/pci/host/pcie-iproc.h 2018-05-10 11:31:32.461402704 +0800 +@@ -93,6 +93,9 @@ struct iproc_pcie { + struct resource mem; + struct pci_bus *root_bus; + struct phy *phy; ++#ifdef CONFIG_PCIE_XGS_IPROC ++ struct phy_device *mdio_phy; ++#endif + int (*map_irq)(const struct pci_dev *, u8, u8); + bool ep_is_internal; + bool has_apb_err_disable; +@@ -108,9 +111,11 @@ struct iproc_pcie { + struct iproc_msi *msi; + }; + ++#ifndef CONFIG_PCIE_XGS_IPROC + int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res); + int iproc_pcie_remove(struct iproc_pcie *pcie); + int iproc_pcie_shutdown(struct iproc_pcie *pcie); ++#endif + + #ifdef CONFIG_PCIE_IPROC_MSI + int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/pci/host/pcie-xgs-iproc.c b/drivers/pci/host/pcie-xgs-iproc.c +--- a/drivers/pci/host/pcie-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/pci/host/pcie-xgs-iproc.c 2018-05-10 11:31:32.461402704 +0800 +@@ -0,0 +1,541 @@ ++/* ++ * Copyright (C) 2014 Hauke Mehrtens ++ * Copyright (C) 2015 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "pcie-iproc.h" ++ ++#define CLK_CONTROL_OFFSET 0x000 ++ ++#define CFG_IND_ADDR_OFFSET 0x120 ++#define CFG_IND_ADDR_MASK 0x00001ffc ++#define CFG_IND_DATA_OFFSET 0x124 ++ ++#define CFG_ADDR_OFFSET 0x1f8 ++#define CFG_ADDR_BUS_NUM_SHIFT 20 ++#define CFG_ADDR_BUS_NUM_MASK 0x0ff00000 ++#define CFG_ADDR_DEV_NUM_SHIFT 15 ++#define CFG_ADDR_DEV_NUM_MASK 0x000f8000 ++#define CFG_ADDR_FUNC_NUM_SHIFT 12 ++#define CFG_ADDR_FUNC_NUM_MASK 0x00007000 ++#define CFG_ADDR_REG_NUM_SHIFT 2 ++#define CFG_ADDR_REG_NUM_MASK 0x00000ffc ++#define CFG_ADDR_CFG_TYPE_SHIFT 0 ++#define CFG_ADDR_CFG_TYPE_MASK 0x00000003 ++ ++#define CFG_DATA_OFFSET 0x1fc ++ ++#define SYS_RC_INTX_EN 0x330 ++#define SYS_RC_INTX_MASK 0xf ++ ++#define IPROC_PCI_EXP_CAP 0xac ++ ++struct pcie_sw_wa { ++ const char *wa_name; ++ void (*wa_func)(struct iproc_pcie *pcie); ++}; ++ ++extern void xgs_phy_wr_reg(struct phy_device *phydev, u32 regnum, u16 data); ++ ++static inline struct iproc_pcie *iproc_pcie_data(struct pci_bus *bus) ++{ ++ struct iproc_pcie *pcie; ++#ifdef CONFIG_ARM ++ struct pci_sys_data *sys = bus->sysdata; ++ ++ pcie = sys->private_data; ++#else ++ pcie = bus->sysdata; ++#endif ++ return pcie; ++} ++ ++/** ++ * Note access to the configuration registers are protected at the higher layer ++ * by 'pci_lock' in drivers/pci/access.c ++ */ ++static void __iomem *iproc_pcie_map_cfg_bus(struct iproc_pcie *pcie, ++ int busno, unsigned int devfn, ++ int where) ++{ ++ u32 slot = PCI_SLOT(devfn); ++ u32 fn = PCI_FUNC(devfn); ++ u32 val; ++ ++ /* root complex access */ ++ if (busno == 0) { ++ if (slot >= 1) ++ return NULL; ++ writel(where & CFG_IND_ADDR_MASK, ++ pcie->base + CFG_IND_ADDR_OFFSET); ++ return (pcie->base + CFG_IND_DATA_OFFSET); ++ } ++ ++ if (fn > 1) ++ return NULL; ++ ++ /* EP device access */ ++ val = (busno << CFG_ADDR_BUS_NUM_SHIFT) | ++ (slot << CFG_ADDR_DEV_NUM_SHIFT) | ++ (fn << CFG_ADDR_FUNC_NUM_SHIFT) | ++ (where & CFG_ADDR_REG_NUM_MASK) | ++ (1 & CFG_ADDR_CFG_TYPE_MASK); ++ writel(val, pcie->base + CFG_ADDR_OFFSET); ++ ++ return (pcie->base + CFG_DATA_OFFSET); ++} ++ ++static void __iomem *iproc_pcie_bus_map_cfg_bus(struct pci_bus *bus, ++ unsigned int devfn, ++ int where) ++{ ++ return iproc_pcie_map_cfg_bus(iproc_pcie_data(bus), bus->number, devfn, ++ where); ++} ++ ++static int iproc_pci_raw_config_read32(struct iproc_pcie *pcie, ++ unsigned int devfn, int where, ++ int size, u32 *val) ++{ ++ void __iomem *addr; ++ ++ addr = iproc_pcie_map_cfg_bus(pcie, 0, devfn, where & ~0x3); ++ if (!addr) { ++ *val = ~0; ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ } ++ ++ *val = readl(addr); ++ ++ if (size <= 2) ++ *val = (*val >> (8 * (where & 3))) & ((1 << (size * 8)) - 1); ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++static int iproc_pci_raw_config_write32(struct iproc_pcie *pcie, ++ unsigned int devfn, int where, ++ int size, u32 val) ++{ ++ void __iomem *addr; ++ u32 mask, tmp; ++ ++ addr = iproc_pcie_map_cfg_bus(pcie, 0, devfn, where & ~0x3); ++ if (!addr) ++ return PCIBIOS_DEVICE_NOT_FOUND; ++ ++ if (size == 4) { ++ writel(val, addr); ++ return PCIBIOS_SUCCESSFUL; ++ } ++ ++ mask = ~(((1 << (size * 8)) - 1) << ((where & 0x3) * 8)); ++ tmp = readl(addr) & mask; ++ tmp |= val << ((where & 0x3) * 8); ++ writel(tmp, addr); ++ ++ return PCIBIOS_SUCCESSFUL; ++} ++ ++ ++static struct pci_ops iproc_pcie_ops = { ++ .map_bus = iproc_pcie_bus_map_cfg_bus, ++ .read = pci_generic_config_read32, ++ .write = pci_generic_config_write32, ++}; ++ ++static inline void pcie_wrong_gen2_wa(struct iproc_pcie * pcie) ++{ ++ xgs_phy_wr_reg(pcie->mdio_phy, 0x8633, 0x190); ++ xgs_phy_wr_reg(pcie->mdio_phy, 0x8639, 0x191); ++} ++ ++static void iproc_pcie_reset(struct iproc_pcie *pcie) ++{ ++ /* configured as RC and send a downstream reset */ ++ writel(0, pcie->base + CLK_CONTROL_OFFSET); ++ mdelay(1); ++ writel(1, pcie->base + CLK_CONTROL_OFFSET); ++ msleep(100); ++} ++ ++static void pcie_rc_wa(struct iproc_pcie * pcie) ++{ ++ /* Setting for PCIe Serdes PLL output */ ++ xgs_phy_wr_reg(pcie->mdio_phy, 0x2103, 0x2b1c); ++ xgs_phy_wr_reg(pcie->mdio_phy, 0x1300, 0x000b); ++ msleep(100); ++} ++ ++/* currently for Greyhound */ ++static void pcie_tx_de_emp_wa(struct iproc_pcie * pcie) ++{ ++ u32 tmp32; ++ ++ iproc_pci_raw_config_read32(pcie, 0, 0xdc, 4, &tmp32); ++ tmp32 |= (0x1 << 6); ++ iproc_pci_raw_config_write32(pcie, 0, 0xdc, 4, tmp32); ++ iproc_pci_raw_config_read32(pcie, 0, 0xdc, 4, &tmp32); ++} ++ ++static const struct pcie_sw_wa pcie_wa_tab[] = { ++ { ++ .wa_name = "pcie_wrong_gen2", ++ .wa_func = pcie_wrong_gen2_wa, ++ }, ++ { ++ .wa_name = "pcie_rc", ++ .wa_func = pcie_rc_wa, ++ }, ++ { ++ .wa_name = "pcie_perst", ++ .wa_func = iproc_pcie_reset, ++ }, ++ { ++ .wa_name = "pcie_tx_de_emp", ++ .wa_func = pcie_tx_de_emp_wa, ++ }, ++}; ++ ++/* ++ * Run the specific pcie workaround function specified in "pcie_wa_tab", ++ * if "wa_name" is found on the "wa-list" property of pcie node. ++ */ ++static void pcie_sw_wa_func(const char *wa_name, struct iproc_pcie *pcie) ++{ ++ struct device_node *np = pcie->dev->of_node; ++ int wa_num_max = ARRAY_SIZE(pcie_wa_tab); ++ int wa_num = of_property_count_strings(np, "wa-list"); ++ const char *wa_name_dts; ++ int i; ++ ++ /* workaround required? */ ++ if (wa_num <= 0) ++ return; ++ ++ for (i = 0; i < wa_num; i++) { ++ of_property_read_string_index(np, "wa-list", i, &wa_name_dts); ++ if (!strcmp(wa_name, wa_name_dts)) ++ break; ++ } ++ ++ /* The wa_name is found on wa-list of pcie node? */ ++ if (i == wa_num) ++ return; ++ ++ for (i = 0; i < wa_num_max; i++) ++ if (!strcmp(pcie_wa_tab[i].wa_name, wa_name)) { ++ pcie_wa_tab[i].wa_func(pcie); ++ break; ++ } ++} ++ ++static int iproc_pcie_check_link(struct iproc_pcie *pcie) ++{ ++ struct device *dev = pcie->dev; ++ u32 hdr_type, link_ctrl, link_status, class; ++ bool link_is_active = false; ++ ++ /* make sure we are not in EP mode */ ++ iproc_pci_raw_config_read32(pcie, 0, PCI_HEADER_TYPE, 1, &hdr_type); ++ if ((hdr_type & 0x7f) != PCI_HEADER_TYPE_BRIDGE) { ++ dev_err(dev, "in EP mode, hdr=%#02x\n", hdr_type); ++ return -EFAULT; ++ } ++ ++ /* SB2/GH/HR3/GH2 */ ++ pcie_sw_wa_func("pcie_rc", pcie); ++ ++ /* GH/HR3/GH2 */ ++ pcie_sw_wa_func("pcie_perst", pcie); ++ ++ /* Not enabled in DT file currently */ ++ pcie_sw_wa_func("pcie_tx_de_emp", pcie); ++ ++ /* Force class to PCI_CLASS_BRIDGE_PCI (0x0604) */ ++#define PCI_BRIDGE_CTRL_REG_OFFSET 0x43c ++#define PCI_CLASS_BRIDGE_MASK 0xffff00 ++#define PCI_CLASS_BRIDGE_SHIFT 8 ++ iproc_pci_raw_config_read32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET, ++ 4, &class); ++ class &= ~PCI_CLASS_BRIDGE_MASK; ++ class |= (PCI_CLASS_BRIDGE_PCI << PCI_CLASS_BRIDGE_SHIFT); ++ iproc_pci_raw_config_write32(pcie, 0, PCI_BRIDGE_CTRL_REG_OFFSET, ++ 4, class); ++ ++ /* check link status to see if link is active */ ++ iproc_pci_raw_config_read32(pcie, 0, IPROC_PCI_EXP_CAP + PCI_EXP_LNKSTA, ++ 2, &link_status); ++ if (link_status & PCI_EXP_LNKSTA_NLW) ++ link_is_active = true; ++ ++ if (!link_is_active) { ++ /* try GEN 1 link speed */ ++#define PCI_TARGET_LINK_SPEED_MASK 0xf ++#define PCI_TARGET_LINK_SPEED_GEN2 0x2 ++#define PCI_TARGET_LINK_SPEED_GEN1 0x1 ++ iproc_pci_raw_config_read32(pcie, 0, ++ IPROC_PCI_EXP_CAP + PCI_EXP_LNKCTL2, ++ 4, &link_ctrl); ++ if ((link_ctrl & PCI_TARGET_LINK_SPEED_MASK) == ++ PCI_TARGET_LINK_SPEED_GEN2) { ++ link_ctrl &= ~PCI_TARGET_LINK_SPEED_MASK; ++ link_ctrl |= PCI_TARGET_LINK_SPEED_GEN1; ++ iproc_pci_raw_config_write32(pcie, 0, ++ IPROC_PCI_EXP_CAP + PCI_EXP_LNKCTL2, ++ 4, link_ctrl); ++ msleep(100); ++ ++ iproc_pci_raw_config_read32(pcie, 0, ++ IPROC_PCI_EXP_CAP + PCI_EXP_LNKSTA, ++ 2, &link_status); ++ if (link_status & PCI_EXP_LNKSTA_NLW) ++ link_is_active = true; ++ } ++ } ++ ++ dev_info(pcie->dev, "link: %s\n", link_is_active ? "UP" : "DOWN"); ++ ++ return link_is_active ? 0 : -ENODEV; ++} ++ ++static void iproc_pcie_enable(struct iproc_pcie *pcie) ++{ ++ writel(SYS_RC_INTX_MASK, pcie->base + SYS_RC_INTX_EN); ++} ++ ++static int iproc_pcie_msi_enable(struct iproc_pcie *pcie) ++{ ++ struct device_node *msi_node; ++ ++ msi_node = of_parse_phandle(pcie->dev->of_node, "msi-parent", 0); ++ if (!msi_node) ++ return -ENODEV; ++ ++ /* ++ * If another MSI controller is being used, the call below should fail ++ * but that is okay ++ */ ++ return iproc_msi_init(pcie, msi_node); ++} ++ ++static void iproc_pcie_msi_disable(struct iproc_pcie *pcie) ++{ ++ iproc_msi_exit(pcie); ++} ++ ++static int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res) ++{ ++ struct device *dev; ++ int ret; ++ void *sysdata; ++ struct pci_bus *child; ++ struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); ++ ++ if (!pcie || !pcie->dev || !pcie->base) ++ return -EINVAL; ++ ++ dev = pcie->dev; ++ ++ ret = devm_request_pci_bus_resources(dev, res); ++ if (ret) ++ return ret; ++ ++ ret = phy_init(pcie->phy); ++ if (ret) { ++ dev_err(pcie->dev, "unable to initialize PCIe PHY\n"); ++ return ret; ++ } ++ ++ ret = phy_power_on(pcie->phy); ++ if (ret) { ++ dev_err(pcie->dev, "unable to power on PCIe PHY\n"); ++ goto err_exit_phy; ++ } ++ ++ iproc_pcie_reset(pcie); ++ ++#ifdef CONFIG_ARM ++ pcie->sysdata.private_data = pcie; ++ sysdata = &pcie->sysdata; ++#else ++ sysdata = pcie; ++#endif ++ ++ ret = iproc_pcie_check_link(pcie); ++ if (ret) { ++ dev_err(pcie->dev, "no PCIe EP device detected\n"); ++ goto err_power_off_phy; ++ } ++ ++ iproc_pcie_enable(pcie); ++ ++ if (IS_ENABLED(CONFIG_PCI_MSI)) ++ if (iproc_pcie_msi_enable(pcie)) ++ dev_info(pcie->dev, "not using iProc MSI\n"); ++ ++ list_splice_init(res, &host->windows); ++ host->busnr = 0; ++ host->dev.parent = dev; ++ host->ops = &iproc_pcie_ops; ++ host->sysdata = sysdata; ++ host->map_irq = pcie->map_irq; ++ host->swizzle_irq = pci_common_swizzle; ++ ++ ret = pci_scan_root_bus_bridge(host); ++ if (ret < 0) { ++ dev_err(dev, "failed to scan host: %d\n", ret); ++ goto err_power_off_phy; ++ } ++ ++ pci_assign_unassigned_bus_resources(host->bus); ++ ++ pcie->root_bus = host->bus; ++ ++ list_for_each_entry(child, &host->bus->children, node) ++ pcie_bus_configure_settings(child); ++ ++ pci_bus_add_devices(host->bus); ++ ++ return 0; ++ ++err_power_off_phy: ++ phy_power_off(pcie->phy); ++err_exit_phy: ++ phy_exit(pcie->phy); ++ ++ return ret; ++} ++ ++static int iproc_pcie_probe(struct platform_device *pdev) ++{ ++ struct iproc_pcie *pcie; ++ struct device_node *np = pdev->dev.of_node; ++ struct device_node *mdio_phy_np = NULL; ++ struct resource reg; ++ struct pci_host_bridge *bridge; ++ resource_size_t iobase = 0; ++ LIST_HEAD(res); ++ int ret; ++ ++ bridge = devm_pci_alloc_host_bridge(&pdev->dev, sizeof(*pcie)); ++ if (!bridge) ++ return -ENOMEM; ++ ++ pcie = pci_host_bridge_priv(bridge); ++ ++ pcie->dev = &pdev->dev; ++ platform_set_drvdata(pdev, pcie); ++ ++ pcie->type = (enum iproc_pcie_type)np->data; ++ ++ ret = of_address_to_resource(np, 0, ®); ++ if (ret < 0) { ++ dev_err(pcie->dev, "unable to obtain controller resources\n"); ++ return ret; ++ } ++ ++ pcie->base = devm_ioremap_resource(pcie->dev, ®); ++ if (IS_ERR(pcie->base)) ++ return PTR_ERR(pcie->base); ++ ++ /* MSI message base addr*/ ++ pcie->base_addr = reg.start; ++ ++ /* PHY use is optional */ ++ pcie->phy = devm_phy_get(&pdev->dev, "pcie-phy"); ++ if (IS_ERR(pcie->phy)) { ++ if (PTR_ERR(pcie->phy) == -EPROBE_DEFER) ++ return -EPROBE_DEFER; ++ pcie->phy = NULL; ++ } ++ ++ /* PHY controlled through MDIO for HX4/KT2 */ ++ mdio_phy_np = of_parse_phandle(np, "mdio-phy-handle", 0); ++ if (mdio_phy_np) ++ pcie->mdio_phy = of_phy_find_device(mdio_phy_np); ++ ++ ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &iobase); ++ if (ret) { ++ dev_err(pcie->dev, ++ "unable to get PCI host bridge resources\n"); ++ return ret; ++ } ++ ++ /* HX4/KT2/HR2 */ ++ pcie_sw_wa_func("pcie_wrong_gen2", pcie); ++ ++ pcie->map_irq = of_irq_parse_and_map_pci; ++ ++ ret = iproc_pcie_setup(pcie, &res); ++ if (ret) ++ dev_err(pcie->dev, "PCIe controller setup failed\n"); ++ ++ pci_free_resource_list(&res); ++ ++ return ret; ++} ++ ++static int iproc_pcie_remove(struct platform_device *pdev) ++{ ++ struct iproc_pcie *pcie = platform_get_drvdata(pdev); ++ ++ pci_stop_root_bus(pcie->root_bus); ++ pci_remove_root_bus(pcie->root_bus); ++ ++ iproc_pcie_msi_disable(pcie); ++ ++ phy_power_off(pcie->phy); ++ phy_exit(pcie->phy); ++ ++ return 0; ++} ++ ++static const struct of_device_id iproc_pcie_of_match_table[] = { ++ { ++ .compatible = "brcm,iproc-pcie", ++ .data = (int *)IPROC_PCIE_PAXB, ++ }, ++ { /* sentinel */ } ++}; ++MODULE_DEVICE_TABLE(of, iproc_pcie_of_match_table); ++ ++static struct platform_driver iproc_pcie_pltfm_driver = { ++ .driver = { ++ .name = "iproc-pcie", ++ .of_match_table = of_match_ptr(iproc_pcie_of_match_table), ++ }, ++ .probe = iproc_pcie_probe, ++ .remove = iproc_pcie_remove, ++}; ++ ++module_platform_driver(iproc_pcie_pltfm_driver); ++ ++MODULE_DESCRIPTION("Broadcom XGS iProc PCIe driver"); ++MODULE_LICENSE("GPL v2"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/Makefile b/drivers/soc/bcm/Makefile +--- a/drivers/soc/bcm/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/soc/bcm/Makefile 2018-05-10 11:31:33.013403309 +0800 +@@ -1,2 +1,3 @@ + obj-$(CONFIG_RASPBERRYPI_POWER) += raspberrypi-power.o + obj-$(CONFIG_SOC_BRCMSTB) += brcmstb/ ++obj-$(CONFIG_ARCH_XGS_IPROC) += xgs_iproc/ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/xgs_iproc/Makefile b/drivers/soc/bcm/xgs_iproc/Makefile +--- a/drivers/soc/bcm/xgs_iproc/Makefile 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/xgs_iproc/Makefile 2018-05-10 11:31:33.017403314 +0800 +@@ -0,0 +1 @@ ++obj-$(CONFIG_ARCH_XGS_IPROC) += xgs-iproc-misc-setup.o xgs-iproc-idm.o xgs-iproc.o iproc-cmic.o iproc-cmicx.o iproc-cmicd.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/xgs_iproc/iproc-cmic.c b/drivers/soc/bcm/xgs_iproc/iproc-cmic.c +--- a/drivers/soc/bcm/xgs_iproc/iproc-cmic.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/xgs_iproc/iproc-cmic.c 2018-05-10 11:31:33.017403314 +0800 +@@ -0,0 +1,161 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++extern const struct sbus_ops cmicx_sbus_ops; ++extern const struct sbus_ops cmicd_sbus_ops; ++ ++static struct iproc_cmic *cmic; ++ ++int iproc_cmic_schan_reg32_write(u32 blk_type, u32 addr, u32 val) ++{ ++ if (cmic && cmic->sbus_ops) { ++ if (cmic->sbus_ops->reg32_write) { ++ return cmic->sbus_ops->reg32_write(cmic, blk_type, addr, val); ++ } ++ } ++ return -EINVAL; ++} ++ ++u32 iproc_cmic_schan_reg32_read(u32 blk_type, u32 addr) ++{ ++ if (cmic && cmic->sbus_ops) { ++ if (cmic->sbus_ops->reg32_read) { ++ return cmic->sbus_ops->reg32_read(cmic, blk_type, addr); ++ } ++ } ++ return 0; ++} ++ ++int iproc_cmic_schan_reg64_write(u32 blk_type, u32 addr, u64 val) ++{ ++ if (cmic && cmic->sbus_ops) { ++ if (cmic->sbus_ops->reg64_write) { ++ return cmic->sbus_ops->reg64_write(cmic, blk_type, addr, val); ++ } ++ } ++ return -EINVAL; ++} ++ ++u64 iproc_cmic_schan_reg64_read(u32 blk_type, u32 addr) ++{ ++ if (cmic && cmic->sbus_ops) { ++ if (cmic->sbus_ops->reg64_read) { ++ return cmic->sbus_ops->reg64_read(cmic, blk_type, addr); ++ } ++ } ++ return 0; ++} ++ ++int iproc_cmic_schan_ucmem_write(u32 blk_type, u32 *mem) ++{ ++ if (cmic && cmic->sbus_ops) { ++ if (cmic->sbus_ops->ucmem_write) { ++ return cmic->sbus_ops->ucmem_write(cmic, blk_type, mem); ++ } ++ } ++ return -EINVAL; ++} ++ ++int iproc_cmic_schan_ucmem_read(u32 blk_type, u32 *mem) ++{ ++ if (cmic && cmic->sbus_ops) { ++ if (cmic->sbus_ops->ucmem_read) { ++ return cmic->sbus_ops->ucmem_read(cmic, blk_type, mem); ++ } ++ } ++ return -EINVAL; ++} ++ ++void inline __iomem *iproc_cmic_base_get(void) ++{ ++ if (cmic && cmic->base) { ++ return cmic->base; ++ } ++ return NULL; ++} ++ ++/**************************************************************************** ++ ***************************************************************************/ ++static int cmic_probe(struct platform_device *pdev) ++{ ++ struct device_node *np = pdev->dev.of_node; ++ ++ cmic = devm_kzalloc(&pdev->dev, sizeof(*cmic), GFP_KERNEL); ++ if (!cmic) { ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(pdev, cmic); ++ cmic->dev = &pdev->dev; ++ ++ cmic->base = (void *)of_iomap(np, 0); ++ if (IS_ERR(cmic->base)) { ++ dev_err(&pdev->dev, "Unable to iomap CMIC resource\n"); ++ return PTR_ERR(cmic->base); ++ } ++ ++ if (of_device_is_compatible(np, "brcm,iproc-cmicx")) { ++ cmic->sbus_ops = &cmicx_sbus_ops; ++ } else if (of_device_is_compatible(np, "brcm,iproc-cmicd")) { ++ cmic->sbus_ops = &cmicd_sbus_ops; ++ } ++ ++ if (cmic->sbus_ops) { ++ if (cmic->sbus_ops->init) { ++ /* Initial cmic */ ++ cmic->sbus_ops->init(cmic); ++ } ++ } ++ ++ return 0; ++} ++ ++static int cmic_remove(struct platform_device *pdev) ++{ ++ if (cmic->base) { ++ iounmap(cmic->base); ++ } ++ ++ devm_kfree(&pdev->dev, cmic); ++ cmic = NULL; ++ ++ return 0; ++} ++ ++static const struct of_device_id iproc_cmic_of_match[] = { ++ {.compatible = "brcm,iproc-cmicx",}, ++ {.compatible = "brcm,iproc-cmicd",}, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, iproc_cmic_of_match); ++ ++static struct platform_driver iproc_cmic_driver = { ++ .driver = { ++ .name = "iproc_cmic", ++ .of_match_table = iproc_cmic_of_match, ++ }, ++ .probe = cmic_probe, ++ .remove = cmic_remove, ++}; ++ ++module_platform_driver(iproc_cmic_driver); ++MODULE_LICENSE("GPL"); ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/xgs_iproc/iproc-cmicd.c b/drivers/soc/bcm/xgs_iproc/iproc-cmicd.c +--- a/drivers/soc/bcm/xgs_iproc/iproc-cmicd.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/xgs_iproc/iproc-cmicd.c 2018-05-10 11:31:33.017403314 +0800 +@@ -0,0 +1,166 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define CMICD_SBUS_RING_MAP_0_7(base) (base + 0x10098) ++#define CMICD_SBUS_RING_MAP_8_15(base) (base + 0x1009C) ++#define CMICD_SBUS_RING_MAP_16_23(base) (base + 0x100A0) ++#define CMICD_SBUS_RING_MAP_24_31(base) (base + 0x100A4) ++#define CMICD_SCHAN_CH0_CTRL(base) (base + 0x10000) ++#define CMICD_SCHAN_CH0_MESSAGE(base) (base + 0x1000c) ++ ++#define READ_MEMORY_CMD_MSG 0x07 ++#define READ_MEMORY_ACK_MSG 0x08 ++#define WRITE_MEMORY_CMD_MSG 0x09 ++#define WRITE_MEMORY_ACK_MSG 0x0a ++#define READ_REGISTER_CMD_MSG 0x0b ++#define READ_REGISTER_ACK_MSG 0x0c ++#define WRITE_REGISTER_CMD_MSG 0x0d ++#define WRITE_REGISTER_ACK_MSG 0x0e ++#define SBUSV4_REGTYPE_SHIFT 25 ++#define SBUSV4_REGADDR_SHIFT 8 ++#define SBUSV4_OPCODE_SHIFT 26 ++#define SBUSV4_BLOCKID_SHIFT 19 ++#define SBUSV4_DLEN_SHIFT 7 ++ ++#define CMICD_XLPORT_WC_UCMEM_DATA 0x0 ++#define REG32_DATA_LEN 4 ++#define REG64_DATA_LEN 8 ++#define UCMEM_DATA_LEN 16 ++ ++#define CMICD_BLOCK_ID_TOP 16 ++ ++ ++#define CMICD_CMD(mode, blk, len) ((mode << SBUSV4_OPCODE_SHIFT) | \ ++ (blk << SBUSV4_BLOCKID_SHIFT) | \ ++ (len << SBUSV4_DLEN_SHIFT)) ++ ++static int __cmicd_schan_write(struct iproc_cmic *cmic, ++ u32 cmd, u32 addr, u32 *val, int len) ++{ ++ u32 read = 0x0; ++ void __iomem *msg_addr; ++ int i; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ msg_addr = CMICD_SCHAN_CH0_MESSAGE(cmic->base); ++ writel(cmd, msg_addr); ++ ++ msg_addr += 4; ++ writel(addr, msg_addr); ++ ++ for (i = 0; i < len; i++) { ++ msg_addr += 4; ++ writel(val[i], msg_addr); ++ } ++ ++ writel(0x1, CMICD_SCHAN_CH0_CTRL(cmic->base)); ++ ++ // FIXME, should set timeout ++ while (read != 0x2) { ++ read = readl(CMICD_SCHAN_CH0_CTRL(cmic->base)); ++ } ++ return read; ++} ++ ++static int __cmicd_schan_read(struct iproc_cmic *cmic, ++ u32 cmd, u32 addr, u32 *val, int len) ++{ ++ u32 read = 0x0; ++ void __iomem *msg_addr; ++ int i; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ read = __cmicd_schan_write(cmic, cmd, addr, NULL, 0); ++ if (read != 0x02) { ++ return read; ++ } ++ ++ msg_addr = CMICD_SCHAN_CH0_MESSAGE(cmic->base); ++ for (i = 0; i < len; i++) { ++ msg_addr += 4; ++ val[i] = readl(msg_addr); ++ } ++ return val[0]; ++} ++ ++static int iproc_cmicd_schan_reg32_write(struct iproc_cmic *cmic, ++ u32 blk_type, u32 addr, u32 val) ++{ ++ u32 cmd, block; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ if (blk_type == CMIC_BLOCK_TYPE_TOP) { ++ block = CMICD_BLOCK_ID_TOP; ++ } else { ++ return -EINVAL; ++ } ++ ++ cmd = CMICD_CMD(WRITE_REGISTER_CMD_MSG, block, REG32_DATA_LEN); ++ return __cmicd_schan_write(cmic, cmd, addr, &val, 1); ++} ++ ++static u32 iproc_cmicd_schan_reg32_read(struct iproc_cmic *cmic, ++ u32 blk_type, u32 addr) ++{ ++ u32 cmd, block, val; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ if (blk_type == CMIC_BLOCK_TYPE_TOP) { ++ block = CMICD_BLOCK_ID_TOP; ++ } else { ++ return -EINVAL; ++ } ++ ++ cmd = CMICD_CMD(READ_REGISTER_CMD_MSG, block, REG32_DATA_LEN); ++ return __cmicd_schan_read(cmic, cmd, addr, &val, 1); ++} ++ ++static int iproc_cmicd_init(struct iproc_cmic *cmic) ++{ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ /* Configure SBUS Ring Map for TOP, block id = 16, ring number = 4 */ ++ writel(0x11112200, CMICD_SBUS_RING_MAP_0_7(cmic->base)); ++ writel(0x00430001, CMICD_SBUS_RING_MAP_8_15(cmic->base)); ++ writel(0x00005064, CMICD_SBUS_RING_MAP_16_23(cmic->base)); ++ writel(0x00000000, CMICD_SBUS_RING_MAP_24_31(cmic->base)); ++ ++ return 0; ++} ++ ++const struct sbus_ops cmicd_sbus_ops = { ++ .init = iproc_cmicd_init, ++ .reg32_write = iproc_cmicd_schan_reg32_write, ++ .reg32_read = iproc_cmicd_schan_reg32_read, ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/xgs_iproc/iproc-cmicx.c b/drivers/soc/bcm/xgs_iproc/iproc-cmicx.c +--- a/drivers/soc/bcm/xgs_iproc/iproc-cmicx.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/xgs_iproc/iproc-cmicx.c 2018-05-30 15:50:51.032753168 +0800 +@@ -0,0 +1,269 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define CMICX_TOP_SBUS_TIMEOUT(base) (base + 0x00000) ++#define CMICX_TOP_SBUS_RING_MAP_0_7(base) (base + 0x0000c) ++#define CMICX_TOP_SBUS_RING_MAP_32_39(base) (base + 0x0001c) ++#define CMICX_SCHAN_CH0_CTRL(base) (base + 0x10000) ++#define CMICX_SCHAN_CH0_MESSAGE(base) (base + 0x1000c) ++ ++#define READ_MEMORY_CMD_MSG 0x07 ++#define READ_MEMORY_ACK_MSG 0x08 ++#define WRITE_MEMORY_CMD_MSG 0x09 ++#define WRITE_MEMORY_ACK_MSG 0x0a ++#define READ_REGISTER_CMD_MSG 0x0b ++#define READ_REGISTER_ACK_MSG 0x0c ++#define WRITE_REGISTER_CMD_MSG 0x0d ++#define WRITE_REGISTER_ACK_MSG 0x0e ++#define SBUSV4_REGTYPE_SHIFT 25 ++#define SBUSV4_REGADDR_SHIFT 8 ++#define SBUSV4_OPCODE_SHIFT 26 ++#define SBUSV4_BLOCKID_SHIFT 19 ++#define SBUSV4_DLEN_SHIFT 7 ++ ++#define CMICX_XLPORT_WC_UCMEM_DATA 0x0 ++#define REG32_DATA_LEN 4 ++#define REG64_DATA_LEN 8 ++#define UCMEM_DATA_LEN 16 ++ ++#define CMICX_BLOCK_ID_TOP 7 ++#define CMICX_BLOCK_ID_XLPORT7 38 ++ ++ ++#define CMICX_CMD(mode, blk, len) ((mode << SBUSV4_OPCODE_SHIFT) | \ ++ (blk << SBUSV4_BLOCKID_SHIFT) | \ ++ (len << SBUSV4_DLEN_SHIFT)) ++ ++static int __cmicx_schan_write(struct iproc_cmic *cmic, ++ u32 cmd, u32 addr, u32 *val, int len) ++{ ++ u32 read = 0x0; ++ void __iomem *msg_addr; ++ int i; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ msg_addr = CMICX_SCHAN_CH0_MESSAGE(cmic->base); ++ writel(cmd, msg_addr); ++ ++ msg_addr += 4; ++ writel(addr, msg_addr); ++ ++ for (i = 0; i < len; i++) { ++ msg_addr += 4; ++ writel(val[i], msg_addr); ++ } ++ ++ writel(0x1, CMICX_SCHAN_CH0_CTRL(cmic->base)); ++ ++ // FIXME, should set timeout ++ while (read != 0x2) { ++ read = readl(CMICX_SCHAN_CH0_CTRL(cmic->base)); ++ } ++ return read; ++} ++ ++static int __cmicx_schan_read(struct iproc_cmic *cmic, ++ u32 cmd, u32 addr, u32 *val, int len) ++{ ++ u32 read = 0; ++ void __iomem *msg_addr; ++ int i; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ msg_addr = CMICX_SCHAN_CH0_MESSAGE(cmic->base); ++ writel(cmd, msg_addr); ++ ++ msg_addr += 4; ++ writel(addr, msg_addr); ++ ++ writel(0x1, CMICX_SCHAN_CH0_CTRL(cmic->base)); ++ ++ // FIXME, should set timeout ++ while (read != 0x2) { ++ read = readl(CMICX_SCHAN_CH0_CTRL(cmic->base)); ++ } ++ ++ msg_addr = CMICX_SCHAN_CH0_MESSAGE(cmic->base); ++ for (i = 0; i < len; i++) { ++ msg_addr += 4; ++ val[i] = readl(msg_addr); ++ } ++ ++ if (len == 1) ++ return val[0]; ++ else ++ return val[1]; ++} ++ ++static int iproc_cmicx_schan_reg32_write(struct iproc_cmic *cmic, ++ u32 blk_type, u32 addr, u32 val) ++{ ++ u32 cmd, block; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ if (blk_type == CMIC_BLOCK_TYPE_TOP) { ++ block = CMICX_BLOCK_ID_TOP; ++ } else if (blk_type == CMIC_BLOCK_TYPE_APM) { ++ block = CMICX_BLOCK_ID_XLPORT7; } else { ++ return -EINVAL; ++ } ++ ++ cmd = CMICX_CMD(WRITE_REGISTER_CMD_MSG, block, REG32_DATA_LEN); ++ return __cmicx_schan_write(cmic, cmd, addr, &val, 1); ++} ++ ++static u32 iproc_cmicx_schan_reg32_read(struct iproc_cmic *cmic, ++ u32 blk_type, u32 addr) ++{ ++ u32 cmd, block, val; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ if (blk_type == CMIC_BLOCK_TYPE_TOP) { ++ block = CMICX_BLOCK_ID_TOP; ++ } else if (blk_type == CMIC_BLOCK_TYPE_APM) { ++ block = CMICX_BLOCK_ID_XLPORT7; } else { ++ return -EINVAL; ++ } ++ ++ cmd = CMICX_CMD(READ_REGISTER_CMD_MSG, block, REG32_DATA_LEN); ++ return __cmicx_schan_read(cmic, cmd, addr, &val, 1); ++} ++ ++static int iproc_cmicx_schan_reg64_write(struct iproc_cmic *cmic, ++ u32 blk_type, u32 addr, u64 val) ++{ ++ u32 cmd, block; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ if (blk_type == CMIC_BLOCK_TYPE_TOP) { ++ block = CMICX_BLOCK_ID_TOP; ++ } else if (blk_type == CMIC_BLOCK_TYPE_APM) { ++ block = CMICX_BLOCK_ID_XLPORT7; } else { ++ return -EINVAL; ++ } ++ ++ cmd = CMICX_CMD(WRITE_REGISTER_CMD_MSG, block, REG64_DATA_LEN); ++ return __cmicx_schan_write(cmic, cmd, addr, (u32 *)&val, 2); ++} ++ ++static u64 iproc_cmicx_schan_reg64_read(struct iproc_cmic *cmic, ++ u32 blk_type, u32 addr) ++{ ++ u32 cmd, block; ++ u64 val; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ if (blk_type == CMIC_BLOCK_TYPE_TOP) { ++ block = CMICX_BLOCK_ID_TOP; ++ } else if (blk_type == CMIC_BLOCK_TYPE_APM) { ++ block = CMICX_BLOCK_ID_XLPORT7; } else { ++ return -EINVAL; ++ } ++ ++ cmd = CMICX_CMD(READ_REGISTER_CMD_MSG, block, REG64_DATA_LEN); ++ __cmicx_schan_read(cmic, cmd, addr, (u32 *)&val, 2); ++ return val; ++} ++ ++static int iproc_cmicx_schan_ucmem_write(struct iproc_cmic *cmic, ++ u32 blk_type, u32 *mem) ++{ ++ u32 cmd, block; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ if (blk_type == CMIC_BLOCK_TYPE_TOP) { ++ block = CMICX_BLOCK_ID_TOP; ++ } else if (blk_type == CMIC_BLOCK_TYPE_APM) { ++ block = CMICX_BLOCK_ID_XLPORT7; } else { ++ return -EINVAL; ++ } ++ ++ cmd = CMICX_CMD(WRITE_MEMORY_CMD_MSG, block, UCMEM_DATA_LEN); ++ return __cmicx_schan_write(cmic, cmd, CMICX_XLPORT_WC_UCMEM_DATA, mem, 4); ++} ++ ++static int iproc_cmicx_schan_ucmem_read(struct iproc_cmic *cmic, ++ u32 blk_type, u32 *mem) ++{ ++ u32 cmd, block; ++ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ if (blk_type == CMIC_BLOCK_TYPE_TOP) { ++ block = CMICX_BLOCK_ID_TOP; ++ } else if (blk_type == CMIC_BLOCK_TYPE_APM) { ++ block = CMICX_BLOCK_ID_XLPORT7; } else { ++ return -EINVAL; ++ } ++ ++ cmd = CMICX_CMD(READ_MEMORY_CMD_MSG, block, UCMEM_DATA_LEN); ++ return __cmicx_schan_read(cmic, cmd, CMICX_XLPORT_WC_UCMEM_DATA, mem, 2); ++} ++ ++static int iproc_cmicx_init(struct iproc_cmic *cmic) ++{ ++ if (!cmic || !cmic->base) { ++ return -EINVAL; ++ } ++ ++ /* ++ * SBUS ring and block number: ++ * ring 5: TOP(7) ++ * ring 7: XLPORT7(38) ++ */ ++ writel(0x52222100, CMICX_TOP_SBUS_RING_MAP_0_7(cmic->base)); ++ writel(0x07500066, CMICX_TOP_SBUS_RING_MAP_32_39(cmic->base)); ++ writel(0x5000, CMICX_TOP_SBUS_TIMEOUT(cmic->base)); ++ ++ return 0; ++} ++ ++const struct sbus_ops cmicx_sbus_ops = { ++ .init = iproc_cmicx_init, ++ .reg32_write = iproc_cmicx_schan_reg32_write, ++ .reg32_read = iproc_cmicx_schan_reg32_read, ++ .reg64_write = iproc_cmicx_schan_reg64_write, ++ .reg64_read = iproc_cmicx_schan_reg64_read, ++ .ucmem_write = iproc_cmicx_schan_ucmem_write, ++ .ucmem_read = iproc_cmicx_schan_ucmem_read, ++}; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/xgs_iproc/xgs-iproc-idm.c b/drivers/soc/bcm/xgs_iproc/xgs-iproc-idm.c +--- a/drivers/soc/bcm/xgs_iproc/xgs-iproc-idm.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/xgs_iproc/xgs-iproc-idm.c 2018-05-10 11:31:33.017403314 +0800 +@@ -0,0 +1,309 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define IPROC_IDM_COMPATIBLE "brcm,iproc-idm" ++ ++#define IDM_ERROR_LOG_ENABLE 0x33A ++#define IDM_ERROR_LOG_CLEAR 0x3 ++ ++#define IDM_ERROR_LOG_CONTROL_REG(base) (base + 0x900) ++#define IDM_ERROR_LOG_COMPLETE_REG(base) (base + 0x904) ++#define IDM_ERROR_LOG_STATUS_REG(base) (base + 0x908) ++#define IDM_ERROR_LOG_ADDR_LSB_REG(base) (base + 0x90c) ++#define IDM_ERROR_LOG_ID_REG(base) (base + 0x914) ++#define IDM_ERROR_LOG_FLAGS_REG(base) (base + 0x91c) ++#define IDM_INTERRUPT_STATUS_REG(base) (base + 0xa00) ++ ++enum support_dev_ids { ++ XGS_IPROC_HX4 = 0, ++ XGS_IPROC_KT2, ++ XGS_IPROC_HR2, ++ XGS_IPROC_GH, ++ XGS_IPROC_SB2, ++ XGS_IPROC_HR3, ++ XGS_IPROC_GH2, ++ XGS_IPROC_WH2, ++ XGS_IPROC_HX5, ++ XGS_IPROC_MAX_DEVS, ++}; ++ ++static struct xgs_iproc_dev_infos_s { ++ char dt_compat_str[32]; ++ u32 dev_id; ++ u32 dmac_reset_offset; ++} xgs_iproc_dev_infos[] = { ++ { "brcm,helix4", XGS_IPROC_HX4, 0x14800 }, ++ { "brcm,katana2", XGS_IPROC_KT2, 0x14800 }, ++ { "brcm,hurricane2", XGS_IPROC_HR2, 0x14800 }, ++ { "brcm,greyhound", XGS_IPROC_GH, 0x14800 }, ++ { "brcm,saber2", XGS_IPROC_SB2, 0xf800 }, ++ { "brcm,hurricane3", XGS_IPROC_HR3, 0xf800 }, ++ { "brcm,greyhound2", XGS_IPROC_GH2, 0xf800 }, ++ { "brcm,wolfhound2", XGS_IPROC_WH2, 0xf800 }, ++ { "brcm,helix5", XGS_IPROC_HX5, 0x10800 }, ++ { "", 0, 0 } ++}; ++ ++#define IDM_BASE_ADDR_NUM 2 ++#define IDM_BASE_ADDR_MASK 0x10000000 ++#define IDM_BASE_ADDR_AREA(val) ((val & IDM_BASE_ADDR_MASK) >> 28) ++#define IDM_OFFSET_MASK 0x0FFFFFFF ++ ++static struct xgs_iproc_idm_err_offset_s { ++ u32 ihost_s1[XGS_IPROC_MAX_DEVS]; ++ u32 ihost_s0[XGS_IPROC_MAX_DEVS]; ++ u32 axi_pcie_s0[XGS_IPROC_MAX_DEVS]; ++ u32 ddr_s1[XGS_IPROC_MAX_DEVS]; ++ u32 ddr_s2[XGS_IPROC_MAX_DEVS]; ++ u32 cmic_s0[XGS_IPROC_MAX_DEVS]; ++ u32 apby_s0[XGS_IPROC_MAX_DEVS]; ++ u32 rom_s0[XGS_IPROC_MAX_DEVS]; ++ u32 nand_idm[XGS_IPROC_MAX_DEVS]; ++ u32 qspi_idm[XGS_IPROC_MAX_DEVS]; ++ u32 a9jtag_s0[XGS_IPROC_MAX_DEVS]; ++ u32 sram_s0[XGS_IPROC_MAX_DEVS]; ++ u32 apbz_s0[XGS_IPROC_MAX_DEVS]; ++ u32 axiic_ds_3[XGS_IPROC_MAX_DEVS]; ++ u32 apbw_idm[XGS_IPROC_MAX_DEVS]; ++ u32 apbx_idm[XGS_IPROC_MAX_DEVS]; ++ u32 axiic_ds_0[XGS_IPROC_MAX_DEVS]; ++ u32 periph_s0[XGS_IPROC_MAX_DEVS]; ++ u32 genres_s0[XGS_IPROC_MAX_DEVS]; ++} xgs_iproc_idm_err_offset = { ++ /* HX4, KT2, HR2, GH, SB2, HR3, ++ GH2, WH2, HX5 */ ++ { 0x00007000, 0x00007000, 0x00007000, 0x00006000, 0x00006000, 0x00006000, ++ 0x00006000, 0x00006000, 0x0 }, /* IHOST_S1_IDM */ ++ { 0x00008000, 0x00008000, 0x00008000, 0x00007000, 0x00007000, 0x00007000, ++ 0x00007000, 0x00007000, 0x00014000 }, /* IHOST_S0_IDM */ ++ { 0x0000b000, 0x0000b000, 0x0000b000, 0x00008000, 0x00008000, 0x00008000, ++ 0x00008000, 0x00008000, 0x0000a000 }, /* AXI_PCIE_S0_IDM */ ++ { 0x00009000, 0x00009000, 0x00009000, 0x10002000, 0x10002000, 0x00004000, ++ 0x10002000, 0x00004000, 0x0001a000 }, /* DDR_S1_IDM */ ++ { 0x0000a000, 0x0000a000, 0x0000a000, 0x10003000, 0x10003000, 0x00005000, ++ 0x10003000, 0x00005000, 0x0001b000 }, /* DDR_S2_IDM */ ++ { 0x0000d000, 0x0000d000, 0x0000d000, 0x0000a000, 0x0000a000, 0x0000a000, ++ 0x0000a000, 0x0000a000, 0x0000b000 }, /* CMICD_S0_IDM */ ++ { 0x0000f000, 0x0000f000, 0x0000f000, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0000c000 }, /* APBY_S0_IDM */ ++ { 0x0001a000, 0x0001a000, 0x0001a000, 0x10004000, 0x10004000, 0x0001a000, ++ 0x10004000, 0x0001a000, 0x0 }, /* ROM_S0_IDM */ ++ { 0x0001b000, 0x0001b000, 0x0001b000, 0x10005000, 0x10005000, 0x0001d000, ++ 0x10005000, 0x0001d000, 0x0 }, /* NAND_IDM */ ++ { 0x0001c000, 0x0001c000, 0x0001c000, 0x10006000, 0x10006000, 0x0001f000, ++ 0x10006000, 0x0001f000, 0x0 }, /* QSPI_IDM */ ++ { 0x0001d000, 0x0001d000, 0x0001d000, 0x00019000, 0x00019000, 0x00019000, ++ 0x00019000, 0x00019000, 0x0 }, /* A9JTAG_S0_IDM */ ++ { 0x00020000, 0x00020000, 0x00020000, 0x0001b000, 0x0001b000, 0x0, ++ 0x0001b000, 0x0, 0x0 }, /* SRAM_S0_IDM */ ++ { 0x00021000, 0x00021000, 0x00021000, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x00017000 }, /* APBZ_S0_IDM */ ++ { 0x00023000, 0x00023000, 0x00023000, 0x0001e000, 0x0001e000, 0x0, ++ 0x0001e000, 0x0, 0x0 }, /* AXIIC_DS_3_IDM */ ++ { 0x00031000, 0x00031000, 0x00031000, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x0 }, /* APBW_IDM */ ++ { 0x00032000, 0x00032000, 0x00032000, 0x00030000, 0x00030000, 0x00030000, ++ 0x00030000, 0x00030000, 0x0 }, /* APBX_IDM */ ++ { 0x00041000, 0x00041000, 0x00041000, 0x00020000, 0x00020000, 0x00020000, ++ 0x00020000, 0x00020000, 0x00053000 }, /* AXIIC_DS_0_IDM */ ++ { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x00018000 }, /* PERIPH_S0_IDM */ ++ { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, ++ 0x0, 0x0, 0x00019000 }, /* GENRES_S0_IDM */ ++}; ++ ++struct xgs_iproc_idm { ++ u32 curr_dev; ++ void __iomem *idm_base[IDM_BASE_ADDR_NUM]; ++ u32 dmac_reset_offset; ++}; ++ ++static struct xgs_iproc_idm xgs_iproc_idm = { 0 }; ++ ++/********************************************************************************** ++***********************************************************************************/ ++void inline __iomem *get_iproc_idm_base(int idx) ++{ ++ if (idx >= IDM_BASE_ADDR_NUM) ++ return NULL; ++ ++ return xgs_iproc_idm.idm_base[idx]; ++} ++ ++int xgs_iproc_idm_dmac_reset(void) ++{ ++ void __iomem *reset_base = NULL; ++ ++ if (xgs_iproc_idm.idm_base[0] == NULL || ++ xgs_iproc_idm.dmac_reset_offset == 0) { ++ return -EINVAL; ++ } ++ ++ reset_base = xgs_iproc_idm.idm_base[0] + xgs_iproc_idm.dmac_reset_offset; ++ writel(readl(reset_base) & ~0x1, reset_base); ++ ++ return 0; ++} ++ ++static int idm_error_log_dump(void __iomem *idm_addr) ++{ ++ void __iomem *reg_addr; ++ u32 val; ++ ++ reg_addr = (void __iomem *)IDM_ERROR_LOG_STATUS_REG(idm_addr); ++ if ((val = readl(reg_addr)) > 0) { ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, val); ++ ++ reg_addr = (void __iomem *)IDM_ERROR_LOG_ADDR_LSB_REG(idm_addr); ++ val = readl(reg_addr); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, val); ++ ++ reg_addr = (void __iomem *)IDM_ERROR_LOG_ID_REG(idm_addr); ++ val = readl(reg_addr); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, val); ++ ++ reg_addr = (void __iomem *)IDM_ERROR_LOG_FLAGS_REG(idm_addr); ++ val = readl(reg_addr); ++ printk(KERN_DEBUG "%s: %d, %08x\n", __func__, __LINE__, val); ++ ++ reg_addr = (void __iomem *)IDM_ERROR_LOG_COMPLETE_REG(idm_addr); ++ writel(IDM_ERROR_LOG_CLEAR, reg_addr); ++ ++ reg_addr = (void __iomem *)IDM_ERROR_LOG_STATUS_REG(idm_addr); ++ val = readl(reg_addr); ++ printk(KERN_DEBUG "%s: %d, %d\n", __func__, __LINE__, val); ++ } ++ ++ return 0; ++} ++ ++static irqreturn_t idm_timeout_handler(int val, void *ptr) ++{ ++ u32 idx, offset; ++ void __iomem *idm_addr; ++ u32 i, cnt, *idm_item; ++ ++ if (xgs_iproc_idm.curr_dev == XGS_IPROC_MAX_DEVS) ++ return IRQ_HANDLED; ++ ++ cnt = sizeof(struct xgs_iproc_idm_err_offset_s) / (sizeof(u32) * XGS_IPROC_MAX_DEVS); ++ for (i = 0; i < cnt; i++) { ++ idm_item = (u32*)((u32*)(&xgs_iproc_idm_err_offset) + i * XGS_IPROC_MAX_DEVS); ++ offset = idm_item[xgs_iproc_idm.curr_dev]; ++ if (offset != 0) { ++ idx = IDM_BASE_ADDR_AREA(offset); ++ if (xgs_iproc_idm.idm_base[idx]) { ++ idm_addr = xgs_iproc_idm.idm_base[idx] + (offset & IDM_OFFSET_MASK); ++ idm_error_log_dump(idm_addr); ++ } ++ } ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static int init_request_idm_timeout(void) ++{ ++ void __iomem *idm_addr; ++ void __iomem *reg_addr; ++ u32 i, cnt, *idm_item; ++ u32 idx, offset; ++ ++ if (xgs_iproc_idm.curr_dev == XGS_IPROC_MAX_DEVS) ++ return IRQ_HANDLED; ++ ++ /* clear all pending idm interrupts */ ++ idm_timeout_handler(0, NULL); ++ ++ /* enable idm error log for all slaves */ ++ cnt = sizeof(struct xgs_iproc_idm_err_offset_s) / (sizeof(u32) * XGS_IPROC_MAX_DEVS); ++ for (i = 0; i < cnt; i++) { ++ idm_item = (u32*)((u32*)(&xgs_iproc_idm_err_offset) + i * XGS_IPROC_MAX_DEVS); ++ offset = idm_item[xgs_iproc_idm.curr_dev]; ++ if (offset != 0) { ++ idx = IDM_BASE_ADDR_AREA(offset); ++ if (xgs_iproc_idm.idm_base[idx]) { ++ idm_addr = xgs_iproc_idm.idm_base[idx] + (offset & IDM_OFFSET_MASK); ++ reg_addr = (void __iomem *)IDM_ERROR_LOG_CONTROL_REG(idm_addr); ++ writel(IDM_ERROR_LOG_ENABLE, reg_addr); ++ } ++ } ++ } ++ ++ return 0; ++} ++ ++int xgs_iproc_idm_init(void) ++{ ++ struct device_node *np; ++ int idx, ret = 0; ++ int irq, irqs_total; ++ ++ /* Get IDM base addr */ ++ np = of_find_compatible_node(NULL, NULL, IPROC_IDM_COMPATIBLE); ++ if (!np) { ++ pr_err("%s: No IDM node found\n", __func__); ++ return -ENODEV; ++ } ++ ++ xgs_iproc_idm.idm_base[0] = of_iomap(np, 0); ++ if (!xgs_iproc_idm.idm_base[0]) { ++ return -ENOMEM; ++ } ++ ++ /* ++ * Second IDM base addr required for GH/SB2/GH2 IDM timeout handling. ++ * For other devices, the second IDM base addr is not used. So, it is ++ * fine even the addr is NULL. ++ */ ++ xgs_iproc_idm.idm_base[1] = of_iomap(np, 1); ++ ++ /* Get the current platform */ ++ idx = 0; ++ while(1) { ++ if (strlen(xgs_iproc_dev_infos[idx].dt_compat_str) == 0) ++ return -EINVAL; ++ if (of_machine_is_compatible(xgs_iproc_dev_infos[idx].dt_compat_str)) ++ break; ++ idx++; ++ } ++ xgs_iproc_idm.curr_dev = xgs_iproc_dev_infos[idx].dev_id; ++ xgs_iproc_idm.dmac_reset_offset = xgs_iproc_dev_infos[idx].dmac_reset_offset; ++ ++ /* Setup idm timeout handler for debug purpose */ ++ init_request_idm_timeout(); ++ ++ irqs_total = of_irq_count(np); ++ if (!irqs_total) ++ return -EINVAL; ++ ++ for (idx = 0; idx < irqs_total; idx++) { ++ irq = of_irq_get(np, idx); ++ ret = request_irq(irq, (irq_handler_t)idm_timeout_handler, ++ IRQF_PERCPU, "IDM", NULL); ++ if (ret != 0) ++ printk(KERN_WARNING "%s: request_irq return = %d\n", __func__, ret); ++ } ++ ++ return ret; ++} +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/xgs_iproc/xgs-iproc-misc-setup.c b/drivers/soc/bcm/xgs_iproc/xgs-iproc-misc-setup.c +--- a/drivers/soc/bcm/xgs_iproc/xgs-iproc-misc-setup.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/xgs_iproc/xgs-iproc-misc-setup.c 2018-05-10 11:31:33.017403314 +0800 +@@ -0,0 +1,88 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++ ++#define IPROC_DMU_PCU_COMPATIBLE "brcm,iproc-dmu-pcu" ++#define IPROC_WRAP_CTRL_COMPATIBLE "brcm,iproc-wrap-ctrl" ++#define KT2_WRAP_MISC_COMPATIBLE "brcm,kt2-wrap-misc" ++ ++static void __iomem *iproc_dmu_pcu_base = NULL; ++static void __iomem *iproc_wrap_ctrl_base = NULL; ++ ++extern void request_idm_timeout_interrupts(struct platform_device *); ++ ++void inline __iomem *get_iproc_dmu_pcu_base(void) ++{ ++ return iproc_dmu_pcu_base; ++} ++ ++void inline __iomem *get_iproc_wrap_ctrl_base(void) ++{ ++ return iproc_wrap_ctrl_base; ++} ++ ++int inline is_wh2_amac_sgmii(void) ++{ ++ return readl(get_iproc_wrap_ctrl_base() + 0xa8) & 0x04; ++} ++ ++int xgs_iproc_misc_setup(void) ++{ ++ struct device_node *np; ++ void __iomem *wrap_misc_reg = NULL; ++ u32 tmp; ++ u32 wrap_misc_offset, serdes_ctrl_sel, serdes_mdio_sel; ++ ++ /* Get DMU/PCU base addr */ ++ np = of_find_compatible_node(NULL, NULL, IPROC_DMU_PCU_COMPATIBLE); ++ if (!np) { ++ pr_err("%s: No dmu/pcu node found\n", __func__); ++ return -ENODEV ; ++ } ++ ++ iproc_dmu_pcu_base = of_iomap(np, 0); ++ if (!iproc_dmu_pcu_base) ++ return -ENOMEM; ++ ++ /* Get WRAP CTRL base addr */ ++ np = of_find_compatible_node(NULL, NULL, IPROC_WRAP_CTRL_COMPATIBLE); ++ if (!np) { ++ pr_err("%s: No wrap ctrl node found\n", __func__); ++ return -ENODEV; ++ } ++ ++ iproc_wrap_ctrl_base = of_iomap(np, 0); ++ if (!iproc_wrap_ctrl_base) ++ return -ENOMEM; ++ ++ /* Enable AMAC SERDES MDIO SEL/CTRL for HX4/KT2 */ ++ if (!of_property_read_u32_index(np, "amac-serdes-mdio-ctrl-sel", 0, ++ &wrap_misc_offset)) { ++ of_property_read_u32_index(np, "amac-serdes-mdio-ctrl-sel", 1, ++ &serdes_ctrl_sel); ++ of_property_read_u32_index(np, "amac-serdes-mdio-ctrl-sel", 2, ++ &serdes_mdio_sel); ++ ++ wrap_misc_reg = (void __iomem *)(iproc_wrap_ctrl_base + ++ wrap_misc_offset); ++ tmp = readl(wrap_misc_reg); ++ tmp |= (1 << serdes_ctrl_sel) | (1 << serdes_mdio_sel); ++ writel(tmp, wrap_misc_reg); ++ } ++ ++ return 1; ++} +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/soc/bcm/xgs_iproc/xgs-iproc.c b/drivers/soc/bcm/xgs_iproc/xgs-iproc.c +--- a/drivers/soc/bcm/xgs_iproc/xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/soc/bcm/xgs_iproc/xgs-iproc.c 2018-05-10 11:31:33.021403318 +0800 +@@ -0,0 +1,104 @@ ++/* ++ * Copyright (C) 2016 Broadcom ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++/* Currently, this driver is only support for Helix5. As for the other ++ * XGS IProc chips, the initial code and reset handler are defined in ++ * mach-iproc/board_bu.c ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define DMU_CRU_RESET_OFFSET 0x200 ++ ++static int xgs_iproc_restart(struct notifier_block *nb, ++ unsigned long action, void *data) ++{ ++ void * __iomem reg_addr; ++ u32 val; ++ ++ /* CRU_RESET register */ ++ reg_addr = get_iproc_dmu_pcu_base() + DMU_CRU_RESET_OFFSET; ++ ++ /* set iproc_reset_n to 0 */ ++ val = readl(reg_addr); ++ val &= ~((u32) 1 << 1); ++ ++ writel(val, reg_addr); ++ ++ /* Wait for reset */ ++ while (1) { ++ cpu_do_idle(); ++ } ++ ++ return 0; ++} ++ ++static struct notifier_block xgs_iproc_nb = { ++ .notifier_call = xgs_iproc_restart, ++ .priority = 192, ++}; ++ ++static char * xgs_iproc_dt_compat_str[] = { ++ "brcm,helix5", ++ "", ++}; ++ ++static int __init xgs_iproc_init(void) ++{ ++ int ret; ++ int idx = 0; ++ ++ while(1) { ++ if (strlen(xgs_iproc_dt_compat_str[idx]) == 0) { ++ return -EINVAL; ++ } ++ if (of_machine_is_compatible(xgs_iproc_dt_compat_str[idx])) { ++ break; ++ } ++ idx++; ++ } ++ ++ ret = xgs_iproc_misc_setup(); ++ if (ret < 0) { ++ return ret; ++ } ++ ++ /* Init idm and setup idm timeout handler for debug purpose */ ++ /* xgs_iproc_idm_init should be init before reset dmac */ ++ ret = xgs_iproc_idm_init(); ++ if (ret < 0) { ++ return ret; ++ } ++ ++ /* FIXME, need confirm whether we need reset the DMAC or not */ ++ xgs_iproc_idm_dmac_reset(); ++ ++ /* Populate platform devices */ ++ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); ++ ++ if (register_reboot_notifier(&xgs_iproc_nb)) { ++ printk("Register reboot handler failed\n"); ++ } ++ ++ return 0; ++} ++arch_initcall(xgs_iproc_init); ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/spi/Kconfig b/drivers/spi/Kconfig +--- a/drivers/spi/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/spi/Kconfig 2018-05-10 11:31:33.033403332 +0800 +@@ -162,8 +162,8 @@ config SPI_BCM63XX_HSSPI + config SPI_BCM_QSPI + tristate "Broadcom BSPI and MSPI controller support" + depends on ARCH_BRCMSTB || ARCH_BCM || ARCH_BCM_IPROC || \ +- BMIPS_GENERIC || COMPILE_TEST +- default ARCH_BCM_IPROC ++ ARCH_XGS_IPROC || BMIPS_GENERIC || COMPILE_TEST ++ default ARCH_BCM_IPROC || ARCH_XGS_IPROC + help + Enables support for the Broadcom SPI flash and MSPI controller. + Select this option for any one of BRCMSTB, iProc NSP and NS2 SoCs +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c +--- a/drivers/spi/spi-bcm-qspi.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/spi/spi-bcm-qspi.c 2018-05-10 11:31:33.033403332 +0800 +@@ -88,7 +88,7 @@ + #define BSPI_BPP_MODE_SELECT_MASK BIT(8) + #define BSPI_BPP_ADDR_SELECT_MASK BIT(16) + +-#define BSPI_READ_LENGTH 512 ++//#define BSPI_READ_LENGTH 512 + + /* MSPI register offsets */ + #define MSPI_SPCR0_LSB 0x000 +@@ -118,6 +118,8 @@ + + #define MSPI_MSPI_STATUS_SPIF BIT(0) + ++#define CRU_CTRL_REG 0x0 ++ + #define INTR_BASE_BIT_SHIFT 0x02 + #define INTR_COUNT 0x07 + +@@ -171,6 +173,7 @@ enum base_type { + MSPI, + BSPI, + CHIP_SELECT, ++ CRU_CTRL, + BASEMAX, + }; + +@@ -195,12 +197,14 @@ struct bcm_qspi_dev_id { + struct qspi_trans { + struct spi_transfer *trans; + int byte; ++ int slots; + bool mspi_last_trans; + }; + + struct bcm_qspi { + struct platform_device *pdev; + struct spi_master *master; ++ struct spi_device *spi_dev; + struct clk *clk; + u32 base_clk; + u32 max_speed_hz; +@@ -453,11 +457,12 @@ static int bcm_qspi_bspi_set_mode(struct + qspi->xfer_mode.flex_mode = true; + + if (!bcm_qspi_bspi_ver_three(qspi)) { +- u32 val, mask; ++ u32 val, mask, endian; + +- val = bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL); ++ val = qspi->s3_strap_override_ctrl; + mask = BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE; +- if (val & mask || qspi->s3_strap_override_ctrl & mask) { ++ endian = BSPI_STRAP_OVERRIDE_CTRL_ENDAIN_MODE; ++ if ((val & mask) && (val & ~(mask | endian))) { + qspi->xfer_mode.flex_mode = false; + bcm_qspi_write(qspi, BSPI, BSPI_FLEX_MODE_ENABLE, 0); + error = bcm_qspi_bspi_set_override(qspi, msg, hp); +@@ -570,6 +575,8 @@ static void bcm_qspi_update_parms(struct + static int bcm_qspi_setup(struct spi_device *spi) + { + struct bcm_qspi_parms *xp; ++ struct bcm_qspi *qspi = spi_master_get_devdata(spi->master); ++ u32 tmp; + + if (spi->bits_per_word > 16) + return -EINVAL; +@@ -581,8 +588,20 @@ static int bcm_qspi_setup(struct spi_dev + return -ENOMEM; + spi_set_ctldata(spi, xp); + } +- xp->speed_hz = spi->max_speed_hz; ++ + xp->mode = spi->mode; ++ xp->speed_hz = spi->max_speed_hz; ++ ++ /* Set BSPI clock rate */ ++ tmp = bcm_qspi_read(qspi, CRU_CTRL, CRU_CTRL_REG); ++ tmp &= ~0x6; ++ if (spi->max_speed_hz >= 62500000) ++ tmp |= 0x6; ++ else if (spi->max_speed_hz >= 50000000) ++ tmp |= 0x2; ++ else if (spi->max_speed_hz >= 31250000) ++ tmp |= 0x4; ++ bcm_qspi_write(qspi, CRU_CTRL, CRU_CTRL_REG, tmp); + + if (spi->bits_per_word) + xp->bits_per_word = spi->bits_per_word; +@@ -674,22 +693,25 @@ static void read_from_hw(struct bcm_qspi + tp = qspi->trans_pos; + + for (slot = 0; slot < slots; slot++) { ++ if (tp.trans->rx_buf) { + if (tp.trans->bits_per_word <= 8) { + u8 *buf = tp.trans->rx_buf; + + if (buf) +- buf[tp.byte] = read_rxram_slot_u8(qspi, slot); ++ buf[tp.byte] = ++ read_rxram_slot_u8(qspi, slot); + dev_dbg(&qspi->pdev->dev, "RD %02x\n", + buf ? buf[tp.byte] : 0xff); + } else { + u16 *buf = tp.trans->rx_buf; + + if (buf) +- buf[tp.byte / 2] = read_rxram_slot_u16(qspi, +- slot); ++ buf[tp.byte / 2] = ++ read_rxram_slot_u16(qspi, slot); + dev_dbg(&qspi->pdev->dev, "RD %04x\n", + buf ? buf[tp.byte] : 0xffff); + } ++ } + + update_qspi_trans_byte_count(qspi, &tp, + TRANS_STATUS_BREAK_NONE); +@@ -767,6 +789,9 @@ static int write_to_hw(struct bcm_qspi * + slot++; + } + ++ /* save slot number for read_from_hw() */ ++ qspi->trans_pos.slots = slot; ++ + if (!slot) { + dev_err(&qspi->pdev->dev, "%s: no data to send?", __func__); + goto done; +@@ -798,9 +823,9 @@ static int bcm_qspi_bspi_flash_read(stru + struct spi_flash_read_message *msg) + { + struct bcm_qspi *qspi = spi_master_get_devdata(spi->master); +- u32 addr = 0, len, rdlen, len_words; ++ u32 addr = 0, len, len_words; + int ret = 0; +- unsigned long timeo = msecs_to_jiffies(100); ++ unsigned long timeo = msecs_to_jiffies(1000); + struct bcm_qspi_soc_intc *soc_intc = qspi->soc_intc; + + if (bcm_qspi_bspi_ver_three(qspi)) +@@ -825,30 +850,20 @@ static int bcm_qspi_bspi_flash_read(stru + else + addr = msg->from & 0x00ffffff; + +- if (bcm_qspi_bspi_ver_three(qspi) == true) +- addr = (addr + 0xc00000) & 0xffffff; +- +- /* +- * read into the entire buffer by breaking the reads +- * into RAF buffer read lengths +- */ + len = msg->len; +- qspi->bspi_rf_msg_idx = 0; + +- do { +- if (len > BSPI_READ_LENGTH) +- rdlen = BSPI_READ_LENGTH; +- else +- rdlen = len; ++ if (bcm_qspi_bspi_ver_three(qspi) == true) ++ addr = (addr + 0xc00000) & 0xffffff; + + reinit_completion(&qspi->bspi_done); + bcm_qspi_enable_bspi(qspi); +- len_words = (rdlen + 3) >> 2; ++ len_words = (len + 3) >> 2; + qspi->bspi_rf_msg = msg; + qspi->bspi_rf_msg_status = 0; +- qspi->bspi_rf_msg_len = rdlen; +- dev_dbg(&qspi->pdev->dev, +- "bspi xfr addr 0x%x len 0x%x", addr, rdlen); ++ qspi->bspi_rf_msg_idx = 0; ++ qspi->bspi_rf_msg_len = len; ++ dev_dbg(&qspi->pdev->dev, "bspi xfr addr 0x%x len 0x%x", addr, len); ++ + bcm_qspi_write(qspi, BSPI, BSPI_RAF_START_ADDR, addr); + bcm_qspi_write(qspi, BSPI, BSPI_RAF_NUM_WORDS, len_words); + bcm_qspi_write(qspi, BSPI, BSPI_RAF_WATERMARK, 0); +@@ -867,15 +884,11 @@ static int bcm_qspi_bspi_flash_read(stru + if (!wait_for_completion_timeout(&qspi->bspi_done, timeo)) { + dev_err(&qspi->pdev->dev, "timeout waiting for BSPI\n"); + ret = -ETIMEDOUT; +- break; ++ } else { ++ /* set the return length for the caller */ ++ msg->retlen = len; + } + +- /* set msg return length */ +- msg->retlen += rdlen; +- addr += rdlen; +- len -= rdlen; +- } while (len); +- + return ret; + } + +@@ -884,25 +897,22 @@ static int bcm_qspi_transfer_one(struct + struct spi_transfer *trans) + { + struct bcm_qspi *qspi = spi_master_get_devdata(master); +- int slots; +- unsigned long timeo = msecs_to_jiffies(100); ++ unsigned long timeo = msecs_to_jiffies(1000); + + bcm_qspi_chip_select(qspi, spi->chip_select); + qspi->trans_pos.trans = trans; + qspi->trans_pos.byte = 0; ++ qspi->spi_dev = spi; + +- while (qspi->trans_pos.byte < trans->len) { + reinit_completion(&qspi->mspi_done); + +- slots = write_to_hw(qspi, spi); ++ write_to_hw(qspi, spi); ++ + if (!wait_for_completion_timeout(&qspi->mspi_done, timeo)) { + dev_err(&qspi->pdev->dev, "timeout waiting for MSPI\n"); + return -ETIMEDOUT; + } + +- read_from_hw(qspi, slots); +- } +- + return 0; + } + +@@ -1012,7 +1022,24 @@ static irqreturn_t bcm_qspi_mspi_l2_isr( + bcm_qspi_write(qspi, MSPI, MSPI_MSPI_STATUS, status); + if (qspi->soc_intc) + soc_intc->bcm_qspi_int_ack(soc_intc, MSPI_DONE); ++ ++ if (qspi->trans_pos.trans->tx_buf && ++ (qspi->trans_pos.trans->len <= MSPI_NUM_CDRAM)) { + complete(&qspi->mspi_done); ++ spi_finalize_current_transfer(qspi->master); ++ return IRQ_HANDLED; ++ } ++ ++ read_from_hw(qspi, qspi->trans_pos.slots); ++ ++ if (qspi->trans_pos.trans) { ++ write_to_hw(qspi, qspi->spi_dev); ++ } ++ else { ++ complete(&qspi->mspi_done); ++ spi_finalize_current_transfer(qspi->master); ++ } ++ + return IRQ_HANDLED; + } + +@@ -1031,6 +1058,8 @@ static irqreturn_t bcm_qspi_bspi_lr_l2_i + if (qspi->bspi_rf_msg_len == 0) { + qspi->bspi_rf_msg = NULL; + if (qspi->soc_intc) { ++ /* Ack BSPI done interrupt */ ++ soc_intc->bcm_qspi_int_ack(soc_intc, BSPI_DONE); + /* disable soc BSPI interrupt */ + soc_intc->bcm_qspi_int_set(soc_intc, BSPI_DONE, + false); +@@ -1042,11 +1071,12 @@ static irqreturn_t bcm_qspi_bspi_lr_l2_i + bcm_qspi_bspi_lr_clear(qspi); + else + bcm_qspi_bspi_flush_prefetch_buffers(qspi); +- } +- ++ } else { + if (qspi->soc_intc) +- /* clear soc BSPI interrupt */ +- soc_intc->bcm_qspi_int_ack(soc_intc, BSPI_DONE); ++ /* Ack FIFO full interrupt */ ++ soc_intc->bcm_qspi_int_ack(soc_intc, ++ BSPI_FIFO_FULL); ++ } + } + + status &= INTR_BSPI_LR_SESSION_DONE_MASK; +@@ -1233,8 +1263,6 @@ int bcm_qspi_probe(struct platform_devic + master->dev.of_node = dev->of_node; + master->num_chipselect = NUM_CHIPSELECT; + +- qspi->big_endian = of_device_is_big_endian(dev->of_node); +- + if (!of_property_read_u32(dev->of_node, "num-cs", &val)) + master->num_chipselect = val; + +@@ -1276,6 +1304,26 @@ int bcm_qspi_probe(struct platform_devic + } + } + ++ /* iProc BSPI clock is set through CRU control */ ++ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cru_ctrl"); ++ if (res) { ++ qspi->base[CRU_CTRL] = devm_ioremap_resource(dev, res); ++ if (IS_ERR(qspi->base[CRU_CTRL])) { ++ ret = PTR_ERR(qspi->base[CRU_CTRL]); ++ goto qspi_probe_err; ++ } ++ } ++ ++ qspi->big_endian = of_device_is_big_endian(dev->of_node); ++ ++ val = bcm_qspi_read(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL); ++ if (qspi->big_endian == 0 && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) { ++ val |= BSPI_STRAP_OVERRIDE_CTRL_ENDAIN_MODE; ++ val |= BSPI_STRAP_OVERRIDE_CTRL_OVERRIDE; ++ bcm_qspi_write(qspi, BSPI, BSPI_STRAP_OVERRIDE_CTRL, val); ++ } ++ qspi->s3_strap_override_ctrl = val; ++ + qspi->dev_ids = kcalloc(num_irqs, sizeof(struct bcm_qspi_dev_id), + GFP_KERNEL); + if (!qspi->dev_ids) { +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/spi/spi-bcm-qspi.h b/drivers/spi/spi-bcm-qspi.h +--- a/drivers/spi/spi-bcm-qspi.h 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/spi/spi-bcm-qspi.h 2018-05-10 11:31:33.033403332 +0800 +@@ -59,7 +59,8 @@ enum { + MSPI_DONE = 0x1, + BSPI_DONE = 0x2, + BSPI_ERR = 0x4, +- MSPI_BSPI_DONE = 0x7 ++ MSPI_BSPI_DONE = 0x7, ++ BSPI_FIFO_FULL = 0x8 + }; + + struct bcm_qspi_soc_intc { +@@ -95,6 +96,8 @@ static inline u32 get_qspi_mask(int type + return INTR_MSPI_DONE_MASK; + case BSPI_DONE: + return BSPI_LR_INTERRUPTS_ALL; ++ case BSPI_FIFO_FULL: ++ return INTR_BSPI_LR_FULLNESS_REACHED_MASK; + case MSPI_BSPI_DONE: + return QSPI_INTERRUPTS_ALL; + case BSPI_ERR: +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/spi/spi-iproc-qspi.c b/drivers/spi/spi-iproc-qspi.c +--- a/drivers/spi/spi-iproc-qspi.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/spi/spi-iproc-qspi.c 2018-05-10 11:31:33.041403341 +0800 +@@ -143,6 +143,7 @@ static int bcm_iproc_remove(struct platf + static const struct of_device_id bcm_iproc_of_match[] = { + { .compatible = "brcm,spi-nsp-qspi" }, + { .compatible = "brcm,spi-ns2-qspi" }, ++ { .compatible = "brcm,spi-xgs-iproc-qspi" }, + {}, + }; + MODULE_DEVICE_TABLE(of, bcm_iproc_of_match); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/legacy/serial.c b/drivers/usb/gadget/legacy/serial.c +--- a/drivers/usb/gadget/legacy/serial.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/gadget/legacy/serial.c 2018-05-10 11:31:33.753404129 +0800 +@@ -250,7 +250,7 @@ static int __init init(void) + */ + if (use_acm) { + serial_config_driver.label = "CDC ACM config"; +- serial_config_driver.bConfigurationValue = 2; ++ serial_config_driver.bConfigurationValue = 1; + device_desc.bDeviceClass = USB_CLASS_COMM; + device_desc.idProduct = + cpu_to_le16(GS_CDC_PRODUCT_ID); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/Kconfig b/drivers/usb/gadget/udc/Kconfig +--- a/drivers/usb/gadget/udc/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/gadget/udc/Kconfig 2018-05-10 11:31:33.753404129 +0800 +@@ -439,6 +439,17 @@ config USB_GADGET_XILINX + dynamically linked module called "udc-xilinx" and force all + gadget drivers to also be dynamically linked. + ++config USB_XGS_IPROC_UDC ++ tristate "Broadcom XGS IPROC USB Device driver" ++ depends on ARCH_XGS_IPROC && USB_GADGET ++ default n ++ help ++ USB peripheral controller driver for Broadcom XGS IPROC USB 2 device. ++ ++ Say "y" to link the driver statically, or "m" to build a dynamically ++ linked module called "xgs_iproc_udc" and force all gadget drivers to ++ also be dynamically linked. ++ + # + # LAST -- dummy/emulated controller + # +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/Makefile b/drivers/usb/gadget/udc/Makefile +--- a/drivers/usb/gadget/udc/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/gadget/udc/Makefile 2018-05-10 11:31:33.753404129 +0800 +@@ -38,5 +38,6 @@ obj-$(CONFIG_USB_FOTG210_UDC) += fotg210 + obj-$(CONFIG_USB_MV_U3D) += mv_u3d_core.o + obj-$(CONFIG_USB_GR_UDC) += gr_udc.o + obj-$(CONFIG_USB_GADGET_XILINX) += udc-xilinx.o ++obj-$(CONFIG_USB_XGS_IPROC_UDC) += xgs_iproc_udc.o + obj-$(CONFIG_USB_SNP_UDC_PLAT) += snps_udc_plat.o + obj-$(CONFIG_USB_BDC_UDC) += bdc/ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/bdc/Kconfig b/drivers/usb/gadget/udc/bdc/Kconfig +--- a/drivers/usb/gadget/udc/bdc/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/gadget/udc/bdc/Kconfig 2018-05-10 11:31:33.757404134 +0800 +@@ -16,7 +16,21 @@ comment "Platform Support" + config USB_BDC_PCI + tristate "BDC support for PCIe based platforms" + depends on USB_PCI +- default USB_BDC_UDC ++ default n + help + Enable support for platforms which have BDC connected through PCIe, such as Lego3 FPGA platform. ++ ++config USB_BDC_XGS_IPROC ++ tristate "BDC support for broadcom XGS IPROC platforms" ++ depends on ARCH_XGS_IPROC && USB_GADGET ++ default n ++ ++ help ++ Enable support for Broadcom XGS IPROC platforms which have BDC, such ++ as Helix 5 platform. ++ ++ Say "y" to link the driver statically, or "m" to build a dynamically ++ linked module called "xgs_iproc_udc" and force all gadget drivers to ++ also be dynamically linked. ++ + endif +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/bdc/Makefile b/drivers/usb/gadget/udc/bdc/Makefile +--- a/drivers/usb/gadget/udc/bdc/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/gadget/udc/bdc/Makefile 2018-05-10 11:31:33.757404134 +0800 +@@ -7,3 +7,5 @@ ifneq ($(CONFIG_USB_GADGET_VERBOSE),) + endif + + obj-$(CONFIG_USB_BDC_PCI) += bdc_pci.o ++obj-$(CONFIG_USB_BDC_XGS_IPROC) += bdc_xgs_iproc.o ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/bdc/bdc_xgs_iproc.c b/drivers/usb/gadget/udc/bdc/bdc_xgs_iproc.c +--- a/drivers/usb/gadget/udc/bdc/bdc_xgs_iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/usb/gadget/udc/bdc/bdc_xgs_iproc.c 2018-05-10 11:31:33.761404138 +0800 +@@ -0,0 +1,126 @@ ++/* ++ * bdc_xgs_iproc.c - BDC platform driver for Broadco XGS IPROC platforms. ++ * ++ * Copyright (C) 2014-2016, Broadcom Corporation. 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 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. ++ */ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "bdc.h" ++ ++struct bdc_xgs_iproc { ++ struct device *dev; ++ struct platform_device *bdc; ++}; ++ ++static int bdc_xgs_iproc_probe(struct platform_device *pdev) ++{ ++ struct resource res[2]; ++ struct platform_device *bdc; ++ struct bdc_xgs_iproc *data; ++ struct device_node *np = pdev->dev.of_node; ++ int irq; ++ int ret = -ENOMEM; ++ ++ data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); ++ if (!data) { ++ return -ENOMEM; ++ } ++ data->dev = &pdev->dev; ++ ++ bdc = platform_device_alloc(BRCM_BDC_NAME, PLATFORM_DEVID_AUTO); ++ if (!bdc) { ++ return -ENOMEM; ++ } ++ ++ memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res)); ++ ++ if (of_address_to_resource(np, 0, &res[0]) < 0) { ++ dev_err(&pdev->dev, ++ "failed to get BDC registers\n"); ++ of_node_put(np); ++ return -ENXIO; ++ } ++ res[0].name = BRCM_BDC_NAME; ++ res[0].flags = IORESOURCE_MEM; ++ ++ irq = platform_get_irq(pdev, 0); ++ if (irq < 0) { ++ dev_err(&pdev->dev, ++ "failed to get BDC IRQ\n"); ++ return -ENXIO; ++ } ++ res[1].start = irq; ++ res[1].name = BRCM_BDC_NAME; ++ res[1].flags = IORESOURCE_IRQ; ++ ++ ret = platform_device_add_resources(bdc, res, ARRAY_SIZE(res)); ++ if (ret) { ++ dev_err(&pdev->dev, ++ "couldn't add resources to bdc device\n"); ++ return ret; ++ } ++ ++ platform_set_drvdata(pdev, data); ++ ++ dma_set_coherent_mask(&bdc->dev, pdev->dev.coherent_dma_mask); ++ bdc->dev.dma_mask = pdev->dev.dma_mask; ++ bdc->dev.dma_parms = pdev->dev.dma_parms; ++ bdc->dev.parent = &pdev->dev; ++ data->bdc = bdc; ++ ++ ret = platform_device_add(bdc); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to register bdc device\n"); ++ platform_device_put(bdc); ++ return ret; ++ } ++ ++ return 0; ++} ++ ++static int bdc_xgs_iproc_remove(struct platform_device *pdev) ++{ ++ struct bdc_xgs_iproc *data = platform_get_drvdata(pdev); ++ ++ platform_device_unregister(data->bdc); ++ devm_kfree(&pdev->dev, data); ++ ++ return 0; ++} ++ ++static const struct of_device_id bdc_xgs_iproc_ids[] = { ++ { .compatible = "brcm,bdc,hx5", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, bdc_xgs_iproc_ids); ++ ++static struct platform_driver bdc_xgs_iproc_driver = { ++ .probe = bdc_xgs_iproc_probe, ++ .remove = bdc_xgs_iproc_remove, ++ .driver = { ++ .name = "bdc-xgs-iproc", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(bdc_xgs_iproc_ids), ++ }, ++}; ++ ++module_platform_driver(bdc_xgs_iproc_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_LICENSE("GPL"); ++MODULE_DESCRIPTION("BDC platform driver for Broadcom XGS IPROC platforms"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/xgs_iproc_udc.c b/drivers/usb/gadget/udc/xgs_iproc_udc.c +--- a/drivers/usb/gadget/udc/xgs_iproc_udc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/usb/gadget/udc/xgs_iproc_udc.c 2018-05-10 11:31:33.789404169 +0800 +@@ -0,0 +1,2039 @@ ++/* ++ * Copyright 2017 Broadcom Limited ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++/****************************************************************************/ ++/** ++* @file bcm_dwc_udc.c ++* ++* @brief Broadcom Linux driver for DWC USB 2.0 Device Controller (UDC) ++* ++* This driver implements the Linux Gadget driver API as defined in usb_gadget.h ++* ++* @note ++* ++* This driver was written with the intent of being able to support any ++* variations on how this block is integrated into different Broadcom chips. ++* ++* There is a requirement on how the DWC UDC is configured. In particular, this ++* driver requires that the following options be defined and enabled in the ++* UDC core. ++* ++* UDC20AHB_CNAK_CLR_ENH_CC ++* UDC20AHB_STALL_SET_ENH_CC ++* UDC20AHB_SNAK_ENH_CC ++* ++* Some other UDC attributes can be supported by setting compile time options ++* or with some minor modifications to the source code. Ideally these would ++* be run-time info that is provided by the device instance to the driver. ++* These attributes include the following. ++* ++* IPROC_UDC_EP_CNT ++* IPROC_UDC_EP_MAX_PKG_SIZE ++* Type of each endpoint: Control, IN, OUT, or Bidirectional ++*/ ++/****************************************************************************/ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "xgs_iproc_udc.h" ++ ++#define XGS_IPROC_UDC_NAME "xgs-iproc-udc" ++ ++#define DMA_ADDR_INVALID (~(dma_addr_t)0) ++/* ++ * FRAME_NUM_INVALID is used for ISOC IN transfers for frame alignment. ++ * The device specifies the interval at which it wants to do transfers, ++ * but the host initiates all transfers. If the interval is some multiple ++ * number of frames, the device has no idea which frame in an interval ++ * window the host is going to start transfers. This could even be at a ++ * point many frames beyond the current window, as the starting point ++ * can be very application dependant and subject to an indeterminate ++ * amount of latency. ++ */ ++#define FRAME_NUM_INVALID (~(u32)0) ++#define ENOERROR 0 ++ ++/* ---- Private Function Prototypes -------------------------------------- */ ++#ifdef IPROC_UDC_DEBUG ++static void iproc_dbg_dma_dump(struct iproc_udc *udc); ++static void iproc_dbg_dma_dump_desc(char *label, struct iproc_udc_dma_desc *virt, ++ struct iproc_udc_dma_desc *phys); ++static void iproc_dbg_dma_dump_ep(struct iproc_ep *ep); ++#endif /* IPROC_UDC_DEBUG */ ++ ++/* ---- Private Variables ------------------------------------------------ */ ++static const struct { ++ const char *name; ++ const int type; ++ const int msize; ++ const struct usb_ep_caps caps; ++} xgs_iproc_ep_info[] = { ++#define EP_INFO(_name, _type, _size, _caps) \ ++ { \ ++ .name = _name, \ ++ .type = _type, \ ++ .msize = _size, \ ++ .caps = _caps, \ ++ } ++ ++ EP_INFO("ep0", USB_ENDPOINT_XFER_CONTROL, IPROC_UDC_CTRL_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_CONTROL, USB_EP_CAPS_DIR_ALL)), ++ EP_INFO("ep1in", USB_ENDPOINT_XFER_ISOC, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_IN)), ++ EP_INFO("ep2out", USB_ENDPOINT_XFER_ISOC, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_ISO, USB_EP_CAPS_DIR_OUT)), ++ EP_INFO("ep3in", USB_ENDPOINT_XFER_BULK, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_IN)), ++ EP_INFO("ep4out", USB_ENDPOINT_XFER_BULK, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_BULK, USB_EP_CAPS_DIR_OUT)), ++ EP_INFO("ep5in", USB_ENDPOINT_XFER_INT, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_IN)), ++ EP_INFO("ep6out", USB_ENDPOINT_XFER_INT, IPROC_UDC_EP_MAX_PKG_SIZE, ++ USB_EP_CAPS(USB_EP_CAPS_TYPE_INT, USB_EP_CAPS_DIR_OUT)), ++#undef EP_INFO ++}; ++ ++/*********************************************************************** ++ * Convenience functions ++ ***********************************************************************/ ++static inline struct iproc_udc *gadget_to_udc(struct usb_gadget *g) ++{ ++ return container_of(g, struct iproc_udc, gadget); ++} ++ ++static inline struct iproc_ep *our_ep(struct usb_ep *ep) ++{ ++ return container_of(ep, struct iproc_ep, usb_ep); ++} ++ ++static inline struct iproc_ep_req *our_req(struct usb_request *req) ++{ ++ return container_of(req, struct iproc_ep_req, usb_req); ++} ++ ++/**************************************************************************** ++ * DMA descriptor chain routines. ++ * ++ * dma_desc_chain_reset - Initialize chain in preparation for transfer ++ * dma_desc_chain_full - Indicates if no descriptors in chain for available for use. ++ * dma_desc_chain_alloc - Get next free descriptor for use. Have to check if chain not full first. ++ * dma_desc_chain_empty - Indicates if no descriptors in the chain are being used. ++ * dma_desc_chain_head - Pointer to 1st entry in chain. Have to check if chain not empty first. ++ * dma_desc_chain_free - Frees up 1st entry for use. Only do this if DMA for this descriptor has completed. ++ * ++ ***************************************************************************/ ++static inline struct iproc_udc_dma_desc *dma_desc_chain_alloc(struct iproc_ep *ep) ++{ ++ u32 idx; ++ ++ idx = ep->dma.add_idx++; ++ ++ return &ep->dma.vir_addr->desc[IPROC_EP_DMA_DESC_IDX(idx)]; ++} ++ ++static inline int dma_desc_chain_empty(struct iproc_ep *ep) ++{ ++ return ep->dma.add_idx == ep->dma.rm_idx; ++} ++ ++static inline void dma_desc_chain_free(struct iproc_ep *ep) ++{ ++ ep->dma.rm_idx++; ++} ++ ++static inline int dma_desc_chain_full(struct iproc_ep *ep) ++{ ++ return (!dma_desc_chain_empty(ep) && (IPROC_EP_DMA_DESC_IDX(ep->dma.add_idx) == IPROC_EP_DMA_DESC_IDX(ep->dma.rm_idx))); ++} ++ ++static inline struct iproc_udc_dma_desc *dma_desc_chain_head(struct iproc_ep *ep) ++{ ++ return (&ep->dma.vir_addr->desc[IPROC_EP_DMA_DESC_IDX(ep->dma.rm_idx)]); ++} ++ ++static inline void dma_desc_chain_reset(struct iproc_ep *ep) ++{ ++ ep->dma.add_idx = 0; ++ ep->dma.rm_idx = 0; ++} ++ ++/**************************************************************************** ++ * ++ * Platform device level alloc / free of memory used for DMA descriptors. ++ * A single block of memory static in size is used for DMA descriptors. ++ * Each endpoint has a small number of descriptors for its exclusive use. ++ * These are chained in a loop. See bcm_udc_dwc.h and iproc_dma_ep_init() ++ * for more details. ++ * ++ ***************************************************************************/ ++static int iproc_platform_dma_alloc(struct platform_device *platformDevP, ++ struct iproc_udc *udc) ++{ ++ udc->dma.vir_addr = dma_alloc_coherent(&platformDevP->dev, ++ sizeof(struct iproc_udc_dma), ++ (dma_addr_t *)&udc->dma.phy_addr, GFP_KERNEL); ++ ++ if (!udc->dma.vir_addr) { ++ dev_err(udc->dev, "dma_alloc_coherent() failed\n"); ++ return -ENOMEM; ++ } ++ ++ return ENOERROR; ++} ++ ++static void iproc_platform_dma_free(struct platform_device *platformDevP, ++ struct iproc_udc *udc) ++{ ++ int idx; ++ ++ dma_free_coherent(&platformDevP->dev, sizeof(struct iproc_udc_dma), ++ udc->dma.vir_addr, (dma_addr_t)udc->dma.phy_addr); ++ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx ++) { ++ if (udc->ep[idx].dma.align_buff) { ++ dma_free_coherent(NULL, udc->ep[idx].dma.align_len, ++ udc->ep[idx].dma.align_buff, ++ udc->ep[idx].dma.align_addr); ++ udc->ep[idx].dma.align_buff = NULL; ++ } ++ } ++} ++ ++/*************************************************************************** ++ * Routines for debug dump of DMA descriptors ++ **************************************************************************/ ++#ifdef IPROC_UDC_DEBUG ++static void iproc_dbg_dma_dump(struct iproc_udc *udc) ++{ ++ int idx; ++ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) ++ iproc_dbg_dma_dump_ep(&udc->ep[idx]); ++} ++ ++static void iproc_dbg_dma_dump_desc(char *label, struct iproc_udc_dma_desc *virt, ++ struct iproc_udc_dma_desc *phys) ++{ ++ printk("%s virt=0x%p phys=0x%p: 0x%08x 0x%08x 0x%08x", ++ label, virt, phys, virt->status, virt->reserved, virt->buf_addr); ++} ++ ++static void iproc_dbg_dma_dump_ep(struct iproc_ep *ep) ++{ ++ int idx; ++ ++ printk("EP %d DMA\n", ep->num); ++ printk(" setup\n"); ++ iproc_dbg_dma_dump_desc(" ", ++ (struct iproc_udc_dma_desc *)&ep->dma.vir_addr->setup, ++ (struct iproc_udc_dma_desc *)&ep->dma.phy_addr->setup); ++ printk(" desc\n"); ++ ++ for (idx = 0; idx < IPROC_EP_DMA_DESC_CNT; idx++) { ++ iproc_dbg_dma_dump_desc(" ", &ep->dma.vir_addr->desc[idx], ++ &ep->dma.phy_addr->desc[idx]); ++ ++ /* Don't bother displaying entries beyond the last. */ ++ if (IPROC_USBD_READ(ep->dma.vir_addr->desc[idx].status) & ++ REG_DMA_STAT_LAST_DESC) ++ break; ++ } ++} ++#endif /* IPROC_UDC_DEBUG */ ++ ++/**************************************************************************** ++ * Initialization of DMA descriptors at the endpoint level. ++ ***************************************************************************/ ++static void iproc_dma_ep_init(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ int idx; ++ ++ /** @todo shorten names to virtAddr physAddr?? */ ++ ep->dma.vir_addr = &udc->dma.vir_addr->ep[ep->num]; ++ ep->dma.phy_addr = &udc->dma.phy_addr->ep[ep->num]; ++ ++ /* ++ * Control endpoints only do setup in the OUT direction, so only need to set the ++ * buffer address for that direction. The buffer is set, even if not a control ++ * endpoint, just to simplify things. There's no harm with this. ++ */ ++ ep->dma.vir_addr->setup.status = cpu_to_le32(REG_DMA_STAT_BUF_HOST_BUSY); ++ wmb(); ++ iproc_usbd_ep_dma_buf_addr_set(udc->usbd_regs, ep->num, USB_DIR_OUT, &ep->dma.phy_addr->setup); ++ ++ /* ++ * Take ownership of the DMA descriptors, and chain them in a loop. This allows a small number ++ * descriptors to be used for requests. Need to have the DWC DMA Descriptor Update option enabled ++ * in the device control register in order to do this. When a transfer for a descriptor completes, ++ * the descriptor will get re-used if there's still data left in a request to transfer. See the ++ * iproc_dma_data_rm_done() and iproc_dma_data_add_ready() routines. ++ */ ++ /** @todo Put these in endpoint context?? */ ++ for (idx = 0; idx < IPROC_EP_DMA_DESC_CNT; idx++) { ++ ep->dma.vir_addr->desc[idx].status = ++ cpu_to_le32(REG_DMA_STAT_BUF_HOST_BUSY); ++ wmb(); ++ ep->dma.vir_addr->desc[idx].next_addr = ++ cpu_to_le32((u32)&ep->dma.phy_addr->desc[idx+1]); ++ } ++ ep->dma.vir_addr->desc[(IPROC_EP_DMA_DESC_CNT - 1)].next_addr = ++ cpu_to_le32((u32)&ep->dma.phy_addr->desc[0]); ++ ++ /* ++ * To simplify things, register the descriptor chain in both directions. Control endpoints are the ++ * only type that will be transferring in both directions, but they will only be transferring in one ++ * direction at a time, so should not be any issues with using the same descriptor set for both directions. ++ * For single direction endpoints, the other direction will not be used. ++ */ ++ ++ iproc_usbd_ep_dma_desc_addr_set(udc->usbd_regs, ep->num, USB_DIR_OUT, ++ &ep->dma.phy_addr->desc[0]); ++ iproc_usbd_ep_dma_desc_addr_set(udc->usbd_regs, ep->num, USB_DIR_IN, ++ &ep->dma.phy_addr->desc[0]); ++} ++ ++/**************************************************************************** ++ * DMA data routines. ++ * ++ * A gadget usb_request buf is used for the data. The entire buf contents may ++ * or may not fit into the descriptor chain at once. When the DMA transfer ++ * associated with a descriptor completes, the descriptor is re-used to add ++ * more segments of the usb_request to the chain as necessary. ++ * ++ * iproc_dma_data_init - Initialization in preparation for DMA of usb_request. ++ * iproc_dma_data_add_ready - Adds usb_request segments into DMA chain until full or no segments left ++ * iproc_dma_data_rm_done - Removes usb_request segments from DMA chain that have completed transfer ++ * iproc_dma_data_finish - Final stage of DMA of the usb_request ++ * ++ ***************************************************************************/ ++static void iproc_dma_data_init(struct iproc_ep *ep) ++{ ++ struct iproc_ep_req *req; ++ struct iproc_udc *udc = ep->udc; ++ ++ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); ++ ++ if (req->dma_aligned) { ++ /* ++ * This buffer needs to be aligned in order to DMA. We do this by copying into a special buffer we ++ * have for this purpose. Save the original DMA physical address so it can be restored later. ++ * This may not be used, but we'll do it anyways. Then set the DMA address to the aligned buffer ++ * address. Only the DMA physical address is used for the transfers, so the original buffer virtual ++ * address does not need to be changed. Then copy the data into the aligned buffer. ++ */ ++ /** @todo Really only need to do the memcpy for IN data */ ++ ++ req->orig_dma_addr = req->usb_req.dma; ++ req->usb_req.dma = ep->dma.align_addr; ++ memcpy(ep->dma.align_buff, req->usb_req.buf, req->usb_req.length); ++ } ++ ++ ep->dma.done = 0; ++ ep->dma.done_len = 0; ++ ep->dma.todo_len = ep->dma.usb_req->length; ++ ep->dma.buf_addr = ep->dma.usb_req->dma; ++ ep->dma.status = REG_DMA_STAT_RX_SUCCESS; ++ ++ if ((ep->dir == USB_DIR_IN) && (ep->type != USB_ENDPOINT_XFER_ISOC)) { ++ /* ++ * For IN transfers, do not need to segment the buffer into max packet portions ++ * for the DMA descriptors. The hardware will automatically segment into max ++ * packet sizes as necessary. ++ */ ++ ep->dma.max_buf_len = ep->usb_ep.maxpacket; ++ ++ /* ++ * If the request is of zero length, then force the zero flag so iproc_dma_data_add_ready() ++ * will queue the request. Conversely, if the gadget has set the zero flag, leave ++ * it set only if it is needed (request length is a multiple of maxpacket) ++ */ ++ if (ep->dma.usb_req->length == 0) ++ ep->dma.usb_req->zero = 1; ++ else if (ep->dma.usb_req->zero) ++ ep->dma.usb_req->zero = ++ (ep->dma.usb_req->length % ep->usb_ep.maxpacket)? 0 : 1; ++ } else { ++ ep->dma.max_buf_len = ep->usb_ep.maxpacket; ++ } ++ ++ dma_desc_chain_reset(ep); ++ ++ iproc_usbd_ep_irq_en(udc->usbd_regs, ep->num, ep->dir); ++} ++ ++static void iproc_dma_data_finish(struct iproc_ep *ep) ++{ ++ struct iproc_ep_req *req; ++ struct iproc_udc *udc = ep->udc; ++ ++ iproc_usbd_ep_irq_dis(udc->usbd_regs, ep->num, ep->dir); ++ iproc_usbd_ep_dma_dis(udc->usbd_regs, ep->num, ep->dir); ++ ++ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); ++ ++ if (req->dma_aligned) { ++ /* ++ * The original request buffer was not aligned properly, so a special buffer was used ++ * for the transfer. Copy the aligned buffer contents into the original. Also restore ++ * the original dma physical address. ++ */ ++ /** @todo Really only need to do the memcpy for OUT setup/data */ ++ memcpy(req->usb_req.buf, ep->dma.align_buff, req->usb_req.length); ++ req->usb_req.dma = req->orig_dma_addr; ++ } ++} ++ ++static void iproc_dma_data_add_ready(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ volatile struct iproc_udc_dma_desc *dma_desc = NULL; ++ u32 status; ++ u32 len; ++ int enable_dma = 0; ++ ++ /* ++ * DMA must be disabled while this loop is running, as multi-descriptor transfers ++ * will have the descriptor chain in an intermediate state until the last descriptor ++ * is written and the chain terminated. ++ */ ++ if (iproc_usbd_dma_status(udc->usbd_regs)) { ++ enable_dma = 1; ++ iproc_usbd_dma_dis(udc->usbd_regs); ++ } ++ ++ if (!ep->dma.todo_len) ++ ep->dma.usb_req->zero = 1; ++ ++ /* ++ * Will only have one request in the chain at a time. Add request segments to the ++ * chain until all parts of the request have been put in the chain or the chain ++ * has no more room. ++ */ ++ while (!dma_desc_chain_full(ep) && (ep->dma.todo_len || ep->dma.usb_req->zero)) { ++ /* ++ * Get the next descriptor in the chain, and then fill the descriptor contents as needed. ++ * Do not set the descriptor buffer status to ready until last to ensure there's no ++ * contention with the hardware. ++ */ ++ dma_desc = dma_desc_chain_alloc(ep); ++ ++ len = ep->dma.todo_len < ep->dma.max_buf_len ? ep->dma.todo_len : ep->dma.max_buf_len; ++ ep->dma.todo_len -= len; ++ ++ status = 0; ++ ++ if (len < ep->dma.max_buf_len) { ++ /* ++ * If this segment is less than the max, then it is the last segment. There's no need to ++ * send a closing ZLP, although this segment might be a ZLP. Regardless, clear the ZLP flag ++ * to ensure that the processing of this request finishes. Also set the end of the descriptor ++ * chain. ++ */ ++ ep->dma.usb_req->zero = 0; ++ status |= REG_DMA_STAT_LAST_DESC; ++ } else if ((ep->dma.todo_len == 0) && !ep->dma.usb_req->zero) { ++ /* ++ * Segment is of the max packet length. Since there's nothing left, it has to also be the last ++ * last segment. No closing ZLP segment requested, just set the end of the descriptor chain. ++ */ ++ status |= REG_DMA_STAT_LAST_DESC; ++ } ++ ++ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC)) { ++ /* ++ * Increment the frame number for transmit, then use it for the next packet. The frame number ++ * may get larger than its 13-bit size, but the mask will handle the wrap-around so we don't ++ * need to add checks for this condition. E.g. 0x7ff + 1 = 0x800. 0x800 & 0x7ff = 0 which ++ * is the next number in the sequence. ++ */ ++ /** @todo Handle ISOC PIDs and frame numbers used with HS high bandwidth transfers */ ++ /** @todo Might not need to set the last descriptor status. Currently restricting ++ * IN ISOC transfers to the max packet size. ++ */ ++ status |= REG_DMA_STAT_LAST_DESC; ++ ++ ep->dma.frame_num += ep->dma.frame_incr; ++ status |= ((ep->dma.frame_num << REG_DMA_STAT_FRAME_NUM_SHIFT) & ++ REG_DMA_STAT_FRAME_NUM_MASK); ++ } ++ ++ IPROC_USBD_WRITE(dma_desc->buf_addr, ep->dma.buf_addr); ++ status |= (len << REG_DMA_STAT_BYTE_CNT_SHIFT); ++ IPROC_USBD_WRITE(dma_desc->status, status | REG_DMA_STAT_BUF_HOST_READY); ++ wmb(); ++ ep->dma.buf_addr += len; ++ ++ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC)) { ++ /* With ISOC transfers, only enable one DMA descriptors at a time. ++ */ ++ /** @todo Determine if FIFO will overflow. If it does not, then can remove this check. ++ * This may not even be an issue if the buffer size is restricted to the max packet size ++ * when a request is submitted to the endpoint. ++ */ ++ break; ++ } ++ } /* while */ ++ ++ /* Set LAST bit on last descriptor we've configured */ ++ if (dma_desc) ++ IPROC_USBD_BITS_SET(dma_desc->status, REG_DMA_STAT_LAST_DESC); ++ ++ if (enable_dma) ++ iproc_usbd_dma_en(udc->usbd_regs); ++} ++ ++static void iproc_dma_data_rm_done(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ volatile struct iproc_udc_dma_desc *dma_desc; ++ u32 status; ++ u32 len; ++ ++ /* ++ * Will only have one request in the chain at a time. Remove any completed ++ * request segments from the chain so any segments awaiting transfer can ++ * be put in the chain. ++ */ ++ while (!dma_desc_chain_empty(ep)) { ++ /* ++ * Examine the first entry in the chain. If its status is not done, then there's ++ * nothing to remove. ++ */ ++ dma_desc = dma_desc_chain_head(ep); ++ ++ if ((IPROC_USBD_READ(dma_desc->status) & REG_DMA_STAT_BUF_MASK) != ++ REG_DMA_STAT_BUF_DMA_DONE) ++ break; ++ ++ /* ++ * The transfer of this request segment has completed. Save the status info and then ++ * take ownership of the descriptor. It is simpler to do this than modifying parts of ++ * the descriptor in order to take ownership. Don't put the descriptor back in the chain ++ * until all info affected by the status has been updated, just to be safe. ++ */ ++ status = IPROC_USBD_READ(dma_desc->status); ++ IPROC_USBD_WRITE(dma_desc->status, REG_DMA_STAT_BUF_HOST_BUSY); ++ wmb(); ++ ++ len = (status & REG_DMA_STAT_NON_ISO_BYTE_CNT_MASK) >> ++ REG_DMA_STAT_NON_ISO_BYTE_CNT_SHIFT; ++ ++ /* RX: For multiple descriptors, len is cumulative, not absolute. ++ * RX: So only adjust the dma fields when we get to the last descriptor ++ * TX: Each descriptor entry is absolute, count them all ++ */ ++ if ((ep->dir == USB_DIR_IN) || (status & REG_DMA_STAT_LAST_DESC)) { ++ ep->dma.done_len += len; ++ ep->dma.usb_req->actual += len; ++ } ++ ++ if ((status & REG_DMA_STAT_RX_MASK) != REG_DMA_STAT_RX_SUCCESS) { ++ ep->dma.status = status & REG_DMA_STAT_RX_MASK; ++ ep->dma.usb_req->status = -EIO; ++ dev_warn(udc->dev, "%s: DMA error: desc=0x%p status=0x%x len=%d add=0x%x remove=0x%x\n", ++ ep->usb_ep.name, dma_desc, status, len, ep->dma.add_idx, ep->dma.rm_idx); ++ } ++ ++ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC)){ ++ /** @todo Determine if this special processing needs to be done. May not to do this if the ++ * buffer size is restricted to the max packet size when a request is submitted to the endpoint. ++ */ ++ if (ep->dma.usb_req->actual == ep->dma.usb_req->length) ++ ep->dma.usb_req->status = ENOERROR; ++ dma_desc_chain_reset(ep); ++ } else { ++ dma_desc_chain_free(ep); ++ } ++ } ++ ++ /* When last segment processed, update status if there has not been an error */ ++ if (!ep->dma.todo_len && (ep->dma.usb_req->status == -EINPROGRESS)) ++ ep->dma.usb_req->status = ENOERROR; ++} ++ ++/**************************************************************************** ++ * Control Endpoint SETUP related routines. ++ * ++ * iproc_ep_setup_init - Prepares for next SETUP Rx. Status indicates if STALL req'd. ++ * iproc_ep_setup_process - Handle Rx of a SETUP. ++ ***************************************************************************/ ++static void iproc_ep_setup_init(struct iproc_ep *ep, int status) ++{ ++ struct iproc_udc *udc = ep->udc; ++ ++ /* Re-enable transfers to the SETUP buffer, clear IN and OUT NAKs, and re-enable OUT interrupts. */ ++ ep->dma.vir_addr->setup.status = cpu_to_le32(REG_DMA_STAT_BUF_HOST_READY); ++ ep->dir = USB_DIR_OUT; ++ ep->stopped = 0; ++ ++ if (status == ENOERROR) { ++ /* Handling of previous SETUP was OK. Just clear any NAKs. */ ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, USB_DIR_OUT); ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, USB_DIR_IN); ++ } else { ++ /* ++ * Handling of previous SETUP failed. Set the STALL. This will get cleared ++ * when the next SETUP is rx'd. ++ */ ++ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, USB_DIR_IN); ++ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, USB_DIR_OUT); ++ } ++ ++ iproc_usbd_ep_irq_en(udc->usbd_regs, ep->num, USB_DIR_OUT); ++ iproc_usbd_ep_dma_en(udc->usbd_regs, ep->num, USB_DIR_OUT); ++} ++ ++void iproc_ep_setup_process(struct iproc_ep *ep, struct usb_ctrlrequest *setup) ++{ ++ struct iproc_udc *udc = ep->udc; ++ u32 value; ++ u32 index; ++ u32 length; ++ int status; ++ ++ value = le16_to_cpu(setup->wValue); ++ index = le16_to_cpu(setup->wIndex); ++ length = le16_to_cpu(setup->wLength); ++ ++ /* ++ * Any SETUP packets appearing here need to be handled by the gadget driver. Some SETUPs may have ++ * already been silently handled and acknowledged by the DWC UDC. The exceptions to this rule are the ++ * USB_REQ_SET_CONFIGURATION and USB_REQ_SET_INTERFACE, which have been only partially handled with ++ * the expectation that some additional software processing is required in order to complete these requests. ++ * Thus, they have not been acknowledged by the DWC UDC. There is no DATA stage for these requests. ++ */ ++ ++ /* ++ * Set the direction of the subsequent DATA stage of a control transfer. This is an ++ * optional stage. It may not exist for all control transfers. If there is a DATA ++ * stage, this info is used for DMA operations for any requests received from the ++ * Gadget driver. ++ */ ++ ++ ep->dir = setup->bRequestType & USB_ENDPOINT_DIR_MASK; ++ ++ if (ep->num != 0) { ++ /** @todo Make changes here if the Linux USB gadget ever supports a control endpoint other ++ * than endpoint 0. The DWC UDC supports multiple control endpoints, and this driver has ++ * been written with this in mind. To make things work, really need to change the Gadget ++ * setup() callback parameters to provide an endpoint context, or add something similar ++ * to the usb_ep structure, or possibly use a usb_request to hold a setup data packet. ++ */ ++ dev_err(udc->dev, "%s: control transfer not supported\n", ep->usb_ep.name); ++ status = -EOPNOTSUPP; ++ } else { ++ /* ++ * Forward the SETUP to the gadget driver for processing. The appropriate directional ++ * interrupt and NAK clear will happen when the DATA stage request is queued. ++ */ ++ spin_unlock(&udc->lock); ++ status = udc->gadget_driver->setup(&udc->gadget, setup); ++ spin_lock(&udc->lock); ++ } ++ ++ if (status < 0) { ++ /* ++ * Error occurred during the processing of the SETUP, so enable STALL. This condition ++ * can only be cleared with the RX of another SETUP, so prepare for that event. ++ */ ++ dev_err(udc->dev, "%s: SETUP %02x.%02x STALL; status=%d\n", ++ ep->usb_ep.name, setup->bRequestType, setup->bRequest, status); ++ ++ iproc_ep_setup_init(ep, status); ++ } else if (length == 0) { ++ /* No DATA stage. Just need to prepare for the next SETUP. */ ++ iproc_ep_setup_init(ep, ENOERROR); ++ } else { ++ /* ++ * The SETUP stage processing has completed OK, and there may or may not be a request queued ++ * for the DATA stage. When the DATA stage completes, preparation for the RX of the next ++ * SETUP will be done. ++ */ ++ } ++} ++ ++static void iproc_udc_req_xfer_done(struct iproc_ep *ep, struct iproc_ep_req *req, int status) ++{ ++ struct iproc_udc *udc = ep->udc; ++ u32 stopped; ++ ++ list_del_init(&req->list_node); ++ ++ if (req->usb_req.status == -EINPROGRESS) ++ req->usb_req.status = status; ++ ++ if (req->dma_aligned) { ++ req->dma_aligned = 0; ++ } else if (req->dma_mapped) { ++ /* ++ * A physical address was not provided for the DMA buffer. Release any resources ++ * that were requested by the driver. ++ */ ++ dma_unmap_single(udc->gadget.dev.parent, req->usb_req.dma, req->usb_req.length, ++ (ep->dir == USB_DIR_IN ? DMA_TO_DEVICE : DMA_FROM_DEVICE)); ++ ++ req->dma_mapped = 0; ++ req->usb_req.dma = DMA_ADDR_INVALID; ++ } ++ ++ /* ++ * Disable DMA operations during completion callback. The callback may cause requests to be ++ * added to the queue, but we don't want to change the state of the queue head. ++ */ ++ stopped = ep->stopped; ++ ep->stopped = 1; ++ spin_unlock(&udc->lock); ++ req->usb_req.complete(&ep->usb_ep, &req->usb_req); ++ spin_lock(&udc->lock); ++ ep->stopped = stopped; ++} ++ ++static void iproc_udc_req_xfer_process(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ struct iproc_ep_req *req; ++ ++ /* @todo Current transfer is always the queue head. ++ * Do we need a separate pointer? Maybe just a pointer to usb_request ++ */ ++ if (!ep->dma.usb_req) { ++ dev_err(udc->dev, "%s: No request being transferred\n", ep->usb_ep.name); ++ return; ++ } ++ ++ iproc_usbd_ep_dma_dis(udc->usbd_regs, ep->num, ep->dir); ++ iproc_dma_data_rm_done(ep); ++ ++ if (ep->dma.usb_req->status != -EINPROGRESS) { ++ /* ++ * Current transfer stage has finished. This may or may not be with error. ++ * Complete the transfer as needed before starting the next one, if any. ++ */ ++ iproc_dma_data_finish(ep); ++ ++ if ((ep->type == USB_ENDPOINT_XFER_CONTROL) && (ep->dir == USB_DIR_IN) ++ && (ep->dma.usb_req->status == ENOERROR)) { ++ /* ++ * For the status phase of control IN transfers, the hardware requires that an OUT DMA transfer ++ * actually takes place. This should be just an OUT ZLP, and we will re-use the IN buffer that ++ * just completed transfer for this purpose. There should be no harm in doing this, even if the ++ * OUT status is more than a ZLP. ++ */ ++ ep->dir = USB_DIR_OUT; ++ iproc_dma_data_init(ep); ++ } else { ++ /* ++ * All transfer stages have completed. Return the request to the gadget driver, and then ++ * setup for the next transfer. ++ */ ++ iproc_udc_req_xfer_done(ep, list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node), ENOERROR); ++ ++ if (ep->type == USB_ENDPOINT_XFER_CONTROL) ++ iproc_ep_setup_init(ep, ENOERROR); ++ ++ if (list_empty(&ep->list_queue)) { ++ /** @todo Probably should more closely bind this to iproc_dma_data_finish. */ ++ ep->dma.usb_req = NULL; ++ } else { ++ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); ++ ep->dma.usb_req = &req->usb_req; ++ iproc_dma_data_init(ep); ++ } ++ } ++ } ++ ++ if (ep->dma.usb_req != NULL) { ++ iproc_dma_data_add_ready(ep); ++ iproc_usbd_ep_dma_en(udc->usbd_regs, ep->num, ep->dir); ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, ep->dir); ++ } ++} ++ ++static void iproc_udc_req_xfer_error(struct iproc_ep *ep, int status) ++{ ++ struct iproc_udc *udc = ep->udc; ++ ++ if (!ep->dma.usb_req) { ++ dev_err(udc->dev, "%s: No request being transferred\n", ep->usb_ep.name); ++ return; ++ } ++ ++ /** @todo abort current DMA, start next transfer if there is one. */ ++ ep->dma.usb_req->status = status; ++ iproc_udc_req_xfer_process(ep); ++} ++ ++static void iproc_udc_ops_disconnect(struct iproc_udc *udc) ++{ ++ struct iproc_ep *ep; ++ int idx; ++ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { ++ ep = &udc->ep[idx]; ++ ++ if (ep->dma.usb_req) { ++ /* Flush DMA, reqeust still pending */ ++ iproc_usbd_ep_fifo_flush_en(udc->usbd_regs, 0, USB_DIR_IN); ++ iproc_usbd_ep_fifo_flush_dis(udc->usbd_regs, 0, USB_DIR_IN); ++ ++ iproc_udc_req_xfer_process(ep); ++ } ++ } ++} ++ ++static void iproc_udc_ops_shutdown(struct iproc_udc *udc) ++{ ++ struct iproc_ep *ep; ++ ++ udc->ep[0].desc = NULL; ++ list_for_each_entry(ep, &udc->gadget.ep_list, usb_ep.ep_list) ++ ep->desc = NULL; ++ ++ udc->gadget.dev.driver = NULL; ++ udc->gadget_driver = NULL; ++} ++ ++/**************************************************************************** ++ * IRQ routines. ++ * ++ * xgs_iproc_udc_isr - top level entry point. ++ * iproc_cfg_isr - device (endpoint 0) set config interrupt handler ++ * iproc_inf_isr - device (endpoint 0) set interface interrupt handler ++ * iproc_speed_isr - device speed enumeration done interrupt handler ++ * iproc_ep_in_isr - top level IN endpoint related interrupt handler ++ * iproc_ep_out_isr - top level OUT endpoint related interrupt handler ++ * iproc_ep_out_setup_isr - Control endpoint SETUP Rx handler. This may get ++ * called directly as the result of an endpoint OUT interrupt, or ++ * indirectly as the result of device SET_CFG or SET_INTF. ++ ***************************************************************************/ ++static void iproc_cfg_isr(struct iproc_udc *udc) ++{ ++ struct usb_ctrlrequest setup; ++ int idx; ++ u16 cfg; ++ ++ /* ++ * Device Configuration SETUP has been received. This is not placed in the SETUP ++ * DMA buffer. The packet has to be re-created here so it can be forwarded to the ++ * gadget driver to act upon. ++ */ ++ ++ cfg = (u16) iproc_usbd_cfg_num(udc->usbd_regs); ++ ++ setup.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE; ++ setup.bRequest = USB_REQ_SET_CONFIGURATION; ++ setup.wValue = cpu_to_le16(cfg); ++ setup.wIndex = 0; ++ setup.wLength = 0; ++ ++ /* ++ * Setting the configuration number before the gadget responds is a bit presumptious, but should ++ * not be fatal. ++ */ ++ /** @todo Do not set endpoint 0? Or is it a don't care? */ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) ++ iproc_usbd_ep_cfg_set(udc->usbd_regs, idx, cfg); ++ ++ printk(KERN_INFO "SET CFG=%d\n", cfg); ++ ++ iproc_ep_setup_process(&udc->ep[0], &setup); ++ iproc_usbd_setup_done(udc->usbd_regs); ++} ++ ++static void iproc_inf_isr(struct iproc_udc *udc) ++{ ++ struct usb_ctrlrequest setup; ++ u32 idx; ++ u16 intf; ++ u16 alt; ++ ++ /* ++ * Device Interface SETUP has been received. This is not placed in the SETUP ++ * DMA buffer. The packet has to be re-created here so it can be forwarded to the ++ * gadget driver to act upon. ++ */ ++ intf = (u16)iproc_usbd_intf_num(udc->usbd_regs); ++ alt = (u16)iproc_usbd_alt_num(udc->usbd_regs); ++ ++ setup.bRequestType = USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_INTERFACE; ++ setup.bRequest = USB_REQ_SET_INTERFACE; ++ setup.wValue = cpu_to_le16(alt); ++ setup.wIndex = cpu_to_le16(intf); ++ setup.wLength = 0; ++ ++ /* ++ * Setting the interface numbers before the gadget responds is a bit ++ * presumptious, but should not be fatal. ++ */ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { ++ iproc_usbd_ep_alt_set(udc->usbd_regs, idx, alt); ++ iproc_usbd_ep_intf_set(udc->usbd_regs, idx, intf); ++ } ++ ++ iproc_ep_setup_process(&udc->ep[0], &setup); ++ iproc_usbd_setup_done(udc->usbd_regs); ++} ++ ++static void iproc_speed_isr(struct iproc_udc *udc) ++{ ++ u32 speed; ++ ++ speed = udc->gadget.speed; ++ ++ switch(iproc_usbd_speed_get(udc->usbd_regs)) { ++ case USB_SPEED_HIGH: ++ printk(KERN_INFO "HIGH SPEED\n"); ++ udc->gadget.speed = USB_SPEED_HIGH; ++ break; ++ case USB_SPEED_FULL: ++ printk(KERN_INFO "FULL SPEED\n"); ++ udc->gadget.speed = USB_SPEED_FULL; ++ break; ++ case USB_SPEED_LOW: ++ dev_warn(udc->dev, "low speed not supported\n"); ++ udc->gadget.speed = USB_SPEED_LOW; ++ break; ++ default: ++ dev_err(udc->dev, "unknown speed=0x%x\n", iproc_usbd_speed_get(udc->usbd_regs)); ++ break; ++ } ++ ++ if ((speed == USB_SPEED_UNKNOWN) && (udc->gadget.speed != USB_SPEED_UNKNOWN)) { ++ /* ++ * Speed has not been enumerated before, so now we can initialize transfers on endpoint 0. ++ * Also have to disable the NAKs at a global level, which has been in place while waiting ++ * for enumeration to complete. ++ */ ++ iproc_ep_setup_init(&udc->ep[0], ENOERROR); ++ iproc_usbd_nak_response_dis(udc->usbd_regs); ++ } ++} ++ ++static void iproc_ep_in_isr(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ u32 status; ++ ++ status = iproc_usbd_ep_stat_active(udc->usbd_regs, ep->num, USB_DIR_IN); ++ iproc_usbd_ep_stat_clear(udc->usbd_regs, ep->num, USB_DIR_IN, status); ++ ++ if (!status) ++ return; ++ ++ /** @todo check might only be for direction... */ ++ if ((ep->dir != USB_DIR_IN) && (ep->type != USB_ENDPOINT_XFER_CONTROL)) { ++ dev_err(udc->dev, "%s: unexpected IN interrupt\n", ep->usb_ep.name); ++ return; ++ } ++ ++ if (ep->dir != USB_DIR_IN) ++ /* This probably should not be happening */ ++ dev_warn(udc->dev, "%s: CTRL dir OUT\n", ep->usb_ep.name); ++ ++ if ((ep->type == USB_ENDPOINT_XFER_ISOC) && ++ (status & (USBD_EP_STAT_IN_XFER_DONE | USBD_EP_STAT_DMA_BUF_UNAVAIL))) ++ dev_warn(udc->dev, "%s: ISOC IN unexpected status=0x%x\n", ep->usb_ep.name, status); ++ ++ if (status & USBD_EP_STAT_IN_TOKEN_RX) { ++ /* ++ * If there's any IN requests, the DMA should be setup and ready to go if ++ * the endpoint is not an ISOC. Nothing to do in this case. However, if ++ * this is an ISOC endpoint, then this interrupt implies there was no ++ * data available for this frame number. This will happen if the gadget ++ * does not have any data queued to send in this frame, or we have been ++ * waiting for this event to occur so we can get alignment with the host ++ * for the interval. This alignment is necessary when the interval is ++ * greater than one frame / uframe. E.g. for an audio stream sending ++ * samples @ 5ms intervals on a FS link, this corresponds to a period ++ * of 5 frames. Samples with be queued for every 5th frame number after ++ * the frame number in which this interrupt occurred. ++ */ ++ status &= ~USBD_EP_STAT_IN_TOKEN_RX; ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, USB_DIR_IN); ++ ++ if ((ep->type == USB_ENDPOINT_XFER_ISOC)) { ++ /* Always align to the current frame number for subsequent transfers. */ ++ ep->dma.frame_num = iproc_usbd_last_rx_frame_num(udc->usbd_regs); ++ if (ep->dma.usb_req != NULL) { ++ /* ++ * Might have something queued when waiting for alignment. If something is queued, ++ * it is already too late for the current transfer point. It will also have been ++ * placed in the queue at some point before this interrupt, and it will be stale ++ * if we try to transmit at the next transfer point. ++ */ ++ ep->dma.usb_req->status = -EREMOTEIO; ++ iproc_udc_req_xfer_process(ep); ++ } ++ } ++ } ++ ++ if (status & USBD_EP_STAT_IN_DMA_DONE) { ++ /* ++ * DMA has completed, but cannot start next transfer until USBD_EP_STAT_IN_XFER_DONE. ++ * To avoid race conditions and other issues, do not release the current transfer until both ++ * interrupts have arrived. Normally this interrupt will arrive at or before the IN_XFER_DONE, ++ * but there have been situations when the system is under load that this interrupt might ++ * arrive after the IN_XFER_DONE, in which case we will need to do the processing now. ++ * The exception to this rule is for ISOC endpoints. They will only get this interrupt to ++ * indicate that DMA has completed. ++ */ ++ status &= ~USBD_EP_STAT_IN_DMA_DONE; ++ ++ if ((ep->type == USB_ENDPOINT_XFER_ISOC)) { ++ iproc_udc_req_xfer_process(ep); ++ } else if (ep->dma.done & USBD_EP_STAT_IN_XFER_DONE) { ++ /* ++ * Did not receive the IN_DMA_DONE interrupt for this request before or ++ * at the same time as the IN_XFER_DONE interrupt, so the request ++ * processing was postponed until the IN_DMA_DONE interrupt arrived. ++ * See handling of IN_XFER_DONE status below. ++ */ ++ iproc_udc_req_xfer_process(ep); ++ } else { ++ /* ++ * IN_DMA_DONE received. Save this info so request processing will be ++ * done when the IN_XFER_DONE interrupt is received. This may happen ++ * immediately, idx.e. both IN_DMA_DONE and IN_XFER_DONE status are ++ * set when the interrupt processing takes place. ++ */ ++ ep->dma.done = USBD_EP_STAT_IN_DMA_DONE; ++ } ++ } ++ ++ if (status & USBD_EP_STAT_IN_XFER_DONE) { ++ status &= ~(USBD_EP_STAT_IN_XFER_DONE); ++ status &= ~(USBD_EP_STAT_IN_FIFO_EMPTY); ++ ++ if (ep->dma.done & USBD_EP_STAT_IN_DMA_DONE) { ++ /* ++ * Have received both the IN_DMA_DONE and IN_XFER_DONE interrupts ++ * for this request. OK to process the request (remove the request ++ * and start the next one). ++ */ ++ iproc_udc_req_xfer_process(ep); ++ } else { ++ /* ++ * Have not received the IN_DMA_DONE interrupt for this request. ++ * Need to postpone processing of the request until the IN_DMA_DONE ++ * interrupt occurs. See handling of IN_DMA_DONE status above. ++ */ ++ ep->dma.done = USBD_EP_STAT_IN_XFER_DONE; ++ } ++ } ++ ++ /* Clear the FIFO EMPTY bit, not to print error message */ ++ status &= ~(USBD_EP_STAT_IN_FIFO_EMPTY); ++ ++ if (status & USBD_EP_STAT_DMA_BUF_UNAVAIL) { ++ dev_err(udc->dev, "%s: DMA BUF NOT AVAIL\n", ep->usb_ep.name); ++ status &= ~(USBD_EP_STAT_DMA_BUF_UNAVAIL); ++ iproc_udc_req_xfer_process(ep); ++ } ++ ++ if (status & USBD_EP_STAT_DMA_ERROR) { ++ status &= ~USBD_EP_STAT_DMA_ERROR; ++ dev_err(udc->dev, "%s: DMA ERROR\n", ep->usb_ep.name); ++ iproc_udc_req_xfer_error(ep, -EIO); ++ } ++ ++ if (status) ++ dev_err(udc->dev, "exit: %s %s: unknown status=0x%x\n", ++ __func__, ep->usb_ep.name, status); ++} ++ ++static void iproc_ep_out_setup_isr(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ struct iproc_udc_dma_setup *dma; ++ ++ dma = &ep->dma.vir_addr->setup; ++ if ((IPROC_USBD_READ(dma->status) & REG_DMA_STAT_BUF_MASK) != ++ REG_DMA_STAT_BUF_DMA_DONE) { ++ dev_err(udc->dev, "%s: unexpected DMA buf status=0x%x\n", ep->usb_ep.name, ++ (IPROC_USBD_READ(dma->status) & REG_DMA_STAT_BUF_MASK)); ++ iproc_ep_setup_init(ep, ENOERROR); ++ } else if ((IPROC_USBD_READ(dma->status) & REG_DMA_STAT_RX_MASK) ++ != REG_DMA_STAT_RX_SUCCESS) { ++ dev_err(udc->dev, "%s: unexpected DMA rx status=0x%x\n", ep->usb_ep.name, ++ (IPROC_USBD_READ(dma->status) & REG_DMA_STAT_RX_MASK)); ++ iproc_ep_setup_init(ep, ENOERROR); ++ } else { ++ if (ep->num != 0) { ++ /** @todo Handle the cfg / intf / alt fields of the DMA status. This will only be any issue ++ * once the Linux Gadget driver framework supports control transfers on an endpoint other ++ * than 0. ++ */ ++ dev_warn(udc->dev, "%s: CTRL xfr support not complete\n", ep->usb_ep.name); ++ } ++ /* ++ * Take ownership of the descriptor while processing the request. Ownership will be released ++ * when ready to Rx SETUP again. ++ */ ++ IPROC_USBD_BITS_MODIFY(dma->status, REG_DMA_STAT_BUF_MASK, ++ REG_DMA_STAT_BUF_HOST_BUSY); ++ iproc_ep_setup_process(ep, (struct usb_ctrlrequest *)&dma->data1); ++ } ++} ++ ++static void iproc_ep_out_isr(struct iproc_ep *ep) ++{ ++ struct iproc_udc *udc = ep->udc; ++ u32 status; ++ ++ status = iproc_usbd_ep_stat_active(udc->usbd_regs, ep->num, USB_DIR_OUT); ++ iproc_usbd_ep_stat_clear(udc->usbd_regs, ep->num, USB_DIR_OUT, status); ++ ++ /* ++ * Remove the Rx packet size field from the status. The datasheet states this field is not used ++ * in DMA mode, but that is not true. ++ */ ++ status &= USBD_EP_STAT_ALL; ++ ++ if (!status) ++ return; ++ ++ if ((ep->dir != USB_DIR_OUT) && (ep->type != USB_ENDPOINT_XFER_CONTROL)) { ++ dev_err(udc->dev, "%s: unexpected OUT interrupt\n", ep->usb_ep.name); ++ return; ++ } ++ ++ if (ep->dir != USB_DIR_OUT) ++ /* This probably should not be happening */ ++ dev_err(udc->dev, "%s: CTRL dir IN\n", ep->usb_ep.name); ++ ++ if (status & USBD_EP_STAT_OUT_DMA_DATA_DONE) { ++ status &= ~USBD_EP_STAT_OUT_DMA_DATA_DONE; ++ iproc_udc_req_xfer_process(ep); ++ } ++ ++ if (status & USBD_EP_STAT_OUT_DMA_SETUP_DONE) { ++ status &= ~USBD_EP_STAT_OUT_DMA_SETUP_DONE; ++ iproc_ep_out_setup_isr(ep); ++ } ++ ++ if (status & USBD_EP_STAT_DMA_BUF_UNAVAIL) { ++ /** @todo Verify under what situations this can happen. Should be when chain has emptied but last desc not reached */ ++ /** @todo status for desc updates */ ++ ++ status &= ~USBD_EP_STAT_DMA_BUF_UNAVAIL; ++ dev_err(udc->dev, "%s: DMA BUF NOT AVAIL\n", ep->usb_ep.name); ++ iproc_udc_req_xfer_process(ep); ++ } ++ ++ if (status & USBD_EP_STAT_DMA_ERROR) { ++ status &= ~USBD_EP_STAT_DMA_ERROR; ++ dev_err(udc->dev, "%s: DMA ERROR\n", ep->usb_ep.name); ++ /** @todo merge XferError and XferProcess?? */ ++ iproc_udc_req_xfer_error(ep, -EIO); ++ } ++ ++ if (status) ++ dev_err(udc->dev, "%s: unknown status=0x%x\n", ep->usb_ep.name, status); ++} ++ ++irqreturn_t xgs_iproc_udc_isr(int irq, void *context) ++{ ++ struct iproc_udc *udc = NULL; ++ unsigned long flags; ++ u32 stat, epin_stat, epout_stat; ++ int idx; ++ ++ udc = (struct iproc_udc *)context; ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ if (!udc || !udc->gadget_driver) { ++ dev_err(udc->dev, "Invalid context or no driver registered: irq dev=0x%x\n", ++ iproc_usbd_irq_active(udc->usbd_regs)); ++ ++ iproc_usbd_irq_clear(udc->usbd_regs, USBD_IRQ_ALL); ++ iproc_usbd_ep_irq_list_clear(udc->usbd_regs, USB_DIR_IN, ~0); ++ iproc_usbd_ep_irq_list_clear(udc->usbd_regs, USB_DIR_OUT, ~0); ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ return IRQ_HANDLED; ++ } ++ ++ stat = iproc_usbd_irq_active(udc->usbd_regs); ++ epin_stat = iproc_usbd_ep_irq_list_active(udc->usbd_regs, USB_DIR_IN); ++ epout_stat = iproc_usbd_ep_irq_list_active(udc->usbd_regs, USB_DIR_OUT); ++ ++ if (!(stat || epin_stat || epout_stat)) ++ return IRQ_NONE; ++ ++ iproc_usbd_irq_clear(udc->usbd_regs, stat); ++ iproc_usbd_ep_irq_list_clear(udc->usbd_regs, USB_DIR_IN, epin_stat); ++ iproc_usbd_ep_irq_list_clear(udc->usbd_regs, USB_DIR_OUT, epout_stat); ++ ++ /* ++ * Handle the SET_CFG and SET_INTF interrupts after the endpoint and other device interrupts. ++ * There can be some race conditions where we have an endpoint 0 interrupt pending for the ++ * completion of a previous endpoint 0 transfer (e.g. a GET config) when a SETUP arrives ++ * corresponding to the SET_CFG and SET_INTF. Need to complete the processing of the previous ++ * transfer before handling the next one, idx.e. the SET_CFG or SET_INTF. ++ */ ++ if (stat & USBD_IRQ_BUS_RESET) ++ dev_info(udc->dev, "BUS reset\n"); ++ ++ if (stat & USBD_IRQ_BUS_SUSPEND) ++ dev_dbg(udc->dev, "BUS suspend\n"); ++ ++ if (stat & USBD_IRQ_BUS_IDLE) { ++ dev_dbg(udc->dev, "BUS idle\n"); ++ iproc_udc_ops_disconnect(udc); ++ } ++ ++ if (stat & USBD_IRQ_SPEED_ENUM_DONE) { ++ dev_dbg(udc->dev, "BUS speed enum done\n"); ++ iproc_speed_isr(udc); ++ } ++ ++ /* endpoint interrupts handler */ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { ++ if (epin_stat & (1 << idx)) ++ iproc_ep_in_isr(&udc->ep[idx]); ++ if (epout_stat & (1 << idx)) ++ iproc_ep_out_isr(&udc->ep[idx]); ++ } ++ ++ /* SET_CFG and SET_INTF interrupts handler */ ++ if (stat & USBD_IRQ_SET_CFG) ++ iproc_cfg_isr(udc); ++ if (stat & USBD_IRQ_SET_INTF) ++ iproc_inf_isr(udc); ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return IRQ_HANDLED; ++} ++ ++/*************************************************************************** ++* Endpoint request operations ++***************************************************************************/ ++static void iproc_udc_req_queue_flush(struct iproc_ep *ep, int status) ++{ ++ struct iproc_udc *udc = ep->udc; ++ struct iproc_ep_req *req; ++ ++ ep->stopped = 1; ++ iproc_usbd_ep_ops_finish(udc->usbd_regs, ep->num); ++ ++ while (!list_empty(&ep->list_queue)) { ++ req = list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node); ++ iproc_udc_req_xfer_done(ep, req, status); ++ } ++ ++ ep->dma.usb_req = NULL; ++} ++ ++ ++static void iproc_udc_req_xfer_add(struct iproc_ep *ep, struct iproc_ep_req *req) ++{ ++ struct iproc_udc *udc = ep->udc; ++ list_add_tail(&req->list_node, &ep->list_queue); ++ ++ /** @todo Is this necessary?? Stopped happens as a result of a halt, complete(), dequeue(), nuke(). ++ * nuke() is called when ep disabled, during setup processing, and by udc_queisce(). The latter is ++ * called during vbus state change (cable insert/remove), USB reset interrupt, and gadget deregister. ++ */ ++ if (ep->stopped) ++ return; ++ ++ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC) && ++ ep->dma.usb_req && (ep->dma.frame_num == FRAME_NUM_INVALID)) { ++ /* ++ * Gadget has a request already queued, but still have not received an IN token from the host ++ * and the interval window is not aligned. Queued packet is now very stale, so remove it. ++ */ ++ ++ iproc_dma_data_finish(ep); ++ /** @todo Move set of ep->dma.usb_req to iproc_dma_data_init() and iproc_dma_data_finish() routines. */ ++ ep->dma.usb_req = NULL; ++ iproc_udc_req_xfer_done(ep, list_first_entry(&ep->list_queue, struct iproc_ep_req, list_node), -EREMOTEIO); ++ } ++ ++ /** @todo Current transfer is always the queue head. Do we need a separate pointer? Maybe just a pointer to usb_request ++ * need to know if the queue head has already been loaded. Maybe that's the point of the "stopped". ++ */ ++ if (!ep->dma.usb_req) { ++ if ((ep->dir == USB_DIR_IN) && (ep->type == USB_ENDPOINT_XFER_ISOC) && ++ (ep->dma.frame_num == FRAME_NUM_INVALID)) { ++ /* ++ * Delay any ISOC IN DMA operations until it is known what frame number the host ++ * is going to start transfers with. Normally might just return requests until ++ * this event occurs. However, the zero gadget does not submit requests based on ++ * its own timer or similar, so if the request is returned right away things are ++ * going to thrash, as another request will be immediately submitted. ++ */ ++ ep->dma.usb_req = &(list_first_entry(&ep->list_queue, ++ struct iproc_ep_req, list_node))->usb_req; ++ iproc_dma_data_init(ep); ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, ep->dir); ++ iproc_usbd_ep_irq_en(udc->usbd_regs, ep->num, ep->dir); ++ } else { ++ req = list_first_entry(&ep->list_queue, ++ struct iproc_ep_req, list_node); ++ ep->dma.usb_req = &req->usb_req; ++ iproc_dma_data_init(ep); ++ iproc_dma_data_add_ready(ep); ++ iproc_usbd_ep_nak_clear(udc->usbd_regs, ep->num, ep->dir); ++ iproc_usbd_ep_dma_en(udc->usbd_regs, ep->num, ep->dir); ++ ++ /* needed for gadget commands to complete correctly - possible locking issue */ ++ mdelay(3); ++ } ++ } ++} ++ ++/* ++ * UDC Operations routines. ++ * iproc_udc_ops_finish - Finish / terminate all UDC operations ++ * iproc_udc_ops_start - Start UDC operations. Happens after a Gadget driver attaches. ++ * iproc_udc_ops_stop - Stop UDC operations. Happens after a Gadget driver detaches. ++ */ ++static void iproc_udc_ops_finish(struct iproc_udc *udc) ++{ ++ /* do nothing */ ++ return; ++} ++ ++static void iproc_udc_ops_start(struct iproc_udc *udc) ++{ ++ int idx; ++ ++ /* ++ * Just enable interrupts for now. Endpoint 0 will get enabled once the speed enumeration ++ * has completed. The Device DMA enable is global in scope. There's endpoint specific ++ * DMA enables that will happen later. ++ */ ++ iproc_usbd_irq_en(udc->usbd_regs, (USBD_IRQ_SPEED_ENUM_DONE | ++ USBD_IRQ_BUS_SUSPEND | ++ USBD_IRQ_BUS_IDLE | ++ USBD_IRQ_BUS_RESET | ++ USBD_IRQ_SET_INTF | ++ USBD_IRQ_SET_CFG)); ++ iproc_usbd_dma_en(udc->usbd_regs); ++ ++ /* Enable interrupts for all configured endpoints */ ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; ++idx) { ++ if (udc->ep[idx].usb_ep.name) { ++ iproc_usbd_ep_irq_en(udc->usbd_regs, udc->ep[idx].num, USB_DIR_OUT); ++ iproc_usbd_ep_irq_en(udc->usbd_regs, udc->ep[idx].num, USB_DIR_IN); ++ } ++ } ++ iproc_usbd_nak_response_dis(udc->usbd_regs); ++} ++ ++static void iproc_udc_ops_stop(struct iproc_udc *udc) ++{ ++ struct iproc_ep *ep; ++ ++ iproc_usbd_dma_dis(udc->usbd_regs); ++ iproc_usbd_irq_dis(udc->usbd_regs, USBD_IRQ_ALL); ++ iproc_usbd_irq_clear(udc->usbd_regs, USBD_IRQ_ALL); ++ ++ udc->gadget.speed = USB_SPEED_UNKNOWN; ++ ++ iproc_udc_req_queue_flush(&udc->ep[0], -ESHUTDOWN); ++ ++ list_for_each_entry(ep, &udc->gadget.ep_list, usb_ep.ep_list) ++ iproc_udc_req_queue_flush(ep, -ESHUTDOWN); ++} ++ ++/* ++ * APIs used by a Gadget driver to attach / detach from the UDC driver. ++ */ ++static int xgs_iproc_udc_start(struct usb_gadget *gadget, ++ struct usb_gadget_driver *gadget_driver) ++{ ++ struct iproc_udc *udc = gadget_to_udc(gadget); ++ unsigned long flags; ++ ++ if (!udc) { ++ dev_err(udc->dev, "UDC driver not initialized\n"); ++ return -ENODEV; ++ } ++ ++ if (!gadget_driver || !gadget_driver->setup || ++ gadget_driver->max_speed < USB_SPEED_FULL) { ++ dev_err(udc->dev, "invalid gadget driver\n" ); ++ return -EINVAL; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ if (udc->gadget_driver) { ++ spin_unlock_irqrestore(&udc->lock, flags); ++ dev_err(udc->dev, "UDC driver busy\n"); ++ return -EBUSY; ++ } ++ ++ /* Hook up the gadget driver to the UDC controller driver */ ++ gadget_driver->driver.bus = NULL; ++ udc->gadget_driver = gadget_driver; ++ udc->gadget.dev.driver = &gadget_driver->driver; ++ udc->pullup_on = 1; ++ ++ iproc_udc_ops_start(udc); ++ /* un-stop the control endpoint */ ++ udc->ep[0].stopped = 0; ++ iproc_usbd_bus_conn(udc->usbd_regs); ++ ++ iproc_usbd_setup_done(udc->usbd_regs); ++ iproc_usbd_dma_en(udc->usbd_regs); ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ENOERROR; ++} ++ ++static int xgs_iproc_udc_stop(struct usb_gadget *gadget) ++{ ++ unsigned long flags; ++ struct iproc_udc *udc = gadget_to_udc(gadget); ++ ++ if (!udc) { ++ dev_err(udc->dev, "UDC driver not initialized\n"); ++ return -ENODEV; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ udc->ep[0].stopped = 1; ++ iproc_udc_ops_stop(udc); ++ udelay(20); ++ udc->pullup_on = 0; ++ iproc_usbd_bus_disconn(udc->usbd_regs); ++ iproc_udc_ops_shutdown(udc); ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ENOERROR; ++} ++ ++/* ++ * Linux Gadget endpoint operations. See usb_ep_ops in usb_gadget.h. ++ */ ++static int xgs_iproc_ep_enable(struct usb_ep *usb_ep, const struct usb_endpoint_descriptor *desc) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ unsigned long flags; ++ u32 xferType; ++ int ret = ENOERROR; ++ ++ if (!usb_ep || (ep->beq_addr != desc->bEndpointAddress)) { ++ dev_err(udc->dev, "invalid endpoint (%p)\n", usb_ep); ++ return -EINVAL; ++ } ++ ++ if (!desc || (desc->bDescriptorType != USB_DT_ENDPOINT)) { ++ dev_err(udc->dev, "ep%d: invalid descriptor=%p type=%d\n", ep->num, desc, desc ? desc->bDescriptorType : -1); ++ return -EINVAL; ++ } ++ ++ if (desc == ep->desc) { ++ dev_warn(udc->dev, "ep%d: already enabled with same descriptor\n", ep->num); ++ return -EEXIST; ++ } ++ ++ if (ep->desc) { ++ dev_warn(udc->dev, "ep%d: already enabled with another descriptor\n", ep->num); ++ return -EBUSY; ++ } ++ ++ if (!udc->gadget_driver || (udc->gadget.speed == USB_SPEED_UNKNOWN)) { ++ dev_warn(udc->dev, "%s: invalid device state\n", ep->usb_ep.name); ++ return -ESHUTDOWN; ++ } ++ ++ xferType = desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK; ++ if ((ep->dir == USB_DIR_IN) && (xferType == USB_ENDPOINT_XFER_ISOC)) { ++ if ((desc->bInterval < 1) || (desc->bInterval > 16)) { ++ dev_err(udc->dev, "%s: invalid ISOC bInterval=%u\n", ep->usb_ep.name, desc->bInterval); ++ return -ERANGE; ++ } ++ ++ /* ++ * We don't know when the host will send the first ISO IN request, so we need to set up ++ * to capture that event so we can align subsequent transfers to that particular frame ++ * number. Also set the frame number increment. The endpoint descriptor specifies this ++ * as a power of 2 (2**(n-1)). Translate this into a specific number of frames. ++ */ ++ ep->dma.frame_num = FRAME_NUM_INVALID; ++ ep->dma.frame_incr = 1 << (desc->bInterval - 1); ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ ep->desc = desc; ++ ep->stopped = 0; ++ ++ /** @todo Rework the UdcEpCfg() so it includes iproc_usbd_ep_cfg_set() ... */ ++ iproc_usbd_ep_cfg_set(udc->usbd_regs, ep->num, iproc_usbd_cfg_num(udc->usbd_regs)); ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ret; ++} ++ ++static int xgs_iproc_ep_disable(struct usb_ep *usb_ep) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ unsigned long flags; ++ int ret = ENOERROR; ++ ++ if (!usb_ep) { ++ dev_err(udc->dev, "invalid endpoint\n"); ++ return -EINVAL; ++ } ++ ++ if (!ep->desc) { ++ dev_warn(udc->dev, "%s: already disabled\n", ep->usb_ep.name); ++ return ENOERROR; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ iproc_udc_req_queue_flush(ep, -ESHUTDOWN); ++ iproc_usbd_ep_irq_dis(udc->usbd_regs, ep->num, ep->dir); ++ ep->desc = NULL; ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ret; ++} ++ ++struct usb_request * xgs_iproc_ep_alloc_request(struct usb_ep *usb_ep, gfp_t gfp_flags) ++{ ++ struct iproc_ep_req *req; ++ ++ if (!usb_ep) ++ return NULL; ++ ++ if ((req = kzalloc(sizeof(*req), gfp_flags)) != NULL) { ++ /* ++ * Set the usb_req.dma to DMA_ADDR_INVALID so it can be determined if the usb_req.buf needs ++ * to be mapped when the request is subsequently queued. ++ */ ++ INIT_LIST_HEAD(&req->list_node); ++ req->usb_req.dma = DMA_ADDR_INVALID; ++ ++ return &req->usb_req; ++ } ++ ++ return NULL; ++} ++ ++static void xgs_iproc_ep_free_request(struct usb_ep *usb_ep, struct usb_request *usb_req) ++{ ++ struct iproc_ep_req *req = our_req(usb_req); ++ ++ if (usb_req) ++ kfree(req); ++} ++ ++static int xgs_iproc_ep_queue(struct usb_ep *usb_ep, struct usb_request *usb_req, gfp_t gfp_flags) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ struct iproc_ep_req *req = our_req(usb_req); ++ unsigned long flags; ++ int ret = ENOERROR; ++ ++ if (!usb_ep || !usb_req || !req->usb_req.complete || !req->usb_req.buf || !list_empty(&req->list_node)) { ++ dev_err(udc->dev, "invalid request\n"); ++ return -EINVAL; ++ } ++ ++ if (!ep->desc && (ep->num != 0)) { ++ dev_err(udc->dev, "%s: invalid EP state\n", ep->usb_ep.name); ++ return -EFAULT; ++ } ++ ++ if ((ep->type == USB_ENDPOINT_XFER_CONTROL) && !list_empty(&ep->list_queue)) { ++ dev_err(udc->dev, "%s: CTRL EP queue not empty\n", ep->usb_ep.name); ++ return -EPERM; ++ } ++ ++ if (usb_req->length > 16384 /* FSG_BUFLEN */) { ++ dev_err(udc->dev, "%s: request too big, length=%u\n", ep->usb_ep.name, usb_req->length); ++ return -E2BIG; ++ } ++ ++ /* ++ * Restrict ISOC IN requests to the max packet size. Assumption is that it does not make ++ * much sense to have more than one interval's (scheduled bandwidth's) worth of data. ++ */ ++ if ((ep->type == USB_ENDPOINT_XFER_ISOC) && (ep->dir == USB_DIR_IN) && (usb_req->length > ep->usb_ep.maxpacket)) { ++ dev_err(udc->dev, "%s: request > scheduled bandwidth, length=%u\n", ep->usb_ep.name, usb_req->length); ++ return -EFBIG; ++ } ++ ++ if (!udc->gadget_driver || (udc->gadget.speed == USB_SPEED_UNKNOWN)) { ++ dev_warn(udc->dev, "%s: invalid device state\n", ep->usb_ep.name); ++ return -ESHUTDOWN; ++ } ++ ++ if (((u32)req->usb_req.buf) & 0x3UL) { ++ /* ++ * The DMA buffer does not have the alignment required by the hardware. We keep an endpoint level ++ * buffer available to handle this situation if it arises. If we don't currently have one available ++ * for this purpose, or if the current one is not large enough, then allocate a new one. Since ++ * we only have one buffer, we won't copy into the buffer until we are ready to do the DMA transfer. ++ * Mark the request as needing this alignment (copy). ++ */ ++ if ((ep->dma.align_buff != NULL) && (ep->dma.align_len < req->usb_req.length)) { ++ dma_free_coherent(NULL, ep->dma.align_len, ep->dma.align_buff, ep->dma.align_addr); ++ ep->dma.align_buff = NULL; ++ } ++ ++ if (ep->dma.align_buff == NULL) { ++ ep->dma.align_len = req->usb_req.length; ++ ep->dma.align_buff = dma_alloc_coherent(NULL, ep->dma.align_len, &(ep->dma.align_addr), GFP_KERNEL); ++ } ++ ++ if (ep->dma.align_buff == NULL) { ++ dev_err(udc->dev, "%s: dma_alloc_coherent() failed, length=%u\n", ep->usb_ep.name, usb_req->length); ++ return -ENOMEM; ++ } ++ req->dma_aligned = 1; ++ } else if ((req->usb_req.dma == DMA_ADDR_INVALID) || (req->usb_req.dma == 0)) { ++ /* A physical address was not provided for the DMA buffer, so request it. */ ++ req->dma_mapped = 1; ++ req->usb_req.dma = dma_map_single(udc->gadget.dev.parent, ++ req->usb_req.buf, ++ req->usb_req.length, ++ ep->dir == USB_DIR_IN ? ++ DMA_TO_DEVICE : DMA_FROM_DEVICE); ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ req->usb_req.status = -EINPROGRESS; ++ req->usb_req.actual = 0; ++ ++ if ((ep->type == USB_ENDPOINT_XFER_CONTROL) && (ep->dir == USB_DIR_OUT) && (req->usb_req.length == 0)) { ++ /* ++ * This might happen if gadget driver decides to send zero length packet (ZLP) during STATUS phase ++ * of a control transfer. This may happen for the cases where there is not a DATA phase. Just consider ++ * things complete. ZLP will be issued by hardware. See the handling of SETUP packets for more details ++ * on control transfer processing. ++ */ ++ iproc_udc_req_xfer_done(ep, req, ENOERROR); ++ } else { ++ if (req->usb_req.length == 0) ++ req->usb_req.zero = 1; ++ iproc_udc_req_xfer_add(ep, req); ++ } ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ret; ++} ++ ++static int xgs_iproc_ep_dequeue(struct usb_ep *usb_ep, struct usb_request *usb_req) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ struct iproc_ep_req *req = our_req(usb_req); ++ unsigned long flags; ++ int ret = ENOERROR; ++ ++ if (!usb_ep || !usb_req) { ++ dev_err(udc->dev, "invalid request\n"); ++ return -EINVAL; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ /* Make sure it's actually queued on this endpoint */ ++ list_for_each_entry(req, &ep->list_queue, list_node) { ++ if (&req->usb_req == usb_req) ++ break; ++ } ++ ++ if (&req->usb_req != usb_req) { ++ spin_unlock_irqrestore(&udc->lock, flags); ++ dev_err(udc->dev, "%s: request not queued\n", ep->usb_ep.name); ++ return -ENOLINK; ++ } ++ ++ /** @todo Handle case where the request is in progress, or completed but not dequeued */ ++ ++ iproc_udc_req_xfer_done(ep, req, -ECONNRESET); ++ spin_unlock_irqrestore(&udc->lock, flags); ++ ++ return ret; ++} ++ ++static int xgs_iproc_ep_set_halt(struct usb_ep *usb_ep, int enable) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ unsigned long flags; ++ int ret = ENOERROR; ++ ++ if (!usb_ep) { ++ dev_err(udc->dev, "invalid request\n"); ++ return -EINVAL; ++ } ++ ++ if (ep->type == USB_ENDPOINT_XFER_ISOC) { ++ dev_warn(udc->dev, "%s: ISO HALT operations not supported\n", ep->usb_ep.name); ++ return -EOPNOTSUPP; ++ } ++ ++ if (enable && (ep->dir == USB_DIR_IN) && !list_empty(&ep->list_queue)) { ++ /* Only allow halt on an IN EP if its queue is empty */ ++ dev_err(udc->dev, "%s: IN queue not empty\n", ep->usb_ep.name); ++ return -EAGAIN; ++ } ++ ++ if (!enable && (ep->type == USB_ENDPOINT_XFER_CONTROL)) { ++ /* ++ * Halt clear for a control EP should only be handled as part of the subsequent SETUP ++ * exchange that occurs after the Halt was set. ++ */ ++ dev_warn(udc->dev, "%s: CTRL HALT clear\n", ep->usb_ep.name); ++ return -EPROTO; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ if (!enable) { ++ iproc_usbd_ep_stall_dis(udc->usbd_regs, ep->num, ep->dir); ++ } else if (ep->type != USB_ENDPOINT_XFER_CONTROL) { ++ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, ep->dir); ++ } else { ++ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, USB_DIR_IN); ++ iproc_usbd_ep_stall_en(udc->usbd_regs, ep->num, USB_DIR_OUT); ++ } ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++ mdelay(2); ++ ++ return ret; ++} ++ ++static int xgs_iproc_ep_fifo_status(struct usb_ep *usb_ep) ++{ ++ /* ++ * The DWC UDC core doesn't have a mechanism for determining the number of bytes ++ * currently in a FIFO. The best that can be done is determine whether or not a ++ * FIFO is empty. However, for the situation where a single Rx FIFO is being ++ * used for all endpoints, if cannot be determined which OUT and CTRL EP's are ++ * affected if the Rx FIFO is not empty. ++ */ ++ return -EOPNOTSUPP; ++} ++ ++static void xgs_iproc_ep_fifo_flush(struct usb_ep *usb_ep) ++{ ++ struct iproc_ep *ep = our_ep(usb_ep); ++ struct iproc_udc *udc = ep->udc; ++ unsigned long flags; ++ ++ if (!usb_ep) { ++ dev_err(udc->dev, "invalid request\n"); ++ return; ++ } ++ ++ /* ++ * FIFO flush for a control EP does not make any sense. The SETUP protocol ++ * should eliminate the need to flush. ++ */ ++ if (ep->type == USB_ENDPOINT_XFER_CONTROL) { ++ dev_warn(udc->dev, "%s: CTRL FIFO flush\n", ep->usb_ep.name); ++ return; ++ } ++ ++ if (iproc_usbd_ep_fifo_empty(udc->usbd_regs, ep->num, ep->dir)) { ++ dev_warn(udc->dev, "%s: FIFO empty\n", ep->usb_ep.name); ++ return; ++ } ++ ++ spin_lock_irqsave(&udc->lock, flags); ++ ++ iproc_usbd_ep_fifo_flush_en(udc->usbd_regs, ep->num, ep->dir); ++ ++ spin_unlock_irqrestore(&udc->lock, flags); ++} ++ ++ ++/*************************************************************************** ++ * Linux proc file system functions ++ ***************************************************************************/ ++#ifdef CONFIG_USB_GADGET_DEBUG_FILES ++#include ++ ++static const char udc_proc_file_name[] = "driver/" XGS_IPROC_UDC_NAME; ++ ++static int proc_file_show(struct seq_file *s, void *_) ++{ ++ return 0; ++} ++ ++static int proc_file_open(struct inode *inode, struct file *file) ++{ ++ return(single_open(file, proc_file_show, NULL)); ++} ++ ++static struct file_operations udc_proc_file_ops = ++{ ++ .open = proc_file_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = single_release, ++}; ++ ++static void xgs_iproc_udc_proc_create(void) ++{ ++ proc_create(udc_proc_file_name, 0, NULL, &udc_proc_file_ops); ++} ++ ++static void xgs_iproc_udc_proc_remove(void) ++{ ++ remove_proc_entry(udc_proc_file_name, NULL); ++} ++ ++#else ++ ++static void xgs_iproc_udc_proc_create(void) {} ++static void xgs_iproc_udc_proc_remove(void) {} ++ ++#endif ++ ++static struct usb_gadget_ops xgs_iproc_udc_ops = { ++ .udc_start = xgs_iproc_udc_start, ++ .udc_stop = xgs_iproc_udc_stop, ++}; ++ ++static struct usb_ep_ops xgs_iproc_udc_ep_ops = { ++ .enable = xgs_iproc_ep_enable, ++ .disable = xgs_iproc_ep_disable, ++ .alloc_request = xgs_iproc_ep_alloc_request, ++ .free_request = xgs_iproc_ep_free_request, ++ .queue = xgs_iproc_ep_queue, ++ .dequeue = xgs_iproc_ep_dequeue, ++ .set_halt = xgs_iproc_ep_set_halt, ++ .fifo_status = xgs_iproc_ep_fifo_status, ++ .fifo_flush = xgs_iproc_ep_fifo_flush, ++}; ++ ++static const struct of_device_id xgs_iproc_udc_ids[] = { ++ { .compatible = "brcm,usbd-xgs-iproc", }, ++ { .compatible = "brcm,usbd-xgs-hx4", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, xgs_iproc_udc_ids); ++ ++static void iproc_udc_ops_init(struct iproc_udc *udc) ++{ ++ int idx; ++ struct iproc_ep *ep; ++ ++ iproc_usbd_ops_init(udc->usbd_regs); ++ ++ /* ++ * See usb/gadget/epautoconf.c for endpoint naming conventions. ++ * Control endpoints are bi-directional, but initial transfer (SETUP stage) is always OUT. ++ */ ++ /** @todo Really should make the non endpoint 0 init attributes configurable by the chip specific part ++ * of the driver, idx.e. the device instantiation. The settings below are for a chip specific DWG UDC ++ * core configuration. Also should incorporate the DWG UDC endpoint type attribute as part of this, ++ * which can be control, IN, OUT, or bidirectional. ++ */ ++ INIT_LIST_HEAD(&udc->gadget.ep_list); ++ for (idx = 0; idx < IPROC_UDC_EP_CNT; idx++) { ++ ep = &udc->ep[idx]; ++ ++ ep->udc = udc; ++ ep->num = idx; ++ ++ ep->dir = (xgs_iproc_ep_info[idx].caps.dir_in) ? USB_DIR_IN : USB_DIR_OUT;; ++ ep->beq_addr = idx | ep->dir; ++ ep->stopped = 0; ++ ep->type = xgs_iproc_ep_info[idx].type; ++ ++ ep->usb_ep.name = xgs_iproc_ep_info[idx].name; ++ ep->usb_ep.caps = xgs_iproc_ep_info[idx].caps; ++ ep->usb_ep.ops = &xgs_iproc_udc_ep_ops; ++ list_add_tail(&ep->usb_ep.ep_list, &udc->gadget.ep_list); ++ usb_ep_set_maxpacket_limit(&ep->usb_ep, xgs_iproc_ep_info[idx].msize); ++ ep->usb_ep.desc = NULL; ++ INIT_LIST_HEAD(&ep->list_queue); ++ ++ iproc_usbd_ep_ops_init(udc->usbd_regs, ep->num, ep->type, ++ ep->dir, xgs_iproc_ep_info[idx].msize); ++ ++ iproc_dma_ep_init(ep); ++ } ++ ++ udc->gadget.ep0 = &udc->ep[0].usb_ep; ++ list_del(&udc->ep[0].usb_ep.ep_list); ++ ++ iproc_usbd_self_pwr_en(udc->usbd_regs); ++} ++ ++ ++/**************************************************************************** ++ ***************************************************************************/ ++static int xgs_iproc_udc_probe(struct platform_device *pdev) ++{ ++ int ret = ENOERROR; ++ struct device *dev = &pdev->dev; ++ struct device_node *dn = dev->of_node; ++ struct iproc_udc *udc = NULL; ++ struct usb_phy *phy; ++ struct resource *res; ++ void __iomem *usbd_base; ++ int irq; ++ ++ phy = devm_usb_get_phy_by_phandle(dev, "usb-phy", 0); ++ if (IS_ERR(phy)) { ++ dev_err(dev, "unable to find transceiver\n"); ++ return PTR_ERR(phy); ++ } ++ ++ /* HX4 SVK always is identified as HOST, because GPIO pin 0 is always low, ++ * even the strap setting of JP1803 is device mode. ++ */ ++ if (!of_device_is_compatible(dn, "brcm,usbd-xgs-hx4")) ++ if (phy->flags != IPROC_USB_MODE_DEVICE) ++ return -ENODEV; ++ ++ irq = platform_get_irq(pdev, 0); ++ ++ udc = devm_kzalloc(dev, sizeof(*udc), GFP_KERNEL); ++ if (!udc) { ++ dev_err(dev, "devm_kzalloc() failed\n" ); ++ return -ENOMEM; ++ } ++ ++ platform_set_drvdata(pdev, udc); ++ udc->dev = dev; ++ spin_lock_init(&udc->lock); ++ ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ usbd_base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(usbd_base)) { ++ dev_err(dev, "can't ioremap USB2D base addr\n"); ++ return PTR_ERR(usbd_base); ++ } ++ ++ udc->usbd_regs = (struct iproc_usbd_regs *)usbd_base; ++ ++ ret = usb_phy_init(phy); ++ if (ret < 0) { ++ dev_err(dev, "initial usb transceiver failed.\n"); ++ return ret; ++ } ++ ++ ret = iproc_platform_dma_alloc(pdev, udc); ++ if (ret < 0) { ++ dev_err(dev, "iproc_platform_dma_alloc() failed\n"); ++ return ret; ++ } ++ ++ /* gadget init */ ++ udc->gadget.name = XGS_IPROC_UDC_NAME; ++ udc->gadget.speed = USB_SPEED_UNKNOWN; ++ udc->gadget.max_speed = USB_SPEED_HIGH; ++ udc->gadget.ops = &xgs_iproc_udc_ops; ++ ++ iproc_udc_ops_init(udc); ++ ++ iproc_usbd_irq_dis(udc->usbd_regs, USBD_IRQ_ALL); ++ iproc_usbd_irq_clear(udc->usbd_regs, USBD_IRQ_ALL); ++ ++ ret = devm_request_irq(dev, irq, xgs_iproc_udc_isr, 0, ++ XGS_IPROC_UDC_NAME, (void *)udc); ++ if (ret < 0) { ++ dev_err(dev, "error requesting IRQ #%d\n", irq); ++ goto err1; ++ } ++ ++ ret = usb_add_gadget_udc(dev, &udc->gadget); ++ if (ret < 0) { ++ dev_err(dev, "usb_add_gadget_udc() failed\n"); ++ goto err1; ++ } ++ ++ xgs_iproc_udc_proc_create(); ++ ++ return ENOERROR; ++ ++err1: ++ iproc_platform_dma_free(pdev, udc); ++ ++ return ret; ++} ++ ++static int xgs_iproc_udc_remove(struct platform_device *pdev) ++{ ++ struct iproc_udc *udc = platform_get_drvdata(pdev); ++ ++ if (udc) { ++ xgs_iproc_udc_proc_remove(); ++ ++ usb_del_gadget_udc(&udc->gadget); ++ iproc_udc_ops_finish(udc); ++ ++ platform_set_drvdata(pdev, NULL); ++ iproc_platform_dma_free(pdev, udc); ++ } ++ ++ return ENOERROR; ++} ++ ++/* ++ * Generic platform device driver definition. ++ */ ++static struct platform_driver xgs_iproc_udc_driver = ++{ ++ .probe = xgs_iproc_udc_probe, ++ .remove = xgs_iproc_udc_remove, ++ .driver = { ++ .name = XGS_IPROC_UDC_NAME, ++ .owner = THIS_MODULE, ++ .of_match_table = xgs_iproc_udc_ids, ++ }, ++}; ++ ++module_platform_driver(xgs_iproc_udc_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("Broadcom USB Device Controller(UDC) driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/xgs_iproc_udc.h b/drivers/usb/gadget/udc/xgs_iproc_udc.h +--- a/drivers/usb/gadget/udc/xgs_iproc_udc.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/usb/gadget/udc/xgs_iproc_udc.h 2018-05-10 11:31:33.789404169 +0800 +@@ -0,0 +1,157 @@ ++/* ++ * Copyright 2017 Broadcom Limited ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _XGS_IPROC_UDC_H_ ++#define _XGS_IPROC_UDC_H_ ++ ++#include ++#include "xgs_iproc_usbd_regs.h" ++ ++#define IPROC_UDC_EP_CNT 7 ++#define IPROC_UDC_CTRL_MAX_PKG_SIZE 64 ++#define IPROC_UDC_EP_MAX_PKG_SIZE 512 ++ ++/* ++ * Some unsigned number trickery for indexing into DMA descriptor chain. If the ++ * decriptor count is some power of 2, then we can use the mask to extract ++ * an index and not worry about wrap around as the unsigned variables are ++ * incremented. E.g. in following, IDX(0), IDX(4), IDX(8), ..., IDX(0xffffc) ++ * all produce the same result, i.e. 0. ++ */ ++#define IPROC_EP_DMA_DESC_CNT 1 ++#define IPROC_EP_DMA_DESC_IDX_MASK (IPROC_EP_DMA_DESC_CNT - 1) ++#define IPROC_EP_DMA_DESC_IDX(_idx) ((_idx) & IPROC_EP_DMA_DESC_IDX_MASK) ++ ++/* Some DWC UDC DMA descriptor layout definitions. See datasheet for details. */ ++ ++struct iproc_udc_dma_setup { ++ unsigned int status; ++ unsigned int reserved; ++ unsigned int data1; ++ unsigned int data2; ++}; ++ ++struct iproc_udc_dma_desc { ++ unsigned int status; ++ unsigned int reserved; ++ unsigned int buf_addr; ++ unsigned int next_addr; ++}; ++ ++/* ++ * Common DMA descriptor layout used for all endpoints. Only control endpoints ++ * need the setup descriptor, but in order to simply things it is defined for ++ * all. It may be possible to omit this altogether, and just use one of data ++ * descriptors for setup instead. The control transfer protocol should allow ++ * this to be done. ++ */ ++struct iproc_ep_dma { ++ struct iproc_udc_dma_setup setup; ++ struct iproc_udc_dma_desc desc[IPROC_EP_DMA_DESC_CNT]; ++}; ++ ++/* Structure used for DMA descriptor allocation. Not really necessary but convenient. */ ++struct iproc_udc_dma { ++ struct iproc_ep_dma ep[IPROC_UDC_EP_CNT]; ++}; ++ ++/* ++ * Structure used to hold endpoint specific information. There's one of these for ++ * each endpoint. ++ * ++ * The Rx/Tx FIFO sizes are used for RAM allocation purposes. Each transfer ++ * direction has its own RAM that is used for all the FIFOs in that direction. ++ * The RAM gets segmented (allocated) as each endpoint gets enabled. This dynamic ++ * allocation FIFO sizes gives flexibility, and does not require that an ++ * endpoint's size be fixed at run-time or during compilation. If there's not ++ * enough FIFO RAM as required by a gadget's endpoint definitions, then an ++ * error will occur for the enabling of any endpoints after the FIFO RAM has ++ * become exhausted. ++ * ++ * The DMA virtual address is used for all descriptor operations. The DMA ++ * physical address is for convenience (setting hardware registers, obtaining ++ * addresses for descriptor chaining, etc.). The DMA descriptors are not ++ * allocated on a per-endpoint basis. These are just pointers into the ++ * large block that was allocated for all endpoints. ++ */ ++struct iproc_ep { ++ struct usb_ep usb_ep; /* usb_gadget.h */ ++ const struct usb_endpoint_descriptor *desc; /* usb/ch9.h */ ++ struct list_head list_queue; /* active BCM_UDC_EP_REQ's for the endpoint */ ++ struct iproc_udc *udc; /* endpoint owner (UDC controller) */ ++ unsigned int num; ++ unsigned int dir; /* USB_DIR_xxx (direction) */ ++ unsigned int type; /* USB_ENDPOINT_XFER_xxx */ ++ unsigned int beq_addr; /* dirn | type */ ++ unsigned int stopped : 1; ++ struct { ++ struct iproc_ep_dma *vir_addr; ++ struct iproc_ep_dma *phy_addr; ++ struct usb_request *usb_req; /* Current request being DMA'd */ ++ ++ /** @todo Some of the below are duplicates of usb_request elements. Use usb_request instead. */ ++ unsigned int max_buf_len; /* Max buffer length to use with a descriptor */ ++ unsigned int done_len; /* Length of request DMA'd so far */ ++ unsigned int todo_len; /* Length of request left to DMA */ ++ unsigned int add_idx; /* descriptor chain index */ ++ unsigned int rm_idx; /* descriptor chain index */ ++ unsigned int buf_addr; /* Location in request to DMA */ ++ unsigned int frame_num; /* Frame number for ISOC transfers */ ++ unsigned int frame_incr; /* Frame number increment (period) */ ++ unsigned int status; ++ unsigned int done; /* DMA and USB transfer completion indication (IN_DMA_DONE and IN_XFER_DONE) */ ++ void *align_buff; /* Aligned buffer. Only used if usb_req buffer not aligned properly. */ ++ dma_addr_t align_addr; /* Aligned buffer physical address */ ++ unsigned int align_len; /* Aligned buffer length */ ++ } dma; ++}; ++ ++/* ++ * Structure used to hold controller information. There should be one of these ++ * for each controller. Most likely there's only one. ++ * ++ * The Rx/Tx FIFO space are used for RAM allocation purposes. These track how ++ * much RAM is available for use as a FIFO. When an endpoint is enabled, these ++ * are check to see if there's enough RAM for a FIFO of the desired length as ++ * implied by the max packet size. ++ */ ++struct iproc_udc { ++ struct usb_gadget gadget; /* usb_gadget.h */ ++ struct usb_gadget_driver *gadget_driver; /* usb_gadget.h */ ++ struct completion *dev_release; /* Used for coordination during device removal */ ++ spinlock_t lock; ++ struct device *dev; ++ unsigned int irq_num; ++ struct iproc_ep ep[IPROC_UDC_EP_CNT]; ++ struct iproc_usbd_regs *usbd_regs; ++ struct { ++ struct iproc_udc_dma *vir_addr; ++ struct iproc_udc_dma *phy_addr; ++ } dma; ++ unsigned int vbus_active : 1; /* Indicates if VBUS is present */ ++ unsigned int pullup_on : 1; /* Indicates if pull up is on */ ++}; ++ ++/* ++ * Structure used to hold an endpoint transfer request. Can be any number of ++ * these for an endpoint. ++ */ ++struct iproc_ep_req { ++ struct usb_request usb_req; /* usb_gadget.h */ ++ struct list_head list_node; /* For linking in the BCM_UDC_EP request queue */ ++ dma_addr_t orig_dma_addr; /* Original buffer DMA address (physical). */ ++ unsigned dma_mapped : 1; /* Indicates if address mapping req'd. See usb_gadget.h */ ++ unsigned dma_aligned : 1; /* Indicates if buffer duplication done for alignment. */ ++}; ++ ++#endif /* _XGS_IPROC_UDC_H_ */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/gadget/udc/xgs_iproc_usbd_regs.h b/drivers/usb/gadget/udc/xgs_iproc_usbd_regs.h +--- a/drivers/usb/gadget/udc/xgs_iproc_usbd_regs.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/usb/gadget/udc/xgs_iproc_usbd_regs.h 2018-05-10 11:31:33.789404169 +0800 +@@ -0,0 +1,969 @@ ++/* ++ * Copyright 2017 Broadcom Limited ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _USBD_REGS_H_ ++#define _USBD_REGS_H_ ++ ++#include ++#include ++ ++#define USBD_MULTI_RX_FIFO 0 ++ ++#define USBD_EP_CFG_CNT 10 ++#define USBD_REG_EP_CNT 16 ++ ++#define USBD_IRQ_REMOTEWAKEUP_DELTA REG_INTR_REMOTE_WAKEUP_DELTA ++#define USBD_IRQ_SPEED_ENUM_DONE REG_INTR_SPD_ENUM_DONE ++#define USBD_IRQ_SOF_DETECTED REG_INTR_SOF_RX ++#define USBD_IRQ_BUS_SUSPEND REG_INTR_BUS_SUSPEND ++#define USBD_IRQ_BUS_RESET REG_INTR_BUS_RESET ++#define USBD_IRQ_BUS_IDLE REG_INTR_BUS_IDLE ++#define USBD_IRQ_SET_INTF REG_INTR_SET_INTF_RX ++#define USBD_IRQ_SET_CFG REG_INTR_SET_CFG_RX ++#define USBD_IRQ_ALL (USBD_IRQ_REMOTEWAKEUP_DELTA | \ ++ USBD_IRQ_SPEED_ENUM_DONE | \ ++ USBD_IRQ_SOF_DETECTED | \ ++ USBD_IRQ_BUS_SUSPEND | \ ++ USBD_IRQ_BUS_RESET | \ ++ USBD_IRQ_BUS_IDLE | \ ++ USBD_IRQ_SET_INTF | \ ++ USBD_IRQ_SET_CFG) ++ ++#define USBD_EP_STAT_DMA_ERROR REG_EP_FIFO_STATUS_AHB_BUS_ERROR ++#define USBD_EP_STAT_DMA_BUF_UNAVAIL REG_EP_FIFO_STATUS_DMA_BUF_NOT_AVAIL ++#define USBD_EP_STAT_IN_TOKEN_RX REG_EP_FIFO_STATUS_IN_TOKEN_RX ++#define USBD_EP_STAT_IN_DMA_DONE REG_EP_FIFO_STATUS_IN_DMA_DONE ++#define USBD_EP_STAT_IN_FIFO_EMPTY REG_EP_FIFO_STATUS_IN_FIFO_EMPTY ++#define USBD_EP_STAT_IN_XFER_DONE REG_EP_FIFO_STATUS_IN_XFER_DONE ++#define USBD_EP_STAT_OUT_DMA_DATA_DONE REG_EP_FIFO_STATUS_OUT_DMA_DATA_DONE ++#define USBD_EP_STAT_OUT_DMA_SETUP_DONE REG_EP_FIFO_STATUS_OUT_DMA_SETUP_DONE ++#define USBD_EP_STAT_ALL (USBD_EP_STAT_DMA_ERROR | \ ++ USBD_EP_STAT_DMA_BUF_UNAVAIL | \ ++ USBD_EP_STAT_IN_TOKEN_RX | \ ++ USBD_EP_STAT_IN_DMA_DONE | \ ++ USBD_EP_STAT_IN_XFER_DONE | \ ++ USBD_EP_STAT_OUT_DMA_DATA_DONE | \ ++ USBD_EP_STAT_OUT_DMA_SETUP_DONE) ++ ++ ++#define REG8_RSVD(start, end) u8 rsvd_##start[(end - start) / sizeof(u8)] ++#define REG16_RSVD(start, end) u16 rsvd_##start[(end - start) / sizeof(u16)] ++#define REG32_RSVD(start, end) u32 rsvd_##start[(end - start) / sizeof(u32)] ++ ++struct iproc_usbd_ep_fifo_regs { ++ uint ctrl; ++ uint status; ++ uint size1; ++ uint size2; /* Buf Size OUT/Max PKT SIZE */ ++ uint buf_addr; ++ uint desc_addr; ++ REG32_RSVD(0x18, 0x20); ++}; ++ ++struct iproc_usbd_regs { ++ struct iproc_usbd_ep_fifo_regs ep_fifo_in[USBD_REG_EP_CNT]; ++ struct iproc_usbd_ep_fifo_regs ep_fifo_out[USBD_REG_EP_CNT]; ++ uint dev_cfg; ++ uint dev_ctrl; ++ uint dev_status; ++ uint dev_irq_status; ++ uint dev_irq_mask; ++ uint ep_irq_status; ++ uint ep_irq_mask; ++ uint test_mode; ++ uint rel_num; ++ REG32_RSVD(0x424, 0x500); ++ REG32_RSVD(0x500, 0x504); ++ uint ep_cfg[USBD_REG_EP_CNT]; ++ REG32_RSVD(0x544, 0x800); ++ uint rx_fifo[256]; ++ uint tx_fifo[256]; ++ uint strap; ++}; ++ ++ ++struct iproc_usbd_idm_regs { ++ REG32_RSVD(0x000, 0x408); ++ uint io_ctrl; ++ REG32_RSVD(0x40C, 0x500); ++ uint io_status; ++ REG32_RSVD(0x504, 0x800); ++ uint reset_ctrl; ++ uint reset_status; ++ REG32_RSVD(0x808, 0xA00); ++ uint irq_status; ++}; ++ ++/* ++ * The endpoint type field in the FIFO control register has the same enumeration ++ * as the USB protocol. Not going to define it here. ++ */ ++#define REG_EP_FIFO_CTRL_OUT_FLUSH_ENABLE (1 << 12) ++#define REG_EP_FIFO_CTRL_OUT_CLOSE_DESC (1 << 11) ++#define REG_EP_FIFO_CTRL_IN_SEND_NULL (1 << 10) ++#define REG_EP_FIFO_CTRL_OUT_DMA_ENABLE (1 << 9) ++#define REG_EP_FIFO_CTRL_NAK_CLEAR (1 << 8) ++#define REG_EP_FIFO_CTRL_NAK_SET (1 << 7) ++#define REG_EP_FIFO_CTRL_NAK_IN_PROGRESS (1 << 6) ++#define REG_EP_FIFO_CTRL_TYPE_SHIFT 4 ++#define REG_EP_FIFO_CTRL_TYPE_MASK (3 << REG_EP_FIFO_CTRL_TYPE_SHIFT) ++#define REG_EP_FIFO_CTRL_IN_DMA_ENABLE (1 << 3) ++#define REG_EP_FIFO_CTRL_SNOOP_ENABLE (1 << 2) ++#define REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE (1 << 1) ++#define REG_EP_FIFO_CTRL_STALL_ENABLE (1 << 0) ++ ++#define REG_EP_FIFO_STATUS_CLOSE_DESC_CLEAR (1 << 28) ++#define REG_EP_FIFO_STATUS_IN_XFER_DONE (1 << 27) ++#define REG_EP_FIFO_STATUS_STALL_SET_RX (1 << 26) ++#define REG_EP_FIFO_STATUS_STALL_CLEAR_RX (1 << 25) ++#define REG_EP_FIFO_STATUS_IN_FIFO_EMPTY (1 << 24) ++#define REG_EP_FIFO_STATUS_IN_DMA_DONE (1 << 10) ++#define REG_EP_FIFO_STATUS_AHB_BUS_ERROR (1 << 9) ++#define REG_EP_FIFO_STATUS_OUT_FIFO_EMPTY (1 << 8) ++#define REG_EP_FIFO_STATUS_DMA_BUF_NOT_AVAIL (1 << 7) ++#define REG_EP_FIFO_STATUS_IN_TOKEN_RX (1 << 6) ++#define REG_EP_FIFO_STATUS_OUT_DMA_SETUP_DONE (1 << 5) ++#define REG_EP_FIFO_STATUS_OUT_DMA_DATA_DONE (1 << 4) ++ ++#define REG_EP_FIFO_SIZE1_OUT_ISOC_PID_SHIFT 16 ++#define REG_EP_FIFO_SIZE1_OUT_ISOC_PID_MASK (3 << REG_EP_FIFO_SIZE1_OUT_ISOC_PID_SHIFT) ++#define REG_EP_FIFO_SIZE1_IN_DEPTH_SHIFT 0 ++#define REG_EP_FIFO_SIZE1_IN_DEPTH_MASK (0xffff << REG_EP_FIFO_SIZE1_IN_DEPTH_SHIFT) ++#define REG_EP_FIFO_SIZE1_OUT_FRAME_NUM_SHIFT REG_EP_FIFO_SIZE1_IN_DEPTH_SHIFT ++#define REG_EP_FIFO_SIZE1_OUT_FRAME_NUM_MASK REG_EP_FIFO_SIZE1_IN_DEPTH_MASK ++ ++#define REG_EP_FIFO_SIZE2_OUT_DEPTH_SHIFT 16 ++#define REG_EP_FIFO_SIZE2_OUT_DEPTH_MASK (0xffff << REG_EP_FIFO_SIZE2_OUT_DEPTH_SHIFT) ++#define REG_EP_FIFO_SIZE2_PKT_MAX_SHIFT 0 ++#define REG_EP_FIFO_SIZE2_PKT_MAX_MASK (0xffff << REG_EP_FIFO_SIZE2_PKT_MAX_SHIFT) ++ ++/* ++ * The endpoint type field in the config register has the same enumeration ++ * as the USB protocol. Not going to define it here. ++ */ ++#define REG_EP_CFG_PKT_MAX_SHIFT 19 ++#define REG_EP_CFG_PKT_MAX_MASK (0x7ff << REG_EP_CFG_PKT_MAX_SHIFT) ++#define REG_EP_CFG_ALT_NUM_SHIFT 15 ++#define REG_EP_CFG_ALT_NUM_MASK (0xf << REG_EP_CFG_ALT_NUM_SHIFT) ++#define REG_EP_CFG_INTF_NUM_SHIFT 11 ++#define REG_EP_CFG_INTF_NUM_MASK (0xf << REG_EP_CFG_INTF_NUM_SHIFT) ++#define REG_EP_CFG_CFG_NUM_SHIFT 7 ++#define REG_EP_CFG_CFG_NUM_MASK (0xf << REG_EP_CFG_CFG_NUM_SHIFT) ++#define REG_EP_CFG_TYPE_SHIFT 5 ++#define REG_EP_CFG_TYPE_MASK (0x3 << REG_EP_CFG_TYPE_SHIFT) ++#define REG_EP_CFG_DIRN_IN (1 << 4) ++#define REG_EP_CFG_DIRN_OUT 0 ++#define REG_EP_CFG_FIFO_NUM_SHIFT 0 ++#define REG_EP_CFG_FIFO_NUM_MASK (0xf << REG_EP_CFG_FIFO_NUM_SHIFT) ++ ++/* Endpoint Interrupt register definitions */ ++#define REG_EP_INTR_OUT_SHIFT 16 ++#define REG_EP_INTR_OUT_MASK (0xffff << REG_EP_INTR_OUT_SHIFT) ++#define REG_EP_INTR_IN_SHIFT 0 ++#define REG_EP_INTR_IN_MASK (0xffff << REG_EP_INTR_IN_SHIFT) ++ ++/* Device Controller register definitions */ ++#define REG_CFG_ULPI_DDR_ENABLE (1 << 19) ++#define REG_CFG_SET_DESCRIPTOR_ENABLE (1 << 18) ++#define REG_CFG_CSR_PROGRAM_ENABLE (1 << 17) ++#define REG_CFG_HALT_STALL_ENABLE (1 << 16) ++#define REG_CFG_HS_TIMEOUT_CALIB_SHIFT 13 ++#define REG_CFG_HS_TIMEOUT_CALIB_MASK (7 << REG_CFG_HS_TIMEOUT_CALIB_SHIFT) ++#define REG_CFG_FS_TIMEOUT_CALIB_SHIFT 10 ++#define REG_CFG_FS_TIMEOUT_CALIB_MASK (7 << REG_CFG_FS_TIMEOUT_CALIB_SHIFT) ++#define REG_CFG_STATUS_1_ENABLE (1 << 8) ++#define REG_CFG_STATUS_ENABLE (1 << 7) ++#define REG_CFG_UTMI_BI_DIRN_ENABLE (1 << 6) ++#define REG_CFG_UTMI_8BIT_ENABLE (1 << 5) ++#define REG_CFG_SYNC_FRAME_ENABLE (1 << 4) ++#define REG_CFG_SELF_PWR_ENABLE (1 << 3) ++#define REG_CFG_REMOTE_WAKEUP_ENABLE (1 << 2) ++#define REG_CFG_SPD_SHIFT 0 ++#define REG_CFG_SPD_MASK (3 << REG_CFG_SPD_SHIFT) ++#define REG_CFG_SPD_HS (0 << REG_CFG_SPD_SHIFT) ++#define REG_CFG_SPD_FS (1 << REG_CFG_SPD_SHIFT) ++#define REG_CFG_SPD_LS (2 << REG_CFG_SPD_SHIFT) ++#define REG_CFG_SPD_FS_48MHZ (3 << REG_CFG_SPD_SHIFT) ++ ++#define REG_CTRL_DMA_OUT_THRESHOLD_LEN_SHIFT 24 ++#define REG_CTRL_DMA_OUT_THRESHOLD_LEN_MASK (0xff << REG_CTRL_DMA_OUT_THRESHOLD_LEN_SHIFT) ++#define REG_CTRL_DMA_BURST_LEN_SHIFT 16 ++#define REG_CTRL_DMA_BURST_LEN_MASK (0xff << REG_CTRL_DMA_BURST_LEN_SHIFT) ++#define REG_CTRL_OUT_FIFO_FLUSH_ENABLE (1 << 14) ++#define REG_CTRL_CSR_DONE (1 << 13) ++#define REG_CTRL_OUT_NAK_ALL_ENABLE (1 << 12) ++#define REG_CTRL_DISCONNECT_ENABLE (1 << 10) ++#define REG_CTRL_DMA_MODE_ENABLE (1 << 9) ++#define REG_CTRL_DMA_BURST_ENABLE (1 << 8) ++#define REG_CTRL_DMA_OUT_THRESHOLD_ENABLE (1 << 7) ++#define REG_CTRL_DMA_BUFF_FILL_MODE_ENABLE (1 << 6) ++#define REG_CTRL_ENDIAN_BIG_ENABLE (1 << 5) ++#define REG_CTRL_DMA_DESC_UPDATE_ENABLE (1 << 4) ++#define REG_CTRL_DMA_IN_ENABLE (1 << 3) /*TX DMA Enable */ ++#define REG_CTRL_DMA_OUT_ENABLE (1 << 2) /*RX DMA Enable */ ++#define REG_CTRL_RESUME_SIGNAL_ENABLE (1 << 0) ++#define REG_CTRL_LE_ENABLE 0 ++ ++#define REG_STAT_SOF_FRAME_NUM_SHIFT 18 ++#define REG_STAT_SOF_FRAME_NUM_MASK (0x3fff << REG_STAT_SOF_FRAME_NUM_SHIFT) ++#define REG_STAT_REMOTE_WAKEUP_ALLOWED (1 << 17) ++#define REG_STAT_PHY_ERROR (1 << 16) ++#define REG_STAT_OUT_FIFO_EMPTY (1 << 15) ++#define REG_STAT_SPD_SHIFT 13 ++#define REG_STAT_SPD_MASK (3 << REG_STAT_SPD_SHIFT) ++#define REG_STAT_SPD_HS (0 << REG_STAT_SPD_SHIFT) ++#define REG_STAT_SPD_FS (1 << REG_STAT_SPD_SHIFT) ++#define REG_STAT_SPD_LS (2 << REG_STAT_SPD_SHIFT) ++#define REG_STAT_SPD_FS_48MHZ (3 << REG_STAT_SPD_SHIFT) ++#define REG_STAT_BUS_SUSPENDED (1 << 12) ++#define REG_STAT_ALT_NUM_SHIFT 8 ++#define REG_STAT_ALT_NUM_MASK (0xf << REG_STAT_ALT_NUM_SHIFT) ++#define REG_STAT_INTF_NUM_SHIFT 4 ++#define REG_STAT_INTF_NUM_MASK (0xf << REG_STAT_INTF_NUM_SHIFT) ++#define REG_STAT_CFG_NUM_SHIFT 0 ++#define REG_STAT_CFG_NUM_MASK (0xf << REG_STAT_CFG_NUM_SHIFT) ++ ++#define REG_INTR_REMOTE_WAKEUP_DELTA (1 << 7) /*Remote Wakeup Delta*/ ++#define REG_INTR_SPD_ENUM_DONE (1 << 6) /*ENUM Speed Completed*/ ++#define REG_INTR_SOF_RX (1 << 5) /*SOF Token Detected */ ++#define REG_INTR_BUS_SUSPEND (1 << 4) /*SUSPEND State Detected*/ ++#define REG_INTR_BUS_RESET (1 << 3) /*RESET State Detected */ ++#define REG_INTR_BUS_IDLE (1 << 2) /*IDLE State Detected*/ ++#define REG_INTR_SET_INTF_RX (1 << 1) /*Received SET_INTERFACE CMD*/ ++#define REG_INTR_SET_CFG_RX (1 << 0) /*Received SET_CONFIG CMD*/ ++ ++/* DMA Descriptor definitions */ ++#define REG_DMA_STAT_BUF_SHIFT 30 ++#define REG_DMA_STAT_BUF_HOST_READY (0 << REG_DMA_STAT_BUF_SHIFT) ++#define REG_DMA_STAT_BUF_DMA_BUSY (1 << REG_DMA_STAT_BUF_SHIFT) ++#define REG_DMA_STAT_BUF_DMA_DONE (2 << REG_DMA_STAT_BUF_SHIFT) ++#define REG_DMA_STAT_BUF_HOST_BUSY (3 << REG_DMA_STAT_BUF_SHIFT) ++#define REG_DMA_STAT_BUF_MASK (3 << REG_DMA_STAT_BUF_SHIFT) ++#define REG_DMA_STAT_RX_SHIFT 28 ++#define REG_DMA_STAT_RX_SUCCESS (0 << REG_DMA_STAT_RX_SHIFT) ++#define REG_DMA_STAT_RX_ERR_DESC (1 << REG_DMA_STAT_RX_SHIFT) ++#define REG_DMA_STAT_RX_ERR_BUF (3 << REG_DMA_STAT_RX_SHIFT) ++#define REG_DMA_STAT_RX_MASK (3 << REG_DMA_STAT_RX_SHIFT) ++#define REG_DMA_STAT_CFG_NUM_SHIFT 24 ++#define REG_DMA_STAT_CFG_NUM_MASK (0xf << REG_DMA_STAT_CFG_NUM_SHIFT) ++#define REG_DMA_STAT_INTF_NUM_SHIFT 20 ++#define REG_DMA_STAT_INTF_NUM_MASK (0xf << REG_DMA_STAT_INTF_NUM_SHIFT) ++#define REG_DMA_STAT_ALT_NUM_SHIFT 16 ++#define REG_DMA_STAT_ALT_NUM_MASK (0xf << REG_DMA_STAT_ALT_NUM_SHIFT) ++#define REG_DMA_STAT_LAST_DESC (1 << 27) ++#define REG_DMA_STAT_FRAME_NUM_SHIFT 16 ++#define REG_DMA_STAT_FRAME_NUM_MASK (0x7ff << REG_DMA_STAT_FRAME_NUM_SHIFT) ++#define REG_DMA_STAT_BYTE_CNT_SHIFT 0 ++#define REG_DMA_STAT_ISO_PID_SHIFT 14 ++#define REG_DMA_STAT_ISO_PID_MASK (0x3 << REG_DMA_STAT_ISO_PID_SHIFT) ++#define REG_DMA_STAT_ISO_BYTE_CNT_SHIFT REG_DMA_STAT_BYTE_CNT_SHIFT ++#define REG_DMA_STAT_ISO_BYTE_CNT_MASK (0x3fff << REG_DMA_STAT_ISO_BYTE_CNT_SHIFT) ++#define REG_DMA_STAT_NON_ISO_BYTE_CNT_SHIFT REG_DMA_STAT_BYTE_CNT_SHIFT ++#define REG_DMA_STAT_NON_ISO_BYTE_CNT_MASK (0xffff << REG_DMA_STAT_NON_ISO_BYTE_CNT_SHIFT) ++ ++/* USB2D IDM definitions */ ++#define IPROC_USB2D_IDM_REG_IO_CTRL_DIRECT_CLK_ENABLE (1 << 0) ++#define IPROC_USB2D_IDM_REG_RESET_CTRL_RESET (1 << 0) ++ ++/* Inline Function Definitions */ ++static inline uint ++usbd_reg32_read(volatile uint *reg) ++{ ++ return (le32_to_cpu(*reg)); ++} ++ ++static inline void usbd_reg32_write(volatile uint *reg, uint value) ++{ ++ *reg = cpu_to_le32(value); ++} ++ ++static inline void usbd_reg32_bits_set(volatile uint *reg, uint bits) ++{ ++ uint tmp; ++ tmp = usbd_reg32_read(reg); ++ tmp |= bits; ++ usbd_reg32_write(reg, tmp); ++} ++ ++static inline void usbd_reg32_bits_clear(volatile uint *reg, uint bits) ++{ ++ uint tmp; ++ tmp = usbd_reg32_read(reg); ++ tmp &= ~bits; ++ usbd_reg32_write(reg, tmp); ++} ++ ++static inline void usbd_reg32_bits_modify(volatile uint *reg, uint mask, uint value) ++{ ++ uint tmp; ++ tmp = usbd_reg32_read(reg); ++ tmp &= ~mask; ++ tmp |= value; ++ usbd_reg32_write(reg, tmp); ++} ++ ++#define IPROC_USBD_READ(_r) usbd_reg32_read(&_r) ++#define IPROC_USBD_WRITE(_r, _v) usbd_reg32_write(&_r, _v) ++#define IPROC_USBD_BITS_SET(_r, _b) usbd_reg32_bits_set(&_r, _b) ++#define IPROC_USBD_BITS_CLEAR(_r, _b) usbd_reg32_bits_clear(&_r, _b) ++#define IPROC_USBD_BITS_MODIFY(_r, _m, _v) usbd_reg32_bits_modify(&_r, _m, _v) ++ ++/***************************************************************************** ++* @brief Connect / Disconnect to USB BUS ++*****************************************************************************/ ++static inline void iproc_usbd_bus_conn(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, REG_CTRL_DISCONNECT_ENABLE); ++} ++ ++static inline void iproc_usbd_bus_disconn(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_ctrl, REG_CTRL_DISCONNECT_ENABLE); ++} ++ ++/***************************************************************************** ++* @brief USB BUS suspend status ++* @return ++* true : BUS is in suspend state ++* false : BUS is not in suspend state ++*****************************************************************************/ ++static inline bool iproc_usbd_bus_suspend(struct iproc_usbd_regs *base) ++{ ++ return (IPROC_USBD_READ(base->dev_status) & REG_STAT_BUS_SUSPENDED) ? true : false; ++} ++ ++/***************************************************************************** ++* @brief Retrieve setting numbers from last Rx'd SET_CONFIGURATION or ++* SET_INTERFACE request ++* @return ++* Setting Number ++*****************************************************************************/ ++static inline uint iproc_usbd_alt_num(struct iproc_usbd_regs *base) ++{ ++ return ((IPROC_USBD_READ(base->dev_status) & REG_STAT_ALT_NUM_MASK) >> REG_STAT_ALT_NUM_SHIFT); ++} ++ ++static inline uint iproc_usbd_cfg_num(struct iproc_usbd_regs *base) ++{ ++ return ((IPROC_USBD_READ(base->dev_status) & REG_STAT_CFG_NUM_MASK) >> REG_STAT_CFG_NUM_SHIFT); ++} ++ ++static inline uint iproc_usbd_intf_num(struct iproc_usbd_regs *base) ++{ ++ return ((IPROC_USBD_READ(base->dev_status) & REG_STAT_INTF_NUM_MASK) >> REG_STAT_INTF_NUM_SHIFT); ++} ++ ++ ++/***************************************************************************** ++* @brief Disable / Enable DMA operations at the device level (all endpoints) ++*****************************************************************************/ ++static inline void iproc_usbd_dma_dis(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, (REG_CTRL_DMA_IN_ENABLE | REG_CTRL_DMA_OUT_ENABLE)); ++} ++ ++static inline void iproc_usbd_dma_en(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_ctrl, (REG_CTRL_DMA_IN_ENABLE | REG_CTRL_DMA_OUT_ENABLE)); ++} ++ ++static inline bool iproc_usbd_dma_status(struct iproc_usbd_regs *base) ++{ ++ return (IPROC_USBD_READ(base->dev_ctrl) & REG_CTRL_DMA_OUT_ENABLE ? true : false); ++} ++ ++/***************************************************************************** ++* @brief Retrieve Frame number contained in last Rx'd SOF packet ++* @return ++* Frame Number in the following format. ++* bits[13:3] milli-second frame number ++* bits[2:0] micro-frame number ++* @note ++* For full and low speed connections, the microframe number will be zero. ++*****************************************************************************/ ++static inline uint iproc_usbd_last_rx_frame_num(struct iproc_usbd_regs *base) ++{ ++ return((IPROC_USBD_READ(base->dev_status) & REG_STAT_SOF_FRAME_NUM_MASK) >> REG_STAT_SOF_FRAME_NUM_SHIFT); ++} ++ ++/***************************************************************************** ++* @brief Device level interrupt operations ++* @note ++* Use the USBD_IRQ_xxx definitions with these routines. These ++* definitions are bit-wise, and allow operations on multiple interrupts ++* by OR'ing the definitions together. ++* DeviceIrqClear(), DeviceIrqDisable(), DeviceIrqEnable() use their mask ++* parameter to operate only on the interrupts set in the mask. E.g. ++* DeviceIrqEnable( DEVICE_IRQ_SET_INTF ); ++* DeviceIrqEnable( DEVICE_IRQ_SET_CFG ); ++* and ++* DeviceIrqEnable( DEVICE_IRQ_SET_INTF | DEVICE_IRQ_SET_CFG ); ++* are equivalent. ++* DeviceIrqMask() returns a mask of all the interrupts that are enabled. ++* DeviceIrqStatus() returns a mask of all the interrupts that have an active status. ++*****************************************************************************/ ++static inline uint iproc_usbd_irq_active(struct iproc_usbd_regs *base) ++{ ++ return(IPROC_USBD_READ(base->dev_irq_status)); ++} ++ ++static inline void iproc_usbd_irq_clear(struct iproc_usbd_regs *base, uint mask) ++{ ++ IPROC_USBD_WRITE(base->dev_irq_status, mask); ++} ++ ++static inline void iproc_usbd_irq_dis(struct iproc_usbd_regs *base, uint mask) ++{ ++ IPROC_USBD_BITS_SET(base->dev_irq_mask, mask); ++} ++ ++static inline void iproc_usbd_irq_en(struct iproc_usbd_regs *base, uint mask) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_irq_mask, mask); ++} ++static inline uint iproc_usbd_irq_mask(struct iproc_usbd_regs *base) ++{ ++ return((~IPROC_USBD_READ(base->dev_irq_mask)) & USBD_IRQ_ALL); ++} ++ ++/***************************************************************************** ++* @brief Disable / Enable NAK responses for all OUT endpoints. ++*****************************************************************************/ ++static inline void iproc_usbd_nak_response_dis(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, REG_CTRL_OUT_NAK_ALL_ENABLE); ++} ++ ++static inline void iproc_usbd_nak_response_en(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_ctrl, REG_CTRL_OUT_NAK_ALL_ENABLE); ++} ++ ++/***************************************************************************** ++* @brief PHY error detected ++*****************************************************************************/ ++static inline bool iproc_usbd_phy_err_detect(struct iproc_usbd_regs *base) ++{ ++ return(IPROC_USBD_READ(base->dev_status) & REG_STAT_PHY_ERROR ? true : false); ++} ++ ++/***************************************************************************** ++* @brief Remote Wakeup operations. ++* DeviceRemoteWakeupEnable() and DeviceRemoteWakeupDisable() are used to ++* specify device if is going to attempt this. ++* DeviceRemoteWakeupAllowed() indicates if host has enabled this feature. ++* The associated DEVICE_IRQ_REMOTEWAKEUP_DELTA can be used to determine ++* changes to the status of this feature. ++* DeviceRemoteWakeupStart(); delayMsec(1); DeviceRemoteWakeupStop(); is ++* used for controlling the wakeup signalling. ++*****************************************************************************/ ++static inline bool iproc_usbd_wakeup_allow(struct iproc_usbd_regs *base) ++{ ++ return(IPROC_USBD_READ(base->dev_status) & REG_STAT_REMOTE_WAKEUP_ALLOWED ? true : false); ++} ++ ++static inline void iproc_usbd_wakeup_dis(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_cfg, REG_CFG_REMOTE_WAKEUP_ENABLE); ++} ++ ++static inline void iproc_usbd_wakeup_en(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_cfg, REG_CFG_REMOTE_WAKEUP_ENABLE); ++} ++ ++static inline void iproc_usbd_wakeup_start(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_ctrl, REG_CTRL_RESUME_SIGNAL_ENABLE); ++} ++ ++static inline void iproc_usbd_wakeup_stop(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, REG_CTRL_RESUME_SIGNAL_ENABLE); ++} ++ ++/***************************************************************************** ++* @brief Control whether or not device advertises itself as self-powered. ++*****************************************************************************/ ++static inline void iproc_usbd_self_pwr_dis(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_cfg, REG_CFG_SELF_PWR_ENABLE); ++} ++ ++static inline void iproc_usbd_self_pwr_en(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_cfg, REG_CFG_SELF_PWR_ENABLE); ++} ++ ++/***************************************************************************** ++* @brief Control whether or not device SET DESCRIPTOR support is enabled. ++* If disabled, STALL will be issued upon receipt of a SET DESCRIPTOR request. ++*****************************************************************************/ ++static inline void iproc_usbd_set_desc_dis(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_cfg, REG_CFG_SET_DESCRIPTOR_ENABLE); ++} ++ ++static inline void iproc_usbd_set_desc_en(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_cfg, REG_CFG_SET_DESCRIPTOR_ENABLE); ++} ++ ++/***************************************************************************** ++* @brief Device SET configuration or SET interface has completed. ++* If disabled, STALL will be issued upon receipt of a SET DESCRIPTOR request. ++*****************************************************************************/ ++static inline void iproc_usbd_setup_done(struct iproc_usbd_regs *base) ++{ ++ IPROC_USBD_BITS_SET(base->dev_ctrl, REG_CTRL_CSR_DONE); ++} ++ ++/***************************************************************************** ++* @brief Link speed routines. ++* Use the usbDevHw_DEVICE_SPEED_xxx definitions with these routines. These ++* DeviceSpeedRequested() indicates the desired link speed. ++* DeviceSpeedEnumerated() returns the speed negotiated with the host. ++* The associated DEVICE_IRQ_SPEED_ENUM_DONE can be used to determine ++* when speed negotiation has completed. ++*****************************************************************************/ ++static inline uint iproc_usbd_speed_get(struct iproc_usbd_regs *base) ++{ ++ switch(IPROC_USBD_READ(base->dev_status) & REG_STAT_SPD_MASK) { ++ case REG_STAT_SPD_LS: ++ return(USB_SPEED_LOW); ++ ++ case REG_STAT_SPD_HS: ++ return(USB_SPEED_HIGH); ++ ++ case REG_STAT_SPD_FS: ++ case REG_STAT_SPD_FS_48MHZ: ++ return(USB_SPEED_FULL); ++ } ++ ++ return USB_SPEED_FULL; ++} ++ ++static inline void iproc_usbd_speed_req(struct iproc_usbd_regs *base, uint speed) ++{ ++ IPROC_USBD_BITS_CLEAR(base->dev_cfg, REG_CFG_SPD_MASK); ++ ++ switch(speed) { ++ case USB_SPEED_LOW: ++ IPROC_USBD_BITS_SET(base->dev_cfg, REG_CFG_SPD_LS); ++ break; ++ ++ case USB_SPEED_HIGH: ++ IPROC_USBD_BITS_SET(base->dev_cfg, REG_CFG_SPD_HS); ++ break; ++ ++ case USB_SPEED_FULL: ++ default: ++ IPROC_USBD_BITS_SET(base->dev_cfg, REG_CFG_SPD_FS); ++ break; ++ } ++} ++ ++/***************************************************************************** ++* @brief Finalize (terminate) / Initialize Endpoint operations ++* @param num - Endpoint number ++* @param dirn - Endpoint direction. See ENDPT_DIRN_xxx definitions ++* @param dirn - Endpoint type. See ENDPT_TYPE_xxx definitions ++* @param dirn - Endpoint max packet size. ++*****************************************************************************/ ++static inline void iproc_usbd_ep_ops_finish(struct iproc_usbd_regs *base, uint num) ++{ ++} ++ ++static inline void iproc_usbd_ep_ops_init(struct iproc_usbd_regs *base, uint num, uint type, uint dirn, uint maxPktSize) ++{ ++ if ((type == USB_ENDPOINT_XFER_CONTROL) || (dirn == USB_DIR_OUT)) { ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].ctrl, (type << REG_EP_FIFO_CTRL_TYPE_SHIFT)); ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].status, IPROC_USBD_READ(base->ep_fifo_out[num].status)); ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].size1, 0); ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].size2, ((maxPktSize >> 2) << 16) | maxPktSize); ++#if USBD_MULTI_RX_FIFO ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].size2, ((maxPktSize + 3) >> 2) << REG_EP_FIFO_SIZE2_OUT_DEPTH_SHIFT)); ++#endif ++ } ++ ++ if ((type == USB_ENDPOINT_XFER_CONTROL) || (dirn == USB_DIR_IN)) { ++ IPROC_USBD_WRITE(base->ep_fifo_in[num].ctrl, (type << REG_EP_FIFO_CTRL_TYPE_SHIFT)); ++ IPROC_USBD_WRITE(base->ep_fifo_in[num].size2, (maxPktSize << REG_EP_FIFO_SIZE2_PKT_MAX_SHIFT)); ++ IPROC_USBD_WRITE(base->ep_fifo_in[num].size1, (maxPktSize >> 2)); ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE); ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, (REG_EP_FIFO_CTRL_NAK_SET | REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE)); ++ } ++ ++ IPROC_USBD_WRITE(base->ep_cfg[num], (num << REG_EP_CFG_FIFO_NUM_SHIFT) | ++ (type << REG_EP_CFG_TYPE_SHIFT) | ++ (maxPktSize << REG_EP_CFG_PKT_MAX_SHIFT) | ++ (dirn == USB_DIR_OUT ? REG_EP_CFG_DIRN_OUT : REG_EP_CFG_DIRN_IN)); ++} ++ ++/***************************************************************************** ++* @brief Endpoint Configuration / Interface / Alternate number operations ++* @param num - Endpoint number ++* @param cfg - Configuration number ++* @param intf - Interface number ++* @param alt - Alternate number ++*****************************************************************************/ ++static inline void iproc_usbd_ep_alt_set(struct iproc_usbd_regs *base, uint num, uint alt) ++{ ++ IPROC_USBD_BITS_MODIFY(base->ep_cfg[num], REG_EP_CFG_ALT_NUM_MASK, (alt << REG_EP_CFG_ALT_NUM_SHIFT)); ++} ++ ++static inline void iproc_usbd_ep_cfg_set(struct iproc_usbd_regs *base, uint num, uint cfg) ++{ ++ IPROC_USBD_BITS_MODIFY(base->ep_cfg[num], REG_EP_CFG_CFG_NUM_MASK, (cfg << REG_EP_CFG_CFG_NUM_SHIFT)); ++} ++ ++static inline void iproc_usbd_ep_intf_set(struct iproc_usbd_regs *base, uint num, uint intf) ++{ ++ IPROC_USBD_BITS_MODIFY(base->ep_cfg[num], REG_EP_CFG_INTF_NUM_MASK, (intf << REG_EP_CFG_INTF_NUM_SHIFT)); ++} ++ ++ ++/***************************************************************************** ++* @brief Endpoint DMA routines ++* @param num - Endpoint number ++* @param addr - physical address of buffer or descriptor ++*****************************************************************************/ ++static inline void iproc_usbd_ep_dma_dis(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) { ++#if USBD_MULTI_RX_FIFO ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_OUT_DMA_ENABLE); ++#else ++ /* ++ * With a single RX FIFO, do not want to do anything, as there might be another OUT capable ++ * endpoint still active and wanting DMA enabled. If theory this should be OK, as long as ++ * the DMA descriptor buffer status fields are the last thing updated before being set to ++ * HOST ready, or the first thing updated when being set to HOST busy. Hopefully no ++ * situations arise such that there's contention with the hardware with doing this. ++ */ ++#endif ++ } else { ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_IN_DMA_ENABLE); ++ } ++} ++ ++static inline void iproc_usbd_ep_dma_en(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) { ++#if USBD_MULTI_RX_FIFO ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_OUT_DMA_ENABLE); ++#else ++ IPROC_USBD_BITS_SET(base->dev_ctrl, REG_CTRL_DMA_OUT_ENABLE); ++#endif ++ } else { ++ /* Set the Poll bit in the control register */ ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_IN_DMA_ENABLE); ++ } ++} ++ ++static inline void iproc_usbd_ep_dma_buf_addr_set(struct iproc_usbd_regs *base, uint num, uint dirn, void *addr) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].buf_addr, (uint)addr); ++} ++ ++static inline void iproc_usbd_ep_dma_desc_addr_set(struct iproc_usbd_regs *base, uint num, uint dirn, void *addr) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].desc_addr, (uint)addr); ++ else ++ IPROC_USBD_WRITE(base->ep_fifo_in[num].desc_addr, (uint)addr); ++} ++ ++/***************************************************************************** ++* @brief Endpoint FIFO routines ++* @param num - Endpoint number ++* @note The flush operation is a state. Once enabled, FIFO contents are discared ++* until disabled. Usually enable upon endpoint termination or error, and ++* then disable once operations are to resume normally. ++*****************************************************************************/ ++static inline bool iproc_usbd_ep_fifo_empty(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) { ++#if USBD_MULTI_RX_FIFO ++ return(base->ep_fifo_out[num].status & REG_EP_FIFO_STATUS_OUT_FIFO_EMPTY ? true : false); ++#else ++ return(base->dev_status & REG_STAT_OUT_FIFO_EMPTY ? true : false); ++#endif ++ } ++ ++ return(base->ep_fifo_in[num].status & REG_EP_FIFO_STATUS_IN_FIFO_EMPTY ? true : false); ++} ++ ++static inline void iproc_usbd_ep_fifo_flush_dis(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) { ++#if USBD_MULTI_RX_FIFO ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_OUT_FLUSH_ENABLE); ++#else ++ IPROC_USBD_BITS_CLEAR(base->dev_ctrl, REG_CTRL_OUT_FIFO_FLUSH_ENABLE); ++#endif ++ } ++ else { ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE); ++ } ++} ++ ++static inline void iproc_usbd_ep_fifo_flush_en(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) { ++#if USBD_MULTI_RX_FIFO ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_OUT_FLUSH_ENABLE); ++#else ++ IPROC_USBD_BITS_SET(base->dev_ctrl, REG_CTRL_OUT_FIFO_FLUSH_ENABLE); ++#endif ++ } else { ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_IN_FLUSH_ENABLE); ++ } ++} ++ ++/***************************************************************************** ++* @brief Endpoint Frame Number routines ++* @param num - Endpoint number ++* @return Frame number of last packet received on the endpoint, and in the following format. ++* bits[13:3] milli-second frame number ++* bits[2:0] micro-frame number ++* @note Really only applicable to OUT endpoints. IN will always return 0. ++*****************************************************************************/ ++static inline uint iproc_usbd_ep_frame_num(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ return((IPROC_USBD_READ(base->ep_fifo_out[num].size1) & REG_EP_FIFO_SIZE1_OUT_FRAME_NUM_MASK) >> ++ REG_EP_FIFO_SIZE1_OUT_FRAME_NUM_SHIFT); ++ ++ return(0); ++} ++ ++/***************************************************************************** ++* @brief Endpoint IRQ / status routines ++* @param num - Endpoint number ++* @note ++* Cannot set specific status for Endpoint interrupts. Can only do operations ++* in a global sense. Once an interrupt occurs for an endpoint, the endpoint ++* status has to be checked for the particular type of interrupt that occurred. ++* ++* The iproc_usbd_ep_irq_en() and iproc_usbd_ep_irq_dis() are used for ++* operations on a specific endpoint. These routines may or may not be used in ++* the context of interrupt processing. ++* ++* Use the usbDevHw_EndptIrqListXxx() routines for operations using a bit-wise ++* list of endpoints (bit 0 for endpoint 0, etc.). Typical use would be for ++* interrupt processing. ++* ++* Use the USBD_EP_STAT_xxx definitions with the status routines. These ++* definitions are bit-wise, and allow operations on multiple conditions ++* by OR'ing the definitions together. ++*****************************************************************************/ ++static inline void iproc_usbd_ep_irq_clear(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_WRITE(base->ep_irq_status, (1 << num) << REG_EP_INTR_OUT_SHIFT); ++ else ++ IPROC_USBD_WRITE(base->ep_irq_status, (1 << num) << REG_EP_INTR_IN_SHIFT); ++} ++ ++static inline void iproc_usbd_ep_irq_dis(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_BITS_SET(base->ep_irq_mask, ((1 << num) << REG_EP_INTR_OUT_SHIFT)); ++ else ++ IPROC_USBD_BITS_SET(base->ep_irq_mask, ((1 << num) << REG_EP_INTR_IN_SHIFT)); ++} ++ ++static inline void iproc_usbd_ep_irq_en(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_BITS_CLEAR(base->ep_irq_mask, ((1 << num) << REG_EP_INTR_OUT_SHIFT)); ++ else ++ IPROC_USBD_BITS_CLEAR(base->ep_irq_mask, ((1 << num) << REG_EP_INTR_IN_SHIFT)); ++} ++ ++static inline uint iproc_usbd_ep_irq_list_active(struct iproc_usbd_regs *base, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ return((IPROC_USBD_READ(base->ep_irq_status) & REG_EP_INTR_OUT_MASK) >> REG_EP_INTR_OUT_SHIFT); ++ ++ return((IPROC_USBD_READ(base->ep_irq_status) & REG_EP_INTR_IN_MASK) >> REG_EP_INTR_IN_SHIFT); ++} ++ ++static inline void iproc_usbd_ep_irq_list_clear(struct iproc_usbd_regs *base, uint dirn, uint mask) ++{ ++ if (dirn == USB_DIR_OUT) /*strat from bit 16 */ ++ IPROC_USBD_WRITE(base->ep_irq_status, (mask << REG_EP_INTR_OUT_SHIFT)); ++ else /* start from bit 0 */ ++ IPROC_USBD_WRITE(base->ep_irq_status, (mask << REG_EP_INTR_IN_SHIFT)); ++} ++ ++static inline uint iproc_usbd_ep_stat_active(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) /* End Point Status register */ ++ return(IPROC_USBD_READ(base->ep_fifo_out[num].status)); ++ ++ return(IPROC_USBD_READ(base->ep_fifo_in[num].status)); ++} ++ ++static inline void iproc_usbd_ep_stat_clear(struct iproc_usbd_regs *base, uint num, uint dirn, uint mask) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_WRITE(base->ep_fifo_out[num].status, mask); ++ else ++ IPROC_USBD_WRITE(base->ep_fifo_in[num].status, mask); ++} ++ ++/***************************************************************************** ++* @brief Endpoint NAK routines ++* @param num - Endpoint number ++* @note A NAK response can be enabled by the application by the EndptNakEnable(). ++* The EndptNakInProgress() is used to determine if the controller is ++* currently actively sending NAKs. This may have been a result of the ++* EndptNakEnable() or automatically by the controller under certain ++* conditions. The EndptNakClear() must be used to terminate the NAKs. ++*****************************************************************************/ ++static inline void iproc_usbd_ep_nak_clear(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_NAK_CLEAR); ++ else ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_NAK_CLEAR); ++} ++ ++static inline void iproc_usbd_ep_nak_en(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_NAK_SET); ++ else ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_NAK_SET); ++} ++ ++static inline void iproc_usbd_ep_nak_dis(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_NAK_SET); ++ else ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_NAK_SET); ++} ++ ++static inline bool iproc_usbd_ep_nak_progress(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ return (IPROC_USBD_READ(base->ep_fifo_out[num].ctrl) & REG_EP_FIFO_CTRL_NAK_IN_PROGRESS) ? true : false; ++ ++ return (IPROC_USBD_READ(base->ep_fifo_in[num].ctrl) & REG_EP_FIFO_CTRL_NAK_IN_PROGRESS) ? true : false; ++} ++ ++/***************************************************************************** ++* @brief Endpoint Stall routines ++* Disable / Enable STALL responses (halt feature) on a given endpoint. ++* @param num - Endpoint number ++*****************************************************************************/ ++static inline void iproc_usbd_ep_stall_dis(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_STALL_ENABLE); ++ else ++ IPROC_USBD_BITS_CLEAR(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_STALL_ENABLE); ++} ++ ++static inline void iproc_usbd_ep_stall_en(struct iproc_usbd_regs *base, uint num, uint dirn) ++{ ++#if USBD_MULTI_RX_FIFO ++ if (!(IPROC_USBD_READ(base->ep_fifo_out[num].status) & REG_EP_FIFO_STATUS_OUT_FIFO_EMPTY)) ++#else ++ if (!(IPROC_USBD_READ(base->dev_status) & REG_STAT_OUT_FIFO_EMPTY)) ++#endif ++ return; ++ ++ if (dirn == USB_DIR_OUT) ++ IPROC_USBD_BITS_SET(base->ep_fifo_out[num].ctrl, REG_EP_FIFO_CTRL_STALL_ENABLE); ++ else ++ IPROC_USBD_BITS_SET(base->ep_fifo_in[num].ctrl, REG_EP_FIFO_CTRL_STALL_ENABLE); ++} ++ ++ ++/***************************************************************************** ++* @brief Initialize device controller operations ++*****************************************************************************/ ++static inline void iproc_usbd_ops_init(struct iproc_usbd_regs *base) ++{ ++ int idx; ++ ++ iproc_usbd_dma_dis(base); ++ iproc_usbd_irq_dis(base, USBD_IRQ_ALL); ++ iproc_usbd_irq_clear(base, USBD_IRQ_ALL); ++ ++ /* @todo Create and use usbDevHw_EndptIrqListDisable?? */ ++ for (idx = 0; idx < USBD_EP_CFG_CNT; idx++) { ++ iproc_usbd_ep_irq_dis(base, idx, USB_DIR_IN); ++ iproc_usbd_ep_irq_clear(base, idx, USB_DIR_IN); ++ iproc_usbd_ep_stat_clear(base, idx, USB_DIR_IN, ++ iproc_usbd_ep_stat_active(base, idx, USB_DIR_IN)); ++ ++ iproc_usbd_ep_irq_dis(base, idx, USB_DIR_OUT); ++ iproc_usbd_ep_irq_clear(base, idx, USB_DIR_OUT); ++ iproc_usbd_ep_stat_clear(base, idx, USB_DIR_OUT, ++ iproc_usbd_ep_stat_active(base, idx, USB_DIR_OUT)); ++ } ++ ++ IPROC_USBD_WRITE(base->dev_cfg, (REG_CFG_SET_DESCRIPTOR_ENABLE | ++ REG_CFG_UTMI_8BIT_ENABLE | ++ REG_CFG_CSR_PROGRAM_ENABLE | ++ REG_CFG_SPD_HS)); ++ ++ IPROC_USBD_WRITE(base->dev_ctrl, (REG_CTRL_LE_ENABLE | ++ REG_CTRL_DISCONNECT_ENABLE | ++ REG_CTRL_DMA_MODE_ENABLE | ++ REG_CTRL_DMA_IN_ENABLE | ++ REG_CTRL_DMA_OUT_ENABLE | ++ REG_CTRL_DMA_DESC_UPDATE_ENABLE | ++ REG_CTRL_OUT_NAK_ALL_ENABLE | ++ REG_CTRL_DMA_OUT_THRESHOLD_LEN_MASK | ++ REG_CTRL_DMA_BURST_LEN_MASK | ++#if !USBD_MULTI_RX_FIFO ++ REG_CTRL_OUT_FIFO_FLUSH_ENABLE | ++#endif ++ REG_CTRL_DMA_BURST_ENABLE)); ++ ++ IPROC_USBD_WRITE(base->dev_irq_mask, (REG_INTR_BUS_IDLE | REG_INTR_SOF_RX)); ++ IPROC_USBD_WRITE(base->ep_irq_mask,0); ++} ++ ++/***************************************************************************** ++* @brief Disable / Enable USB device ++*****************************************************************************/ ++static inline void iproc_usbd_dis(struct iproc_usbd_idm_regs *idm_base) ++{ ++ /* reset usb device */ ++ IPROC_USBD_BITS_SET(idm_base->reset_ctrl, IPROC_USB2D_IDM_REG_RESET_CTRL_RESET); ++ ++ /* disable usb device clock */ ++ IPROC_USBD_BITS_CLEAR(idm_base->io_ctrl, IPROC_USB2D_IDM_REG_IO_CTRL_DIRECT_CLK_ENABLE); ++ mdelay(10); ++} ++ ++static inline void iproc_usbd_en(struct iproc_usbd_idm_regs *idm_base) ++{ ++ /* enable usb device clock */ ++ IPROC_USBD_BITS_SET(idm_base->io_ctrl, IPROC_USB2D_IDM_REG_IO_CTRL_DIRECT_CLK_ENABLE); ++ mdelay(10); ++ ++ /* get usb device out of reset */ ++ IPROC_USBD_BITS_CLEAR(idm_base->reset_ctrl, IPROC_USB2D_IDM_REG_RESET_CTRL_RESET); ++ mdelay(100); ++} ++ ++#endif /* _USBD_REGS_H_ */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig +--- a/drivers/usb/host/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/host/Kconfig 2018-05-10 11:31:33.793404173 +0800 +@@ -214,6 +214,13 @@ config USB_EHCI_HCD_STI + Enable support for the on-chip EHCI controller found on + STMicroelectronics consumer electronics SoC's. + ++config USB_EHCI_XGS_IPROC ++ bool "BRCM XGS iProc EHCI patch" ++ depends on (ARCH_XGS_IPROC && USB_EHCI_HCD_PLATFORM) ++ default n ++ ---help--- ++ This option is for BRCM XGS iProc EHCI patch ++ + config USB_EHCI_HCD_AT91 + tristate "Support for Atmel on-chip EHCI USB controller" + depends on USB_EHCI_HCD && ARCH_AT91 +@@ -591,6 +598,13 @@ config USB_OHCI_HCD_PLATFORM + + If unsure, say N. + ++config USB_OHCI_XGS_IPROC ++ bool "BRCM XGS iProc OHCI patch" ++ depends on (ARCH_XGS_IPROC && USB_OHCI_HCD_PLATFORM) ++ default n ++ ---help--- ++ This option is for BRCM XGS iProc OHCI patch ++ + config USB_OCTEON_OHCI + bool "Octeon on-chip OHCI support (DEPRECATED)" + depends on CAVIUM_OCTEON_SOC +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c +--- a/drivers/usb/host/ehci-platform.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/host/ehci-platform.c 2018-05-10 11:31:33.793404173 +0800 +@@ -43,6 +43,12 @@ + #define EHCI_MAX_RSTS 4 + #define hcd_to_ehci_priv(h) ((struct ehci_platform_priv *)hcd_to_ehci(h)->priv) + ++#if IS_ENABLED(CONFIG_USB_EHCI_XGS_IPROC) ++#include ++#include ++#define BCM_USB_FIFO_THRESHOLD 0x00800040 ++#endif ++ + struct ehci_platform_priv { + struct clk *clks[EHCI_MAX_CLKS]; + struct reset_control *rsts[EHCI_MAX_RSTS]; +@@ -152,10 +158,24 @@ static int ehci_platform_probe(struct pl + struct ehci_platform_priv *priv; + struct ehci_hcd *ehci; + int err, irq, phy_num, clk = 0, rst; ++ struct usb_phy __maybe_unused *phy; + + if (usb_disabled()) + return -ENODEV; + ++ if (IS_ENABLED(CONFIG_USB_EHCI_XGS_IPROC)) { ++ phy = devm_usb_get_phy_by_phandle(&dev->dev, "usb-phy", 0); ++ if (IS_ERR(phy)) { ++ dev_err(&dev->dev, "unable to find transceiver\n"); ++ return PTR_ERR(phy); ++ } ++ ++ if (phy->flags != IPROC_USB_MODE_HOST) ++ return -ENODEV; ++ ++ usb_phy_init(phy); ++ } ++ + /* + * Use reasonable defaults so platforms don't have to provide these + * with DT probing on ARM. +@@ -296,12 +316,20 @@ static int ehci_platform_probe(struct pl + hcd->rsrc_start = res_mem->start; + hcd->rsrc_len = resource_size(res_mem); + ++ if (IS_ENABLED(CONFIG_USB_EHCI_XGS_IPROC)) ++ hcd->usb_phy = phy; ++ + err = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (err) + goto err_power; + + device_wakeup_enable(hcd->self.controller); + device_enable_async_suspend(hcd->self.controller); ++ ++ if (IS_ENABLED(CONFIG_USB_EHCI_XGS_IPROC)) ++ ehci_writel(ehci, BCM_USB_FIFO_THRESHOLD, ++ &ehci->regs->reserved4[6]); ++ + platform_set_drvdata(dev, hcd); + + return err; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/host/ohci-platform.c b/drivers/usb/host/ohci-platform.c +--- a/drivers/usb/host/ohci-platform.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/host/ohci-platform.c 2018-05-10 11:31:33.805404187 +0800 +@@ -37,6 +37,13 @@ + #define OHCI_MAX_RESETS 2 + #define hcd_to_ohci_priv(h) ((struct ohci_platform_priv *)hcd_to_ohci(h)->priv) + ++#if IS_ENABLED(CONFIG_USB_OHCI_XGS_IPROC) ++#include ++#include ++#define UHCRHDA_REG_OFFSET 0x48 ++#define UHCRHDA_OCPM BIT(11) ++#endif ++ + struct ohci_platform_priv { + struct clk *clks[OHCI_MAX_CLKS]; + struct reset_control *resets[OHCI_MAX_RESETS]; +@@ -120,10 +127,24 @@ static int ohci_platform_probe(struct pl + struct ohci_platform_priv *priv; + struct ohci_hcd *ohci; + int err, irq, phy_num, clk = 0, rst = 0; ++ struct usb_phy __maybe_unused *phy; + + if (usb_disabled()) + return -ENODEV; + ++ if (IS_ENABLED(CONFIG_USB_OHCI_XGS_IPROC)) { ++ phy = devm_usb_get_phy_by_phandle(&dev->dev, "usb-phy", 0); ++ if (IS_ERR(phy)) { ++ dev_err(&dev->dev, "unable to find transceiver\n"); ++ return PTR_ERR(phy); ++ } ++ ++ if (phy->flags != IPROC_USB_MODE_HOST) ++ return -ENODEV; ++ ++ usb_phy_init(phy); ++ } ++ + /* + * Use reasonable defaults so platforms don't have to provide these + * with DT probing on ARM. +@@ -264,6 +285,13 @@ static int ohci_platform_probe(struct pl + hcd->rsrc_start = res_mem->start; + hcd->rsrc_len = resource_size(res_mem); + ++ if (IS_ENABLED(CONFIG_USB_OHCI_XGS_IPROC)) { ++ if (of_find_property(dev->dev.of_node, "iproc-ocpm-fix", NULL)) ++ writel(readl(hcd->regs + UHCRHDA_REG_OFFSET) | ++ UHCRHDA_OCPM, hcd->regs + UHCRHDA_REG_OFFSET); ++ hcd->usb_phy = phy; ++ } ++ + err = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (err) + goto err_power; +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig +--- a/drivers/usb/phy/Kconfig 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/phy/Kconfig 2018-05-10 11:31:33.833404217 +0800 +@@ -202,4 +202,18 @@ config USB_ULPI_VIEWPORT + Provides read/write operations to the ULPI phy register set for + controllers with a viewport register (e.g. Chipidea/ARC controllers). + ++config USBPHY_XGS_IPROC ++ tristate "BRCM iProc USB controller support" ++ depends on ARCH_XGS_IPROC ++ select USB_PHY ++ help ++ BRCM iProc USB controller support ++ ++config USB_XGS_IPROC_DRD ++ tristate "BRCM iProc USB DRD controller support" ++ depends on ARCH_XGS_IPROC ++ select USB_PHY ++ help ++ BRCM iProc USB DRD controller support ++ + endmenu +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile +--- a/drivers/usb/phy/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/usb/phy/Makefile 2018-05-10 11:31:33.833404217 +0800 +@@ -26,3 +26,5 @@ obj-$(CONFIG_USB_MXS_PHY) += phy-mxs-us + obj-$(CONFIG_USB_ULPI) += phy-ulpi.o + obj-$(CONFIG_USB_ULPI_VIEWPORT) += phy-ulpi-viewport.o + obj-$(CONFIG_KEYSTONE_USB_PHY) += phy-keystone.o ++obj-$(CONFIG_USBPHY_XGS_IPROC) += phy-xgs-iproc.o ++obj-$(CONFIG_USB_XGS_IPROC_DRD) += phy-xgs-iproc-drd.o +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/phy/phy-xgs-iproc-drd.c b/drivers/usb/phy/phy-xgs-iproc-drd.c +--- a/drivers/usb/phy/phy-xgs-iproc-drd.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/usb/phy/phy-xgs-iproc-drd.c 2018-05-10 11:31:33.837404222 +0800 +@@ -0,0 +1,270 @@ ++/* ++ * $Copyright Open Broadcom Corporation$ ++ * ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define ICFG_USB_CTRL_ADDR(base) (base + 0x00) ++#define ICFG_USB_CTRL__DRD_FORCE_HOST_MODE 6 ++#define ICFG_USB_CTRL__DRD_FORCE_DEVICE_MODE 5 ++#define ICFG_USB_CTRL__XHC_CSR_RESET 4 ++#define ICFG_USB_CTRL__BDC_CSR_RESET 3 ++#define ICFG_USB_CTRL__DRD_SOFT_RESET 2 ++#define ICFG_USB_CTRL__XHC_SOFT_RESET 1 ++#define ICFG_USB_CTRL__BDC_SOFT_RESET 0 ++ ++#define IPROC_WRAP_USBPHY_CTRL_0_ADDR(base) (base + 0x00) ++#define IPROC_WRAP_USBPHY_CTRL_0__PHY_ISO 18 ++#define IPROC_WRAP_USBPHY_CTRL_0__PLL_CTRL_45 17 ++#define IPROC_WRAP_USBPHY_CTRL_0__PLL_SUSPEND_EN 16 ++#define IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB 15 ++#define IPROC_WRAP_USBPHY_CTRL_0__RESETB 14 ++#define IPROC_WRAP_USBPHY_CTRL_2_ADDR(base) (base + 0x08) ++#define IPROC_WRAP_USBPHY_CTRL_2__AFE_LDO_PWRDWNB 2 ++#define IPROC_WRAP_USBPHY_CTRL_2__AFE_PLL_PWRDWNB 1 ++#define IPROC_WRAP_USBPHY_CTRL_2__AFE_BG_PWRDWNB 0 ++#define IPROC_WRAP_MISC_STATUS_0_ADDR(base) (base + 0x1c) ++#define IPROC_WRAP_MISC_STATUS_0__USBPHY_PLL_LOCK 0 ++#define IPROC_WRAP_MISC_STATUS_1_ADDR(base) (base + 0x20) ++ ++struct iproc_usb_priv { ++ struct usb_phy phy; ++ struct device *dev; ++ struct device_node *dn; ++ void __iomem *wrap_base; ++ void __iomem *icfg_usb_base; ++}; ++ ++extern void __iomem *get_iproc_wrap_ctrl_base(void); ++ ++/*************************************************************************** ++**************************************************************************** ++***************************************************************************/ ++static int iproc_usb_phy_init(struct usb_phy *phy) ++{ ++ struct iproc_usb_priv *iproc_usb_data = container_of(phy, struct iproc_usb_priv, phy); ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ struct device *dev = iproc_usb_data->dev; ++ uint val; ++ ulong mask, count = 0; ++ ++ if (!wrap_base) { ++ return -EINVAL; ++ } ++ ++ /* FIXME. PHY initial sequence, need to get the sequence from DE */ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_0__PHY_ISO); ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_0__PLL_SUSPEND_EN); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB); ++ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_0__RESETB); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_2__AFE_BG_PWRDWNB); ++ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_2__AFE_LDO_PWRDWNB); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ udelay(10); ++ ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_2__AFE_BG_PWRDWNB); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ udelay(150); ++ ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_2__AFE_LDO_PWRDWNB); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ udelay(160); ++ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~(1 << IPROC_WRAP_USBPHY_CTRL_0__PHY_ISO); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ udelay(20); ++ ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ mdelay(20); ++ ++ ++ /* check pll_lock */ ++ mask = (1 << IPROC_WRAP_MISC_STATUS_0__USBPHY_PLL_LOCK); ++ do { ++ val = readl_relaxed(IPROC_WRAP_MISC_STATUS_0_ADDR(wrap_base)); ++ if ((val & mask) == mask) { ++ break; ++ } else { ++ udelay(10); ++ count ++; ++ } ++ } while(count <= 10); ++ if (count > 10) { ++ dev_err(dev, "%s : PLL not lock! IPROC_WRAP_MISC_STATUS_0 = 0x%.8x\n", ++ __FUNCTION__, val); ++ } ++ ++ val = readl_relaxed(IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= (1 << IPROC_WRAP_USBPHY_CTRL_0__RESETB); ++ writel_relaxed(val, IPROC_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ udelay(2); ++ ++ return 0; ++} ++ ++static int iproc_usb_reset(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *icfg_usb_base = iproc_usb_data->icfg_usb_base; ++ uint val; ++ ++ if (!icfg_usb_base) { ++ return -EINVAL; ++ } ++ ++ /* Put DRD into reset state */ ++ val = readl_relaxed(ICFG_USB_CTRL_ADDR(icfg_usb_base)); ++ val |= (1 << ICFG_USB_CTRL__DRD_SOFT_RESET); ++ writel_relaxed(val, ICFG_USB_CTRL_ADDR(icfg_usb_base)); ++ ++ /* Put BDC and XHC into reset state */ ++ val = readl_relaxed(ICFG_USB_CTRL_ADDR(icfg_usb_base)); ++ val |= (1 << ICFG_USB_CTRL__BDC_SOFT_RESET); ++ val |= (1 << ICFG_USB_CTRL__XHC_SOFT_RESET); ++ writel_relaxed(val, ICFG_USB_CTRL_ADDR(icfg_usb_base)); ++ ++ mdelay(10); ++ ++ /* Get the BDC and XHC out of reset */ ++ val = readl_relaxed(ICFG_USB_CTRL_ADDR(icfg_usb_base)); ++ val &= ~(1 << ICFG_USB_CTRL__BDC_SOFT_RESET); ++ val &= ~(1 << ICFG_USB_CTRL__XHC_SOFT_RESET); ++ writel_relaxed(val, ICFG_USB_CTRL_ADDR(icfg_usb_base)); ++ ++ /* Get the DRD out of reset */ ++ val = readl_relaxed(ICFG_USB_CTRL_ADDR(icfg_usb_base)); ++ val &= ~(1 << ICFG_USB_CTRL__DRD_SOFT_RESET); ++ writel_relaxed(val, ICFG_USB_CTRL_ADDR(icfg_usb_base)); ++ ++ return 0; ++} ++ ++static int xgs_iproc_drd_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *dn = pdev->dev.of_node; ++ struct iproc_usb_priv *iproc_usb_data; ++ int ret; ++ ++ if (!of_device_is_available(dn)) { ++ return -ENODEV; ++ } ++ ++ iproc_usb_data = devm_kzalloc(dev, sizeof(*iproc_usb_data), GFP_KERNEL); ++ if (!iproc_usb_data) { ++ dev_err(dev, "devm_kzalloc() failed\n" ); ++ return -ENOMEM; ++ } ++ memset(iproc_usb_data, 0, sizeof(*iproc_usb_data)); ++ platform_set_drvdata(pdev, iproc_usb_data); ++ ++ iproc_usb_data->dev = dev; ++ ++ iproc_usb_data->wrap_base = get_iproc_wrap_ctrl_base(); ++ if (!iproc_usb_data->wrap_base) { ++ dev_err(&pdev->dev, "can't iomap usb phy base address\n"); ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ iproc_usb_data->icfg_usb_base = (void *)of_iomap(dn, 1); ++ if (!iproc_usb_data->icfg_usb_base) { ++ dev_err(&pdev->dev, "can't iomap icfg usb base address\n"); ++ ret = -ENOMEM; ++ goto err; ++ } ++ ++ iproc_usb_data->phy.dev = dev; ++ iproc_usb_data->phy.type = USB_PHY_TYPE_USB2; ++ iproc_usb_data->phy.init = iproc_usb_phy_init; ++ ++ iproc_usb_reset(iproc_usb_data); ++ iproc_usb_phy_init(&iproc_usb_data->phy); ++ ++ ret = usb_add_phy_dev(&iproc_usb_data->phy); ++ if (ret) { ++ dev_err(&pdev->dev, "failed to add the phy device\n"); ++ goto err; ++ } ++ ++ return 0; ++ ++err: ++ if (iproc_usb_data->icfg_usb_base) { ++ iounmap(iproc_usb_data->icfg_usb_base); ++ } ++ if (iproc_usb_data) { ++ iounmap(iproc_usb_data); ++ } ++ ++ return ret; ++} ++ ++static int xgs_iproc_drd_remove(struct platform_device *pdev) ++{ ++ struct iproc_usb_priv *iproc_usb_data = platform_get_drvdata(pdev); ++ ++ usb_remove_phy(&iproc_usb_data->phy); ++ ++ platform_set_drvdata(pdev, NULL); ++ if (iproc_usb_data->icfg_usb_base) { ++ iounmap(iproc_usb_data->icfg_usb_base); ++ } ++ ++ if (iproc_usb_data) { ++ iounmap(iproc_usb_data); ++ } ++ ++ return 0; ++} ++ ++static const struct of_device_id xgs_iproc_drd_dt_ids[] = { ++ { .compatible = "brcm,usb-phy,hx5", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, xgs_iproc_drd_dt_ids); ++ ++static struct platform_driver xgs_iproc_drd_driver = ++{ ++ .driver = { ++ .name = "usb-phy", ++ .owner = THIS_MODULE, ++ .of_match_table = of_match_ptr(xgs_iproc_drd_dt_ids), ++ }, ++ .probe = xgs_iproc_drd_probe, ++ .remove = xgs_iproc_drd_remove, ++}; ++ ++module_platform_driver(xgs_iproc_drd_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("Broadcom USB DRD controller driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/usb/phy/phy-xgs-iproc.c b/drivers/usb/phy/phy-xgs-iproc.c +--- a/drivers/usb/phy/phy-xgs-iproc.c 1970-01-01 08:00:00.000000000 +0800 ++++ b/drivers/usb/phy/phy-xgs-iproc.c 2018-05-10 11:31:33.837404222 +0800 +@@ -0,0 +1,701 @@ ++/* ++ * Copyright 2017 Broadcom Limited ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++ ++#define USB2_IDM_IO_CONTROL_DIRECT_ADDR(base) (base + 0x408) ++#define USB2_IDM_RESET_CONTROL_ADDR(base) (base + 0x800) ++#define IPROC_WRAP_MISC_STATUS__USBPHY_PLL_LOCK BIT(1) ++#define USB2_IDM_RESET_CONTROL__RESET BIT(0) ++#define USB2_IDM_IO_CONTROL_DIRECT__clk_enable BIT(0) ++ ++/* HX4 */ ++#define HX4_WRAP_XGPLL_CTRL_0_ADDR(base) (base + 0x1c) ++#define HX4_WRAP_XGPLL_CTRL_4_ADDR(base) (base + 0x2c) ++#define HX4_WRAP_USBPHY_CTRL_ADDR(base) (base + 0x34) ++#define HX4_WRAP_MISC_STATUS_ADDR(base) (base + 0x38) ++#define IPROC_CLK_NDIV_40 0x80 ++#define IPROC_CLK_NDIV_20 0x8C ++#define USB_CLK_NDIV_MASK 0xFE7FFE00 ++#define USB_CLK_PLL_RESET_MASK 0xFF7FFE00 ++#define USB_CLK_PHY_RESET_MASK 0xFFFFFE00 ++#define USB_CLK_NDIV_40 0x30 ++#define USB_CLK_NDIV_20 0x60 ++#define HX4_XGPLL_CTRL_4__NDIV_INT_R 0 ++#define HX4_XGPLL_CTRL_4__NDIV_INT_WIDTH 8 ++#define HX4_XGPLL_CTRL_0__CH3_MDIV_R 8 ++#define HX4_XGPLL_CTRL_0__CH3_MDIV_WIDTH 8 ++ ++/* KT2 */ ++#define KT2_PLL_CTRL_REG_3_ADDR(base) (base + 0x0c) ++#define KT2_PLL_CTRL_REG_5_ADDR(base) (base + 0x14) ++#define KT2_WRAP_USBPHY_CTRL_ADDR(base) (base + 0x20) ++#define KT2_WRAP_MISC_STATUS_ADDR(base) (base + 0x28) ++#define KT2_PLL_CTRL_REG_3__NDIV_INT_R 0 ++#define KT2_PLL_CTRL_REG_3__NDIV_INT_WIDTH 10 ++#define KT2_PLL_CTRL_REG_5__CH1_MDIV_R 0 ++#define KT2_PLL_CTRL_REG_5__CH1_MDIV_WIDTH 8 ++ ++/* SB2/GH/GH2/HR3 */ ++#define IPROC_WRAP_USBPHY_CTRL_0__PHY_IDDQ BIT(26) ++#define IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB BIT(25) ++#define IPROC_WRAP_USBPHY_CTRL_0__RESETB BIT(24) ++#define IPROC_WRAP_USBPHY_CTRL_2__PHY_ISO BIT(17) ++#define IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B0 BIT(0) ++#define IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B11 BIT(11) ++ ++/* SB2 */ ++#define SB2_WRAP_USBPHY_CTRL_0_ADDR(base) (base + 0x28) ++#define SB2_WRAP_USBPHY_CTRL_2_ADDR(base) (base + 0x30) ++#define SB2_WRAP_MISC_STATUS_ADDR(base) (base + 0x44) ++#define IPROC_WRAP_TOP_STRAP_CTRL_ADDR(base) (base + 0x70) ++#define IPROC_WRAP_TOP_STRAP_CTRL__USB_DEVICE BIT(10) ++ ++/* GH/GH2/HR3 */ ++#define GH_WRAP_USBPHY_CTRL_0_ADDR(base) (base + 0x44) ++#define GH_WRAP_USBPHY_CTRL_2_ADDR(base) (base + 0x4c) ++#define GH_WRAP_MISC_STATUS_ADDR(base) (base + 0x58) ++#define IPROC_WRAP_TOP_STRAP_STATUS_ADDR(base) (base + 0xa4) ++#define IPROC_WRAP_TOP_STRAP_STATUS__USB2_SEL BIT(17) ++ ++/* GH2 */ ++#define USBH_Utmi_p0Ctl(base) (base + 0x10) ++ ++ ++struct iproc_usb_priv { ++ struct usb_phy phy; ++ struct phy_device *mdio_phy; ++ void __iomem *wrap_base; ++ void __iomem *idm_base; ++ void __iomem *utmi_base; ++ int usb_mode; ++ int init_count; ++}; ++ ++extern void __iomem *get_iproc_wrap_ctrl_base(void); ++extern void xgs_phy_wr_reg(struct phy_device *phydev, u32 regnum, u16 data); ++extern u16 xgs_phy_rd_reg(struct phy_device *phydev, u32 regnum); ++extern void xgs_sb2_usb_phy_wr_reg(struct phy_device *phydev, u32 regnum, ++ u16 data); ++ ++/*************************************************************************** ++**************************************************************************** ++***************************************************************************/ ++ ++ ++/* check pll_lock */ ++static bool check_usbphy_pll_lock(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ void __iomem *wrap_addr = NULL; ++ struct device_node *dn = iproc_usb_data->phy.dev->of_node; ++ u32 val=0, mask; ++ u32 count = 0; ++ ++ if (of_device_is_compatible(dn, "brcm,usb-phy-hx4")) ++ wrap_addr = HX4_WRAP_MISC_STATUS_ADDR(wrap_base); ++ else if (of_device_is_compatible(dn, "brcm,usb-phy-kt2")) ++ wrap_addr = KT2_WRAP_MISC_STATUS_ADDR(wrap_base); ++ else if (of_device_is_compatible(dn, "brcm,usb-phy-sb2")) ++ wrap_addr = SB2_WRAP_MISC_STATUS_ADDR(wrap_base); ++ else if (of_device_is_compatible(dn, "brcm,usb-phy-gh") || ++ of_device_is_compatible(dn, "brcm,usb-phy-hr3") || ++ of_device_is_compatible(dn, "brcm,usb-phy-gh2")) ++ wrap_addr = GH_WRAP_MISC_STATUS_ADDR(wrap_base); ++ ++ if (!wrap_addr) { ++ dev_warn(iproc_usb_data->phy.dev, "No wrap addr specified\n"); ++ return 0; ++ } ++ ++ mask = IPROC_WRAP_MISC_STATUS__USBPHY_PLL_LOCK; ++ do { ++ val = readl(wrap_addr); ++ if ((val & mask) == mask) ++ break; ++ ++ udelay(10); ++ count ++; ++ } while(count <= 10); ++ ++ if (count <= 10) ++ return 1; ++ ++ dev_warn(iproc_usb_data->phy.dev, ++ "PLL not locked: IPROC_WRAP_MISC_STATUS = %x\n", val); ++ return 0; ++} ++ ++static int xgs_iproc_usb_phy_mode(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ struct device *dev = iproc_usb_data->phy.dev; ++ struct device_node *dn = dev->of_node; ++ int usb_mode = IPROC_USB_MODE_HOST; ++ u32 __maybe_unused val; ++ int __maybe_unused gpio_pin, ret; ++ ++ if (!wrap_base) ++ dev_warn(dev, "no wrap base addr"); ++ ++ if (of_device_is_compatible(dn, "brcm,usb-phy-hx4") || ++ of_device_is_compatible(dn, "brcm,usb-phy-kt2")) { ++ /* gpio pin 4 to control host/device mode */ ++ gpio_pin = of_get_named_gpio(dev->of_node, "usbdev-gpio", 0); ++ ++ if (gpio_pin < 0) { ++ /* default to 4 */ ++ dev_warn(dev, "No gpio pin set for USB device detection\n"); ++ gpio_pin = 4; ++ } ++ ++ ret = devm_gpio_request(dev, gpio_pin, "usbdev-gpio"); ++ if (ret) { ++ dev_warn(dev, "request gpio #%d fail\n", gpio_pin); ++ /* Use default host mode */ ++ return usb_mode; ++ } ++ ++ gpio_direction_input(gpio_pin); ++ val = gpio_get_value(gpio_pin); ++ if (val) ++ usb_mode = IPROC_USB_MODE_DEVICE; ++ ++ devm_gpio_free(dev, gpio_pin); ++ } else if (of_device_is_compatible(dn, "brcm,usb-phy-sb2")) { ++ /* u-boot enable this bit to indicate usb in host mode */ ++ val = readl(IPROC_WRAP_TOP_STRAP_CTRL_ADDR(wrap_base)); ++ if (!(val & IPROC_WRAP_TOP_STRAP_CTRL__USB_DEVICE)) ++ usb_mode = IPROC_USB_MODE_DEVICE; ++ } else if (of_device_is_compatible(dn, "brcm,usb-phy-gh") || ++ of_device_is_compatible(dn, "brcm,usb-phy-hr3") || ++ of_device_is_compatible(dn, "brcm,usb-phy-gh2")) { ++ /* u-boot enable this bit to indicate usb in host mode */ ++ val = readl(IPROC_WRAP_TOP_STRAP_STATUS_ADDR(wrap_base)); ++ if (!(val & IPROC_WRAP_TOP_STRAP_STATUS__USB2_SEL)) ++ usb_mode = IPROC_USB_MODE_DEVICE; ++ } ++ ++ dev_info(dev, "usb mode: %s\n", ++ usb_mode == IPROC_USB_MODE_DEVICE ? "DEVICE" : "HOST"); ++ ++ return usb_mode; ++} ++ ++/* Returns USB PHY PLL ref clock in MHz for HX4/KT2 */ ++static u32 _get_usb_clk(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ struct device_node *dn = iproc_usb_data->phy.dev->of_node; ++ u32 ndiv, mdiv, refclk; ++ u32 val; ++ ++ if (of_device_is_compatible(dn, "brcm,usb-phy-hx4")) { ++ val = readl(HX4_WRAP_XGPLL_CTRL_4_ADDR(wrap_base)); ++ ndiv = ((val >> HX4_XGPLL_CTRL_4__NDIV_INT_R) & ++ ~(0xFFFFFFFF << HX4_XGPLL_CTRL_4__NDIV_INT_WIDTH)); ++ ++ val = readl(HX4_WRAP_XGPLL_CTRL_0_ADDR(wrap_base)); ++ mdiv = ((val >> HX4_XGPLL_CTRL_0__CH3_MDIV_R) & ++ ~(0xFFFFFFFF << HX4_XGPLL_CTRL_0__CH3_MDIV_WIDTH)); ++ } else /*if (of_device_is_compatible(dn, "brcm,usb-phy-kt2"))*/ { ++ val = readl(KT2_PLL_CTRL_REG_3_ADDR(wrap_base)); ++ ndiv = ((val >> KT2_PLL_CTRL_REG_3__NDIV_INT_R) & ++ ~(0xFFFFFFFF << KT2_PLL_CTRL_REG_3__NDIV_INT_WIDTH)); ++ ++ /* read channel 1 mdiv */ ++ val = readl(KT2_PLL_CTRL_REG_5_ADDR(wrap_base)); ++ mdiv = ((val >> KT2_PLL_CTRL_REG_5__CH1_MDIV_R) & ++ ~(0xFFFFFFFF << KT2_PLL_CTRL_REG_5__CH1_MDIV_WIDTH)); ++ } ++ ++ refclk = (25 * ndiv) / mdiv; ++ ++ return refclk; ++} ++ ++static void hx4_clk_setup(void __iomem *wrap_base) ++{ ++ u32 val, ndiv; ++ void __iomem *wrap_addr = HX4_WRAP_USBPHY_CTRL_ADDR(wrap_base); ++ ++ val = readl(HX4_WRAP_XGPLL_CTRL_4_ADDR(wrap_base)); ++ ndiv = ((val >> HX4_XGPLL_CTRL_4__NDIV_INT_R) & ++ ~(0xFFFFFFFF << HX4_XGPLL_CTRL_4__NDIV_INT_WIDTH)); ++ ++ if (ndiv == IPROC_CLK_NDIV_40) { ++ val = readl(wrap_addr); ++ val = (val & USB_CLK_NDIV_MASK) | USB_CLK_NDIV_40; ++ writel(val, wrap_addr); ++ udelay(10); ++ val = (val & USB_CLK_PLL_RESET_MASK) | USB_CLK_NDIV_40; ++ writel(val, wrap_addr); ++ udelay(10); ++ val = (val & USB_CLK_PHY_RESET_MASK) | USB_CLK_NDIV_40; ++ writel(val, wrap_addr); ++ udelay(10); ++ } else if (ndiv == IPROC_CLK_NDIV_20) { ++ val = readl(wrap_addr); ++ val = (val & USB_CLK_NDIV_MASK) | USB_CLK_NDIV_20; ++ writel(val, wrap_addr); ++ udelay(10); ++ val = (val & USB_CLK_PLL_RESET_MASK) | USB_CLK_NDIV_20; ++ writel(val, wrap_addr); ++ udelay(10); ++ val = (val & USB_CLK_PHY_RESET_MASK) | USB_CLK_NDIV_20; ++ writel(val, wrap_addr); ++ udelay(10); ++ } ++} ++ ++static int iproc_usb_phy_hx4_config(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ void __iomem *wrap_addr = NULL; ++ struct device_node *dn = iproc_usb_data->phy.dev->of_node; ++ u32 ndiv, pdiv, miidata; ++ u32 val; ++ ++ if (!wrap_base) ++ return -EINVAL; ++ ++ if (iproc_usb_data->usb_mode == IPROC_USB_MODE_DEVICE) { ++ ndiv = 1920 / _get_usb_clk(iproc_usb_data); ++ pdiv = 1 << 12; ++ miidata = pdiv + ndiv; ++ ++ /* Program NDIV and PDIV into 0x1C register */ ++ xgs_phy_wr_reg(iproc_usb_data->mdio_phy, 0x800c, miidata); ++ mdelay(10); ++ ++ /* Program other PLL parameters into 0x1D register, disable suspend and ++ put PHY into reset */ ++ miidata = 1 << 13 | 3 << 8 | 3 << 4 | 0xa; ++ xgs_phy_wr_reg(iproc_usb_data->mdio_phy, 0x800d, miidata); ++ mdelay(10); ++ ++ /* Program register 0x15, USB device mode set and get PHY out ++ of reset */ ++ miidata = 1 << 2 | 1 << 1; ++ xgs_phy_wr_reg(iproc_usb_data->mdio_phy, 0x8005, miidata); ++ mdelay(10); ++ ++ /* Program register 0x19, set mdio mode */ ++ miidata = 1 << 7; ++ xgs_phy_wr_reg(iproc_usb_data->mdio_phy, 0x8009, miidata); ++ mdelay(10); ++ ++ /* get the PLL out of reset */ ++ miidata = xgs_phy_rd_reg(iproc_usb_data->mdio_phy, 0x800d); ++ miidata |= (1 << 12); ++ xgs_phy_wr_reg(iproc_usb_data->mdio_phy, 0x800d, miidata); ++ mdelay(10); ++ } else { ++ if (of_device_is_compatible(dn, "brcm,usb-phy-hx4")) ++ wrap_addr = HX4_WRAP_USBPHY_CTRL_ADDR(wrap_base); ++ else if (of_device_is_compatible(dn, "brcm,usb-phy-kt2")) ++ wrap_addr = KT2_WRAP_USBPHY_CTRL_ADDR(wrap_base); ++ ++ val = readl(wrap_addr); ++ /* PLL_RESETB = 1 */ ++ val |= BIT(24); ++ writel(val, wrap_addr); ++ ++ mdelay(10); ++ ++ /* check pll_lock */ ++ check_usbphy_pll_lock(iproc_usb_data); ++ ++ val = readl(wrap_addr); ++ /* RESETB = 0 */ ++ val &= ~BIT(23); ++ writel(val, wrap_addr); ++ mdelay(100); ++ ++ if (of_device_is_compatible(dn, "brcm,usb-phy-hx4")) ++ hx4_clk_setup(wrap_base); ++ ++ val = readl(wrap_addr); ++ /* RESETB = 1 */ ++ val |= BIT(23); ++ writel(val, wrap_addr); ++ mdelay(1); ++ } ++ ++ return 0; ++} ++ ++static int iproc_usb_phy_sb2_config(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ u32 val; ++ ++ if (!wrap_base) ++ return -EINVAL; ++ ++ val = readl(SB2_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= 0x0c000000; /* 27:PHY_ISO & 26:PLL_SUSPEND_EN = 1 */ ++ writel(val, SB2_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~0x03000000; /* 25:PLL_RESETB & 24:RESETB = 0 */ ++ writel(val, SB2_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ val = readl(SB2_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val &= ~0x03000000; /* 25:AFE_BG_PWRDWNB & 24:AFE_LDO_PWRDWNB = 0 */ ++ writel(val, SB2_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ udelay(10); ++ val |= 0x02000000; /* 25:AFE_BG_PWRDWNB = 1 */ ++ writel(val, SB2_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ udelay(150); ++ val |= 0x01000000; /* 24:AFE_LDO_PWRDWNB = 1 */ ++ writel(val, SB2_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ udelay(160); ++ ++ val = readl(SB2_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~0x08000000; /* 27:PHY_ISO = 0 */ ++ writel(val, SB2_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ udelay(20); ++ val |= 0x02000000; /* 25:PLL_RESETB = 1 */ ++ writel(val, SB2_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ mdelay(20); ++ ++ /* check pll_lock */ ++ check_usbphy_pll_lock(iproc_usb_data); ++ ++ val = readl(SB2_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= 0x01000000; /* 24:RESETB = 1 */ ++ writel(val, SB2_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ udelay(2); ++ ++ /* adjust tx amplitude */ ++ xgs_sb2_usb_phy_wr_reg(iproc_usb_data->mdio_phy, 0x80aa, 0xeea0); ++ ++ return 0; ++} ++ ++static int iproc_usb_phy_gh_config(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ u32 val; ++ ++ if (!wrap_base) ++ return -EINVAL; ++ ++ val = readl(GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val |= IPROC_WRAP_USBPHY_CTRL_2__PHY_ISO; ++ writel(val, GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ val = readl(GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= IPROC_WRAP_USBPHY_CTRL_0__PHY_IDDQ; ++ writel(val, GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ val = readl(GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val |= IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B0; ++ writel(val, GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ /* set phy_resetb to 0, pll_resetb to 0 */ ++ val = readl(GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~IPROC_WRAP_USBPHY_CTRL_0__RESETB; ++ writel(val, GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ val = readl(GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB; ++ writel(val, GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ /* set p1ctl[11] to 0 */ ++ val = readl(GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val &= ~IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B11; ++ writel(val, GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ /* set phy_iso to 0 */ ++ val = readl(GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val &= ~IPROC_WRAP_USBPHY_CTRL_2__PHY_ISO; ++ writel(val, GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ /* set phy_iddq to 0 */ ++ val = readl(GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val &= ~IPROC_WRAP_USBPHY_CTRL_0__PHY_IDDQ; ++ writel(val, GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ mdelay(1); ++ ++ /* set pll_resetb to 1, phy_resetb to 1 */ ++ val = readl(GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= IPROC_WRAP_USBPHY_CTRL_0__PLL_RESETB; ++ writel(val, GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ val = readl(GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ val |= IPROC_WRAP_USBPHY_CTRL_0__RESETB; ++ writel(val, GH_WRAP_USBPHY_CTRL_0_ADDR(wrap_base)); ++ ++ mdelay(20); ++ ++ /* check pll_lock */ ++ check_usbphy_pll_lock(iproc_usb_data); ++ ++ /* set non_drving to 0 */ ++ val = readl(GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val &= ~IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B0; ++ writel(val, GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ /* set p1ctl[11] to 1 */ ++ val = readl(GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ val |= IPROC_WRAP_USBPHY_CTRL_2__P1CTL_B11; ++ writel(val, GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ ++ return 0; ++} ++ ++static int iproc_usb_phy_gh2_config(struct iproc_usb_priv *iproc_usb_data) ++{ ++ void __iomem *wrap_base = iproc_usb_data->wrap_base; ++ void __iomem *utmi_base = NULL; ++ u32 val; ++ ++ if (!wrap_base) ++ return -EINVAL; ++ ++ /* This value is from DE team to set Internal Power Sequence Mode */ ++ val = readl(IPROC_WRAP_TOP_STRAP_STATUS_ADDR(wrap_base)); ++ if (val & IPROC_WRAP_TOP_STRAP_STATUS__USB2_SEL) { ++ /* host mode */ ++ utmi_base = iproc_usb_data->utmi_base; ++ if (!utmi_base) ++ return -EINVAL; ++ writel(0x0802, USBH_Utmi_p0Ctl(utmi_base)); ++ } else { ++ /* device mode */ ++ writel(0x0806, GH_WRAP_USBPHY_CTRL_2_ADDR(wrap_base)); ++ } ++ ++ mdelay(20); ++ ++ /* check pll_lock */ ++ check_usbphy_pll_lock(iproc_usb_data); ++ ++ return 0; ++} ++ ++static int iproc_usb_phy_init(struct usb_phy *phy) ++{ ++ struct iproc_usb_priv *iproc_usb_data = ++ container_of(phy, struct iproc_usb_priv, phy); ++ struct device *dev = phy->dev; ++ void __iomem *idm_base = iproc_usb_data->idm_base; ++ int ret = 0; ++ u32 val; ++ ++ if (iproc_usb_data->init_count) ++ return 0; ++ else ++ iproc_usb_data->init_count++; ++ ++ if (!iproc_usb_data->wrap_base || !iproc_usb_data->idm_base) ++ return -EINVAL; ++ ++ /* Put USB controller into reset state and disable clock */ ++ val = readl(USB2_IDM_RESET_CONTROL_ADDR(idm_base)); ++ val |= USB2_IDM_RESET_CONTROL__RESET; ++ writel(val, USB2_IDM_RESET_CONTROL_ADDR(idm_base)); ++ ++ val = readl(USB2_IDM_IO_CONTROL_DIRECT_ADDR(idm_base)); ++ val &= ~USB2_IDM_IO_CONTROL_DIRECT__clk_enable; ++ writel(val, USB2_IDM_IO_CONTROL_DIRECT_ADDR(idm_base)); ++ ++ if (of_device_is_compatible(dev->of_node, "brcm,usb-phy-hx4") || ++ of_device_is_compatible(dev->of_node, "brcm,usb-phy-kt2")) ++ ret = iproc_usb_phy_hx4_config(iproc_usb_data); ++ else if (of_device_is_compatible(dev->of_node, "brcm,usb-phy-sb2")) ++ ret = iproc_usb_phy_sb2_config(iproc_usb_data); ++ else if (of_device_is_compatible(dev->of_node, "brcm,usb-phy-gh") || ++ of_device_is_compatible(dev->of_node, "brcm,usb-phy-hr3")) ++ ret = iproc_usb_phy_gh_config(iproc_usb_data); ++ ++ /* Enable clock to USB and get the USB out of reset */ ++ val = readl(USB2_IDM_IO_CONTROL_DIRECT_ADDR(idm_base)); ++ val |= USB2_IDM_IO_CONTROL_DIRECT__clk_enable; ++ writel(val, USB2_IDM_IO_CONTROL_DIRECT_ADDR(idm_base)); ++ ++ mdelay(10); ++ val = readl(USB2_IDM_RESET_CONTROL_ADDR(idm_base)); ++ val &= ~USB2_IDM_RESET_CONTROL__RESET; ++ writel(val, USB2_IDM_RESET_CONTROL_ADDR(idm_base)); ++ mdelay(100); ++ ++ /* For GH2, PHY should be inited after RESET */ ++ if (of_device_is_compatible(dev->of_node, "brcm,usb-phy-gh2")) ++ ret = iproc_usb_phy_gh2_config(iproc_usb_data); ++ ++ return ret; ++} ++ ++static int xgs_iproc_usb_phy_probe(struct platform_device *pdev) ++{ ++ struct device *dev = &pdev->dev; ++ struct device_node *dn = pdev->dev.of_node; ++ struct device_node *mdio_phy_np = NULL; ++ struct iproc_usb_priv *iproc_usb_data; ++ struct resource *res; ++ int gpio_pin; ++ enum of_gpio_flags flags; ++ u32 gpio_active_low; ++ int ret, usb_mode; ++ ++ if (!of_device_is_available(dn)) ++ return -ENODEV; ++ ++ iproc_usb_data = devm_kzalloc(dev, sizeof(*iproc_usb_data), GFP_KERNEL); ++ if (!iproc_usb_data) ++ return -ENOMEM; ++ ++ platform_set_drvdata(pdev, iproc_usb_data); ++ ++ iproc_usb_data->wrap_base = get_iproc_wrap_ctrl_base(); ++ if (!iproc_usb_data->wrap_base) { ++ dev_err(dev, "No wrap_base addr in DT"); ++ return -ENXIO; ++ } ++ ++ gpio_pin = of_get_named_gpio_flags(dn, "vbus-gpio", 0, &flags); ++ if (gpio_pin < 0) { ++ dev_err(dev, "No gpio pin set for USB power\n"); ++ return gpio_pin; ++ } ++ ++ gpio_active_low = flags & OF_GPIO_ACTIVE_LOW; ++ ++ ret = devm_gpio_request(dev, gpio_pin, "usbphy-vbus"); ++ if (ret != 0) { ++ dev_err(dev, "Failed to request gpio #%d\n", gpio_pin); ++ return ret; ++ } ++ ++ iproc_usb_data->phy.dev = dev; ++ usb_mode = xgs_iproc_usb_phy_mode(iproc_usb_data); ++ ++ iproc_usb_data->usb_mode = usb_mode; ++ /* Save host/device mode in phy.flags for use by ECHI/OHCI drivers */ ++ iproc_usb_data->phy.flags = usb_mode; ++ iproc_usb_data->phy.init = iproc_usb_phy_init; ++ iproc_usb_data->phy.type = USB_PHY_TYPE_USB2; ++ ++ if (usb_mode == IPROC_USB_MODE_HOST) { ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); ++ iproc_usb_data->idm_base = ++ devm_ioremap_resource(dev, res); ++ if (IS_ERR(iproc_usb_data->idm_base)) { ++ dev_err(dev, "can't iomap usb2h idm base\n"); ++ return PTR_ERR(iproc_usb_data->idm_base); ++ } ++ ++ /* required for GH2 */ ++ if (of_device_is_compatible(dev->of_node, "brcm,usb-phy-gh2")) { ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 2); ++ iproc_usb_data->utmi_base = ++ devm_ioremap_resource(dev, res); ++ } ++ ++ gpio_direction_output(gpio_pin, 1); ++ /* turn off the power: if active low, then set 1 to turn off */ ++ if (gpio_active_low) ++ gpio_set_value(gpio_pin, 1); ++ else ++ gpio_set_value(gpio_pin, 0); ++ } else { ++ res = platform_get_resource(pdev, IORESOURCE_MEM, 1); ++ iproc_usb_data->idm_base = devm_ioremap_resource(dev, res); ++ if (IS_ERR(iproc_usb_data->idm_base)) { ++ dev_err(dev, "can't iomap usb2d idm base\n"); ++ return PTR_ERR(iproc_usb_data->idm_base); ++ } ++ } ++ ++ ++ /* PHY controlled through MDIO */ ++ mdio_phy_np = of_parse_phandle(dn, "mdio-phy-handle", 0); ++ if (mdio_phy_np) ++ iproc_usb_data->mdio_phy = of_phy_find_device(mdio_phy_np); ++ ++ ret = usb_add_phy_dev(&iproc_usb_data->phy); ++ if (ret) ++ return ret; ++ ++ /* supply power for USB device connected to the host */ ++ if (usb_mode == IPROC_USB_MODE_HOST) { ++ if (gpio_active_low) ++ gpio_set_value(gpio_pin, 0); ++ else ++ gpio_set_value(gpio_pin, 1); ++ } ++ ++ devm_gpio_free(dev, gpio_pin); ++ ++ return 0; ++} ++ ++static int xgs_iproc_usb_phy_remove(struct platform_device *pdev) ++{ ++ struct iproc_usb_priv *iproc_usb_data = platform_get_drvdata(pdev); ++ ++ if (iproc_usb_data) ++ usb_remove_phy(&iproc_usb_data->phy); ++ ++ platform_set_drvdata(pdev, NULL); ++ ++ return 0; ++} ++ ++static const struct of_device_id xgs_iproc_usb_phy_dt_ids[] = { ++ { .compatible = "brcm,usb-phy-hx4", }, ++ { .compatible = "brcm,usb-phy-kt2", }, ++ { .compatible = "brcm,usb-phy-gh", }, ++ { .compatible = "brcm,usb-phy-sb2", }, ++ { .compatible = "brcm,usb-phy-hr3", }, ++ { .compatible = "brcm,usb-phy-gh2", }, ++ { } ++}; ++MODULE_DEVICE_TABLE(of, xgs_iproc_usb_phy_dt_ids); ++ ++static struct platform_driver xgs_iproc_usb_phy_driver = ++{ ++ .driver = { ++ .name = "xgs-usb-phy", ++ .owner = THIS_MODULE, ++ .of_match_table = xgs_iproc_usb_phy_dt_ids, ++ }, ++ .probe = xgs_iproc_usb_phy_probe, ++ .remove = xgs_iproc_usb_phy_remove, ++}; ++ ++module_platform_driver(xgs_iproc_usb_phy_driver); ++ ++MODULE_AUTHOR("Broadcom"); ++MODULE_DESCRIPTION("Broadcom USB phy driver"); ++MODULE_LICENSE("GPL"); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c +--- a/drivers/watchdog/sp805_wdt.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/drivers/watchdog/sp805_wdt.c 2018-05-10 11:31:34.017404421 +0800 +@@ -27,6 +27,8 @@ + #include + #include + #include ++#include ++ + + /* default timeout in seconds */ + #define DEFAULT_TIMEOUT 60 +@@ -74,6 +76,24 @@ module_param(nowayout, bool, 0); + MODULE_PARM_DESC(nowayout, + "Set to 1 to keep watchdog running after device release"); + ++/* This routine get boot status to indicate if the last boot is from WDT */ ++static unsigned int wdt_get_clear_bootstatus( ++ void __iomem *wdt_bootstatus, ++ unsigned int wdt_bootstatus_bit) ++{ ++ unsigned int reg; ++ unsigned int bootstatus = 0; ++ ++ reg = readl_relaxed(wdt_bootstatus); ++ bootstatus = reg & (1 << wdt_bootstatus_bit); ++ ++ if (bootstatus) ++ /* write 1 to clear boot status bit */ ++ writel_relaxed(reg, wdt_bootstatus); ++ ++ return bootstatus; ++} ++ + /* This routine finds load value that will reset system in required timout */ + static int wdt_setload(struct watchdog_device *wdd, unsigned int timeout) + { +@@ -204,6 +224,8 @@ sp805_wdt_probe(struct amba_device *adev + { + struct sp805_wdt *wdt; + int ret = 0; ++ void __iomem *wdt_bootstatus = NULL; ++ unsigned int bootstatus_bit = 0; + + wdt = devm_kzalloc(&adev->dev, sizeof(*wdt), GFP_KERNEL); + if (!wdt) { +@@ -215,6 +237,13 @@ sp805_wdt_probe(struct amba_device *adev + if (IS_ERR(wdt->base)) + return PTR_ERR(wdt->base); + ++ wdt_bootstatus = of_iomap(adev->dev.of_node, 1); ++ if (!wdt_bootstatus) { ++ ret = -ENOMEM; ++ dev_warn(&adev->dev, "of_iomap failed\n"); ++ goto err; ++ } ++ + wdt->clk = devm_clk_get(&adev->dev, NULL); + if (IS_ERR(wdt->clk)) { + dev_warn(&adev->dev, "Clock not found\n"); +@@ -240,6 +269,9 @@ sp805_wdt_probe(struct amba_device *adev + } + amba_set_drvdata(adev, wdt); + ++ wdt->wdd.bootstatus = wdt_get_clear_bootstatus( ++ wdt_bootstatus, bootstatus_bit); ++ + dev_info(&adev->dev, "registration successful\n"); + return 0; + +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/include/linux/phy/xgs_iproc_serdes.h b/include/linux/phy/xgs_iproc_serdes.h +--- a/include/linux/phy/xgs_iproc_serdes.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/include/linux/phy/xgs_iproc_serdes.h 2018-05-10 11:31:34.757405249 +0800 +@@ -0,0 +1,27 @@ ++/* ++ * Copyright (C) 2017 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef _XGS_IPROC_SERDES_H_ ++#define _XGS_IPROC_SERDES_H_ ++ ++/* Specify the used lane number of SERDES */ ++typedef struct xgs_serdes_info_s { ++ u32 lane; ++} xgs_serdes_info_t; ++ ++extern bool xgs_serdes_hx4_amac(struct phy_device *); ++extern bool xgs_serdes_kt2_amac(struct phy_device *); ++extern void xgs_serdes_set_lane(struct phy_device *phy_dev, u32 lane); ++ ++#endif /* _XGS_IPROC_SERDES_H_ */ ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/include/linux/soc/bcm/iproc-cmic.h b/include/linux/soc/bcm/iproc-cmic.h +--- a/include/linux/soc/bcm/iproc-cmic.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/include/linux/soc/bcm/iproc-cmic.h 2018-05-10 11:31:34.797405294 +0800 +@@ -0,0 +1,34 @@ ++#ifndef _IPROC_CMIC_H ++#define _IPROC_CMIC_H ++ ++struct iproc_cmic { ++ void __iomem *base; ++ struct device *dev; ++ ++ const struct sbus_ops *sbus_ops; ++}; ++ ++struct sbus_ops { ++ int (*init)(struct iproc_cmic *cmic); ++ int (*reg32_write)(struct iproc_cmic *cmic, u32 block, u32 addr, u32 val); ++ u32 (*reg32_read)(struct iproc_cmic *cmic, u32 block, u32 addr); ++ int (*reg64_write)(struct iproc_cmic *cmic, u32 block, u32 addr, u64 val); ++ u64 (*reg64_read)(struct iproc_cmic *cmic, u32 block, u32 addr); ++ int (*ucmem_write)(struct iproc_cmic *cmic, u32 block, u32 *mem); ++ int (*ucmem_read)(struct iproc_cmic *cmic, u32 block, u32 *mem); ++}; ++ ++enum cmic_block_type { ++ CMIC_BLOCK_TYPE_TOP = 0, ++ CMIC_BLOCK_TYPE_APM = 1, ++}; ++ ++extern int iproc_cmic_schan_reg32_write(u32 blk_type, u32 addr, u32 val); ++extern u32 iproc_cmic_schan_reg32_read(u32 blk_type, u32 addr); ++extern int iproc_cmic_schan_reg64_write(u32 blk_type, u32 addr, u64 val); ++extern u64 iproc_cmic_schan_reg64_read(u32 blk_type, u32 addr); ++extern int iproc_cmic_schan_ucmem_write(u32 blk_type, u32 *mem); ++extern int iproc_cmic_schan_ucmem_read(u32 blk_type, u32 *mem); ++extern void inline __iomem *iproc_cmic_base_get(void); ++ ++#endif /* _IPROC_CMIC_H */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/include/linux/soc/bcm/xgs-iproc-idm.h b/include/linux/soc/bcm/xgs-iproc-idm.h +--- a/include/linux/soc/bcm/xgs-iproc-idm.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/include/linux/soc/bcm/xgs-iproc-idm.h 2018-05-10 11:31:34.797405294 +0800 +@@ -0,0 +1,21 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef XGS_IPROC_IDM_H ++#define XGS_IPROC_IDM_H ++ ++extern void inline __iomem *get_iproc_idm_base(int idx); ++extern int xgs_iproc_idm_dmac_reset(void); ++extern int xgs_iproc_idm_init(void); ++ ++#endif /* XGS_IPROC_IDM_H */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/include/linux/soc/bcm/xgs-iproc-misc-setup.h b/include/linux/soc/bcm/xgs-iproc-misc-setup.h +--- a/include/linux/soc/bcm/xgs-iproc-misc-setup.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/include/linux/soc/bcm/xgs-iproc-misc-setup.h 2018-05-10 11:31:34.797405294 +0800 +@@ -0,0 +1,22 @@ ++/* ++ * Copyright (C) 2016 Broadcom Corporation ++ * ++ * 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 version 2. ++ * ++ * This program is distributed "as is" WITHOUT ANY WARRANTY of any ++ * kind, whether express or implied; without even the implied warranty ++ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef XGS_IPROC_MISC_SETUP_H ++#define XGS_IPROC_MISC_SETUP_H ++ ++extern int xgs_iproc_misc_setup(void); ++extern void __iomem *get_iproc_wrap_ctrl_base(void); ++extern void __iomem *get_iproc_dmu_pcu_base(void); ++extern int is_wh2_amac_sgmii(void); ++ ++#endif /* XGS_IPROC_MISC_SETUP_H */ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/include/linux/usb/iproc_usb.h b/include/linux/usb/iproc_usb.h +--- a/include/linux/usb/iproc_usb.h 1970-01-01 08:00:00.000000000 +0800 ++++ b/include/linux/usb/iproc_usb.h 2018-05-10 11:31:34.817405317 +0800 +@@ -0,0 +1,23 @@ ++/* ++ * Copyright 2017 Broadcom Limited ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License version 2 as ++ * published by the Free Software Foundation. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ */ ++ ++#ifndef __LINUX_USB_IPROC_USB_H ++#define __LINUX_USB_IPROC_USB_H ++ ++/* USB Flags */ ++ ++#define IPROC_USB_MODE_HOST (0) ++#define IPROC_USB_MODE_DEVICE (1) ++ ++#endif /* __LINUX_USB_IPROC_USB_H */ ++ +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/acpidbg/Makefile b/tools/power/acpi/tools/acpidbg/Makefile +--- a/tools/power/acpi/tools/acpidbg/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/acpidbg/Makefile 1970-01-01 08:00:00.000000000 +0800 +@@ -1,25 +0,0 @@ +-# tools/power/acpi/tools/acpidbg/Makefile - ACPI tool Makefile +-# +-# Copyright (c) 2015, Intel Corporation +-# Author: Lv Zheng +-# +-# 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; version 2 +-# of the License. +- +-include ../../Makefile.config +- +-TOOL = acpidbg +-vpath %.c \ +- ../../../../../drivers/acpi/acpica\ +- ../../common\ +- ../../os_specific/service_layers\ +- . +-CFLAGS += -DACPI_APPLICATION -DACPI_SINGLE_THREAD -DACPI_DEBUGGER\ +- -I. +-LDFLAGS += -lpthread +-TOOL_OBJS = \ +- acpidbg.o +- +-include ../../Makefile.rules +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/acpidbg/acpidbg.c b/tools/power/acpi/tools/acpidbg/acpidbg.c +--- a/tools/power/acpi/tools/acpidbg/acpidbg.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/acpidbg/acpidbg.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,444 +0,0 @@ +-/* +- * ACPI AML interfacing userspace utility +- * +- * Copyright (C) 2015, Intel Corporation +- * Authors: Lv Zheng +- * +- * 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 +- +-/* Headers not included by include/acpi/platform/aclinux.h */ +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include "../../../../../include/linux/circ_buf.h" +- +-#define ACPI_AML_FILE "/sys/kernel/debug/acpi/acpidbg" +-#define ACPI_AML_SEC_TICK 1 +-#define ACPI_AML_USEC_PEEK 200 +-#define ACPI_AML_BUF_SIZE 4096 +- +-#define ACPI_AML_BATCH_WRITE_CMD 0x00 /* Write command to kernel */ +-#define ACPI_AML_BATCH_READ_LOG 0x01 /* Read log from kernel */ +-#define ACPI_AML_BATCH_WRITE_LOG 0x02 /* Write log to console */ +- +-#define ACPI_AML_LOG_START 0x00 +-#define ACPI_AML_PROMPT_START 0x01 +-#define ACPI_AML_PROMPT_STOP 0x02 +-#define ACPI_AML_LOG_STOP 0x03 +-#define ACPI_AML_PROMPT_ROLL 0x04 +- +-#define ACPI_AML_INTERACTIVE 0x00 +-#define ACPI_AML_BATCH 0x01 +- +-#define circ_count(circ) \ +- (CIRC_CNT((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE)) +-#define circ_count_to_end(circ) \ +- (CIRC_CNT_TO_END((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE)) +-#define circ_space(circ) \ +- (CIRC_SPACE((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE)) +-#define circ_space_to_end(circ) \ +- (CIRC_SPACE_TO_END((circ)->head, (circ)->tail, ACPI_AML_BUF_SIZE)) +- +-#define acpi_aml_cmd_count() circ_count(&acpi_aml_cmd_crc) +-#define acpi_aml_log_count() circ_count(&acpi_aml_log_crc) +-#define acpi_aml_cmd_space() circ_space(&acpi_aml_cmd_crc) +-#define acpi_aml_log_space() circ_space(&acpi_aml_log_crc) +- +-#define ACPI_AML_DO(_fd, _op, _buf, _ret) \ +- do { \ +- _ret = acpi_aml_##_op(_fd, &acpi_aml_##_buf##_crc); \ +- if (_ret == 0) { \ +- fprintf(stderr, \ +- "%s %s pipe closed.\n", #_buf, #_op); \ +- return; \ +- } \ +- } while (0) +-#define ACPI_AML_BATCH_DO(_fd, _op, _buf, _ret) \ +- do { \ +- _ret = acpi_aml_##_op##_batch_##_buf(_fd, \ +- &acpi_aml_##_buf##_crc); \ +- if (_ret == 0) \ +- return; \ +- } while (0) +- +- +-static char acpi_aml_cmd_buf[ACPI_AML_BUF_SIZE]; +-static char acpi_aml_log_buf[ACPI_AML_BUF_SIZE]; +-static struct circ_buf acpi_aml_cmd_crc = { +- .buf = acpi_aml_cmd_buf, +- .head = 0, +- .tail = 0, +-}; +-static struct circ_buf acpi_aml_log_crc = { +- .buf = acpi_aml_log_buf, +- .head = 0, +- .tail = 0, +-}; +-static const char *acpi_aml_file_path = ACPI_AML_FILE; +-static unsigned long acpi_aml_mode = ACPI_AML_INTERACTIVE; +-static bool acpi_aml_exit; +- +-static bool acpi_aml_batch_drain; +-static unsigned long acpi_aml_batch_state; +-static char acpi_aml_batch_prompt; +-static char acpi_aml_batch_roll; +-static unsigned long acpi_aml_log_state; +-static char *acpi_aml_batch_cmd = NULL; +-static char *acpi_aml_batch_pos = NULL; +- +-static int acpi_aml_set_fl(int fd, int flags) +-{ +- int ret; +- +- ret = fcntl(fd, F_GETFL, 0); +- if (ret < 0) { +- perror("fcntl(F_GETFL)"); +- return ret; +- } +- flags |= ret; +- ret = fcntl(fd, F_SETFL, flags); +- if (ret < 0) { +- perror("fcntl(F_SETFL)"); +- return ret; +- } +- return ret; +-} +- +-static int acpi_aml_set_fd(int fd, int maxfd, fd_set *set) +-{ +- if (fd > maxfd) +- maxfd = fd; +- FD_SET(fd, set); +- return maxfd; +-} +- +-static int acpi_aml_read(int fd, struct circ_buf *crc) +-{ +- char *p; +- int len; +- +- p = &crc->buf[crc->head]; +- len = circ_space_to_end(crc); +- len = read(fd, p, len); +- if (len < 0) +- perror("read"); +- else if (len > 0) +- crc->head = (crc->head + len) & (ACPI_AML_BUF_SIZE - 1); +- return len; +-} +- +-static int acpi_aml_read_batch_cmd(int unused, struct circ_buf *crc) +-{ +- char *p; +- int len; +- int remained = strlen(acpi_aml_batch_pos); +- +- p = &crc->buf[crc->head]; +- len = circ_space_to_end(crc); +- if (len > remained) { +- memcpy(p, acpi_aml_batch_pos, remained); +- acpi_aml_batch_pos += remained; +- len = remained; +- } else { +- memcpy(p, acpi_aml_batch_pos, len); +- acpi_aml_batch_pos += len; +- } +- if (len > 0) +- crc->head = (crc->head + len) & (ACPI_AML_BUF_SIZE - 1); +- return len; +-} +- +-static int acpi_aml_read_batch_log(int fd, struct circ_buf *crc) +-{ +- char *p; +- int len; +- int ret = 0; +- +- p = &crc->buf[crc->head]; +- len = circ_space_to_end(crc); +- while (ret < len && acpi_aml_log_state != ACPI_AML_LOG_STOP) { +- if (acpi_aml_log_state == ACPI_AML_PROMPT_ROLL) { +- *p = acpi_aml_batch_roll; +- len = 1; +- crc->head = (crc->head + 1) & (ACPI_AML_BUF_SIZE - 1); +- ret += 1; +- acpi_aml_log_state = ACPI_AML_LOG_START; +- } else { +- len = read(fd, p, 1); +- if (len <= 0) { +- if (len < 0) +- perror("read"); +- ret = len; +- break; +- } +- } +- switch (acpi_aml_log_state) { +- case ACPI_AML_LOG_START: +- if (*p == '\n') +- acpi_aml_log_state = ACPI_AML_PROMPT_START; +- crc->head = (crc->head + 1) & (ACPI_AML_BUF_SIZE - 1); +- ret += 1; +- break; +- case ACPI_AML_PROMPT_START: +- if (*p == ACPI_DEBUGGER_COMMAND_PROMPT || +- *p == ACPI_DEBUGGER_EXECUTE_PROMPT) { +- acpi_aml_batch_prompt = *p; +- acpi_aml_log_state = ACPI_AML_PROMPT_STOP; +- } else { +- if (*p != '\n') +- acpi_aml_log_state = ACPI_AML_LOG_START; +- crc->head = (crc->head + 1) & (ACPI_AML_BUF_SIZE - 1); +- ret += 1; +- } +- break; +- case ACPI_AML_PROMPT_STOP: +- if (*p == ' ') { +- acpi_aml_log_state = ACPI_AML_LOG_STOP; +- acpi_aml_exit = true; +- } else { +- /* Roll back */ +- acpi_aml_log_state = ACPI_AML_PROMPT_ROLL; +- acpi_aml_batch_roll = *p; +- *p = acpi_aml_batch_prompt; +- crc->head = (crc->head + 1) & (ACPI_AML_BUF_SIZE - 1); +- ret += 1; +- } +- break; +- default: +- assert(0); +- break; +- } +- } +- return ret; +-} +- +-static int acpi_aml_write(int fd, struct circ_buf *crc) +-{ +- char *p; +- int len; +- +- p = &crc->buf[crc->tail]; +- len = circ_count_to_end(crc); +- len = write(fd, p, len); +- if (len < 0) +- perror("write"); +- else if (len > 0) +- crc->tail = (crc->tail + len) & (ACPI_AML_BUF_SIZE - 1); +- return len; +-} +- +-static int acpi_aml_write_batch_log(int fd, struct circ_buf *crc) +-{ +- char *p; +- int len; +- +- p = &crc->buf[crc->tail]; +- len = circ_count_to_end(crc); +- if (!acpi_aml_batch_drain) { +- len = write(fd, p, len); +- if (len < 0) +- perror("write"); +- } +- if (len > 0) +- crc->tail = (crc->tail + len) & (ACPI_AML_BUF_SIZE - 1); +- return len; +-} +- +-static int acpi_aml_write_batch_cmd(int fd, struct circ_buf *crc) +-{ +- int len; +- +- len = acpi_aml_write(fd, crc); +- if (circ_count_to_end(crc) == 0) +- acpi_aml_batch_state = ACPI_AML_BATCH_READ_LOG; +- return len; +-} +- +-static void acpi_aml_loop(int fd) +-{ +- fd_set rfds; +- fd_set wfds; +- struct timeval tv; +- int ret; +- int maxfd = 0; +- +- if (acpi_aml_mode == ACPI_AML_BATCH) { +- acpi_aml_log_state = ACPI_AML_LOG_START; +- acpi_aml_batch_pos = acpi_aml_batch_cmd; +- if (acpi_aml_batch_drain) +- acpi_aml_batch_state = ACPI_AML_BATCH_READ_LOG; +- else +- acpi_aml_batch_state = ACPI_AML_BATCH_WRITE_CMD; +- } +- acpi_aml_exit = false; +- while (!acpi_aml_exit) { +- tv.tv_sec = ACPI_AML_SEC_TICK; +- tv.tv_usec = 0; +- FD_ZERO(&rfds); +- FD_ZERO(&wfds); +- +- if (acpi_aml_cmd_space()) { +- if (acpi_aml_mode == ACPI_AML_INTERACTIVE) +- maxfd = acpi_aml_set_fd(STDIN_FILENO, maxfd, &rfds); +- else if (strlen(acpi_aml_batch_pos) && +- acpi_aml_batch_state == ACPI_AML_BATCH_WRITE_CMD) +- ACPI_AML_BATCH_DO(STDIN_FILENO, read, cmd, ret); +- } +- if (acpi_aml_cmd_count() && +- (acpi_aml_mode == ACPI_AML_INTERACTIVE || +- acpi_aml_batch_state == ACPI_AML_BATCH_WRITE_CMD)) +- maxfd = acpi_aml_set_fd(fd, maxfd, &wfds); +- if (acpi_aml_log_space() && +- (acpi_aml_mode == ACPI_AML_INTERACTIVE || +- acpi_aml_batch_state == ACPI_AML_BATCH_READ_LOG)) +- maxfd = acpi_aml_set_fd(fd, maxfd, &rfds); +- if (acpi_aml_log_count()) +- maxfd = acpi_aml_set_fd(STDOUT_FILENO, maxfd, &wfds); +- +- ret = select(maxfd+1, &rfds, &wfds, NULL, &tv); +- if (ret < 0) { +- perror("select"); +- break; +- } +- if (ret > 0) { +- if (FD_ISSET(STDIN_FILENO, &rfds)) +- ACPI_AML_DO(STDIN_FILENO, read, cmd, ret); +- if (FD_ISSET(fd, &wfds)) { +- if (acpi_aml_mode == ACPI_AML_BATCH) +- ACPI_AML_BATCH_DO(fd, write, cmd, ret); +- else +- ACPI_AML_DO(fd, write, cmd, ret); +- } +- if (FD_ISSET(fd, &rfds)) { +- if (acpi_aml_mode == ACPI_AML_BATCH) +- ACPI_AML_BATCH_DO(fd, read, log, ret); +- else +- ACPI_AML_DO(fd, read, log, ret); +- } +- if (FD_ISSET(STDOUT_FILENO, &wfds)) { +- if (acpi_aml_mode == ACPI_AML_BATCH) +- ACPI_AML_BATCH_DO(STDOUT_FILENO, write, log, ret); +- else +- ACPI_AML_DO(STDOUT_FILENO, write, log, ret); +- } +- } +- } +-} +- +-static bool acpi_aml_readable(int fd) +-{ +- fd_set rfds; +- struct timeval tv; +- int ret; +- int maxfd = 0; +- +- tv.tv_sec = 0; +- tv.tv_usec = ACPI_AML_USEC_PEEK; +- FD_ZERO(&rfds); +- maxfd = acpi_aml_set_fd(fd, maxfd, &rfds); +- ret = select(maxfd+1, &rfds, NULL, NULL, &tv); +- if (ret < 0) +- perror("select"); +- if (ret > 0 && FD_ISSET(fd, &rfds)) +- return true; +- return false; +-} +- +-/* +- * This is a userspace IO flush implementation, replying on the prompt +- * characters and can be turned into a flush() call after kernel implements +- * .flush() filesystem operation. +- */ +-static void acpi_aml_flush(int fd) +-{ +- while (acpi_aml_readable(fd)) { +- acpi_aml_batch_drain = true; +- acpi_aml_loop(fd); +- acpi_aml_batch_drain = false; +- } +-} +- +-void usage(FILE *file, char *progname) +-{ +- fprintf(file, "usage: %s [-b cmd] [-f file] [-h]\n", progname); +- fprintf(file, "\nOptions:\n"); +- fprintf(file, " -b Specify command to be executed in batch mode\n"); +- fprintf(file, " -f Specify interface file other than"); +- fprintf(file, " /sys/kernel/debug/acpi/acpidbg\n"); +- fprintf(file, " -h Print this help message\n"); +-} +- +-int main(int argc, char **argv) +-{ +- int fd = -1; +- int ch; +- int len; +- int ret = EXIT_SUCCESS; +- +- while ((ch = getopt(argc, argv, "b:f:h")) != -1) { +- switch (ch) { +- case 'b': +- if (acpi_aml_batch_cmd) { +- fprintf(stderr, "Already specify %s\n", +- acpi_aml_batch_cmd); +- ret = EXIT_FAILURE; +- goto exit; +- } +- len = strlen(optarg); +- acpi_aml_batch_cmd = calloc(len + 2, 1); +- if (!acpi_aml_batch_cmd) { +- perror("calloc"); +- ret = EXIT_FAILURE; +- goto exit; +- } +- memcpy(acpi_aml_batch_cmd, optarg, len); +- acpi_aml_batch_cmd[len] = '\n'; +- acpi_aml_mode = ACPI_AML_BATCH; +- break; +- case 'f': +- acpi_aml_file_path = optarg; +- break; +- case 'h': +- usage(stdout, argv[0]); +- goto exit; +- break; +- case '?': +- default: +- usage(stderr, argv[0]); +- ret = EXIT_FAILURE; +- goto exit; +- break; +- } +- } +- +- fd = open(acpi_aml_file_path, O_RDWR | O_NONBLOCK); +- if (fd < 0) { +- perror("open"); +- ret = EXIT_FAILURE; +- goto exit; +- } +- acpi_aml_set_fl(STDIN_FILENO, O_NONBLOCK); +- acpi_aml_set_fl(STDOUT_FILENO, O_NONBLOCK); +- +- if (acpi_aml_mode == ACPI_AML_BATCH) +- acpi_aml_flush(fd); +- acpi_aml_loop(fd); +- +-exit: +- if (fd >= 0) +- close(fd); +- if (acpi_aml_batch_cmd) +- free(acpi_aml_batch_cmd); +- return ret; +-} +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/acpidump/Makefile b/tools/power/acpi/tools/acpidump/Makefile +--- a/tools/power/acpi/tools/acpidump/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/acpidump/Makefile 1970-01-01 08:00:00.000000000 +0800 +@@ -1,55 +0,0 @@ +-# tools/power/acpi/tools/acpidump/Makefile - ACPI tool Makefile +-# +-# Copyright (c) 2015, Intel Corporation +-# Author: Lv Zheng +-# +-# 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; version 2 +-# of the License. +- +-include ../../Makefile.config +- +-TOOL = acpidump +-EXTRA_INSTALL = install-man +-EXTRA_UNINSTALL = uninstall-man +- +-vpath %.c \ +- ../../../../../drivers/acpi/acpica\ +- ./\ +- ../../common\ +- ../../os_specific/service_layers +-CFLAGS += -DACPI_DUMP_APP -I. +-TOOL_OBJS = \ +- apdump.o\ +- apfiles.o\ +- apmain.o\ +- osunixdir.o\ +- osunixmap.o\ +- osunixxf.o\ +- tbprint.o\ +- tbxfroot.o\ +- utascii.o\ +- utbuffer.o\ +- utdebug.o\ +- utexcep.o\ +- utglobal.o\ +- uthex.o\ +- utmath.o\ +- utnonansi.o\ +- utprint.o\ +- utstring.o\ +- utstrtoul64.o\ +- utxferror.o\ +- oslinuxtbl.o\ +- cmfsize.o\ +- getopt.o +- +-include ../../Makefile.rules +- +-install-man: $(srctree)/man/acpidump.8 +- $(ECHO) " INST " acpidump.8 +- $(QUIET) $(INSTALL_DATA) -D $< $(DESTDIR)$(mandir)/man8/acpidump.8 +-uninstall-man: +- $(ECHO) " UNINST " acpidump.8 +- $(QUIET) rm -f $(DESTDIR)$(mandir)/man8/acpidump.8 +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/acpidump/acpidump.h b/tools/power/acpi/tools/acpidump/acpidump.h +--- a/tools/power/acpi/tools/acpidump/acpidump.h 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/acpidump/acpidump.h 1970-01-01 08:00:00.000000000 +0800 +@@ -1,119 +0,0 @@ +-/****************************************************************************** +- * +- * Module Name: acpidump.h - Include file for acpi_dump utility +- * +- *****************************************************************************/ +- +-/* +- * Copyright (C) 2000 - 2017, Intel Corp. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions, and the following disclaimer, +- * without modification. +- * 2. Redistributions in binary form must reproduce at minimum a disclaimer +- * substantially similar to the "NO WARRANTY" disclaimer below +- * ("Disclaimer") and any redistribution must be conditioned upon +- * including a substantially similar Disclaimer requirement for further +- * binary redistribution. +- * 3. Neither the names of the above-listed copyright holders nor the names +- * of any contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * Alternatively, this software may be distributed under the terms of the +- * GNU General Public License ("GPL") version 2 as published by the Free +- * Software Foundation. +- * +- * NO WARRANTY +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR +- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +- * POSSIBILITY OF SUCH DAMAGES. +- */ +- +-/* +- * Global variables. Defined in main.c only, externed in all other files +- */ +-#ifdef _DECLARE_GLOBALS +-#define EXTERN +-#define INIT_GLOBAL(a,b) a=b +-#else +-#define EXTERN extern +-#define INIT_GLOBAL(a,b) a +-#endif +- +-#include +-#include "accommon.h" +-#include "actables.h" +-#include "acapps.h" +- +-/* Globals */ +- +-EXTERN u8 INIT_GLOBAL(gbl_summary_mode, FALSE); +-EXTERN u8 INIT_GLOBAL(gbl_verbose_mode, FALSE); +-EXTERN u8 INIT_GLOBAL(gbl_binary_mode, FALSE); +-EXTERN u8 INIT_GLOBAL(gbl_dump_customized_tables, TRUE); +-EXTERN u8 INIT_GLOBAL(gbl_do_not_dump_xsdt, FALSE); +-EXTERN ACPI_FILE INIT_GLOBAL(gbl_output_file, NULL); +-EXTERN char INIT_GLOBAL(*gbl_output_filename, NULL); +-EXTERN u64 INIT_GLOBAL(gbl_rsdp_base, 0); +- +-/* Action table used to defer requested options */ +- +-struct ap_dump_action { +- char *argument; +- u32 to_be_done; +-}; +- +-#define AP_MAX_ACTIONS 32 +- +-#define AP_DUMP_ALL_TABLES 0 +-#define AP_DUMP_TABLE_BY_ADDRESS 1 +-#define AP_DUMP_TABLE_BY_NAME 2 +-#define AP_DUMP_TABLE_BY_FILE 3 +- +-#define AP_MAX_ACPI_FILES 256 /* Prevent infinite loops */ +- +-/* Minimum FADT sizes for various table addresses */ +- +-#define MIN_FADT_FOR_DSDT (ACPI_FADT_OFFSET (dsdt) + sizeof (u32)) +-#define MIN_FADT_FOR_FACS (ACPI_FADT_OFFSET (facs) + sizeof (u32)) +-#define MIN_FADT_FOR_XDSDT (ACPI_FADT_OFFSET (Xdsdt) + sizeof (u64)) +-#define MIN_FADT_FOR_XFACS (ACPI_FADT_OFFSET (Xfacs) + sizeof (u64)) +- +-/* +- * apdump - Table get/dump routines +- */ +-int ap_dump_table_from_file(char *pathname); +- +-int ap_dump_table_by_name(char *signature); +- +-int ap_dump_table_by_address(char *ascii_address); +- +-int ap_dump_all_tables(void); +- +-u8 ap_is_valid_header(struct acpi_table_header *table); +- +-u8 ap_is_valid_checksum(struct acpi_table_header *table); +- +-u32 ap_get_table_length(struct acpi_table_header *table); +- +-/* +- * apfiles - File I/O utilities +- */ +-int ap_open_output_file(char *pathname); +- +-int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance); +- +-struct acpi_table_header *ap_get_table_from_file(char *pathname, +- u32 *file_size); +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/acpidump/apdump.c b/tools/power/acpi/tools/acpidump/apdump.c +--- a/tools/power/acpi/tools/acpidump/apdump.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/acpidump/apdump.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,437 +0,0 @@ +-/****************************************************************************** +- * +- * Module Name: apdump - Dump routines for ACPI tables (acpidump) +- * +- *****************************************************************************/ +- +-/* +- * Copyright (C) 2000 - 2017, Intel Corp. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions, and the following disclaimer, +- * without modification. +- * 2. Redistributions in binary form must reproduce at minimum a disclaimer +- * substantially similar to the "NO WARRANTY" disclaimer below +- * ("Disclaimer") and any redistribution must be conditioned upon +- * including a substantially similar Disclaimer requirement for further +- * binary redistribution. +- * 3. Neither the names of the above-listed copyright holders nor the names +- * of any contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * Alternatively, this software may be distributed under the terms of the +- * GNU General Public License ("GPL") version 2 as published by the Free +- * Software Foundation. +- * +- * NO WARRANTY +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR +- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +- * POSSIBILITY OF SUCH DAMAGES. +- */ +- +-#include "acpidump.h" +- +-/* Local prototypes */ +- +-static int +-ap_dump_table_buffer(struct acpi_table_header *table, +- u32 instance, acpi_physical_address address); +- +-/****************************************************************************** +- * +- * FUNCTION: ap_is_valid_header +- * +- * PARAMETERS: table - Pointer to table to be validated +- * +- * RETURN: TRUE if the header appears to be valid. FALSE otherwise +- * +- * DESCRIPTION: Check for a valid ACPI table header +- * +- ******************************************************************************/ +- +-u8 ap_is_valid_header(struct acpi_table_header *table) +-{ +- +- if (!ACPI_VALIDATE_RSDP_SIG(table->signature)) { +- +- /* Make sure signature is all ASCII and a valid ACPI name */ +- +- if (!acpi_ut_valid_nameseg(table->signature)) { +- fprintf(stderr, +- "Table signature (0x%8.8X) is invalid\n", +- *(u32 *)table->signature); +- return (FALSE); +- } +- +- /* Check for minimum table length */ +- +- if (table->length < sizeof(struct acpi_table_header)) { +- fprintf(stderr, "Table length (0x%8.8X) is invalid\n", +- table->length); +- return (FALSE); +- } +- } +- +- return (TRUE); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_is_valid_checksum +- * +- * PARAMETERS: table - Pointer to table to be validated +- * +- * RETURN: TRUE if the checksum appears to be valid. FALSE otherwise. +- * +- * DESCRIPTION: Check for a valid ACPI table checksum. +- * +- ******************************************************************************/ +- +-u8 ap_is_valid_checksum(struct acpi_table_header *table) +-{ +- acpi_status status; +- struct acpi_table_rsdp *rsdp; +- +- if (ACPI_VALIDATE_RSDP_SIG(table->signature)) { +- /* +- * Checksum for RSDP. +- * Note: Other checksums are computed during the table dump. +- */ +- rsdp = ACPI_CAST_PTR(struct acpi_table_rsdp, table); +- status = acpi_tb_validate_rsdp(rsdp); +- } else { +- status = acpi_tb_verify_checksum(table, table->length); +- } +- +- if (ACPI_FAILURE(status)) { +- fprintf(stderr, "%4.4s: Warning: wrong checksum in table\n", +- table->signature); +- } +- +- return (AE_OK); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_get_table_length +- * +- * PARAMETERS: table - Pointer to the table +- * +- * RETURN: Table length +- * +- * DESCRIPTION: Obtain table length according to table signature. +- * +- ******************************************************************************/ +- +-u32 ap_get_table_length(struct acpi_table_header *table) +-{ +- struct acpi_table_rsdp *rsdp; +- +- /* Check if table is valid */ +- +- if (!ap_is_valid_header(table)) { +- return (0); +- } +- +- if (ACPI_VALIDATE_RSDP_SIG(table->signature)) { +- rsdp = ACPI_CAST_PTR(struct acpi_table_rsdp, table); +- return (acpi_tb_get_rsdp_length(rsdp)); +- } +- +- /* Normal ACPI table */ +- +- return (table->length); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_dump_table_buffer +- * +- * PARAMETERS: table - ACPI table to be dumped +- * instance - ACPI table instance no. to be dumped +- * address - Physical address of the table +- * +- * RETURN: None +- * +- * DESCRIPTION: Dump an ACPI table in standard ASCII hex format, with a +- * header that is compatible with the acpi_xtract utility. +- * +- ******************************************************************************/ +- +-static int +-ap_dump_table_buffer(struct acpi_table_header *table, +- u32 instance, acpi_physical_address address) +-{ +- u32 table_length; +- +- table_length = ap_get_table_length(table); +- +- /* Print only the header if requested */ +- +- if (gbl_summary_mode) { +- acpi_tb_print_table_header(address, table); +- return (0); +- } +- +- /* Dump to binary file if requested */ +- +- if (gbl_binary_mode) { +- return (ap_write_to_binary_file(table, instance)); +- } +- +- /* +- * Dump the table with header for use with acpixtract utility. +- * Note: simplest to just always emit a 64-bit address. acpi_xtract +- * utility can handle this. +- */ +- fprintf(gbl_output_file, "%4.4s @ 0x%8.8X%8.8X\n", +- table->signature, ACPI_FORMAT_UINT64(address)); +- +- acpi_ut_dump_buffer_to_file(gbl_output_file, +- ACPI_CAST_PTR(u8, table), table_length, +- DB_BYTE_DISPLAY, 0); +- fprintf(gbl_output_file, "\n"); +- return (0); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_dump_all_tables +- * +- * PARAMETERS: None +- * +- * RETURN: Status +- * +- * DESCRIPTION: Get all tables from the RSDT/XSDT (or at least all of the +- * tables that we can possibly get). +- * +- ******************************************************************************/ +- +-int ap_dump_all_tables(void) +-{ +- struct acpi_table_header *table; +- u32 instance = 0; +- acpi_physical_address address; +- acpi_status status; +- int table_status; +- u32 i; +- +- /* Get and dump all available ACPI tables */ +- +- for (i = 0; i < AP_MAX_ACPI_FILES; i++) { +- status = +- acpi_os_get_table_by_index(i, &table, &instance, &address); +- if (ACPI_FAILURE(status)) { +- +- /* AE_LIMIT means that no more tables are available */ +- +- if (status == AE_LIMIT) { +- return (0); +- } else if (i == 0) { +- fprintf(stderr, +- "Could not get ACPI tables, %s\n", +- acpi_format_exception(status)); +- return (-1); +- } else { +- fprintf(stderr, +- "Could not get ACPI table at index %u, %s\n", +- i, acpi_format_exception(status)); +- continue; +- } +- } +- +- table_status = ap_dump_table_buffer(table, instance, address); +- ACPI_FREE(table); +- +- if (table_status) { +- break; +- } +- } +- +- /* Something seriously bad happened if the loop terminates here */ +- +- return (-1); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_dump_table_by_address +- * +- * PARAMETERS: ascii_address - Address for requested ACPI table +- * +- * RETURN: Status +- * +- * DESCRIPTION: Get an ACPI table via a physical address and dump it. +- * +- ******************************************************************************/ +- +-int ap_dump_table_by_address(char *ascii_address) +-{ +- acpi_physical_address address; +- struct acpi_table_header *table; +- acpi_status status; +- int table_status; +- u64 long_address; +- +- /* Convert argument to an integer physical address */ +- +- status = acpi_ut_strtoul64(ascii_address, ACPI_STRTOUL_64BIT, +- &long_address); +- if (ACPI_FAILURE(status)) { +- fprintf(stderr, "%s: Could not convert to a physical address\n", +- ascii_address); +- return (-1); +- } +- +- address = (acpi_physical_address)long_address; +- status = acpi_os_get_table_by_address(address, &table); +- if (ACPI_FAILURE(status)) { +- fprintf(stderr, "Could not get table at 0x%8.8X%8.8X, %s\n", +- ACPI_FORMAT_UINT64(address), +- acpi_format_exception(status)); +- return (-1); +- } +- +- table_status = ap_dump_table_buffer(table, 0, address); +- ACPI_FREE(table); +- return (table_status); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_dump_table_by_name +- * +- * PARAMETERS: signature - Requested ACPI table signature +- * +- * RETURN: Status +- * +- * DESCRIPTION: Get an ACPI table via a signature and dump it. Handles +- * multiple tables with the same signature (SSDTs). +- * +- ******************************************************************************/ +- +-int ap_dump_table_by_name(char *signature) +-{ +- char local_signature[ACPI_NAME_SIZE + 1]; +- u32 instance; +- struct acpi_table_header *table; +- acpi_physical_address address; +- acpi_status status; +- int table_status; +- +- if (strlen(signature) != ACPI_NAME_SIZE) { +- fprintf(stderr, +- "Invalid table signature [%s]: must be exactly 4 characters\n", +- signature); +- return (-1); +- } +- +- /* Table signatures are expected to be uppercase */ +- +- strcpy(local_signature, signature); +- acpi_ut_strupr(local_signature); +- +- /* To be friendly, handle tables whose signatures do not match the name */ +- +- if (ACPI_COMPARE_NAME(local_signature, "FADT")) { +- strcpy(local_signature, ACPI_SIG_FADT); +- } else if (ACPI_COMPARE_NAME(local_signature, "MADT")) { +- strcpy(local_signature, ACPI_SIG_MADT); +- } +- +- /* Dump all instances of this signature (to handle multiple SSDTs) */ +- +- for (instance = 0; instance < AP_MAX_ACPI_FILES; instance++) { +- status = acpi_os_get_table_by_name(local_signature, instance, +- &table, &address); +- if (ACPI_FAILURE(status)) { +- +- /* AE_LIMIT means that no more tables are available */ +- +- if (status == AE_LIMIT) { +- return (0); +- } +- +- fprintf(stderr, +- "Could not get ACPI table with signature [%s], %s\n", +- local_signature, acpi_format_exception(status)); +- return (-1); +- } +- +- table_status = ap_dump_table_buffer(table, instance, address); +- ACPI_FREE(table); +- +- if (table_status) { +- break; +- } +- } +- +- /* Something seriously bad happened if the loop terminates here */ +- +- return (-1); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_dump_table_from_file +- * +- * PARAMETERS: pathname - File containing the binary ACPI table +- * +- * RETURN: Status +- * +- * DESCRIPTION: Dump an ACPI table from a binary file +- * +- ******************************************************************************/ +- +-int ap_dump_table_from_file(char *pathname) +-{ +- struct acpi_table_header *table; +- u32 file_size = 0; +- int table_status = -1; +- +- /* Get the entire ACPI table from the file */ +- +- table = ap_get_table_from_file(pathname, &file_size); +- if (!table) { +- return (-1); +- } +- +- if (!acpi_ut_valid_nameseg(table->signature)) { +- fprintf(stderr, +- "No valid ACPI signature was found in input file %s\n", +- pathname); +- } +- +- /* File must be at least as long as the table length */ +- +- if (table->length > file_size) { +- fprintf(stderr, +- "Table length (0x%X) is too large for input file (0x%X) %s\n", +- table->length, file_size, pathname); +- goto exit; +- } +- +- if (gbl_verbose_mode) { +- fprintf(stderr, +- "Input file: %s contains table [%4.4s], 0x%X (%u) bytes\n", +- pathname, table->signature, file_size, file_size); +- } +- +- table_status = ap_dump_table_buffer(table, 0, 0); +- +-exit: +- ACPI_FREE(table); +- return (table_status); +-} +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/acpidump/apfiles.c b/tools/power/acpi/tools/acpidump/apfiles.c +--- a/tools/power/acpi/tools/acpidump/apfiles.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/acpidump/apfiles.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,257 +0,0 @@ +-/****************************************************************************** +- * +- * Module Name: apfiles - File-related functions for acpidump utility +- * +- *****************************************************************************/ +- +-/* +- * Copyright (C) 2000 - 2017, Intel Corp. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions, and the following disclaimer, +- * without modification. +- * 2. Redistributions in binary form must reproduce at minimum a disclaimer +- * substantially similar to the "NO WARRANTY" disclaimer below +- * ("Disclaimer") and any redistribution must be conditioned upon +- * including a substantially similar Disclaimer requirement for further +- * binary redistribution. +- * 3. Neither the names of the above-listed copyright holders nor the names +- * of any contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * Alternatively, this software may be distributed under the terms of the +- * GNU General Public License ("GPL") version 2 as published by the Free +- * Software Foundation. +- * +- * NO WARRANTY +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR +- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +- * POSSIBILITY OF SUCH DAMAGES. +- */ +- +-#include "acpidump.h" +- +-/* Local prototypes */ +- +-static int ap_is_existing_file(char *pathname); +- +-/****************************************************************************** +- * +- * FUNCTION: ap_is_existing_file +- * +- * PARAMETERS: pathname - Output filename +- * +- * RETURN: 0 on success +- * +- * DESCRIPTION: Query for file overwrite if it already exists. +- * +- ******************************************************************************/ +- +-static int ap_is_existing_file(char *pathname) +-{ +-#if !defined(_GNU_EFI) && !defined(_EDK2_EFI) +- struct stat stat_info; +- +- if (!stat(pathname, &stat_info)) { +- fprintf(stderr, +- "Target path already exists, overwrite? [y|n] "); +- +- if (getchar() != 'y') { +- return (-1); +- } +- } +-#endif +- +- return 0; +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_open_output_file +- * +- * PARAMETERS: pathname - Output filename +- * +- * RETURN: Open file handle +- * +- * DESCRIPTION: Open a text output file for acpidump. Checks if file already +- * exists. +- * +- ******************************************************************************/ +- +-int ap_open_output_file(char *pathname) +-{ +- ACPI_FILE file; +- +- /* If file exists, prompt for overwrite */ +- +- if (ap_is_existing_file(pathname) != 0) { +- return (-1); +- } +- +- /* Point stdout to the file */ +- +- file = fopen(pathname, "w"); +- if (!file) { +- fprintf(stderr, "Could not open output file: %s\n", pathname); +- return (-1); +- } +- +- /* Save the file and path */ +- +- gbl_output_file = file; +- gbl_output_filename = pathname; +- return (0); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_write_to_binary_file +- * +- * PARAMETERS: table - ACPI table to be written +- * instance - ACPI table instance no. to be written +- * +- * RETURN: Status +- * +- * DESCRIPTION: Write an ACPI table to a binary file. Builds the output +- * filename from the table signature. +- * +- ******************************************************************************/ +- +-int ap_write_to_binary_file(struct acpi_table_header *table, u32 instance) +-{ +- char filename[ACPI_NAME_SIZE + 16]; +- char instance_str[16]; +- ACPI_FILE file; +- acpi_size actual; +- u32 table_length; +- +- /* Obtain table length */ +- +- table_length = ap_get_table_length(table); +- +- /* Construct lower-case filename from the table local signature */ +- +- if (ACPI_VALIDATE_RSDP_SIG(table->signature)) { +- ACPI_MOVE_NAME(filename, ACPI_RSDP_NAME); +- } else { +- ACPI_MOVE_NAME(filename, table->signature); +- } +- +- filename[0] = (char)tolower((int)filename[0]); +- filename[1] = (char)tolower((int)filename[1]); +- filename[2] = (char)tolower((int)filename[2]); +- filename[3] = (char)tolower((int)filename[3]); +- filename[ACPI_NAME_SIZE] = 0; +- +- /* Handle multiple SSDts - create different filenames for each */ +- +- if (instance > 0) { +- snprintf(instance_str, sizeof(instance_str), "%u", instance); +- strcat(filename, instance_str); +- } +- +- strcat(filename, FILE_SUFFIX_BINARY_TABLE); +- +- if (gbl_verbose_mode) { +- fprintf(stderr, +- "Writing [%4.4s] to binary file: %s 0x%X (%u) bytes\n", +- table->signature, filename, table->length, +- table->length); +- } +- +- /* Open the file and dump the entire table in binary mode */ +- +- file = fopen(filename, "wb"); +- if (!file) { +- fprintf(stderr, "Could not open output file: %s\n", filename); +- return (-1); +- } +- +- actual = fwrite(table, 1, table_length, file); +- if (actual != table_length) { +- fprintf(stderr, "Error writing binary output file: %s\n", +- filename); +- fclose(file); +- return (-1); +- } +- +- fclose(file); +- return (0); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_get_table_from_file +- * +- * PARAMETERS: pathname - File containing the binary ACPI table +- * out_file_size - Where the file size is returned +- * +- * RETURN: Buffer containing the ACPI table. NULL on error. +- * +- * DESCRIPTION: Open a file and read it entirely into a new buffer +- * +- ******************************************************************************/ +- +-struct acpi_table_header *ap_get_table_from_file(char *pathname, +- u32 *out_file_size) +-{ +- struct acpi_table_header *buffer = NULL; +- ACPI_FILE file; +- u32 file_size; +- acpi_size actual; +- +- /* Must use binary mode */ +- +- file = fopen(pathname, "rb"); +- if (!file) { +- fprintf(stderr, "Could not open input file: %s\n", pathname); +- return (NULL); +- } +- +- /* Need file size to allocate a buffer */ +- +- file_size = cm_get_file_size(file); +- if (file_size == ACPI_UINT32_MAX) { +- fprintf(stderr, +- "Could not get input file size: %s\n", pathname); +- goto cleanup; +- } +- +- /* Allocate a buffer for the entire file */ +- +- buffer = ACPI_ALLOCATE_ZEROED(file_size); +- if (!buffer) { +- fprintf(stderr, +- "Could not allocate file buffer of size: %u\n", +- file_size); +- goto cleanup; +- } +- +- /* Read the entire file */ +- +- actual = fread(buffer, 1, file_size, file); +- if (actual != file_size) { +- fprintf(stderr, "Could not read input file: %s\n", pathname); +- ACPI_FREE(buffer); +- buffer = NULL; +- goto cleanup; +- } +- +- *out_file_size = file_size; +- +-cleanup: +- fclose(file); +- return (buffer); +-} +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/acpidump/apmain.c b/tools/power/acpi/tools/acpidump/apmain.c +--- a/tools/power/acpi/tools/acpidump/apmain.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/acpidump/apmain.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,382 +0,0 @@ +-/****************************************************************************** +- * +- * Module Name: apmain - Main module for the acpidump utility +- * +- *****************************************************************************/ +- +-/* +- * Copyright (C) 2000 - 2017, Intel Corp. +- * All rights reserved. +- * +- * Redistribution and use in source and binary forms, with or without +- * modification, are permitted provided that the following conditions +- * are met: +- * 1. Redistributions of source code must retain the above copyright +- * notice, this list of conditions, and the following disclaimer, +- * without modification. +- * 2. Redistributions in binary form must reproduce at minimum a disclaimer +- * substantially similar to the "NO WARRANTY" disclaimer below +- * ("Disclaimer") and any redistribution must be conditioned upon +- * including a substantially similar Disclaimer requirement for further +- * binary redistribution. +- * 3. Neither the names of the above-listed copyright holders nor the names +- * of any contributors may be used to endorse or promote products derived +- * from this software without specific prior written permission. +- * +- * Alternatively, this software may be distributed under the terms of the +- * GNU General Public License ("GPL") version 2 as published by the Free +- * Software Foundation. +- * +- * NO WARRANTY +- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR +- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +- * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +- * POSSIBILITY OF SUCH DAMAGES. +- */ +- +-#define _DECLARE_GLOBALS +-#include "acpidump.h" +- +-/* +- * acpidump - A portable utility for obtaining system ACPI tables and dumping +- * them in an ASCII hex format suitable for binary extraction via acpixtract. +- * +- * Obtaining the system ACPI tables is an OS-specific operation. +- * +- * This utility can be ported to any host operating system by providing a +- * module containing system-specific versions of these interfaces: +- * +- * acpi_os_get_table_by_address +- * acpi_os_get_table_by_index +- * acpi_os_get_table_by_name +- * +- * See the ACPICA Reference Guide for the exact definitions of these +- * interfaces. Also, see these ACPICA source code modules for example +- * implementations: +- * +- * source/os_specific/service_layers/oswintbl.c +- * source/os_specific/service_layers/oslinuxtbl.c +- */ +- +-/* Local prototypes */ +- +-static void ap_display_usage(void); +- +-static int ap_do_options(int argc, char **argv); +- +-static int ap_insert_action(char *argument, u32 to_be_done); +- +-/* Table for deferred actions from command line options */ +- +-struct ap_dump_action action_table[AP_MAX_ACTIONS]; +-u32 current_action = 0; +- +-#define AP_UTILITY_NAME "ACPI Binary Table Dump Utility" +-#define AP_SUPPORTED_OPTIONS "?a:bc:f:hn:o:r:svxz" +- +-/****************************************************************************** +- * +- * FUNCTION: ap_display_usage +- * +- * DESCRIPTION: Usage message for the acpi_dump utility +- * +- ******************************************************************************/ +- +-static void ap_display_usage(void) +-{ +- +- ACPI_USAGE_HEADER("acpidump [options]"); +- +- ACPI_OPTION("-b", "Dump tables to binary files"); +- ACPI_OPTION("-h -?", "This help message"); +- ACPI_OPTION("-o ", "Redirect output to file"); +- ACPI_OPTION("-r
", "Dump tables from specified RSDP"); +- ACPI_OPTION("-s", "Print table summaries only"); +- ACPI_OPTION("-v", "Display version information"); +- ACPI_OPTION("-z", "Verbose mode"); +- +- ACPI_USAGE_TEXT("\nTable Options:\n"); +- +- ACPI_OPTION("-a
", "Get table via a physical address"); +- ACPI_OPTION("-c ", "Turning on/off customized table dumping"); +- ACPI_OPTION("-f ", "Get table via a binary file"); +- ACPI_OPTION("-n ", "Get table via a name/signature"); +- ACPI_OPTION("-x", "Do not use but dump XSDT"); +- ACPI_OPTION("-x -x", "Do not use or dump XSDT"); +- +- ACPI_USAGE_TEXT("\n" +- "Invocation without parameters dumps all available tables\n" +- "Multiple mixed instances of -a, -f, and -n are supported\n\n"); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_insert_action +- * +- * PARAMETERS: argument - Pointer to the argument for this action +- * to_be_done - What to do to process this action +- * +- * RETURN: Status +- * +- * DESCRIPTION: Add an action item to the action table +- * +- ******************************************************************************/ +- +-static int ap_insert_action(char *argument, u32 to_be_done) +-{ +- +- /* Insert action and check for table overflow */ +- +- action_table[current_action].argument = argument; +- action_table[current_action].to_be_done = to_be_done; +- +- current_action++; +- if (current_action > AP_MAX_ACTIONS) { +- fprintf(stderr, "Too many table options (max %u)\n", +- AP_MAX_ACTIONS); +- return (-1); +- } +- +- return (0); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: ap_do_options +- * +- * PARAMETERS: argc/argv - Standard argc/argv +- * +- * RETURN: Status +- * +- * DESCRIPTION: Command line option processing. The main actions for getting +- * and dumping tables are deferred via the action table. +- * +- *****************************************************************************/ +- +-static int ap_do_options(int argc, char **argv) +-{ +- int j; +- acpi_status status; +- +- /* Command line options */ +- +- while ((j = +- acpi_getopt(argc, argv, AP_SUPPORTED_OPTIONS)) != ACPI_OPT_END) +- switch (j) { +- /* +- * Global options +- */ +- case 'b': /* Dump all input tables to binary files */ +- +- gbl_binary_mode = TRUE; +- continue; +- +- case 'c': /* Dump customized tables */ +- +- if (!strcmp(acpi_gbl_optarg, "on")) { +- gbl_dump_customized_tables = TRUE; +- } else if (!strcmp(acpi_gbl_optarg, "off")) { +- gbl_dump_customized_tables = FALSE; +- } else { +- fprintf(stderr, +- "%s: Cannot handle this switch, please use on|off\n", +- acpi_gbl_optarg); +- return (-1); +- } +- continue; +- +- case 'h': +- case '?': +- +- ap_display_usage(); +- return (1); +- +- case 'o': /* Redirect output to a single file */ +- +- if (ap_open_output_file(acpi_gbl_optarg)) { +- return (-1); +- } +- continue; +- +- case 'r': /* Dump tables from specified RSDP */ +- +- status = +- acpi_ut_strtoul64(acpi_gbl_optarg, +- ACPI_STRTOUL_64BIT, +- &gbl_rsdp_base); +- if (ACPI_FAILURE(status)) { +- fprintf(stderr, +- "%s: Could not convert to a physical address\n", +- acpi_gbl_optarg); +- return (-1); +- } +- continue; +- +- case 's': /* Print table summaries only */ +- +- gbl_summary_mode = TRUE; +- continue; +- +- case 'x': /* Do not use XSDT */ +- +- if (!acpi_gbl_do_not_use_xsdt) { +- acpi_gbl_do_not_use_xsdt = TRUE; +- } else { +- gbl_do_not_dump_xsdt = TRUE; +- } +- continue; +- +- case 'v': /* Revision/version */ +- +- acpi_os_printf(ACPI_COMMON_SIGNON(AP_UTILITY_NAME)); +- return (1); +- +- case 'z': /* Verbose mode */ +- +- gbl_verbose_mode = TRUE; +- fprintf(stderr, ACPI_COMMON_SIGNON(AP_UTILITY_NAME)); +- continue; +- +- /* +- * Table options +- */ +- case 'a': /* Get table by physical address */ +- +- if (ap_insert_action +- (acpi_gbl_optarg, AP_DUMP_TABLE_BY_ADDRESS)) { +- return (-1); +- } +- break; +- +- case 'f': /* Get table from a file */ +- +- if (ap_insert_action +- (acpi_gbl_optarg, AP_DUMP_TABLE_BY_FILE)) { +- return (-1); +- } +- break; +- +- case 'n': /* Get table by input name (signature) */ +- +- if (ap_insert_action +- (acpi_gbl_optarg, AP_DUMP_TABLE_BY_NAME)) { +- return (-1); +- } +- break; +- +- default: +- +- ap_display_usage(); +- return (-1); +- } +- +- /* If there are no actions, this means "get/dump all tables" */ +- +- if (current_action == 0) { +- if (ap_insert_action(NULL, AP_DUMP_ALL_TABLES)) { +- return (-1); +- } +- } +- +- return (0); +-} +- +-/****************************************************************************** +- * +- * FUNCTION: main +- * +- * PARAMETERS: argc/argv - Standard argc/argv +- * +- * RETURN: Status +- * +- * DESCRIPTION: C main function for acpidump utility +- * +- ******************************************************************************/ +- +-#if !defined(_GNU_EFI) && !defined(_EDK2_EFI) +-int ACPI_SYSTEM_XFACE main(int argc, char *argv[]) +-#else +-int ACPI_SYSTEM_XFACE acpi_main(int argc, char *argv[]) +-#endif +-{ +- int status = 0; +- struct ap_dump_action *action; +- u32 file_size; +- u32 i; +- +- ACPI_DEBUG_INITIALIZE(); /* For debug version only */ +- acpi_os_initialize(); +- gbl_output_file = ACPI_FILE_OUT; +- acpi_gbl_integer_byte_width = 8; +- +- /* Process command line options */ +- +- status = ap_do_options(argc, argv); +- if (status > 0) { +- return (0); +- } +- if (status < 0) { +- return (status); +- } +- +- /* Get/dump ACPI table(s) as requested */ +- +- for (i = 0; i < current_action; i++) { +- action = &action_table[i]; +- switch (action->to_be_done) { +- case AP_DUMP_ALL_TABLES: +- +- status = ap_dump_all_tables(); +- break; +- +- case AP_DUMP_TABLE_BY_ADDRESS: +- +- status = ap_dump_table_by_address(action->argument); +- break; +- +- case AP_DUMP_TABLE_BY_NAME: +- +- status = ap_dump_table_by_name(action->argument); +- break; +- +- case AP_DUMP_TABLE_BY_FILE: +- +- status = ap_dump_table_from_file(action->argument); +- break; +- +- default: +- +- fprintf(stderr, +- "Internal error, invalid action: 0x%X\n", +- action->to_be_done); +- return (-1); +- } +- +- if (status) { +- return (status); +- } +- } +- +- if (gbl_output_filename) { +- if (gbl_verbose_mode) { +- +- /* Summary for the output file */ +- +- file_size = cm_get_file_size(gbl_output_file); +- fprintf(stderr, +- "Output file %s contains 0x%X (%u) bytes\n\n", +- gbl_output_filename, file_size, file_size); +- } +- +- fclose(gbl_output_file); +- } +- +- return (status); +-} +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/ec/Makefile b/tools/power/acpi/tools/ec/Makefile +--- a/tools/power/acpi/tools/ec/Makefile 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/ec/Makefile 1970-01-01 08:00:00.000000000 +0800 +@@ -1,17 +0,0 @@ +-# tools/power/acpi/tools/acpidump/Makefile - ACPI tool Makefile +-# +-# Copyright (c) 2015, Intel Corporation +-# Author: Lv Zheng +-# +-# 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; version 2 +-# of the License. +- +-include ../../Makefile.config +- +-TOOL = ec +-TOOL_OBJS = \ +- ec_access.o +- +-include ../../Makefile.rules +diff -uprN -EbwB --no-dereference -X /home/kevin/BRCM_DISK/disk1/xldksw/INTERNAL/release/tools/dontdiff a/tools/power/acpi/tools/ec/ec_access.c b/tools/power/acpi/tools/ec/ec_access.c +--- a/tools/power/acpi/tools/ec/ec_access.c 2017-11-13 02:46:13.000000000 +0800 ++++ b/tools/power/acpi/tools/ec/ec_access.c 1970-01-01 08:00:00.000000000 +0800 +@@ -1,238 +0,0 @@ +-/* +- * ec_access.c +- * +- * Copyright (C) 2010 SUSE Linux Products GmbH +- * Author: +- * Thomas Renninger +- * +- * This work is licensed under the terms of the GNU GPL, version 2. +- */ +- +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +- +- +-#define EC_SPACE_SIZE 256 +-#define SYSFS_PATH "/sys/kernel/debug/ec/ec0/io" +- +-/* TBD/Enhancements: +- - Provide param for accessing different ECs (not supported by kernel yet) +-*/ +- +-static int read_mode = -1; +-static int sleep_time; +-static int write_byte_offset = -1; +-static int read_byte_offset = -1; +-static uint8_t write_value = -1; +- +-void usage(char progname[], int exit_status) +-{ +- printf("Usage:\n"); +- printf("1) %s -r [-s sleep]\n", basename(progname)); +- printf("2) %s -b byte_offset\n", basename(progname)); +- printf("3) %s -w byte_offset -v value\n\n", basename(progname)); +- +- puts("\t-r [-s sleep] : Dump EC registers"); +- puts("\t If sleep is given, sleep x seconds,"); +- puts("\t re-read EC registers and show changes"); +- puts("\t-b offset : Read value at byte_offset (in hex)"); +- puts("\t-w offset -v value : Write value at byte_offset"); +- puts("\t-h : Print this help\n\n"); +- puts("Offsets and values are in hexadecimal number system."); +- puts("The offset and value must be between 0 and 0xff."); +- exit(exit_status); +-} +- +-void parse_opts(int argc, char *argv[]) +-{ +- int c; +- +- while ((c = getopt(argc, argv, "rs:b:w:v:h")) != -1) { +- +- switch (c) { +- case 'r': +- if (read_mode != -1) +- usage(argv[0], EXIT_FAILURE); +- read_mode = 1; +- break; +- case 's': +- if (read_mode != -1 && read_mode != 1) +- usage(argv[0], EXIT_FAILURE); +- +- sleep_time = atoi(optarg); +- if (sleep_time <= 0) { +- sleep_time = 0; +- usage(argv[0], EXIT_FAILURE); +- printf("Bad sleep time: %s\n", optarg); +- } +- break; +- case 'b': +- if (read_mode != -1) +- usage(argv[0], EXIT_FAILURE); +- read_mode = 1; +- read_byte_offset = strtoul(optarg, NULL, 16); +- break; +- case 'w': +- if (read_mode != -1) +- usage(argv[0], EXIT_FAILURE); +- read_mode = 0; +- write_byte_offset = strtoul(optarg, NULL, 16); +- break; +- case 'v': +- write_value = strtoul(optarg, NULL, 16); +- break; +- case 'h': +- usage(argv[0], EXIT_SUCCESS); +- default: +- fprintf(stderr, "Unknown option!\n"); +- usage(argv[0], EXIT_FAILURE); +- } +- } +- if (read_mode == 0) { +- if (write_byte_offset < 0 || +- write_byte_offset >= EC_SPACE_SIZE) { +- fprintf(stderr, "Wrong byte offset 0x%.2x, valid: " +- "[0-0x%.2x]\n", +- write_byte_offset, EC_SPACE_SIZE - 1); +- usage(argv[0], EXIT_FAILURE); +- } +- if (write_value < 0 || +- write_value >= 255) { +- fprintf(stderr, "Wrong byte offset 0x%.2x, valid:" +- "[0-0xff]\n", write_byte_offset); +- usage(argv[0], EXIT_FAILURE); +- } +- } +- if (read_mode == 1 && read_byte_offset != -1) { +- if (read_byte_offset < -1 || +- read_byte_offset >= EC_SPACE_SIZE) { +- fprintf(stderr, "Wrong byte offset 0x%.2x, valid: " +- "[0-0x%.2x]\n", +- read_byte_offset, EC_SPACE_SIZE - 1); +- usage(argv[0], EXIT_FAILURE); +- } +- } +- /* Add additional parameter checks here */ +-} +- +-void dump_ec(int fd) +-{ +- char buf[EC_SPACE_SIZE]; +- char buf2[EC_SPACE_SIZE]; +- int byte_off, bytes_read; +- +- bytes_read = read(fd, buf, EC_SPACE_SIZE); +- +- if (bytes_read == -1) +- err(EXIT_FAILURE, "Could not read from %s\n", SYSFS_PATH); +- +- if (bytes_read != EC_SPACE_SIZE) +- fprintf(stderr, "Could only read %d bytes\n", bytes_read); +- +- printf(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F"); +- for (byte_off = 0; byte_off < bytes_read; byte_off++) { +- if ((byte_off % 16) == 0) +- printf("\n%.2X: ", byte_off); +- printf(" %.2x ", (uint8_t)buf[byte_off]); +- } +- printf("\n"); +- +- if (!sleep_time) +- return; +- +- printf("\n"); +- lseek(fd, 0, SEEK_SET); +- sleep(sleep_time); +- +- bytes_read = read(fd, buf2, EC_SPACE_SIZE); +- +- if (bytes_read == -1) +- err(EXIT_FAILURE, "Could not read from %s\n", SYSFS_PATH); +- +- if (bytes_read != EC_SPACE_SIZE) +- fprintf(stderr, "Could only read %d bytes\n", bytes_read); +- +- printf(" 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F"); +- for (byte_off = 0; byte_off < bytes_read; byte_off++) { +- if ((byte_off % 16) == 0) +- printf("\n%.2X: ", byte_off); +- +- if (buf[byte_off] == buf2[byte_off]) +- printf(" %.2x ", (uint8_t)buf2[byte_off]); +- else +- printf("*%.2x ", (uint8_t)buf2[byte_off]); +- } +- printf("\n"); +-} +- +-void read_ec_val(int fd, int byte_offset) +-{ +- uint8_t buf; +- int error; +- +- error = lseek(fd, byte_offset, SEEK_SET); +- if (error != byte_offset) +- err(EXIT_FAILURE, "Cannot set offset to 0x%.2x", byte_offset); +- +- error = read(fd, &buf, 1); +- if (error != 1) +- err(EXIT_FAILURE, "Could not read byte 0x%.2x from %s\n", +- byte_offset, SYSFS_PATH); +- printf("0x%.2x\n", buf); +- return; +-} +- +-void write_ec_val(int fd, int byte_offset, uint8_t value) +-{ +- int error; +- +- error = lseek(fd, byte_offset, SEEK_SET); +- if (error != byte_offset) +- err(EXIT_FAILURE, "Cannot set offset to 0x%.2x", byte_offset); +- +- error = write(fd, &value, 1); +- if (error != 1) +- err(EXIT_FAILURE, "Cannot write value 0x%.2x to offset 0x%.2x", +- value, byte_offset); +-} +- +-int main(int argc, char *argv[]) +-{ +- int file_mode = O_RDONLY; +- int fd; +- +- parse_opts(argc, argv); +- +- if (read_mode == 0) +- file_mode = O_WRONLY; +- else if (read_mode == 1) +- file_mode = O_RDONLY; +- else +- usage(argv[0], EXIT_FAILURE); +- +- fd = open(SYSFS_PATH, file_mode); +- if (fd == -1) +- err(EXIT_FAILURE, "%s", SYSFS_PATH); +- +- if (read_mode) +- if (read_byte_offset == -1) +- dump_ec(fd); +- else if (read_byte_offset < 0 || +- read_byte_offset >= EC_SPACE_SIZE) +- usage(argv[0], EXIT_FAILURE); +- else +- read_ec_val(fd, read_byte_offset); +- else +- write_ec_val(fd, write_byte_offset, write_value); +- close(fd); +- +- exit(EXIT_SUCCESS); +-} diff --git a/packages/base/any/kernels/4.14-lts/patches/series b/packages/base/any/kernels/4.14-lts/patches/series index 3659add7..84d94c99 100644 --- a/packages/base/any/kernels/4.14-lts/patches/series +++ b/packages/base/any/kernels/4.14-lts/patches/series @@ -1,3 +1,3 @@ +brcm-iproc-4.14.patch 0001-drivers-i2c-muxes-pca954x-deselect-on-exit.patch 0002-driver-support-intel-igb-bcm5461S-phy.patch - diff --git a/packages/base/armel/kernels/kernel-4.14-lts-arm-iproc-all/Makefile b/packages/base/armel/kernels/kernel-4.14-lts-arm-iproc-all/Makefile new file mode 100644 index 00000000..003238cf --- /dev/null +++ b/packages/base/armel/kernels/kernel-4.14-lts-arm-iproc-all/Makefile @@ -0,0 +1 @@ +include $(ONL)/make/pkg.mk \ No newline at end of file diff --git a/packages/base/armel/kernels/kernel-4.14-lts-arm-iproc-all/PKG.yml b/packages/base/armel/kernels/kernel-4.14-lts-arm-iproc-all/PKG.yml new file mode 100644 index 00000000..544b2445 --- /dev/null +++ b/packages/base/armel/kernels/kernel-4.14-lts-arm-iproc-all/PKG.yml @@ -0,0 +1 @@ +!include $ONL/packages/base/any/kernels/lts/APKG.yml VERSION=4.14 ARCH=armel CONFIG=arm-iproc-all diff --git a/packages/base/armel/kernels/kernel-4.14-lts-arm-iproc-all/builds/.gitignore b/packages/base/armel/kernels/kernel-4.14-lts-arm-iproc-all/builds/.gitignore new file mode 100644 index 00000000..9a71a737 --- /dev/null +++ b/packages/base/armel/kernels/kernel-4.14-lts-arm-iproc-all/builds/.gitignore @@ -0,0 +1,3 @@ +linux-* +kernel-* +lib/ diff --git a/packages/base/armel/kernels/kernel-4.14-lts-arm-iproc-all/builds/Makefile b/packages/base/armel/kernels/kernel-4.14-lts-arm-iproc-all/builds/Makefile new file mode 100644 index 00000000..1199c91f --- /dev/null +++ b/packages/base/armel/kernels/kernel-4.14-lts-arm-iproc-all/builds/Makefile @@ -0,0 +1,6 @@ +KERNEL_BUILD_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) +KERNEL_ARCH := arm +KERNEL_LTS_VERSION := 4.14 +KERNEL_CONFIG := arm-iproc-all +#NO_MODULE_BUILDS := 1 +include $(ONL)/packages/base/any/kernels/lts/builds/Makefile