summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/configs/imx6_defconfig353
-rw-r--r--arch/arm/mach-mx6/Kconfig5
-rw-r--r--arch/arm/mach-mx6/Makefile1
-rw-r--r--arch/arm/mach-mx6/board-mx6dl_arm2.h316
-rw-r--r--arch/arm/mach-mx6/board-mx6q_arm2.c1335
-rw-r--r--arch/arm/mach-mx6/board-mx6q_arm2.h317
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabreauto.c31
-rw-r--r--arch/arm/mach-mx6/board-mx6q_sabresd.c2
-rw-r--r--arch/arm/mach-mx6/clock.c99
-rw-r--r--arch/arm/mach-mx6/cpu_op-mx6.c82
-rw-r--r--arch/arm/mach-mx6/crm_regs.h4
-rw-r--r--arch/arm/mach-mx6/devices-imx6q.h12
-rw-r--r--arch/arm/mach-mx6/mm.c16
-rw-r--r--arch/arm/mach-mx6/pcie.c484
-rw-r--r--arch/arm/mach-mx6/system.c7
-rw-r--r--arch/arm/mach-mx6/usb_dr.c14
-rw-r--r--arch/arm/mach-mx6/usb_h2.c34
-rw-r--r--arch/arm/mach-mx6/usb_h3.c34
-rw-r--r--arch/arm/plat-mxc/audmux-v2.c2
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-imx-dma.c2
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-gpmi-nfc.c20
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-perfmon.c12
-rw-r--r--arch/arm/plat-mxc/devices/platform-imx-pxp.c11
-rwxr-xr-xarch/arm/plat-mxc/devices/platform-imx_vpu.c5
-rw-r--r--arch/arm/plat-mxc/devices/platform-viv_gpu.c12
-rwxr-xr-xarch/arm/plat-mxc/dvfs_core.c10
-rwxr-xr-xarch/arm/plat-mxc/gpio.c3
-rwxr-xr-xarch/arm/plat-mxc/include/mach/arc_otg.h4
-rwxr-xr-xarch/arm/plat-mxc/include/mach/common.h1
-rwxr-xr-xarch/arm/plat-mxc/include/mach/devices-common.h6
-rw-r--r--arch/arm/plat-mxc/include/mach/dma.h5
-rwxr-xr-xarch/arm/plat-mxc/include/mach/fsl_usb.h4
-rwxr-xr-xarch/arm/plat-mxc/include/mach/hardware.h7
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx6dl.h3797
-rw-r--r--arch/arm/plat-mxc/include/mach/iomux-mx6q.h2
-rw-r--r--arch/arm/plat-mxc/include/mach/mx6.h619
-rwxr-xr-xarch/arm/plat-mxc/include/mach/mxc.h19
-rwxr-xr-xarch/arm/plat-mxc/include/mach/mxc_edid.h27
-rw-r--r--arch/arm/plat-mxc/include/mach/regs-usbphy-mx6.h3
-rwxr-xr-xarch/arm/plat-mxc/include/mach/system.h3
-rwxr-xr-xarch/arm/plat-mxc/usb_common.c8
-rw-r--r--drivers/dma/Kconfig8
-rw-r--r--drivers/dma/Makefile2
-rw-r--r--drivers/dma/mxs-dma.c36
-rw-r--r--drivers/dma/pxp/Makefile1
-rw-r--r--drivers/dma/pxp/pxp_device.c16
-rw-r--r--drivers/dma/pxp/pxp_dma_v2.c1633
-rw-r--r--drivers/dma/pxp/regs-pxp_v2.h1152
-rw-r--r--drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c6
-rw-r--r--drivers/media/video/mxc/capture/ipu_prp_vf_sdc_bg.c6
-rw-r--r--drivers/media/video/mxc/capture/mxc_v4l2_capture.c97
-rw-r--r--drivers/media/video/mxc/capture/mxc_v4l2_capture.h27
-rw-r--r--drivers/media/video/mxc/capture/ov3640.c41
-rw-r--r--drivers/media/video/mxc/capture/ov5640.c43
-rw-r--r--drivers/media/video/mxc/capture/ov5640_mipi.c39
-rw-r--r--drivers/media/video/mxc/capture/ov5642.c43
-rw-r--r--drivers/media/video/mxc/capture/sensor_clock.c2
-rw-r--r--drivers/mfd/mxc-hdmi-core.c42
-rw-r--r--drivers/misc/mxs-perfmon.c6
-rw-r--r--drivers/mmc/card/block.c4
-rw-r--r--drivers/mmc/core/bus.c13
-rw-r--r--drivers/mmc/core/mmc_ops.c1
-rw-r--r--drivers/mmc/core/sd.c13
-rw-r--r--drivers/mmc/host/sdhci-esdhc-imx.c254
-rw-r--r--drivers/mmc/host/sdhci-esdhc.h4
-rw-r--r--drivers/mtd/nand/Kconfig2
-rw-r--r--drivers/mtd/nand/gpmi-nand/bch-regs.h44
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-lib.c40
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.c7
-rw-r--r--drivers/mtd/nand/gpmi-nand/gpmi-nand.h6
-rw-r--r--drivers/mxc/asrc/mxc_asrc.c50
-rw-r--r--drivers/mxc/ipu3/ipu_common.c6
-rw-r--r--drivers/mxc/vpu/mxc_vpu.c12
-rwxr-xr-xdrivers/net/fec.c30
-rw-r--r--drivers/net/fec_1588.c30
-rw-r--r--drivers/net/fec_1588.h12
-rw-r--r--drivers/net/wireless/ath/Kconfig1
-rw-r--r--drivers/net/wireless/ath/Makefile1
-rw-r--r--drivers/net/wireless/ath/ath6kl/Kconfig17
-rw-r--r--drivers/net/wireless/ath/ath6kl/Makefile35
-rw-r--r--drivers/net/wireless/ath/ath6kl/bmi.c692
-rw-r--r--drivers/net/wireless/ath/ath6kl/bmi.h250
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.c1538
-rw-r--r--drivers/net/wireless/ath/ath6kl/cfg80211.h39
-rw-r--r--drivers/net/wireless/ath/ath6kl/common.h183
-rw-r--r--drivers/net/wireless/ath/ath6kl/core.h546
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.c150
-rw-r--r--drivers/net/wireless/ath/ath6kl/debug.h104
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif-ops.h67
-rw-r--r--drivers/net/wireless/ath/ath6kl/hif.h216
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc.c2466
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc.h596
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_hif.c811
-rw-r--r--drivers/net/wireless/ath/ath6kl/htc_hif.h113
-rw-r--r--drivers/net/wireless/ath/ath6kl/init.c1293
-rw-r--r--drivers/net/wireless/ath/ath6kl/main.c1337
-rw-r--r--drivers/net/wireless/ath/ath6kl/node.c238
-rw-r--r--drivers/net/wireless/ath/ath6kl/sdio.c853
-rw-r--r--drivers/net/wireless/ath/ath6kl/target.h331
-rw-r--r--drivers/net/wireless/ath/ath6kl/txrx.c1452
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.c2762
-rw-r--r--drivers/net/wireless/ath/ath6kl/wmi.h2024
-rw-r--r--drivers/pci/Kconfig2
-rwxr-xr-xdrivers/usb/gadget/arcotg_udc.c31
-rwxr-xr-xdrivers/usb/host/ehci-arc.c19
-rw-r--r--drivers/video/mxc/ldb.c8
-rw-r--r--drivers/video/mxc/mipi_dsi.c7
-rw-r--r--drivers/video/mxc/mxc_edid.c38
-rw-r--r--drivers/video/mxc/mxc_ipuv3_fb.c9
-rw-r--r--drivers/video/mxc/mxcfb_hx8369_wvga.c7
-rw-r--r--drivers/video/mxc_hdmi.c33
-rw-r--r--include/linux/fsl_devices.h2
-rw-r--r--include/linux/ieee80211.h37
-rw-r--r--include/linux/mfd/mxc-hdmi-core.h7
-rw-r--r--include/linux/mmc/card.h2
-rw-r--r--include/linux/mtd/gpmi-nand.h4
-rw-r--r--include/linux/mxc_v4l2.h5
-rw-r--r--include/linux/mxs-dma.h (renamed from arch/arm/mach-mxs/include/mach/dma.h)2
-rw-r--r--include/linux/pxp_dma.h3
-rw-r--r--sound/soc/codecs/cs42888.c4
-rw-r--r--sound/soc/codecs/mxc_hdmi.c143
-rw-r--r--sound/soc/imx/Makefile1
-rw-r--r--sound/soc/imx/imx-cs42888.c10
-rw-r--r--sound/soc/imx/imx-hdmi-dma.c14
-rw-r--r--sound/soc/imx/imx-hdmi.h10
125 files changed, 28357 insertions, 1612 deletions
diff --git a/arch/arm/configs/imx6_defconfig b/arch/arm/configs/imx6_defconfig
index a4b1783be239..8f00d362cc15 100644
--- a/arch/arm/configs/imx6_defconfig
+++ b/arch/arm/configs/imx6_defconfig
@@ -1,7 +1,6 @@
#
# Automatically generated make config: don't edit
-# Linux/arm 2.6.38 Kernel Configuration
-# Tue Jan 17 18:55:30 2012
+# Linux/arm 3.0.15 Kernel Configuration
#
CONFIG_ARM=y
CONFIG_HAVE_PWM=y
@@ -11,6 +10,7 @@ CONFIG_GENERIC_GPIO=y
# CONFIG_ARCH_USES_GETTIMEOFFSET is not set
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_GENERIC_CLOCKEVENTS_BROADCAST=y
+CONFIG_KTIME_SCALAR=y
CONFIG_HAVE_PROC_CPU=y
CONFIG_STACKTRACE_SUPPORT=y
CONFIG_LOCKDEP_SUPPORT=y
@@ -29,7 +29,6 @@ CONFIG_FIQ=y
CONFIG_VECTORS_BASE=0xffff0000
# CONFIG_ARM_PATCH_PHYS_VIRT is not set
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
-CONFIG_CONSTRUCTORS=y
CONFIG_HAVE_IRQ_WORK=y
CONFIG_IRQ_WORK=y
@@ -37,7 +36,6 @@ CONFIG_IRQ_WORK=y
# General setup
#
CONFIG_EXPERIMENTAL=y
-CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_CROSS_COMPILE=""
CONFIG_LOCALVERSION=""
@@ -48,11 +46,13 @@ CONFIG_HAVE_KERNEL_LZO=y
CONFIG_KERNEL_GZIP=y
# CONFIG_KERNEL_LZMA is not set
# CONFIG_KERNEL_LZO is not set
+CONFIG_DEFAULT_HOSTNAME="(none)"
CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_FHANDLE is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
CONFIG_HAVE_GENERIC_HARDIRQS=y
@@ -61,11 +61,8 @@ CONFIG_HAVE_GENERIC_HARDIRQS=y
# IRQ subsystem
#
CONFIG_GENERIC_HARDIRQS=y
-# CONFIG_GENERIC_HARDIRQS_NO_DEPRECATED is not set
CONFIG_HAVE_SPARSE_IRQ=y
-# CONFIG_GENERIC_PENDING_IRQ is not set
-# CONFIG_AUTO_IRQ_AFFINITY is not set
-# CONFIG_IRQ_PER_CPU is not set
+CONFIG_GENERIC_IRQ_SHOW=y
# CONFIG_SPARSE_IRQ is not set
#
@@ -77,6 +74,7 @@ CONFIG_PREEMPT_RCU=y
CONFIG_RCU_FANOUT=32
# CONFIG_RCU_FANOUT_EXACT is not set
# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_RCU_BOOST is not set
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
@@ -90,11 +88,9 @@ CONFIG_LOG_BUF_SHIFT=14
CONFIG_SYSCTL=y
CONFIG_ANON_INODES=y
CONFIG_EXPERT=y
-CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_KALLSYMS=y
-# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -107,6 +103,7 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_AIO=y
+CONFIG_EMBEDDED=y
CONFIG_HAVE_PERF_EVENTS=y
CONFIG_PERF_USE_VMALLOC=y
@@ -197,7 +194,6 @@ CONFIG_FREEZER=y
# System Type
#
CONFIG_MMU=y
-# CONFIG_ARCH_AAEC2000 is not set
# CONFIG_ARCH_INTEGRATOR is not set
# CONFIG_ARCH_REALVIEW is not set
# CONFIG_ARCH_VERSATILE is not set
@@ -212,7 +208,6 @@ CONFIG_MMU=y
# CONFIG_ARCH_FOOTBRIDGE is not set
CONFIG_ARCH_MXC=y
# CONFIG_ARCH_MXS is not set
-# CONFIG_ARCH_STMP3XXX is not set
# CONFIG_ARCH_NETX is not set
# CONFIG_ARCH_H720X is not set
# CONFIG_ARCH_IOP13XX is not set
@@ -229,7 +224,6 @@ CONFIG_ARCH_MXC=y
# CONFIG_ARCH_ORION5X is not set
# CONFIG_ARCH_MMP is not set
# CONFIG_ARCH_KS8695 is not set
-# CONFIG_ARCH_NS9XXX is not set
# CONFIG_ARCH_W90X900 is not set
# CONFIG_ARCH_NUC93X is not set
# CONFIG_ARCH_TEGRA is not set
@@ -242,19 +236,18 @@ CONFIG_ARCH_MXC=y
# CONFIG_ARCH_S3C2410 is not set
# CONFIG_ARCH_S3C64XX is not set
# CONFIG_ARCH_S5P64X0 is not set
-# CONFIG_ARCH_S5P6442 is not set
# CONFIG_ARCH_S5PC100 is not set
# CONFIG_ARCH_S5PV210 is not set
-# CONFIG_ARCH_S5PV310 is not set
+# CONFIG_ARCH_EXYNOS4 is not set
# CONFIG_ARCH_SHARK is not set
# CONFIG_ARCH_TCC_926 is not set
-# CONFIG_ARCH_LH7A40X is not set
# CONFIG_ARCH_U300 is not set
# CONFIG_ARCH_U8500 is not set
# CONFIG_ARCH_NOMADIK is not set
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
# CONFIG_PLAT_SPEAR is not set
+# CONFIG_ARCH_VT8500 is not set
CONFIG_GPIO_PCA953X=y
# CONFIG_KEYBOARD_GPIO_POLLED is not set
CONFIG_IMX_HAVE_PLATFORM_DMA=y
@@ -281,6 +274,7 @@ CONFIG_IMX_HAVE_PLATFORM_IMX_OCOTP=y
CONFIG_IMX_HAVE_PLATFORM_IMX_VIIM=y
CONFIG_IMX_HAVE_PLATFORM_PERFMON=y
CONFIG_IMX_HAVE_PLATFORM_LDB=y
+CONFIG_IMX_HAVE_PLATFORM_IMX_PXP=y
CONFIG_IMX_HAVE_PLATFORM_IMX_SPDIF=y
CONFIG_IMX_HAVE_PLATFORM_VIV_GPU=y
CONFIG_IMX_HAVE_PLATFORM_MXC_HDMI=y
@@ -299,11 +293,11 @@ CONFIG_IMX_HAVE_PLATFORM_IMX_MIPI_CSI2=y
# CONFIG_ARCH_MX2 is not set
# CONFIG_ARCH_MX25 is not set
# CONFIG_ARCH_MX3 is not set
-# CONFIG_ARCH_MXC91231 is not set
-# CONFIG_ARCH_MX5 is not set
+# CONFIG_ARCH_MX503 is not set
+# CONFIG_ARCH_MX51 is not set
CONFIG_ARCH_MX6=y
-CONFIG_FORCE_MAX_ZONEORDER=14
CONFIG_ARCH_MX6Q=y
+CONFIG_FORCE_MAX_ZONEORDER=14
CONFIG_SOC_IMX6Q=y
CONFIG_MACH_MX6Q_ARM2=y
CONFIG_MACH_MX6Q_SABRELITE=y
@@ -313,6 +307,7 @@ CONFIG_MACH_MX6Q_SABREAUTO=y
#
# MX6 Options:
#
+# CONFIG_IMX_PCIE is not set
CONFIG_ISP1504_MXC=y
# CONFIG_MXC_IRQ_PRIOR is not set
CONFIG_MXC_PWM=y
@@ -330,8 +325,8 @@ CONFIG_DMA_ZONE_SIZE=184
#
# Processor Type
#
-CONFIG_CPU_32v6K=y
CONFIG_CPU_V7=y
+CONFIG_CPU_32v6K=y
CONFIG_CPU_32v7=y
CONFIG_CPU_ABRT_EV7=y
CONFIG_CPU_PABRT_V7=y
@@ -366,11 +361,12 @@ CONFIG_CPU_HAS_PMU=y
# CONFIG_ARM_ERRATA_742231 is not set
# CONFIG_PL310_ERRATA_588369 is not set
# CONFIG_ARM_ERRATA_720789 is not set
+# CONFIG_PL310_ERRATA_727915 is not set
CONFIG_ARM_ERRATA_743622=y
CONFIG_ARM_ERRATA_751472=y
# CONFIG_ARM_ERRATA_753970 is not set
-# CONFIG_PL310_ERRATA_727915 is not set
CONFIG_ARM_ERRATA_754322=y
+# CONFIG_ARM_ERRATA_754327 is not set
CONFIG_ARM_GIC=y
#
@@ -380,6 +376,7 @@ CONFIG_ARM_GIC=y
# CONFIG_ARCH_SUPPORTS_MSI is not set
# CONFIG_PCCARD is not set
CONFIG_ARM_ERRATA_764369=y
+# CONFIG_PL310_ERRATA_769419 is not set
#
# Kernel Features
@@ -407,7 +404,9 @@ CONFIG_AEABI=y
# CONFIG_OABI_COMPAT is not set
# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
+CONFIG_HAVE_ARCH_PFN_VALID=y
CONFIG_HIGHMEM=y
+# CONFIG_HIGHPTE is not set
CONFIG_HW_PERF_EVENTS=y
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
@@ -416,13 +415,15 @@ CONFIG_FLAT_NODE_MEM_MAP=y
CONFIG_HAVE_MEMBLOCK=y
CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_COMPACTION is not set
+CONFIG_COMPACTION=y
+CONFIG_MIGRATION=y
# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
-# CONFIG_KSM is not set
+CONFIG_KSM=y
CONFIG_DEFAULT_MMAP_MIN_ADDR=4096
+# CONFIG_CLEANCACHE is not set
CONFIG_ALIGNMENT_TRAP=y
# CONFIG_UACCESS_WITH_MEMCPY is not set
# CONFIG_SECCOMP is not set
@@ -432,9 +433,12 @@ CONFIG_ALIGNMENT_TRAP=y
#
# Boot options
#
+# CONFIG_USE_OF is not set
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw rootfstype=jffs2 ip=off"
+CONFIG_CMDLINE_FROM_BOOTLOADER=y
+# CONFIG_CMDLINE_EXTEND is not set
# CONFIG_CMDLINE_FORCE is not set
# CONFIG_XIP_KERNEL is not set
# CONFIG_KEXEC is not set
@@ -444,9 +448,12 @@ CONFIG_CMDLINE="noinitrd console=ttymxc0,115200 root=/dev/mtdblock2 rw rootfstyp
#
# CPU Power Management
#
+
+#
+# CPU Frequency scaling
+#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
-# CONFIG_CPU_FREQ_DEBUG is not set
CONFIG_CPU_FREQ_STAT=y
# CONFIG_CPU_FREQ_STAT_DETAILS is not set
# CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE is not set
@@ -485,20 +492,19 @@ CONFIG_HAVE_AOUT=y
#
# Power management options
#
-CONFIG_PM=y
-CONFIG_PM_DEBUG=y
-# CONFIG_PM_ADVANCED_DEBUG is not set
-# CONFIG_PM_VERBOSE is not set
-CONFIG_CAN_PM_TRACE=y
-CONFIG_PM_SLEEP_SMP=y
-CONFIG_PM_SLEEP=y
CONFIG_SUSPEND=y
# CONFIG_PM_TEST_SUSPEND is not set
CONFIG_SUSPEND_DEVICE_TIME_DEBUG=y
CONFIG_SUSPEND_FREEZER=y
-CONFIG_APM_EMULATION=y
+CONFIG_PM_SLEEP=y
+CONFIG_PM_SLEEP_SMP=y
CONFIG_PM_RUNTIME=y
-CONFIG_PM_OPS=y
+CONFIG_PM=y
+CONFIG_PM_DEBUG=y
+# CONFIG_PM_ADVANCED_DEBUG is not set
+CONFIG_CAN_PM_TRACE=y
+CONFIG_APM_EMULATION=y
+CONFIG_PM_RUNTIME_CLK=y
CONFIG_ARCH_SUSPEND_POSSIBLE=y
CONFIG_NET=y
@@ -516,7 +522,6 @@ CONFIG_XFRM=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
# CONFIG_IP_ADVANCED_ROUTER is not set
-CONFIG_IP_FIB_HASH=y
CONFIG_IP_PNP=y
CONFIG_IP_PNP_DHCP=y
CONFIG_IP_PNP_BOOTP=y
@@ -568,6 +573,7 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_DCB is not set
# CONFIG_BATMAN_ADV is not set
CONFIG_RPS=y
+CONFIG_RFS_ACCEL=y
CONFIG_XPS=y
#
@@ -590,6 +596,7 @@ CONFIG_CAN_CALC_BITTIMING=y
CONFIG_HAVE_CAN_FLEXCAN=y
CONFIG_CAN_FLEXCAN=y
# CONFIG_CAN_SJA1000 is not set
+# CONFIG_CAN_C_CAN is not set
#
# CAN USB interfaces
@@ -632,24 +639,26 @@ CONFIG_WEXT_CORE=y
CONFIG_WEXT_PROC=y
CONFIG_WEXT_SPY=y
CONFIG_WEXT_PRIV=y
-# CONFIG_CFG80211 is not set
+CONFIG_CFG80211=y
+# CONFIG_NL80211_TESTMODE is not set
+# CONFIG_CFG80211_DEVELOPER_WARNINGS is not set
+# CONFIG_CFG80211_REG_DEBUG is not set
+CONFIG_CFG80211_DEFAULT_PS=y
+# CONFIG_CFG80211_DEBUGFS is not set
+# CONFIG_CFG80211_INTERNAL_REGDB is not set
+CONFIG_CFG80211_WEXT=y
CONFIG_WIRELESS_EXT_SYSFS=y
CONFIG_LIB80211=y
CONFIG_LIB80211_CRYPT_WEP=y
CONFIG_LIB80211_CRYPT_CCMP=y
CONFIG_LIB80211_CRYPT_TKIP=y
# CONFIG_LIB80211_DEBUG is not set
-
-#
-# CFG80211 needs to be enabled for MAC80211
-#
-
-#
-# Some wireless drivers require a rate control algorithm
-#
+# CONFIG_MAC80211 is not set
# CONFIG_WIMAX is not set
CONFIG_RFKILL=y
CONFIG_RFKILL_INPUT=y
+# CONFIG_RFKILL_REGULATOR is not set
+# CONFIG_RFKILL_GPIO is not set
# CONFIG_NET_9P is not set
# CONFIG_CAIF is not set
# CONFIG_CEPH_LIB is not set
@@ -674,8 +683,6 @@ CONFIG_PROC_EVENTS=y
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_TESTS is not set
-CONFIG_MTD_CONCAT=y
-CONFIG_MTD_PARTITIONS=y
# CONFIG_MTD_REDBOOT_PARTS is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
@@ -694,6 +701,7 @@ CONFIG_MTD_BLOCK=y
# CONFIG_SSFDC is not set
# CONFIG_SM_FTL is not set
# CONFIG_MTD_OOPS is not set
+# CONFIG_MTD_SWAP is not set
#
# RAM/ROM/Flash chip drivers
@@ -742,13 +750,14 @@ CONFIG_MTD_NAND_ECC=y
# CONFIG_MTD_NAND_ECC_SMC is not set
CONFIG_MTD_NAND=y
# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_BCH is not set
# CONFIG_MTD_SM_COMMON is not set
# CONFIG_MTD_NAND_MUSEUM_IDS is not set
# CONFIG_MTD_NAND_GPIO is not set
CONFIG_MTD_NAND_IDS=y
# CONFIG_MTD_NAND_DISKONCHIP is not set
# CONFIG_MTD_NAND_NANDSIM is not set
-# CONFIG_MTD_NAND_GPMI_NFC is not set
+# CONFIG_MTD_NAND_GPMI_NAND is not set
# CONFIG_MTD_NAND_PLATFORM is not set
# CONFIG_MTD_ALAUDA is not set
# CONFIG_MTD_ONENAND is not set
@@ -761,10 +770,6 @@ CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_WL_THRESHOLD=4096
CONFIG_MTD_UBI_BEB_RESERVE=1
# CONFIG_MTD_UBI_GLUEBI is not set
-
-#
-# UBI debugging options
-#
# CONFIG_MTD_UBI_DEBUG is not set
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
@@ -779,8 +784,10 @@ CONFIG_BLK_DEV_LOOP=y
# CONFIG_ATA_OVER_ETH is not set
# CONFIG_MG_DISK is not set
# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_SENSORS_LIS3LV02D is not set
CONFIG_MISC_DEVICES=y
# CONFIG_AD525X_DPOT is not set
+# CONFIG_INTEL_MID_PTI is not set
# CONFIG_ICS932S401 is not set
# CONFIG_ENCLOSURE_SERVICES is not set
# CONFIG_APDS9802ALS is not set
@@ -811,6 +818,8 @@ CONFIG_MXS_PERFMON=m
# Texas Instruments shared transport line discipline
#
# CONFIG_TI_ST is not set
+# CONFIG_SENSORS_LIS3_SPI is not set
+# CONFIG_SENSORS_LIS3_I2C is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -881,6 +890,7 @@ CONFIG_ATA_BMDMA=y
#
# PATA SFF controllers with BMDMA
#
+# CONFIG_PATA_ARASAN_CF is not set
#
# PIO-only SFF controllers
@@ -913,7 +923,6 @@ CONFIG_PHYLIB=y
# CONFIG_VITESSE_PHY is not set
# CONFIG_SMSC_PHY is not set
# CONFIG_BROADCOM_PHY is not set
-# CONFIG_BCM63XX_PHY is not set
# CONFIG_ICPLUS_PHY is not set
# CONFIG_REALTEK_PHY is not set
# CONFIG_NATIONAL_PHY is not set
@@ -945,12 +954,21 @@ CONFIG_SMSC911X=y
# CONFIG_KS8851_MLL is not set
CONFIG_FEC=y
# CONFIG_FEC_1588 is not set
+# CONFIG_FTMAC100 is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
CONFIG_WLAN=y
# CONFIG_USB_ZD1201 is not set
+# CONFIG_USB_NET_RNDIS_WLAN is not set
+CONFIG_ATH_COMMON=m
+# CONFIG_ATH_DEBUG is not set
+CONFIG_ATH6KL=m
+# CONFIG_ATH6KL_DEBUG is not set
CONFIG_HOSTAP=y
# CONFIG_HOSTAP_FIRMWARE is not set
+# CONFIG_IWM is not set
+# CONFIG_LIBERTAS is not set
+# CONFIG_MWIFIEX is not set
#
# Enable WiMAX (Networking options) to see the WiMAX drivers
@@ -1004,7 +1022,9 @@ CONFIG_INPUT_EVDEV=y
#
CONFIG_INPUT_KEYBOARD=y
# CONFIG_KEYBOARD_ADP5588 is not set
+# CONFIG_KEYBOARD_ADP5589 is not set
CONFIG_KEYBOARD_ATKBD=y
+# CONFIG_KEYBOARD_QT1070 is not set
# CONFIG_KEYBOARD_QT2160 is not set
# CONFIG_KEYBOARD_LKKBD is not set
CONFIG_KEYBOARD_GPIO=y
@@ -1013,6 +1033,7 @@ CONFIG_KEYBOARD_GPIO=y
# CONFIG_KEYBOARD_LM8323 is not set
# CONFIG_KEYBOARD_MAX7359 is not set
# CONFIG_KEYBOARD_MCS is not set
+# CONFIG_KEYBOARD_MPR121 is not set
# CONFIG_KEYBOARD_IMX is not set
# CONFIG_KEYBOARD_NEWTON is not set
# CONFIG_KEYBOARD_OPENCORES is not set
@@ -1020,7 +1041,6 @@ CONFIG_KEYBOARD_GPIO=y
# CONFIG_KEYBOARD_SUNKBD is not set
# CONFIG_KEYBOARD_XTKBD is not set
# CONFIG_KEYBOARD_MXC is not set
-# CONFIG_KEYBOARD_MPR121 is not set
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
@@ -1028,6 +1048,7 @@ CONFIG_INPUT_TOUCHSCREEN=y
# CONFIG_TOUCHSCREEN_ADS7846 is not set
# CONFIG_TOUCHSCREEN_AD7877 is not set
# CONFIG_TOUCHSCREEN_AD7879 is not set
+# CONFIG_TOUCHSCREEN_ATMEL_MXT is not set
# CONFIG_TOUCHSCREEN_BU21013 is not set
# CONFIG_TOUCHSCREEN_CY8CTMG110 is not set
# CONFIG_TOUCHSCREEN_DYNAPRO is not set
@@ -1038,23 +1059,23 @@ CONFIG_TOUCHSCREEN_EGALAX=y
# CONFIG_TOUCHSCREEN_GUNZE is not set
# CONFIG_TOUCHSCREEN_ELO is not set
# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set
+# CONFIG_TOUCHSCREEN_MAX11801 is not set
# CONFIG_TOUCHSCREEN_MCS5000 is not set
# CONFIG_TOUCHSCREEN_MTOUCH is not set
# CONFIG_TOUCHSCREEN_INEXIO is not set
# CONFIG_TOUCHSCREEN_MK712 is not set
# CONFIG_TOUCHSCREEN_PENMOUNT is not set
-# CONFIG_TOUCHSCREEN_QT602240 is not set
# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
# CONFIG_TOUCHSCREEN_WM97XX is not set
# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set
+# CONFIG_TOUCHSCREEN_TSC2005 is not set
# CONFIG_TOUCHSCREEN_TSC2007 is not set
# CONFIG_TOUCHSCREEN_W90X900 is not set
# CONFIG_TOUCHSCREEN_ST1232 is not set
# CONFIG_TOUCHSCREEN_P1003 is not set
# CONFIG_TOUCHSCREEN_TPS6507X is not set
-# CONFIG_TOUCHSCREEN_MAX11801 is not set
CONFIG_INPUT_MISC=y
# CONFIG_INPUT_AD714X is not set
# CONFIG_INPUT_ATI_REMOTE is not set
@@ -1069,7 +1090,7 @@ CONFIG_INPUT_UINPUT=y
# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
# CONFIG_INPUT_ADXL34X is not set
# CONFIG_INPUT_CMA3000 is not set
-# CONFIG_INPUT_ISL29023 is not set
+CONFIG_INPUT_ISL29023=y
#
# Hardware I/O ports
@@ -1090,9 +1111,14 @@ CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
-CONFIG_DEVKMEM=y
+CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_N_GSM is not set
+# CONFIG_TRACE_SINK is not set
+CONFIG_DEVKMEM=y
#
# Serial drivers
@@ -1112,10 +1138,7 @@ CONFIG_SERIAL_CORE_CONSOLE=y
# CONFIG_SERIAL_ALTERA_JTAGUART is not set
# CONFIG_SERIAL_ALTERA_UART is not set
# CONFIG_SERIAL_IFX6X60 is not set
-CONFIG_UNIX98_PTYS=y
-# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
-CONFIG_LEGACY_PTYS=y
-CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_SERIAL_XILINX_PS_UART is not set
# CONFIG_TTY_PRINTK is not set
CONFIG_FSL_OTP=y
# CONFIG_HVC_DCC is not set
@@ -1146,12 +1169,14 @@ CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_IMX=y
# CONFIG_I2C_OCORES is not set
# CONFIG_I2C_PCA_PLATFORM is not set
+# CONFIG_I2C_PXA_PCI 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_TAOS_EVM is not set
# CONFIG_I2C_TINY_USB is not set
@@ -1169,10 +1194,12 @@ CONFIG_SPI_MASTER=y
#
# SPI Master Controller Drivers
#
+# CONFIG_SPI_ALTERA is not set
CONFIG_SPI_BITBANG=y
# CONFIG_SPI_GPIO is not set
CONFIG_SPI_IMX_VER_2_3=y
CONFIG_SPI_IMX=y
+# CONFIG_SPI_OC_TINY is not set
# CONFIG_SPI_PXA2XX_PCI is not set
# CONFIG_SPI_XILINX is not set
# CONFIG_SPI_DESIGNWARE is not set
@@ -1191,12 +1218,20 @@ CONFIG_SPI_IMX=y
#
# PPS generators support
#
+
+#
+# PTP clock support
+#
+
+#
+# Enable Device Drivers -> PPS to see the PTP clock options.
+#
CONFIG_ARCH_REQUIRE_GPIOLIB=y
CONFIG_GPIOLIB=y
# CONFIG_GPIO_SYSFS is not set
#
-# Memory mapped GPIO expanders:
+# Memory mapped GPIO drivers:
#
# CONFIG_GPIO_BASIC_MMIO is not set
# CONFIG_GPIO_IT8761E is not set
@@ -1231,9 +1266,117 @@ CONFIG_GPIOLIB=y
# MODULbus GPIO expanders:
#
# CONFIG_W1 is not set
-# CONFIG_POWER_SUPPLY is not set
-# CONFIG_HWMON is not set
+CONFIG_POWER_SUPPLY=y
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_APM_POWER is not set
+# CONFIG_TEST_POWER is not set
+# CONFIG_BATTERY_DS2780 is not set
+# CONFIG_BATTERY_DS2782 is not set
+# CONFIG_BATTERY_BQ20Z75 is not set
+# CONFIG_BATTERY_BQ27x00 is not set
+# CONFIG_BATTERY_MAX17040 is not set
+# CONFIG_BATTERY_MAX17042 is not set
+# CONFIG_CHARGER_ISP1704 is not set
+CONFIG_CHARGER_MAX8903=y
+# CONFIG_CHARGER_GPIO is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+
+#
+# Native drivers
+#
+# CONFIG_SENSORS_AD7414 is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADCXX 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_ADT7411 is not set
+# CONFIG_SENSORS_ADT7462 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7475 is not set
+# CONFIG_SENSORS_ASC7621 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS620 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_G760A is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_GPIO_FAN is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_JC42 is not set
+# CONFIG_SENSORS_LINEAGE is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 is not set
+# CONFIG_SENSORS_LM73 is not set
+# CONFIG_SENSORS_LM75 is not set
+# CONFIG_SENSORS_LM77 is not set
+# CONFIG_SENSORS_LM78 is not set
+# CONFIG_SENSORS_LM80 is not set
+# CONFIG_SENSORS_LM83 is not set
+# CONFIG_SENSORS_LM85 is not set
+# CONFIG_SENSORS_LM87 is not set
+# CONFIG_SENSORS_LM90 is not set
+# CONFIG_SENSORS_LM92 is not set
+# CONFIG_SENSORS_LM93 is not set
+# CONFIG_SENSORS_LTC4151 is not set
+# CONFIG_SENSORS_LTC4215 is not set
+# CONFIG_SENSORS_LTC4245 is not set
+# CONFIG_SENSORS_LTC4261 is not set
+# CONFIG_SENSORS_LM95241 is not set
+# CONFIG_SENSORS_MAX1111 is not set
+# CONFIG_SENSORS_MAX16065 is not set
+# CONFIG_SENSORS_MAX1619 is not set
+# CONFIG_SENSORS_MAX6639 is not set
+# CONFIG_SENSORS_MAX6642 is not set
+# CONFIG_SENSORS_MAX17135 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 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_SMM665 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_EMC1403 is not set
+# CONFIG_SENSORS_EMC2103 is not set
+# CONFIG_SENSORS_EMC6W201 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_SCH5627 is not set
+# CONFIG_SENSORS_ADS1015 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_ADS7871 is not set
+# CONFIG_SENSORS_AMC6821 is not set
+# CONFIG_SENSORS_THMC50 is not set
+# CONFIG_SENSORS_TMP102 is not set
+# CONFIG_SENSORS_TMP401 is not set
+# CONFIG_SENSORS_TMP421 is not set
+# CONFIG_SENSORS_VT1211 is not set
+# CONFIG_SENSORS_W83781D is not set
+# CONFIG_SENSORS_W83791D is not set
+# CONFIG_SENSORS_W83792D is not set
+# CONFIG_SENSORS_W83793 is not set
+# CONFIG_SENSORS_W83795 is not set
+# CONFIG_SENSORS_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+CONFIG_SENSORS_MAG3110=y
+# CONFIG_MXC_MMA8450 is not set
+CONFIG_MXC_MMA8451=y
CONFIG_THERMAL=y
+# CONFIG_THERMAL_HWMON is not set
CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_NOWAYOUT=y
@@ -1254,6 +1397,12 @@ CONFIG_SSB_POSSIBLE=y
# Sonics Silicon Backplane
#
# CONFIG_SSB is not set
+CONFIG_BCMA_POSSIBLE=y
+
+#
+# Broadcom specific AMBA
+#
+# CONFIG_BCMA is not set
CONFIG_MFD_SUPPORT=y
CONFIG_MFD_CORE=y
# CONFIG_MFD_88PM860X is not set
@@ -1263,8 +1412,10 @@ CONFIG_MFD_CORE=y
# CONFIG_HTC_PASIC3 is not set
# CONFIG_HTC_I2CPLD is not set
# CONFIG_UCB1400_CORE is not set
+# CONFIG_TPS6105X is not set
# CONFIG_TPS65010 is not set
# CONFIG_TPS6507X is not set
+# CONFIG_MFD_TPS6586X is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_STMPE is not set
# CONFIG_MFD_TC3589X is not set
@@ -1275,6 +1426,7 @@ CONFIG_MFD_CORE=y
# CONFIG_PMIC_DA903X is not set
# CONFIG_PMIC_ADP5520 is not set
# CONFIG_MFD_MAX8925 is not set
+# CONFIG_MFD_MAX8997 is not set
# CONFIG_MFD_MAX8998 is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM831X_I2C is not set
@@ -1283,14 +1435,14 @@ CONFIG_MFD_CORE=y
# CONFIG_MFD_WM8994 is not set
# CONFIG_MFD_PCF50633 is not set
# CONFIG_PMIC_DIALOG is not set
-# CONFIG_MFD_MC13XXX is not set
# CONFIG_MFD_MC_PMIC is not set
# CONFIG_MFD_MC34708 is not set
CONFIG_MFD_PFUZE=y
+# CONFIG_MFD_MC13XXX is not set
# CONFIG_ABX500_CORE is not set
# CONFIG_EZX_PCAP is not set
-# CONFIG_MFD_TPS6586X is not set
# CONFIG_MFD_WL1273_CORE is not set
+# CONFIG_MFD_TPS65910 is not set
# CONFIG_MFD_MAX17135 is not set
CONFIG_MFD_MXC_HDMI=y
CONFIG_REGULATOR=y
@@ -1312,13 +1464,14 @@ CONFIG_REGULATOR_PFUZE100=y
# CONFIG_REGULATOR_TPS6507X is not set
# CONFIG_REGULATOR_ISL6271A is not set
# CONFIG_REGULATOR_AD5398 is not set
-# CONFIG_REGULATOR_TPS6524X is not set
CONFIG_REGULATOR_ANATOP=y
+# CONFIG_REGULATOR_TPS6524X is not set
CONFIG_MEDIA_SUPPORT=y
#
# Multimedia core support
#
+# CONFIG_MEDIA_CONTROLLER is not set
CONFIG_VIDEO_DEV=y
CONFIG_VIDEO_V4L2_COMMON=y
# CONFIG_DVB_CORE is not set
@@ -1351,11 +1504,11 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y
# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
#
-# Encoders/decoders and other helper chips
+# Encoders, decoders, sensors and other helper chips
#
#
-# Audio decoders
+# Audio decoders, processors and mixers
#
# CONFIG_VIDEO_TVAUDIO is not set
# CONFIG_VIDEO_TDA7432 is not set
@@ -1365,7 +1518,6 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y
# CONFIG_VIDEO_MSP3400 is not set
# CONFIG_VIDEO_CS5345 is not set
# CONFIG_VIDEO_CS53L32A is not set
-# CONFIG_VIDEO_M52790 is not set
# CONFIG_VIDEO_TLV320AIC23B is not set
# CONFIG_VIDEO_WM8775 is not set
# CONFIG_VIDEO_WM8739 is not set
@@ -1384,12 +1536,8 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y
# CONFIG_VIDEO_BT856 is not set
# CONFIG_VIDEO_BT866 is not set
# CONFIG_VIDEO_KS0127 is not set
-# CONFIG_VIDEO_OV7670 is not set
-# CONFIG_VIDEO_MT9V011 is not set
-# CONFIG_VIDEO_TCM825X is not set
# CONFIG_VIDEO_SAA7110 is not set
# CONFIG_VIDEO_SAA711X is not set
-# CONFIG_VIDEO_SAA717X is not set
# CONFIG_VIDEO_SAA7191 is not set
# CONFIG_VIDEO_TVP514X is not set
# CONFIG_VIDEO_TVP5150 is not set
@@ -1399,6 +1547,7 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y
#
# Video and audio decoders
#
+# CONFIG_VIDEO_SAA717X is not set
# CONFIG_VIDEO_CX25840 is not set
#
@@ -1413,15 +1562,27 @@ CONFIG_VIDEO_CAPTURE_DRIVERS=y
# CONFIG_VIDEO_SAA7185 is not set
# CONFIG_VIDEO_ADV7170 is not set
# CONFIG_VIDEO_ADV7175 is not set
-# CONFIG_VIDEO_THS7303 is not set
# CONFIG_VIDEO_ADV7343 is not set
# CONFIG_VIDEO_AK881X is not set
#
+# Camera sensor devices
+#
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_MT9V011 is not set
+# CONFIG_VIDEO_TCM825X is not set
+
+#
# Video improvement chips
#
# CONFIG_VIDEO_UPD64031A is not set
# CONFIG_VIDEO_UPD64083 is not set
+
+#
+# Miscelaneous helper chips
+#
+# CONFIG_VIDEO_THS7303 is not set
+# CONFIG_VIDEO_M52790 is not set
# CONFIG_VIDEO_VIVI is not set
CONFIG_VIDEO_MXC_CAMERA=m
@@ -1448,6 +1609,7 @@ CONFIG_VIDEO_MXC_IPU_OUTPUT=y
# CONFIG_VIDEO_CPIA2 is not set
# CONFIG_VIDEO_TIMBERDALE is not set
# CONFIG_VIDEO_SR030PC30 is not set
+# CONFIG_VIDEO_NOON010PC30 is not set
# CONFIG_SOC_CAMERA is not set
CONFIG_V4L_USB_DRIVERS=y
CONFIG_USB_VIDEO_CLASS=m
@@ -1462,9 +1624,11 @@ CONFIG_USB_GSPCA=m
# CONFIG_USB_GSPCA_ETOMS is not set
# CONFIG_USB_GSPCA_FINEPIX is not set
# CONFIG_USB_GSPCA_JEILINJ is not set
+# CONFIG_USB_GSPCA_KINECT is not set
# CONFIG_USB_GSPCA_KONICA is not set
# CONFIG_USB_GSPCA_MARS is not set
# CONFIG_USB_GSPCA_MR97310A is not set
+# CONFIG_USB_GSPCA_NW80X is not set
# CONFIG_USB_GSPCA_OV519 is not set
# CONFIG_USB_GSPCA_OV534 is not set
# CONFIG_USB_GSPCA_OV534_9 is not set
@@ -1491,6 +1655,7 @@ CONFIG_USB_GSPCA=m
# CONFIG_USB_GSPCA_T613 is not set
# CONFIG_USB_GSPCA_TV8532 is not set
# CONFIG_USB_GSPCA_VC032X is not set
+# CONFIG_USB_GSPCA_VICAM is not set
# CONFIG_USB_GSPCA_XIRLINK_CIT is not set
# CONFIG_USB_GSPCA_ZC3XX is not set
# CONFIG_VIDEO_PVRUSB2 is not set
@@ -1540,7 +1705,6 @@ CONFIG_FB_MODE_HELPERS=y
# CONFIG_FB_UDL is not set
# CONFIG_FB_VIRTUAL is not set
# CONFIG_FB_METRONOME is not set
-# CONFIG_FB_MB862XX is not set
# CONFIG_FB_BROADSHEET is not set
CONFIG_BACKLIGHT_LCD_SUPPORT=y
# CONFIG_LCD_CLASS_DEVICE is not set
@@ -1548,6 +1712,7 @@ CONFIG_BACKLIGHT_CLASS_DEVICE=y
# CONFIG_BACKLIGHT_GENERIC is not set
CONFIG_BACKLIGHT_PWM=y
# CONFIG_BACKLIGHT_ADP8860 is not set
+# CONFIG_BACKLIGHT_ADP8870 is not set
#
# Display device support
@@ -1626,6 +1791,7 @@ CONFIG_SND_USB=y
CONFIG_SND_USB_AUDIO=y
# CONFIG_SND_USB_UA101 is not set
# CONFIG_SND_USB_CAIAQ is not set
+# CONFIG_SND_USB_6FIRE is not set
CONFIG_SND_SOC=y
# CONFIG_SND_SOC_CACHE_LZO is not set
CONFIG_SND_SOC_AC97_BUS=y
@@ -1658,27 +1824,26 @@ CONFIG_USB_HID=y
#
# Special HID drivers
#
-# CONFIG_HID_3M_PCT is not set
CONFIG_HID_A4TECH=m
-# CONFIG_HID_ACRUX_FF is not set
+# CONFIG_HID_ACRUX is not set
CONFIG_HID_APPLE=m
CONFIG_HID_BELKIN=m
-# CONFIG_HID_CANDO is not set
CONFIG_HID_CHERRY=m
CONFIG_HID_CHICONY=m
# CONFIG_HID_PRODIKEYS is not set
CONFIG_HID_CYPRESS=m
# CONFIG_HID_DRAGONRISE is not set
# CONFIG_HID_EMS_FF is not set
-# CONFIG_HID_EGALAX is not set
# CONFIG_HID_ELECOM is not set
CONFIG_HID_EZKEY=m
+# CONFIG_HID_KEYTOUCH is not set
# CONFIG_HID_KYE is not set
# CONFIG_HID_UCLOGIC is not set
# CONFIG_HID_WALTOP is not set
CONFIG_HID_GYRATION=m
# CONFIG_HID_TWINHAN is not set
# CONFIG_HID_KENSINGTON is not set
+# CONFIG_HID_LCPOWER is not set
CONFIG_HID_LOGITECH=m
# CONFIG_LOGITECH_FF is not set
# CONFIG_LOGIRUMBLEPAD2_FF is not set
@@ -1686,7 +1851,6 @@ CONFIG_HID_LOGITECH=m
# CONFIG_LOGIWII_FF is not set
# CONFIG_HID_MAGICMOUSE is not set
CONFIG_HID_MICROSOFT=m
-# CONFIG_HID_MOSART is not set
CONFIG_HID_MONTEREY=m
# CONFIG_HID_MULTITOUCH is not set
# CONFIG_HID_NTRIG is not set
@@ -1697,12 +1861,13 @@ CONFIG_HID_PETALYNX=m
# CONFIG_HID_PICOLCD is not set
# CONFIG_HID_QUANTA is not set
# CONFIG_HID_ROCCAT is not set
+# CONFIG_HID_ROCCAT_ARVO is not set
# CONFIG_HID_ROCCAT_KONE is not set
# CONFIG_HID_ROCCAT_KONEPLUS is not set
+# CONFIG_HID_ROCCAT_KOVAPLUS is not set
# CONFIG_HID_ROCCAT_PYRA is not set
CONFIG_HID_SAMSUNG=m
CONFIG_HID_SONY=m
-# CONFIG_HID_STANTUM is not set
CONFIG_HID_SUNPLUS=m
# CONFIG_HID_GREENASIA is not set
# CONFIG_HID_SMARTJOYPLUS is not set
@@ -1771,6 +1936,7 @@ CONFIG_USB_EHCI_ROOT_HUB_TT=y
#
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
@@ -1782,6 +1948,7 @@ CONFIG_USB_STORAGE=y
# CONFIG_USB_STORAGE_ONETOUCH is not set
# CONFIG_USB_STORAGE_KARMA is not set
# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_STORAGE_ENE_UB6250 is not set
# CONFIG_USB_UAS is not set
# CONFIG_USB_LIBUSUAL is not set
@@ -1827,6 +1994,7 @@ CONFIG_USB_GADGET_SELECTED=y
CONFIG_USB_GADGET_ARC=y
CONFIG_USB_ARC=y
# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_FUSB300 is not set
# CONFIG_USB_GADGET_R8A66597 is not set
# CONFIG_USB_GADGET_PXA_U2O is not set
# CONFIG_USB_GADGET_M66592 is not set
@@ -1882,8 +2050,8 @@ CONFIG_MMC_SDHCI=y
CONFIG_MMC_SDHCI_IO_ACCESSORS=y
CONFIG_MMC_SDHCI_PLTFM=y
CONFIG_MMC_SDHCI_ESDHC_IMX=y
-# CONFIG_MMC_MXC is not set
# CONFIG_MMC_DW is not set
+# CONFIG_MMC_VUB300 is not set
# CONFIG_MMC_USHC is not set
# CONFIG_MEMSTICK is not set
CONFIG_NEW_LEDS=y
@@ -1892,6 +2060,7 @@ CONFIG_LEDS_CLASS=y
#
# LED drivers
#
+# CONFIG_LEDS_LM3530 is not set
# CONFIG_LEDS_PCA9532 is not set
# CONFIG_LEDS_GPIO is not set
# CONFIG_LEDS_LP3944 is not set
@@ -1949,10 +2118,13 @@ CONFIG_RTC_INTF_DEV_UIE_EMUL=y
# CONFIG_RTC_DRV_FM3130 is not set
# CONFIG_RTC_DRV_RX8581 is not set
# CONFIG_RTC_DRV_RX8025 is not set
+# CONFIG_RTC_DRV_EM3027 is not set
+# CONFIG_RTC_DRV_RV3029C2 is not set
#
# SPI RTC drivers
#
+# CONFIG_RTC_DRV_M41T93 is not set
# CONFIG_RTC_DRV_M41T94 is not set
# CONFIG_RTC_DRV_DS1305 is not set
# CONFIG_RTC_DRV_DS1390 is not set
@@ -1991,7 +2163,10 @@ CONFIG_DMADEVICES=y
#
# DMA Devices
#
+# CONFIG_DW_DMAC is not set
# CONFIG_MXC_PXP is not set
+CONFIG_MXC_PXP_V2=y
+CONFIG_MXC_PXP_CLIENT_DEVICE=y
# CONFIG_TIMB_DMA is not set
CONFIG_IMX_SDMA=y
# CONFIG_MXS_DMA is not set
@@ -2007,6 +2182,7 @@ CONFIG_DMA_ENGINE=y
# CONFIG_UIO is not set
# CONFIG_STAGING is not set
CONFIG_CLKDEV_LOOKUP=y
+CONFIG_CLKSRC_MMIO=y
#
# MXC support drivers
@@ -2163,6 +2339,7 @@ CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
CONFIG_TMPFS=y
# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_TMPFS_XATTR is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
CONFIG_MISC_FILESYSTEMS=y
@@ -2199,6 +2376,7 @@ CONFIG_CRAMFS=y
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_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
@@ -2212,7 +2390,6 @@ CONFIG_LOCKD=y
CONFIG_LOCKD_V4=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
-# CONFIG_RPCSEC_GSS_KRB5 is not set
# CONFIG_CEPH_FS is not set
# CONFIG_CIFS is not set
# CONFIG_NCP_FS is not set
@@ -2285,6 +2462,7 @@ CONFIG_NLS_UTF8=m
# Kernel hacking
#
# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
CONFIG_ENABLE_WARN_DEPRECATED=y
CONFIG_ENABLE_MUST_CHECK=y
CONFIG_FRAME_WARN=1024
@@ -2293,15 +2471,16 @@ CONFIG_FRAME_WARN=1024
# CONFIG_UNUSED_SYMBOLS is not set
CONFIG_DEBUG_FS=y
# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
# CONFIG_DEBUG_KERNEL is not set
# CONFIG_HARDLOCKUP_DETECTOR is not set
# CONFIG_SLUB_DEBUG_ON is not set
# CONFIG_SLUB_STATS is not set
-CONFIG_BKL=y
# CONFIG_SPARSE_RCU_POINTER is not set
CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_MEMORY_INIT is not set
-# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+CONFIG_RCU_CPU_STALL_TIMEOUT=60
+CONFIG_RCU_CPU_STALL_VERBOSE=y
# CONFIG_LKDTM is not set
CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_HAVE_FUNCTION_TRACER=y
@@ -2316,6 +2495,7 @@ CONFIG_TRACING_SUPPORT=y
# CONFIG_ATOMIC64_SELFTEST is not set
# CONFIG_SAMPLES is not set
CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_TEST_KSTRTOX is not set
# CONFIG_STRICT_DEVMEM is not set
CONFIG_ARM_UNWIND=y
# CONFIG_DEBUG_USER is not set
@@ -2439,7 +2619,6 @@ CONFIG_CRYPTO_HW=y
#
CONFIG_BITREVERSE=y
CONFIG_RATIONAL=y
-CONFIG_GENERIC_FIND_LAST_BIT=y
CONFIG_CRC_CCITT=m
CONFIG_CRC16=y
# CONFIG_CRC_T10DIF is not set
@@ -2457,4 +2636,6 @@ CONFIG_GENERIC_ALLOCATOR=y
CONFIG_HAS_IOMEM=y
CONFIG_HAS_IOPORT=y
CONFIG_HAS_DMA=y
+CONFIG_CPU_RMAP=y
CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
diff --git a/arch/arm/mach-mx6/Kconfig b/arch/arm/mach-mx6/Kconfig
index 83dfa5c33783..aa081b6ce0c1 100644
--- a/arch/arm/mach-mx6/Kconfig
+++ b/arch/arm/mach-mx6/Kconfig
@@ -57,6 +57,7 @@ config MACH_MX6Q_ARM2
select IMX_HAVE_PLATFORM_IMX_MIPI_CSI2
select IMX_HAVE_PLATFORM_PERFMON
select IMX_HAVE_PLATFORM_MXC_MLB
+ select IMX_HAVE_PLATFORM_IMX_PXP
help
Include support for i.MX 6Quad Armadillo2 platform. This includes specific
configurations for the board and its peripherals.
@@ -163,4 +164,8 @@ config MACH_MX6Q_SABREAUTO
comment "MX6 Options:"
+config IMX_PCIE
+ bool "PCI Express support"
+ select PCI
+
endif
diff --git a/arch/arm/mach-mx6/Makefile b/arch/arm/mach-mx6/Makefile
index 6fc9646ba8d2..21f776ab598c 100644
--- a/arch/arm/mach-mx6/Makefile
+++ b/arch/arm/mach-mx6/Makefile
@@ -12,3 +12,4 @@ obj-$(CONFIG_MACH_MX6Q_SABRESD) += board-mx6q_sabresd.o mx6q_sabresd_pmic_pfuze1
obj-$(CONFIG_MACH_MX6Q_SABREAUTO) += board-mx6q_sabreauto.o mx6q_sabreauto_pmic_pfuze100.o
obj-$(CONFIG_SMP) += plat_hotplug.o platsmp.o headsmp.o
obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o
+obj-$(CONFIG_IMX_PCIE) += pcie.o
diff --git a/arch/arm/mach-mx6/board-mx6dl_arm2.h b/arch/arm/mach-mx6/board-mx6dl_arm2.h
new file mode 100644
index 000000000000..9261a28fb6d1
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6dl_arm2.h
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/iomux-mx6dl.h>
+
+static iomux_v3_cfg_t mx6dl_arm2_pads[] = {
+
+ /* UART4 for debug */
+ MX6DL_PAD_KEY_COL0__UART4_TXD,
+ MX6DL_PAD_KEY_ROW0__UART4_RXD,
+ /* USB HSIC ports use the same pin with ENET */
+#ifdef CONFIG_USB_EHCI_ARC_HSIC
+ /* USB H2 strobe/data pin */
+ MX6DL_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE,
+ MX6DL_PAD_RGMII_TXC__USBOH3_H2_DATA,
+
+ /* USB H3 strobe/data pin */
+ MX6DL_PAD_RGMII_RXC__USBOH3_H3_STROBE,
+ MX6DL_PAD_RGMII_RX_CTL__USBOH3_H3_DATA,
+ /* ENET */
+#else
+ MX6DL_PAD_KEY_COL1__ENET_MDIO,
+ MX6DL_PAD_KEY_COL2__ENET_MDC,
+ MX6DL_PAD_RGMII_TXC__ENET_RGMII_TXC,
+ MX6DL_PAD_RGMII_TD0__ENET_RGMII_TD0,
+ MX6DL_PAD_RGMII_TD1__ENET_RGMII_TD1,
+ MX6DL_PAD_RGMII_TD2__ENET_RGMII_TD2,
+ MX6DL_PAD_RGMII_TD3__ENET_RGMII_TD3,
+ MX6DL_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL,
+ MX6DL_PAD_ENET_REF_CLK__ENET_TX_CLK,
+ MX6DL_PAD_RGMII_RXC__ENET_RGMII_RXC,
+ MX6DL_PAD_RGMII_RD0__ENET_RGMII_RD0,
+ MX6DL_PAD_RGMII_RD1__ENET_RGMII_RD1,
+ MX6DL_PAD_RGMII_RD2__ENET_RGMII_RD2,
+ MX6DL_PAD_RGMII_RD3__ENET_RGMII_RD3,
+ MX6DL_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL,
+#ifdef CONFIG_FEC_1588
+ MX6DL_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT,
+#endif
+#endif
+ /* MCLK for csi0 */
+ MX6DL_PAD_GPIO_0__CCM_CLKO,
+ MX6DL_PAD_GPIO_3__CCM_CLKO2,
+
+ /* SD1 */
+ MX6DL_PAD_SD1_CLK__USDHC1_CLK,
+ MX6DL_PAD_SD1_CMD__USDHC1_CMD,
+ MX6DL_PAD_SD1_DAT0__USDHC1_DAT0,
+ MX6DL_PAD_SD1_DAT1__USDHC1_DAT1,
+ MX6DL_PAD_SD1_DAT2__USDHC1_DAT2,
+ MX6DL_PAD_SD1_DAT3__USDHC1_DAT3,
+ /* SD2 */
+ MX6DL_PAD_SD2_CLK__USDHC2_CLK,
+ MX6DL_PAD_SD2_CMD__USDHC2_CMD,
+ MX6DL_PAD_SD2_DAT0__USDHC2_DAT0,
+ MX6DL_PAD_SD2_DAT1__USDHC2_DAT1,
+ MX6DL_PAD_SD2_DAT2__USDHC2_DAT2,
+ MX6DL_PAD_SD2_DAT3__USDHC2_DAT3,
+ /* SD3 */
+ MX6DL_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
+ MX6DL_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
+ MX6DL_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
+ MX6DL_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
+ MX6DL_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
+ MX6DL_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
+ MX6DL_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ,
+ MX6DL_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ,
+ MX6DL_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ,
+ MX6DL_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ,
+ MX6DL_PAD_SD3_RST__USDHC3_RST,
+ /* SD3 VSelect */
+ MX6DL_PAD_GPIO_18__USDHC3_VSELECT,
+ /* SD3_CD and SD3_WP */
+ MX6DL_PAD_NANDF_CS0__GPIO_6_11,
+ MX6DL_PAD_NANDF_CS1__GPIO_6_14,
+ /* SD4 */
+ MX6DL_PAD_SD4_CLK__USDHC4_CLK_50MHZ,
+ MX6DL_PAD_SD4_CMD__USDHC4_CMD_50MHZ,
+ MX6DL_PAD_SD4_DAT0__USDHC4_DAT0_50MHZ,
+ MX6DL_PAD_SD4_DAT1__USDHC4_DAT1_50MHZ,
+ MX6DL_PAD_SD4_DAT2__USDHC4_DAT2_50MHZ,
+ MX6DL_PAD_SD4_DAT3__USDHC4_DAT3_50MHZ,
+ MX6DL_PAD_SD4_DAT4__USDHC4_DAT4_50MHZ,
+ MX6DL_PAD_SD4_DAT5__USDHC4_DAT5_50MHZ,
+ MX6DL_PAD_SD4_DAT6__USDHC4_DAT6_50MHZ,
+ MX6DL_PAD_SD4_DAT7__USDHC4_DAT7_50MHZ,
+ MX6DL_PAD_NANDF_ALE__USDHC4_RST,
+ /* eCSPI1 */
+ MX6DL_PAD_EIM_EB2__ECSPI1_SS0,
+ MX6DL_PAD_EIM_D16__ECSPI1_SCLK,
+ MX6DL_PAD_EIM_D17__ECSPI1_MISO,
+ MX6DL_PAD_EIM_D18__ECSPI1_MOSI,
+ MX6DL_PAD_EIM_D19__ECSPI1_SS1,
+ MX6DL_PAD_EIM_EB2__GPIO_2_30, /*SS0*/
+ MX6DL_PAD_EIM_D19__GPIO_3_19, /*SS1*/
+
+ /* ESAI */
+ MX6DL_PAD_ENET_RXD0__ESAI1_HCKT,
+ MX6DL_PAD_ENET_CRS_DV__ESAI1_SCKT,
+ MX6DL_PAD_ENET_RXD1__ESAI1_FST,
+ MX6DL_PAD_ENET_TX_EN__ESAI1_TX3_RX2,
+ MX6DL_PAD_ENET_TXD1__ESAI1_TX2_RX3,
+ MX6DL_PAD_ENET_TXD0__ESAI1_TX4_RX1,
+ MX6DL_PAD_ENET_MDC__ESAI1_TX5_RX0,
+ MX6DL_PAD_NANDF_CS2__ESAI1_TX0,
+ MX6DL_PAD_NANDF_CS3__ESAI1_TX1,
+
+ /* I2C1 */
+ MX6DL_PAD_CSI0_DAT8__I2C1_SDA,
+ MX6DL_PAD_CSI0_DAT9__I2C1_SCL,
+
+ /* I2C2 */
+ MX6DL_PAD_KEY_COL3__I2C2_SCL,
+ MX6DL_PAD_KEY_ROW3__I2C2_SDA,
+
+ /* DISPLAY */
+ MX6DL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+ MX6DL_PAD_DI0_PIN15__IPU1_DI0_PIN15,
+ MX6DL_PAD_DI0_PIN2__IPU1_DI0_PIN2,
+ MX6DL_PAD_DI0_PIN3__IPU1_DI0_PIN3,
+ MX6DL_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
+ MX6DL_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
+ MX6DL_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
+ MX6DL_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
+ MX6DL_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
+ MX6DL_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
+ MX6DL_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
+ MX6DL_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
+ MX6DL_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
+ MX6DL_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
+ MX6DL_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
+ MX6DL_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
+ MX6DL_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
+ MX6DL_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
+ MX6DL_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
+ MX6DL_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
+ MX6DL_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
+ MX6DL_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
+ MX6DL_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
+ MX6DL_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
+ MX6DL_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20,
+ MX6DL_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
+ MX6DL_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
+ MX6DL_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
+
+ MX6DL_PAD_EIM_D24__GPIO_3_24,
+
+ /* UART2 */
+ MX6DL_PAD_EIM_D26__UART2_RXD,
+ MX6DL_PAD_EIM_D27__UART2_TXD,
+ MX6DL_PAD_EIM_D28__UART2_RTS,
+ MX6DL_PAD_EIM_D29__UART2_CTS,
+
+ /* PWM1 */
+ MX6DL_PAD_GPIO_9__PWM1_PWMO,
+
+ /* DISP0 DET */
+ MX6DL_PAD_EIM_D31__GPIO_3_31,
+
+ /* DISP0 RESET */
+ MX6DL_PAD_EIM_WAIT__GPIO_5_0,
+
+ /* HDMI */
+ MX6DL_PAD_EIM_A25__HDMI_TX_CEC_LINE,
+ MX6DL_PAD_SD1_DAT1__HDMI_TX_OPHYDTB_0,
+ MX6DL_PAD_SD1_DAT0__HDMI_TX_OPHYDTB_1,
+
+ /* USBOTG ID pin */
+ MX6DL_PAD_GPIO_1__USBOTG_ID,
+
+ /* MLB150 */
+ MX6DL_PAD_GPIO_3__MLB_MLBCLK,
+ MX6DL_PAD_GPIO_6__MLB_MLBSIG,
+ MX6DL_PAD_GPIO_2__MLB_MLBDAT,
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_i2c3_pads[] = {
+ MX6DL_PAD_GPIO_5__I2C3_SCL,
+ MX6DL_PAD_GPIO_16__I2C3_SDA,
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_spdif_pads[] = {
+ /* SPDIF */
+ MX6DL_PAD_GPIO_16__SPDIF_IN1,
+ MX6DL_PAD_GPIO_17__SPDIF_OUT1,
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_can_pads[] = {
+ /* CAN1 */
+ MX6DL_PAD_GPIO_7__CAN1_TXCAN,
+ MX6DL_PAD_KEY_ROW2__CAN1_RXCAN,
+ MX6DL_PAD_GPIO_17__GPIO_7_12, /* CAN1 STBY */
+ MX6DL_PAD_GPIO_18__GPIO_7_13, /* CAN1 EN */
+
+ /* CAN2 */
+ MX6DL_PAD_KEY_COL4__CAN2_TXCAN,
+ MX6DL_PAD_KEY_ROW4__CAN2_RXCAN,
+ MX6DL_PAD_CSI0_DAT6__GPIO_5_24, /* CAN2 EN */
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_esai_record_pads[] = {
+ MX6DL_PAD_ENET_RX_ER__ESAI1_HCKR,
+ MX6DL_PAD_ENET_MDIO__ESAI1_SCKR,
+ MX6DL_PAD_ENET_REF_CLK__ESAI1_FSR,
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_csi0_sensor_pads[] = {
+ MX6DL_PAD_GPIO_0__CCM_CLKO,
+ /* ipu1 csi0 */
+ MX6DL_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
+ MX6DL_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
+ MX6DL_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
+ MX6DL_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
+ MX6DL_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
+ MX6DL_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
+ MX6DL_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
+ MX6DL_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
+ MX6DL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
+ MX6DL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
+ MX6DL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
+ /* camera reset */
+ MX6DL_PAD_GPIO_19__GPIO_4_5,
+ /* camera powerdown */
+ MX6DL_PAD_CSI0_DAT5__GPIO_5_23,
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_csi0_tvin_pads[] = {
+ /* ipu1 csi0 */
+ MX6DL_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
+ MX6DL_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
+ MX6DL_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
+ MX6DL_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
+ MX6DL_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
+ MX6DL_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
+ MX6DL_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
+ MX6DL_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
+ MX6DL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
+ MX6DL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
+ MX6DL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
+ /* camera reset */
+ MX6DL_PAD_CSI0_DAT7__GPIO_5_25,
+ /* camera powerdown */
+ MX6DL_PAD_CSI0_DAT5__GPIO_5_23,
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_mipi_sensor_pads[] = {
+ MX6DL_PAD_CSI0_MCLK__CCM_CLKO,
+};
+
+static iomux_v3_cfg_t mx6dl_arm2_audmux_pads[] = {
+
+ /* AUDMUX */
+ MX6DL_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC,
+ MX6DL_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD,
+ MX6DL_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS,
+ MX6DL_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD,
+};
+
+#define MX6DL_USDHC_PAD_SETTING(id, speed) \
+mx6dl_sd##id##_##speed##mhz[] = { \
+ MX6DL_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT4__USDHC##id##_DAT4_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT5__USDHC##id##_DAT5_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT6__USDHC##id##_DAT6_##speed##MHZ, \
+ MX6DL_PAD_SD##id##_DAT7__USDHC##id##_DAT7_##speed##MHZ, \
+}
+
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(3, 50);
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(3, 100);
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(3, 200);
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(4, 50);
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(4, 100);
+static iomux_v3_cfg_t MX6DL_USDHC_PAD_SETTING(4, 200);
+
+/* The GPMI is conflicted with SD3, so init this in the driver. */
+static iomux_v3_cfg_t mx6dl_gpmi_nand[] __initdata = {
+ MX6DL_PAD_NANDF_CLE__RAWNAND_CLE,
+ MX6DL_PAD_NANDF_ALE__RAWNAND_ALE,
+ MX6DL_PAD_NANDF_CS0__RAWNAND_CE0N,
+ MX6DL_PAD_NANDF_CS1__RAWNAND_CE1N,
+ MX6DL_PAD_NANDF_CS2__RAWNAND_CE2N,
+ MX6DL_PAD_NANDF_CS3__RAWNAND_CE3N,
+ MX6DL_PAD_NANDF_RB0__RAWNAND_READY0,
+ MX6DL_PAD_SD4_DAT0__RAWNAND_DQS,
+ MX6DL_PAD_NANDF_D0__RAWNAND_D0,
+ MX6DL_PAD_NANDF_D1__RAWNAND_D1,
+ MX6DL_PAD_NANDF_D2__RAWNAND_D2,
+ MX6DL_PAD_NANDF_D3__RAWNAND_D3,
+ MX6DL_PAD_NANDF_D4__RAWNAND_D4,
+ MX6DL_PAD_NANDF_D5__RAWNAND_D5,
+ MX6DL_PAD_NANDF_D6__RAWNAND_D6,
+ MX6DL_PAD_NANDF_D7__RAWNAND_D7,
+ MX6DL_PAD_SD4_CMD__RAWNAND_RDN,
+ MX6DL_PAD_SD4_CLK__RAWNAND_WRN,
+ MX6DL_PAD_NANDF_WP_B__RAWNAND_RESETN,
+};
diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.c b/arch/arm/mach-mx6/board-mx6q_arm2.c
index c3b46b7a551f..7d20f1cf8572 100644
--- a/arch/arm/mach-mx6/board-mx6q_arm2.c
+++ b/arch/arm/mach-mx6/board-mx6q_arm2.c
@@ -56,7 +56,6 @@
#include <mach/hardware.h>
#include <mach/mxc_dvfs.h>
#include <mach/memory.h>
-#include <mach/iomux-mx6q.h>
#include <mach/imx-uart.h>
#include <mach/viv_gpu.h>
#include <mach/ahci_sata.h>
@@ -78,35 +77,37 @@
#include "cpu_op-mx6.h"
#include "android.h"
-#define MX6Q_ARM2_LDB_BACKLIGHT IMX_GPIO_NR(1, 9)
-#define MX6Q_ARM2_ECSPI1_CS0 IMX_GPIO_NR(2, 30)
-#define MX6Q_ARM2_ECSPI1_CS1 IMX_GPIO_NR(3, 19)
-#define MX6Q_ARM2_DISP0_PWR IMX_GPIO_NR(3, 24)
-#define MX6Q_ARM2_DISP0_I2C_EN IMX_GPIO_NR(3, 28)
-#define MX6Q_ARM2_DISP0_DET_INT IMX_GPIO_NR(3, 31)
-#define MX6Q_ARM2_DISP0_RESET IMX_GPIO_NR(5, 0)
-#define MX6Q_ARM2_SD3_CD IMX_GPIO_NR(6, 11)
-#define MX6Q_ARM2_SD3_WP IMX_GPIO_NR(6, 14)
-#define MX6Q_ARM2_USB_OTG_PWR IMX_GPIO_NR(3, 22)
-#define MX6Q_ARM2_MAX7310_1_BASE_ADDR IMX_GPIO_NR(8, 0)
-#define MX6Q_ARM2_MAX7310_2_BASE_ADDR IMX_GPIO_NR(8, 8)
-#define MX6Q_ARM2_CAP_TCH_INT IMX_GPIO_NR(3, 31)
-
-#define MX6Q_ARM2_IO_EXP_GPIO1(x) \
- (MX6Q_ARM2_MAX7310_1_BASE_ADDR + (x))
-#define MX6Q_ARM2_IO_EXP_GPIO2(x) \
- (MX6Q_ARM2_MAX7310_2_BASE_ADDR + (x))
-
-#define MX6Q_ARM2_CAN1_STBY IMX_GPIO_NR(7, 12)
-#define MX6Q_ARM2_CAN1_EN IMX_GPIO_NR(7, 13)
-#define MX6Q_ARM2_CAN2_STBY MX6Q_ARM2_IO_EXP_GPIO2(1)
-#define MX6Q_ARM2_CAN2_EN IMX_GPIO_NR(5, 24)
-
-#define MX6Q_ARM2_CSI0_RST IMX_GPIO_NR(4, 5)
-#define MX6Q_ARM2_CSI0_PWN IMX_GPIO_NR(5, 23)
-#define MX6Q_ARM2_CSI0_RST_TVIN IMX_GPIO_NR(5, 25)
-
-#define BMCR_PDOWN 0x0800 /* PHY Powerdown */
+#include "board-mx6q_arm2.h"
+#include "board-mx6dl_arm2.h"
+
+/* GPIO PIN, sort by PORT/BIT */
+#define MX6_ARM2_LDB_BACKLIGHT IMX_GPIO_NR(1, 9)
+#define MX6_ARM2_ECSPI1_CS0 IMX_GPIO_NR(2, 30)
+#define MX6_ARM2_ECSPI1_CS1 IMX_GPIO_NR(3, 19)
+#define MX6_ARM2_USB_OTG_PWR IMX_GPIO_NR(3, 22)
+#define MX6_ARM2_DISP0_PWR IMX_GPIO_NR(3, 24)
+#define MX6_ARM2_DISP0_I2C_EN IMX_GPIO_NR(3, 28)
+#define MX6_ARM2_CAP_TCH_INT IMX_GPIO_NR(3, 31)
+#define MX6_ARM2_DISP0_DET_INT IMX_GPIO_NR(3, 31)
+#define MX6_ARM2_CSI0_RST IMX_GPIO_NR(4, 5)
+#define MX6_ARM2_DISP0_RESET IMX_GPIO_NR(5, 0)
+#define MX6_ARM2_CSI0_PWN IMX_GPIO_NR(5, 23)
+#define MX6_ARM2_CAN2_EN IMX_GPIO_NR(5, 24)
+#define MX6_ARM2_CSI0_RST_TVIN IMX_GPIO_NR(5, 25)
+#define MX6_ARM2_SD3_CD IMX_GPIO_NR(6, 11)
+#define MX6_ARM2_SD3_WP IMX_GPIO_NR(6, 14)
+#define MX6_ARM2_CAN1_STBY IMX_GPIO_NR(7, 12)
+#define MX6_ARM2_CAN1_EN IMX_GPIO_NR(7, 13)
+#define MX6_ARM2_MAX7310_1_BASE_ADDR IMX_GPIO_NR(8, 0)
+#define MX6_ARM2_MAX7310_2_BASE_ADDR IMX_GPIO_NR(8, 8)
+
+#define MX6_ARM2_IO_EXP_GPIO1(x) (MX6_ARM2_MAX7310_1_BASE_ADDR + (x))
+#define MX6_ARM2_IO_EXP_GPIO2(x) (MX6_ARM2_MAX7310_2_BASE_ADDR + (x))
+
+#define MX6_ARM2_CAN2_STBY MX6_ARM2_IO_EXP_GPIO2(1)
+
+
+#define BMCR_PDOWN 0x0800 /* PHY Powerdown */
void __init early_console_setup(unsigned long base, struct clk *clk);
static struct clk *sata_clk;
@@ -120,277 +121,6 @@ extern void (*put_cpu_regulator)(void);
extern char *gp_reg_id;
extern void mx6_cpu_regulator_init(void);
-static iomux_v3_cfg_t mx6q_arm2_pads[] = {
-
- /* UART4 for debug */
- MX6Q_PAD_KEY_COL0__UART4_TXD,
- MX6Q_PAD_KEY_ROW0__UART4_RXD,
- /* USB HSIC ports use the same pin with ENET */
-#ifdef CONFIG_USB_EHCI_ARC_HSIC
- /* USB H2 strobe/data pin */
- MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE,
- MX6Q_PAD_RGMII_TXC__USBOH3_H2_DATA,
-
- /* USB H3 strobe/data pin */
- MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE,
- MX6Q_PAD_RGMII_RX_CTL__USBOH3_H3_DATA,
- /* ENET */
-#else
- MX6Q_PAD_KEY_COL1__ENET_MDIO,
- MX6Q_PAD_KEY_COL2__ENET_MDC,
- MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC,
- MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0,
- MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1,
- MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2,
- MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3,
- MX6Q_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL,
- MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK,
- MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC,
- MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0,
- MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1,
- MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2,
- MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3,
- MX6Q_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL,
-#endif
- /* MCLK for csi0 */
- MX6Q_PAD_GPIO_0__CCM_CLKO,
- MX6Q_PAD_GPIO_3__CCM_CLKO2,
-
- /* SD1 */
- MX6Q_PAD_SD1_CLK__USDHC1_CLK,
- MX6Q_PAD_SD1_CMD__USDHC1_CMD,
- MX6Q_PAD_SD1_DAT0__USDHC1_DAT0,
- MX6Q_PAD_SD1_DAT1__USDHC1_DAT1,
- MX6Q_PAD_SD1_DAT2__USDHC1_DAT2,
- MX6Q_PAD_SD1_DAT3__USDHC1_DAT3,
- /* SD2 */
- MX6Q_PAD_SD2_CLK__USDHC2_CLK,
- MX6Q_PAD_SD2_CMD__USDHC2_CMD,
- MX6Q_PAD_SD2_DAT0__USDHC2_DAT0,
- MX6Q_PAD_SD2_DAT1__USDHC2_DAT1,
- MX6Q_PAD_SD2_DAT2__USDHC2_DAT2,
- MX6Q_PAD_SD2_DAT3__USDHC2_DAT3,
- /* SD3 */
- MX6Q_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
- MX6Q_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
- MX6Q_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
- MX6Q_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
- MX6Q_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
- MX6Q_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
- MX6Q_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ,
- MX6Q_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ,
- MX6Q_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ,
- MX6Q_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ,
- MX6Q_PAD_SD3_RST__USDHC3_RST,
- /* SD3 VSelect */
- MX6Q_PAD_GPIO_18__USDHC3_VSELECT,
- /* SD3_CD and SD3_WP */
- MX6Q_PAD_NANDF_CS0__GPIO_6_11,
- MX6Q_PAD_NANDF_CS1__GPIO_6_14,
- /* SD4 */
- MX6Q_PAD_SD4_CLK__USDHC4_CLK_50MHZ,
- MX6Q_PAD_SD4_CMD__USDHC4_CMD_50MHZ,
- MX6Q_PAD_SD4_DAT0__USDHC4_DAT0_50MHZ,
- MX6Q_PAD_SD4_DAT1__USDHC4_DAT1_50MHZ,
- MX6Q_PAD_SD4_DAT2__USDHC4_DAT2_50MHZ,
- MX6Q_PAD_SD4_DAT3__USDHC4_DAT3_50MHZ,
- MX6Q_PAD_SD4_DAT4__USDHC4_DAT4_50MHZ,
- MX6Q_PAD_SD4_DAT5__USDHC4_DAT5_50MHZ,
- MX6Q_PAD_SD4_DAT6__USDHC4_DAT6_50MHZ,
- MX6Q_PAD_SD4_DAT7__USDHC4_DAT7_50MHZ,
- MX6Q_PAD_NANDF_ALE__USDHC4_RST,
- /* eCSPI1 */
- MX6Q_PAD_EIM_EB2__ECSPI1_SS0,
- MX6Q_PAD_EIM_D16__ECSPI1_SCLK,
- MX6Q_PAD_EIM_D17__ECSPI1_MISO,
- MX6Q_PAD_EIM_D18__ECSPI1_MOSI,
- MX6Q_PAD_EIM_D19__ECSPI1_SS1,
- MX6Q_PAD_EIM_EB2__GPIO_2_30, /*SS0*/
- MX6Q_PAD_EIM_D19__GPIO_3_19, /*SS1*/
-
- /* ESAI */
- MX6Q_PAD_ENET_RXD0__ESAI1_HCKT,
- MX6Q_PAD_ENET_CRS_DV__ESAI1_SCKT,
- MX6Q_PAD_ENET_RXD1__ESAI1_FST,
- MX6Q_PAD_ENET_TX_EN__ESAI1_TX3_RX2,
- MX6Q_PAD_ENET_TXD1__ESAI1_TX2_RX3,
- MX6Q_PAD_ENET_TXD0__ESAI1_TX4_RX1,
- MX6Q_PAD_ENET_MDC__ESAI1_TX5_RX0,
- MX6Q_PAD_NANDF_CS2__ESAI1_TX0,
- MX6Q_PAD_NANDF_CS3__ESAI1_TX1,
-
- /* I2C1 */
- MX6Q_PAD_CSI0_DAT8__I2C1_SDA,
- MX6Q_PAD_CSI0_DAT9__I2C1_SCL,
-
- /* I2C2 */
- MX6Q_PAD_KEY_COL3__I2C2_SCL,
- MX6Q_PAD_KEY_ROW3__I2C2_SDA,
-
- /* DISPLAY */
- MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
- MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15,
- MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2,
- MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3,
- MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
- MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
- MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
- MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
- MX6Q_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
- MX6Q_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
- MX6Q_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
- MX6Q_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
- MX6Q_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
- MX6Q_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
- MX6Q_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
- MX6Q_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
- MX6Q_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
- MX6Q_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
- MX6Q_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
- MX6Q_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
- MX6Q_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
- MX6Q_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
- MX6Q_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
- MX6Q_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
- MX6Q_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20,
- MX6Q_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
- MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
- MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
-
- MX6Q_PAD_EIM_D24__GPIO_3_24,
-
- /* UART2 */
- MX6Q_PAD_EIM_D26__UART2_RXD,
- MX6Q_PAD_EIM_D27__UART2_TXD,
- MX6Q_PAD_EIM_D28__UART2_RTS,
- MX6Q_PAD_EIM_D29__UART2_CTS,
-
- /* PWM1 */
- MX6Q_PAD_GPIO_9__PWM1_PWMO,
-
- /* DISP0 DET */
- MX6Q_PAD_EIM_D31__GPIO_3_31,
-
- /* DISP0 RESET */
- MX6Q_PAD_EIM_WAIT__GPIO_5_0,
-
- /* HDMI */
- MX6Q_PAD_EIM_A25__HDMI_TX_CEC_LINE,
- MX6Q_PAD_SD1_DAT1__HDMI_TX_OPHYDTB_0,
- MX6Q_PAD_SD1_DAT0__HDMI_TX_OPHYDTB_1,
-
- /* USBOTG ID pin */
- MX6Q_PAD_GPIO_1__USBOTG_ID,
-
- /* MLB150 */
- MX6Q_PAD_GPIO_3__MLB_MLBCLK,
- MX6Q_PAD_GPIO_6__MLB_MLBSIG,
- MX6Q_PAD_GPIO_2__MLB_MLBDAT,
-};
-
-static iomux_v3_cfg_t mx6q_arm2_i2c3_pads[] = {
- MX6Q_PAD_GPIO_5__I2C3_SCL,
- MX6Q_PAD_GPIO_16__I2C3_SDA,
-};
-
-static iomux_v3_cfg_t mx6q_arm2_spdif_pads[] = {
- /* SPDIF */
- MX6Q_PAD_GPIO_16__SPDIF_IN1,
- MX6Q_PAD_GPIO_17__SPDIF_OUT1,
-};
-
-static iomux_v3_cfg_t mx6q_arm2_can_pads[] = {
- /* CAN1 */
- MX6Q_PAD_GPIO_7__CAN1_TXCAN,
- MX6Q_PAD_KEY_ROW2__CAN1_RXCAN,
- MX6Q_PAD_GPIO_17__GPIO_7_12, /* CAN1 STBY */
- MX6Q_PAD_GPIO_18__GPIO_7_13, /* CAN1 EN */
-
- /* CAN2 */
- MX6Q_PAD_KEY_COL4__CAN2_TXCAN,
- MX6Q_PAD_KEY_ROW4__CAN2_RXCAN,
- MX6Q_PAD_CSI0_DAT6__GPIO_5_24, /* CAN2 EN */
-};
-
-static iomux_v3_cfg_t mx6q_arm2_esai_record_pads[] = {
- MX6Q_PAD_ENET_RX_ER__ESAI1_HCKR,
- MX6Q_PAD_ENET_MDIO__ESAI1_SCKR,
- MX6Q_PAD_ENET_REF_CLK__ESAI1_FSR,
-};
-
-static iomux_v3_cfg_t mx6q_arm2_csi0_sensor_pads[] = {
- MX6Q_PAD_GPIO_0__CCM_CLKO,
- /* ipu1 csi0 */
- MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
- MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
- MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
- MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
- MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
- MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
- MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
- MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
- MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
- MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
- MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
- /* camera reset */
- MX6Q_PAD_GPIO_19__GPIO_4_5,
- /* camera powerdown */
- MX6Q_PAD_CSI0_DAT5__GPIO_5_23,
-};
-
-static iomux_v3_cfg_t mx6q_arm2_csi0_tvin_pads[] = {
- /* ipu1 csi0 */
- MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
- MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
- MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
- MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
- MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
- MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
- MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
- MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
- MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
- MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
- MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
- /* camera reset */
- MX6Q_PAD_CSI0_DAT7__GPIO_5_25,
- /* camera powerdown */
- MX6Q_PAD_CSI0_DAT5__GPIO_5_23,
-};
-
-static iomux_v3_cfg_t mx6q_arm2_mipi_sensor_pads[] = {
- MX6Q_PAD_CSI0_MCLK__CCM_CLKO,
-};
-
-static iomux_v3_cfg_t mx6q_arm2_audmux_pads[] = {
-
- /* AUDMUX */
- MX6Q_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC,
- MX6Q_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD,
- MX6Q_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS,
- MX6Q_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD,
-};
-
-#define MX6Q_USDHC_PAD_SETTING(id, speed) \
-mx6q_sd##id##_##speed##mhz[] = { \
- MX6Q_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \
- MX6Q_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \
- MX6Q_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \
- MX6Q_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \
- MX6Q_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \
- MX6Q_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \
- MX6Q_PAD_SD##id##_DAT4__USDHC##id##_DAT4_##speed##MHZ, \
- MX6Q_PAD_SD##id##_DAT5__USDHC##id##_DAT5_##speed##MHZ, \
- MX6Q_PAD_SD##id##_DAT6__USDHC##id##_DAT6_##speed##MHZ, \
- MX6Q_PAD_SD##id##_DAT7__USDHC##id##_DAT7_##speed##MHZ, \
-}
-
-static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 50);
-static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 100);
-static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 200);
-static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(4, 50);
-static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(4, 100);
-static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(4, 200);
-
enum sd_pad_mode {
SD_PAD_MODE_LOW_SPEED,
SD_PAD_MODE_MED_SPEED,
@@ -401,27 +131,53 @@ static int plt_sd3_pad_change(int clock)
{
static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
+ iomux_v3_cfg_t *sd3_pads_200mhz = NULL;
+ iomux_v3_cfg_t *sd3_pads_100mhz = NULL;
+ iomux_v3_cfg_t *sd3_pads_50mhz = NULL;
+
+ u32 sd3_pads_200mhz_cnt;
+ u32 sd3_pads_100mhz_cnt;
+ u32 sd3_pads_50mhz_cnt;
+
+ if (cpu_is_mx6q()) {
+ sd3_pads_200mhz = mx6q_sd3_200mhz;
+ sd3_pads_100mhz = mx6q_sd3_100mhz;
+ sd3_pads_50mhz = mx6q_sd3_50mhz;
+
+ sd3_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd3_200mhz);
+ sd3_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd3_100mhz);
+ sd3_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd3_50mhz);
+ } else if (cpu_is_mx6dl()) {
+ sd3_pads_200mhz = mx6dl_sd3_200mhz;
+ sd3_pads_100mhz = mx6dl_sd3_100mhz;
+ sd3_pads_50mhz = mx6dl_sd3_50mhz;
+
+ sd3_pads_200mhz_cnt = ARRAY_SIZE(mx6dl_sd3_200mhz);
+ sd3_pads_100mhz_cnt = ARRAY_SIZE(mx6dl_sd3_100mhz);
+ sd3_pads_50mhz_cnt = ARRAY_SIZE(mx6dl_sd3_50mhz);
+ }
+
if (clock > 100000000) {
if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
return 0;
-
+ BUG_ON(!sd3_pads_200mhz);
pad_mode = SD_PAD_MODE_HIGH_SPEED;
- return mxc_iomux_v3_setup_multiple_pads(mx6q_sd3_200mhz,
- ARRAY_SIZE(mx6q_sd3_200mhz));
+ return mxc_iomux_v3_setup_multiple_pads(sd3_pads_200mhz,
+ sd3_pads_200mhz_cnt);
} else if (clock > 52000000) {
if (pad_mode == SD_PAD_MODE_MED_SPEED)
return 0;
-
+ BUG_ON(!sd3_pads_100mhz);
pad_mode = SD_PAD_MODE_MED_SPEED;
- return mxc_iomux_v3_setup_multiple_pads(mx6q_sd3_100mhz,
- ARRAY_SIZE(mx6q_sd3_100mhz));
+ return mxc_iomux_v3_setup_multiple_pads(sd3_pads_100mhz,
+ sd3_pads_100mhz_cnt);
} else {
if (pad_mode == SD_PAD_MODE_LOW_SPEED)
return 0;
-
+ BUG_ON(!sd3_pads_50mhz);
pad_mode = SD_PAD_MODE_LOW_SPEED;
- return mxc_iomux_v3_setup_multiple_pads(mx6q_sd3_50mhz,
- ARRAY_SIZE(mx6q_sd3_50mhz));
+ return mxc_iomux_v3_setup_multiple_pads(sd3_pads_50mhz,
+ sd3_pads_50mhz_cnt);
}
}
@@ -429,103 +185,118 @@ static int plt_sd4_pad_change(int clock)
{
static enum sd_pad_mode pad_mode = SD_PAD_MODE_LOW_SPEED;
+ iomux_v3_cfg_t *sd4_pads_200mhz = NULL;
+ iomux_v3_cfg_t *sd4_pads_100mhz = NULL;
+ iomux_v3_cfg_t *sd4_pads_50mhz = NULL;
+
+ u32 sd4_pads_200mhz_cnt;
+ u32 sd4_pads_100mhz_cnt;
+ u32 sd4_pads_50mhz_cnt;
+
+ if (cpu_is_mx6q()) {
+ sd4_pads_200mhz = mx6q_sd4_200mhz;
+ sd4_pads_100mhz = mx6q_sd4_100mhz;
+ sd4_pads_50mhz = mx6q_sd4_50mhz;
+
+ sd4_pads_200mhz_cnt = ARRAY_SIZE(mx6q_sd4_200mhz);
+ sd4_pads_100mhz_cnt = ARRAY_SIZE(mx6q_sd4_100mhz);
+ sd4_pads_50mhz_cnt = ARRAY_SIZE(mx6q_sd4_50mhz);
+ } else if (cpu_is_mx6dl()) {
+ sd4_pads_200mhz = mx6dl_sd4_200mhz;
+ sd4_pads_100mhz = mx6dl_sd4_100mhz;
+ sd4_pads_50mhz = mx6dl_sd4_50mhz;
+
+ sd4_pads_200mhz_cnt = ARRAY_SIZE(mx6dl_sd4_200mhz);
+ sd4_pads_100mhz_cnt = ARRAY_SIZE(mx6dl_sd4_100mhz);
+ sd4_pads_50mhz_cnt = ARRAY_SIZE(mx6dl_sd4_50mhz);
+ }
+
if (clock > 100000000) {
if (pad_mode == SD_PAD_MODE_HIGH_SPEED)
return 0;
pad_mode = SD_PAD_MODE_HIGH_SPEED;
- return mxc_iomux_v3_setup_multiple_pads(mx6q_sd4_200mhz,
- ARRAY_SIZE(mx6q_sd4_200mhz));
+ return mxc_iomux_v3_setup_multiple_pads(sd4_pads_200mhz,
+ sd4_pads_200mhz_cnt);
} else if (clock > 52000000) {
if (pad_mode == SD_PAD_MODE_MED_SPEED)
return 0;
pad_mode = SD_PAD_MODE_MED_SPEED;
- return mxc_iomux_v3_setup_multiple_pads(mx6q_sd4_100mhz,
- ARRAY_SIZE(mx6q_sd4_100mhz));
+ return mxc_iomux_v3_setup_multiple_pads(sd4_pads_100mhz,
+ sd4_pads_100mhz_cnt);
} else {
if (pad_mode == SD_PAD_MODE_LOW_SPEED)
return 0;
pad_mode = SD_PAD_MODE_LOW_SPEED;
- return mxc_iomux_v3_setup_multiple_pads(mx6q_sd4_50mhz,
- ARRAY_SIZE(mx6q_sd4_50mhz));
+ return mxc_iomux_v3_setup_multiple_pads(sd4_pads_50mhz,
+ sd4_pads_50mhz_cnt);
}
}
-static const struct esdhc_platform_data mx6q_arm2_sd3_data __initconst = {
- .cd_gpio = MX6Q_ARM2_SD3_CD,
- .wp_gpio = MX6Q_ARM2_SD3_WP,
- .support_18v = 1,
- .support_8bit = 1,
- .keep_power_at_suspend = 1,
- .delay_line = 0,
- .platform_pad_change = plt_sd3_pad_change,
-};
-
-/* No card detect signal for SD4 */
-static const struct esdhc_platform_data mx6q_arm2_sd4_data __initconst = {
- .always_present = 1,
- .support_8bit = 1,
- .keep_power_at_suspend = 1,
- .platform_pad_change = plt_sd4_pad_change,
-};
-
-/* The GPMI is conflicted with SD3, so init this in the driver. */
-static iomux_v3_cfg_t mx6q_gpmi_nand[] __initdata = {
- MX6Q_PAD_NANDF_CLE__RAWNAND_CLE,
- MX6Q_PAD_NANDF_ALE__RAWNAND_ALE,
- MX6Q_PAD_NANDF_CS0__RAWNAND_CE0N,
- MX6Q_PAD_NANDF_CS1__RAWNAND_CE1N,
- MX6Q_PAD_NANDF_CS2__RAWNAND_CE2N,
- MX6Q_PAD_NANDF_CS3__RAWNAND_CE3N,
- MX6Q_PAD_NANDF_RB0__RAWNAND_READY0,
- MX6Q_PAD_SD4_DAT0__RAWNAND_DQS,
- MX6Q_PAD_NANDF_D0__RAWNAND_D0,
- MX6Q_PAD_NANDF_D1__RAWNAND_D1,
- MX6Q_PAD_NANDF_D2__RAWNAND_D2,
- MX6Q_PAD_NANDF_D3__RAWNAND_D3,
- MX6Q_PAD_NANDF_D4__RAWNAND_D4,
- MX6Q_PAD_NANDF_D5__RAWNAND_D5,
- MX6Q_PAD_NANDF_D6__RAWNAND_D6,
- MX6Q_PAD_NANDF_D7__RAWNAND_D7,
- MX6Q_PAD_SD4_CMD__RAWNAND_RDN,
- MX6Q_PAD_SD4_CLK__RAWNAND_WRN,
- MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN,
-};
-
-static int gpmi_nfc_platform_init(void)
+static const struct esdhc_platform_data mx6_arm2_sd3_data __initconst = {
+ .cd_gpio = MX6_ARM2_SD3_CD,
+ .wp_gpio = MX6_ARM2_SD3_WP,
+ .support_18v = 1,
+ .support_8bit = 1,
+ .keep_power_at_suspend = 1,
+ .delay_line = 0,
+ .platform_pad_change = plt_sd3_pad_change,
+};
+
+/* No card detect signal for SD4 on ARM2 board*/
+static const struct esdhc_platform_data mx6_arm2_sd4_data __initconst = {
+ .always_present = 1,
+ .support_8bit = 1,
+ .keep_power_at_suspend = 1,
+ .platform_pad_change = plt_sd4_pad_change,
+};
+
+static int __init gpmi_nand_platform_init(void)
{
- return mxc_iomux_v3_setup_multiple_pads(mx6q_gpmi_nand,
- ARRAY_SIZE(mx6q_gpmi_nand));
+ iomux_v3_cfg_t *nand_pads = NULL;
+ u32 nand_pads_cnt;
+
+ if (cpu_is_mx6q()) {
+ nand_pads = mx6q_gpmi_nand;
+ nand_pads_cnt = ARRAY_SIZE(mx6dl_gpmi_nand);
+ } else if (cpu_is_mx6dl()) {
+ nand_pads = mx6dl_gpmi_nand;
+ nand_pads_cnt = ARRAY_SIZE(mx6dl_gpmi_nand);
+
+ }
+ BUG_ON(!nand_pads);
+ return mxc_iomux_v3_setup_multiple_pads(nand_pads, nand_pads_cnt);
}
-static const struct gpmi_nfc_platform_data
-mx6q_gpmi_nfc_platform_data __initconst = {
- .platform_init = gpmi_nfc_platform_init,
+static const struct gpmi_nand_platform_data
+mx6_gpmi_nand_platform_data __initconst = {
+ .platform_init = gpmi_nand_platform_init,
.min_prop_delay_in_ns = 5,
.max_prop_delay_in_ns = 9,
.max_chip_count = 1,
+ .enable_bbt = 1,
};
static const struct anatop_thermal_platform_data
- mx6q_arm2_anatop_thermal_data __initconst = {
+ mx6_arm2_anatop_thermal_data __initconst = {
.name = "anatop_thermal",
};
-static const struct imxuart_platform_data mx6q_uart1_data __initconst = {
- .flags = IMXUART_HAVE_RTSCTS | IMXUART_USE_DCEDTE | IMXUART_SDMA,
+static const struct imxuart_platform_data mx6_arm2_uart1_data __initconst = {
+ .flags = IMXUART_HAVE_RTSCTS | IMXUART_USE_DCEDTE | IMXUART_SDMA,
.dma_req_rx = MX6Q_DMA_REQ_UART2_RX,
.dma_req_tx = MX6Q_DMA_REQ_UART2_TX,
};
-static inline void mx6q_arm2_init_uart(void)
+static inline void mx6_arm2_init_uart(void)
{
imx6q_add_imx_uart(3, NULL);
- imx6q_add_imx_uart(1, &mx6q_uart1_data);
+ imx6q_add_imx_uart(1, &mx6_arm2_uart1_data);
}
-static int mx6q_arm2_fec_phy_init(struct phy_device *phydev)
+static int mx6_arm2_fec_phy_init(struct phy_device *phydev)
{
unsigned short val;
@@ -552,7 +323,7 @@ static int mx6q_arm2_fec_phy_init(struct phy_device *phydev)
return 0;
}
-static int mx6q_arm2_fec_power_hibernate(struct phy_device *phydev)
+static int mx6_arm2_fec_power_hibernate(struct phy_device *phydev)
{
unsigned short val;
@@ -567,52 +338,51 @@ static int mx6q_arm2_fec_power_hibernate(struct phy_device *phydev)
}
static struct fec_platform_data fec_data __initdata = {
- .init = mx6q_arm2_fec_phy_init,
- .power_hibernate = mx6q_arm2_fec_power_hibernate,
- .phy = PHY_INTERFACE_MODE_RGMII,
+ .init = mx6_arm2_fec_phy_init,
+ .power_hibernate = mx6_arm2_fec_power_hibernate,
+ .phy = PHY_INTERFACE_MODE_RGMII,
};
-static int mx6q_arm2_spi_cs[] = {
- MX6Q_ARM2_ECSPI1_CS0,
- MX6Q_ARM2_ECSPI1_CS1,
+static int mx6_arm2_spi_cs[] = {
+ MX6_ARM2_ECSPI1_CS0,
+ MX6_ARM2_ECSPI1_CS1,
};
-static const struct spi_imx_master mx6q_arm2_spi_data __initconst = {
- .chipselect = mx6q_arm2_spi_cs,
- .num_chipselect = ARRAY_SIZE(mx6q_arm2_spi_cs),
+static const struct spi_imx_master mx6_arm2_spi_data __initconst = {
+ .chipselect = mx6_arm2_spi_cs,
+ .num_chipselect = ARRAY_SIZE(mx6_arm2_spi_cs),
};
#if defined(CONFIG_MTD_M25P80) || defined(CONFIG_MTD_M25P80_MODULE)
static struct mtd_partition m25p32_partitions[] = {
{
- .name = "bootloader",
- .offset = 0,
- .size = 0x00040000,
- },
- {
- .name = "kernel",
- .offset = MTDPART_OFS_APPEND,
- .size = MTDPART_SIZ_FULL,
+ .name = "bootloader",
+ .offset = 0,
+ .size = 0x00040000,
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
},
};
static struct flash_platform_data m25p32_spi_flash_data = {
- .name = "m25p32",
- .parts = m25p32_partitions,
- .nr_parts = ARRAY_SIZE(m25p32_partitions),
- .type = "m25p32",
+ .name = "m25p32",
+ .parts = m25p32_partitions,
+ .nr_parts = ARRAY_SIZE(m25p32_partitions),
+ .type = "m25p32",
};
#endif
static struct spi_board_info m25p32_spi0_board_info[] __initdata = {
#if defined(CONFIG_MTD_M25P80)
{
- /* The modalias must be the same as spi device driver name */
- .modalias = "m25p80",
- .max_speed_hz = 20000000,
- .bus_num = 0,
- .chip_select = 1,
- .platform_data = &m25p32_spi_flash_data,
+ /* The modalias must be the same as spi device driver name */
+ .modalias = "m25p80",
+ .max_speed_hz = 20000000,
+ .bus_num = 0,
+ .chip_select = 1,
+ .platform_data = &m25p32_spi_flash_data,
},
#endif
};
@@ -627,9 +397,7 @@ static int max7310_1_setup(struct i2c_client *client,
unsigned gpio_base, unsigned ngpio,
void *context)
{
- int max7310_gpio_value[] = {
- 0, 1, 0, 1, 0, 0, 0, 0,
- };
+ int max7310_gpio_value[] = { 0, 1, 0, 1, 0, 0, 0, 0 };
int n;
@@ -647,7 +415,7 @@ static int max7310_1_setup(struct i2c_client *client,
}
static struct pca953x_platform_data max7310_platdata = {
- .gpio_base = MX6Q_ARM2_MAX7310_1_BASE_ADDR,
+ .gpio_base = MX6_ARM2_MAX7310_1_BASE_ADDR,
.invert = 0,
.setup = max7310_1_setup,
};
@@ -656,9 +424,7 @@ static int max7310_u48_setup(struct i2c_client *client,
unsigned gpio_base, unsigned ngpio,
void *context)
{
- int max7310_gpio_value[] = {
- 1, 1, 1, 1, 0, 1, 0, 0,
- };
+ int max7310_gpio_value[] = { 1, 1, 1, 1, 0, 1, 0, 0 };
int n;
@@ -676,7 +442,7 @@ static int max7310_u48_setup(struct i2c_client *client,
}
static struct pca953x_platform_data max7310_u48_platdata = {
- .gpio_base = MX6Q_ARM2_MAX7310_2_BASE_ADDR,
+ .gpio_base = MX6_ARM2_MAX7310_2_BASE_ADDR,
.invert = 0,
.setup = max7310_u48_setup,
};
@@ -684,46 +450,59 @@ static struct pca953x_platform_data max7310_u48_platdata = {
static void ddc_dvi_init(void)
{
/* enable DVI I2C */
- gpio_set_value(MX6Q_ARM2_DISP0_I2C_EN, 1);
+ gpio_set_value(MX6_ARM2_DISP0_I2C_EN, 1);
/* DISP0 Detect */
- gpio_request(MX6Q_ARM2_DISP0_DET_INT, "disp0-detect");
- gpio_direction_input(MX6Q_ARM2_DISP0_DET_INT);
+ gpio_request(MX6_ARM2_DISP0_DET_INT, "disp0-detect");
+ gpio_direction_input(MX6_ARM2_DISP0_DET_INT);
}
static int ddc_dvi_update(void)
{
/* DVI cable state */
- if (gpio_get_value(MX6Q_ARM2_DISP0_DET_INT) == 1)
+ if (gpio_get_value(MX6_ARM2_DISP0_DET_INT) == 1)
return 1;
- else
- return 0;
+ return 0;
}
static struct fsl_mxc_dvi_platform_data sabr_ddc_dvi_data = {
- .ipu_id = 0,
- .disp_id = 0,
- .init = ddc_dvi_init,
- .update = ddc_dvi_update,
+ .ipu_id = 0,
+ .disp_id = 0,
+ .init = ddc_dvi_init,
+ .update = ddc_dvi_update,
};
-static void mx6q_csi0_io_init(void)
+static void mx6_csi0_io_init(void)
{
if (0 == sgtl5000_en) {
- mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_csi0_sensor_pads,
- ARRAY_SIZE(mx6q_arm2_csi0_sensor_pads));
+ iomux_v3_cfg_t *sensor_pads = NULL;
+ u32 sensor_pads_cnt;
+
+ if (cpu_is_mx6q()) {
+ sensor_pads = mx6q_arm2_csi0_sensor_pads;
+ sensor_pads_cnt = \
+ ARRAY_SIZE(mx6q_arm2_csi0_sensor_pads);
+ } else if (cpu_is_mx6dl()) {
+ sensor_pads = mx6dl_arm2_csi0_sensor_pads;
+ sensor_pads_cnt = \
+ ARRAY_SIZE(mx6dl_arm2_csi0_sensor_pads);
+ }
+
+ BUG_ON(!sensor_pads);
+ mxc_iomux_v3_setup_multiple_pads(sensor_pads, sensor_pads_cnt);
}
/* Camera reset */
- gpio_request(MX6Q_ARM2_CSI0_RST, "cam-reset");
- gpio_direction_output(MX6Q_ARM2_CSI0_RST, 1);
+ gpio_request(MX6_ARM2_CSI0_RST, "cam-reset");
+ gpio_direction_output(MX6_ARM2_CSI0_RST, 1);
/* Camera power down */
- gpio_request(MX6Q_ARM2_CSI0_PWN, "cam-pwdn");
- gpio_direction_output(MX6Q_ARM2_CSI0_PWN, 1);
+ gpio_request(MX6_ARM2_CSI0_PWN, "cam-pwdn");
+ gpio_direction_output(MX6_ARM2_CSI0_PWN, 1);
msleep(1);
- gpio_set_value(MX6Q_ARM2_CSI0_PWN, 0);
+ gpio_set_value(MX6_ARM2_CSI0_PWN, 0);
- /* For MX6Q GPR1 bit19 and bit20 meaning:
+ /* For MX6Q:
+ * GPR1 bit19 and bit20 meaning:
* Bit19: 0 - Enable mipi to IPU1 CSI0
* virtual channel is fixed to 0
* 1 - Enable parallel interface to IPU1 CSI0
@@ -734,79 +513,114 @@ static void mx6q_csi0_io_init(void)
* virtual channel is fixed to 1
* IPU2 CSI0 directly connect to mipi csi2,
* virtual channel is fixed to 2
+ *
+ * For MX6DL:
+ * GPR1 bit 21 and GPR13 bit 0-5, RM has detail information
*/
- mxc_iomux_set_gpr_register(1, 19, 1, 1);
+ if (cpu_is_mx6q())
+ mxc_iomux_set_gpr_register(1, 19, 1, 1);
+ else if (cpu_is_mx6dl())
+ mxc_iomux_set_gpr_register(13, 0, 3, 4);
}
static struct fsl_mxc_camera_platform_data camera_data = {
- .analog_regulator = "DA9052_LDO7",
- .core_regulator = "DA9052_LDO9",
- .mclk = 24000000,
- .csi = 0,
- .io_init = mx6q_csi0_io_init,
+ .analog_regulator = "DA9052_LDO7",
+ .core_regulator = "DA9052_LDO9",
+ .mclk = 24000000,
+ .csi = 0,
+ .io_init = mx6_csi0_io_init,
};
-static void mx6q_csi0_tvin_io_init(void)
+static void mx6_csi0_tvin_io_init(void)
{
if (0 == sgtl5000_en) {
- mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_csi0_tvin_pads,
- ARRAY_SIZE(mx6q_arm2_csi0_tvin_pads));
+ iomux_v3_cfg_t *tvin_pads = NULL;
+ u32 tvin_pads_cnt;
+
+ if (cpu_is_mx6q()) {
+ tvin_pads = mx6q_arm2_csi0_tvin_pads;
+ tvin_pads_cnt = \
+ ARRAY_SIZE(mx6q_arm2_csi0_tvin_pads);
+ } else if (cpu_is_mx6dl()) {
+ tvin_pads = mx6dl_arm2_csi0_tvin_pads;
+ tvin_pads_cnt = \
+ ARRAY_SIZE(mx6dl_arm2_csi0_tvin_pads);
+ }
+
+ BUG_ON(!tvin_pads);
+ mxc_iomux_v3_setup_multiple_pads(tvin_pads, tvin_pads_cnt);
}
/* Tvin reset */
- gpio_request(MX6Q_ARM2_CSI0_RST_TVIN, "tvin-reset");
- gpio_direction_output(MX6Q_ARM2_CSI0_RST_TVIN, 1);
+ gpio_request(MX6_ARM2_CSI0_RST_TVIN, "tvin-reset");
+ gpio_direction_output(MX6_ARM2_CSI0_RST_TVIN, 1);
/* Tvin power down */
- gpio_request(MX6Q_ARM2_CSI0_PWN, "cam-pwdn");
- gpio_direction_output(MX6Q_ARM2_CSI0_PWN, 0);
+ gpio_request(MX6_ARM2_CSI0_PWN, "cam-pwdn");
+ gpio_direction_output(MX6_ARM2_CSI0_PWN, 0);
msleep(1);
- gpio_set_value(MX6Q_ARM2_CSI0_PWN, 1);
+ gpio_set_value(MX6_ARM2_CSI0_PWN, 1);
- mxc_iomux_set_gpr_register(1, 19, 1, 1);
+ if (cpu_is_mx6q())
+ mxc_iomux_set_gpr_register(1, 19, 1, 1);
+ else if (cpu_is_mx6dl())
+ mxc_iomux_set_gpr_register(13, 0, 3, 4);
}
static struct fsl_mxc_tvin_platform_data tvin_data = {
- .io_init = mx6q_csi0_tvin_io_init,
+ .io_init = mx6_csi0_tvin_io_init,
.cvbs = false,
};
-static void mx6q_mipi_sensor_io_init(void)
+static void mx6_mipi_sensor_io_init(void)
{
- mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_mipi_sensor_pads,
- ARRAY_SIZE(mx6q_arm2_mipi_sensor_pads));
+ iomux_v3_cfg_t *mipi_sensor_pads = NULL;
+ u32 mipi_sensor_pads_cnt;
- mxc_iomux_set_gpr_register(1, 19, 1, 0);
+ if (cpu_is_mx6q()) {
+ mipi_sensor_pads = mx6q_arm2_mipi_sensor_pads;
+ mipi_sensor_pads_cnt = ARRAY_SIZE(mx6q_arm2_mipi_sensor_pads);
+ } else if (cpu_is_mx6dl()) {
+ mipi_sensor_pads = mx6dl_arm2_mipi_sensor_pads;
+ mipi_sensor_pads_cnt = ARRAY_SIZE(mx6dl_arm2_mipi_sensor_pads);
+
+ }
+ BUG_ON(!mipi_sensor_pads);
+ mxc_iomux_v3_setup_multiple_pads(mipi_sensor_pads,
+ mipi_sensor_pads_cnt);
+
+ if (cpu_is_mx6q())
+ mxc_iomux_set_gpr_register(1, 19, 1, 0);
+ if (cpu_is_mx6dl())
+ mxc_iomux_set_gpr_register(13, 0, 3, 0);
}
static struct fsl_mxc_camera_platform_data ov5640_mipi_data = {
- .mclk = 24000000,
- .csi = 0,
- .io_init = mx6q_mipi_sensor_io_init,
+ .mclk = 24000000,
+ .csi = 0,
+ .io_init = mx6_mipi_sensor_io_init,
};
static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
{
I2C_BOARD_INFO("cs42888", 0x48),
- },
- {
+ }, {
I2C_BOARD_INFO("ov5640", 0x3c),
.platform_data = (void *)&camera_data,
- },
- {
+ }, {
I2C_BOARD_INFO("adv7180", 0x21),
.platform_data = (void *)&tvin_data,
},
};
-static struct imxi2c_platform_data mx6q_arm2_i2c0_data = {
+static struct imxi2c_platform_data mx6_arm2_i2c0_data = {
.bitrate = 100000,
};
-static struct imxi2c_platform_data mx6q_arm2_i2c1_data = {
+static struct imxi2c_platform_data mx6_arm2_i2c1_data = {
.bitrate = 100000,
};
-static struct imxi2c_platform_data mx6q_arm2_i2c2_data = {
+static struct imxi2c_platform_data mx6_arm2_i2c2_data = {
.bitrate = 400000,
};
@@ -814,19 +628,16 @@ static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
{
I2C_BOARD_INFO("max7310", 0x1F),
.platform_data = &max7310_platdata,
- },
- {
+ }, {
I2C_BOARD_INFO("max7310", 0x1B),
.platform_data = &max7310_u48_platdata,
- },
- {
+ }, {
I2C_BOARD_INFO("mxc_dvi", 0x50),
.platform_data = &sabr_ddc_dvi_data,
- .irq = gpio_to_irq(MX6Q_ARM2_DISP0_DET_INT),
- },
- {
+ .irq = gpio_to_irq(MX6_ARM2_DISP0_DET_INT),
+ }, {
I2C_BOARD_INFO("egalax_ts", 0x4),
- .irq = gpio_to_irq(MX6Q_ARM2_CAP_TCH_INT),
+ .irq = gpio_to_irq(MX6_ARM2_CAP_TCH_INT),
},
};
@@ -834,47 +645,44 @@ static struct i2c_board_info mxc_i2c2_board_info[] __initdata = {
static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
{
I2C_BOARD_INFO("egalax_ts", 0x4),
- .irq = gpio_to_irq(MX6Q_ARM2_CAP_TCH_INT),
- },
- {
+ .irq = gpio_to_irq(MX6_ARM2_CAP_TCH_INT),
+ }, {
I2C_BOARD_INFO("mxc_hdmi_i2c", 0x50),
- },
- {
+ }, {
I2C_BOARD_INFO("ov5640_mipi", 0x3c),
.platform_data = (void *)&ov5640_mipi_data,
- },
- {
+ }, {
I2C_BOARD_INFO("sgtl5000", 0x0a),
},
};
-static void imx6q_arm2_usbotg_vbus(bool on)
+static void imx6_arm2_usbotg_vbus(bool on)
{
if (on)
- gpio_set_value(MX6Q_ARM2_USB_OTG_PWR, 1);
+ gpio_set_value(MX6_ARM2_USB_OTG_PWR, 1);
else
- gpio_set_value(MX6Q_ARM2_USB_OTG_PWR, 0);
+ gpio_set_value(MX6_ARM2_USB_OTG_PWR, 0);
}
-static void __init imx6q_arm2_init_usb(void)
+static void __init mx6_arm2_init_usb(void)
{
int ret = 0;
imx_otg_base = MX6_IO_ADDRESS(MX6Q_USB_OTG_BASE_ADDR);
+
/* disable external charger detect,
* or it will affect signal quality at dp.
*/
- ret = gpio_request(MX6Q_ARM2_USB_OTG_PWR, "usb-pwr");
+ ret = gpio_request(MX6_ARM2_USB_OTG_PWR, "usb-pwr");
if (ret) {
- printk(KERN_ERR"failed to get GPIO MX6Q_ARM2_USB_OTG_PWR:"
- " %d\n", ret);
+ pr_err("failed to get GPIO MX6_ARM2_USB_OTG_PWR:%d\n", ret);
return;
}
- gpio_direction_output(MX6Q_ARM2_USB_OTG_PWR, 0);
+ gpio_direction_output(MX6_ARM2_USB_OTG_PWR, 0);
mxc_iomux_set_gpr_register(1, 13, 1, 1);
- mx6_set_otghost_vbus_func(imx6q_arm2_usbotg_vbus);
+ mx6_set_otghost_vbus_func(imx6_arm2_usbotg_vbus);
mx6_usb_dr_init();
mx6_usb_h1_init();
#ifdef CONFIG_USB_EHCI_ARC_HSIC
@@ -883,20 +691,20 @@ static void __init imx6q_arm2_init_usb(void)
#endif
}
-static struct viv_gpu_platform_data imx6q_gpu_pdata __initdata = {
+static struct viv_gpu_platform_data imx6_gpu_pdata __initdata = {
.reserved_mem_size = SZ_128M,
};
/* HW Initialization, if return 0, initialization is successful. */
-static int mx6q_arm2_sata_init(struct device *dev, void __iomem *addr)
+static int mx6_arm2_sata_init(struct device *dev, void __iomem *addr)
{
u32 tmpdata;
int ret = 0;
struct clk *clk;
/* Enable SATA PWR CTRL_0 of MAX7310 */
- gpio_request(MX6Q_ARM2_MAX7310_1_BASE_ADDR, "SATA_PWR_EN");
- gpio_direction_output(MX6Q_ARM2_MAX7310_1_BASE_ADDR, 1);
+ gpio_request(MX6_ARM2_MAX7310_1_BASE_ADDR, "SATA_PWR_EN");
+ gpio_direction_output(MX6_ARM2_MAX7310_1_BASE_ADDR, 1);
sata_clk = clk_get(dev, "imx_sata_clk");
if (IS_ERR(sata_clk)) {
@@ -949,41 +757,41 @@ release_sata_clk:
put_sata_clk:
clk_put(sata_clk);
/* Disable SATA PWR CTRL_0 of MAX7310 */
- gpio_request(MX6Q_ARM2_MAX7310_1_BASE_ADDR, "SATA_PWR_EN");
- gpio_direction_output(MX6Q_ARM2_MAX7310_1_BASE_ADDR, 0);
+ gpio_request(MX6_ARM2_MAX7310_1_BASE_ADDR, "SATA_PWR_EN");
+ gpio_direction_output(MX6_ARM2_MAX7310_1_BASE_ADDR, 0);
return ret;
}
-static void mx6q_arm2_sata_exit(struct device *dev)
+static void mx6_arm2_sata_exit(struct device *dev)
{
clk_disable(sata_clk);
clk_put(sata_clk);
/* Disable SATA PWR CTRL_0 of MAX7310 */
- gpio_request(MX6Q_ARM2_MAX7310_1_BASE_ADDR, "SATA_PWR_EN");
- gpio_direction_output(MX6Q_ARM2_MAX7310_1_BASE_ADDR, 0);
+ gpio_request(MX6_ARM2_MAX7310_1_BASE_ADDR, "SATA_PWR_EN");
+ gpio_direction_output(MX6_ARM2_MAX7310_1_BASE_ADDR, 0);
}
-static struct ahci_platform_data mx6q_arm2_sata_data = {
- .init = mx6q_arm2_sata_init,
- .exit = mx6q_arm2_sata_exit,
+static struct ahci_platform_data mx6_arm2_sata_data = {
+ .init = mx6_arm2_sata_init,
+ .exit = mx6_arm2_sata_exit,
};
static struct imx_asrc_platform_data imx_asrc_data = {
- .channel_bits = 4,
- .clk_map_ver = 2,
+ .channel_bits = 4,
+ .clk_map_ver = 2,
};
-static void mx6q_sabreauto_reset_mipi_dsi(void)
+static void mx6_arm2_reset_mipi_dsi(void)
{
- gpio_set_value(MX6Q_ARM2_DISP0_PWR, 1);
- gpio_set_value(MX6Q_ARM2_DISP0_RESET, 1);
+ gpio_set_value(MX6_ARM2_DISP0_PWR, 1);
+ gpio_set_value(MX6_ARM2_DISP0_RESET, 1);
udelay(10);
- gpio_set_value(MX6Q_ARM2_DISP0_RESET, 0);
+ gpio_set_value(MX6_ARM2_DISP0_RESET, 0);
udelay(50);
- gpio_set_value(MX6Q_ARM2_DISP0_RESET, 1);
+ gpio_set_value(MX6_ARM2_DISP0_RESET, 1);
/*
* it needs to delay 120ms minimum for reset complete
@@ -992,102 +800,101 @@ static void mx6q_sabreauto_reset_mipi_dsi(void)
}
static struct mipi_dsi_platform_data mipi_dsi_pdata = {
- .ipu_id = 1,
- .disp_id = 1,
- .lcd_panel = "TRULY-WVGA",
- .reset = mx6q_sabreauto_reset_mipi_dsi,
+ .ipu_id = 1,
+ .disp_id = 1,
+ .lcd_panel = "TRULY-WVGA",
+ .reset = mx6_arm2_reset_mipi_dsi,
};
static struct ipuv3_fb_platform_data sabr_fb_data[] = {
{ /*fb0*/
- .disp_dev = "ldb",
- .interface_pix_fmt = IPU_PIX_FMT_RGB666,
- .mode_str = "LDB-XGA",
- .default_bpp = 32,
- .int_clk = false,
+ .disp_dev = "ldb",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB666,
+ .mode_str = "LDB-XGA",
+ .default_bpp = 32,
+ .int_clk = false,
}, {
- .disp_dev = "mipi_dsi",
- .interface_pix_fmt = IPU_PIX_FMT_RGB24,
- .mode_str = "TRULY-WVGA",
- .default_bpp = 24,
- .int_clk = false,
+ .disp_dev = "mipi_dsi",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB24,
+ .mode_str = "TRULY-WVGA",
+ .default_bpp = 24,
+ .int_clk = false,
}, {
- .disp_dev = "ldb",
- .interface_pix_fmt = IPU_PIX_FMT_RGB666,
- .mode_str = "LDB-XGA",
- .default_bpp = 32,
- .int_clk = false,
+ .disp_dev = "ldb",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB666,
+ .mode_str = "LDB-XGA",
+ .default_bpp = 32,
+ .int_clk = false,
}, {
- .disp_dev = "lcd",
- .interface_pix_fmt = IPU_PIX_FMT_RGB565,
- .mode_str = "CLAA-WVGA",
- .default_bpp = 16,
- .int_clk = false,
+ .disp_dev = "lcd",
+ .interface_pix_fmt = IPU_PIX_FMT_RGB565,
+ .mode_str = "CLAA-WVGA",
+ .default_bpp = 16,
+ .int_clk = false,
}
};
static void hdmi_init(int ipu_id, int disp_id)
{
int hdmi_mux_setting;
+ int max_ipu_id = cpu_is_mx6q() ? 1 : 0;
- if ((ipu_id > 1) || (ipu_id < 0)) {
- printk(KERN_ERR"Invalid IPU select for HDMI: %d. Set to 0\n",
- ipu_id);
+ if ((ipu_id > max_ipu_id) || (ipu_id < 0)) {
+ pr_err("Invalid IPU select for HDMI: %d. Set to 0\n", ipu_id);
ipu_id = 0;
}
if ((disp_id > 1) || (disp_id < 0)) {
- printk(KERN_ERR"Invalid DI select for HDMI: %d. Set to 0\n",
- disp_id);
+ pr_err("Invalid DI select for HDMI: %d. Set to 0\n", disp_id);
disp_id = 0;
}
/* Configure the connection between IPU1/2 and HDMI */
- hdmi_mux_setting = 2*ipu_id + disp_id;
+ hdmi_mux_setting = 2 * ipu_id + disp_id;
/* GPR3, bits 2-3 = HDMI_MUX_CTL */
mxc_iomux_set_gpr_register(3, 2, 2, hdmi_mux_setting);
}
static struct fsl_mxc_hdmi_platform_data hdmi_data = {
- .init = hdmi_init,
+ .init = hdmi_init,
};
static struct fsl_mxc_hdmi_core_platform_data hdmi_core_data = {
- .ipu_id = 1,
- .disp_id = 0,
+ .ipu_id = 0,
+ .disp_id = 0,
};
static struct fsl_mxc_lcd_platform_data lcdif_data = {
- .ipu_id = 0,
- .disp_id = 0,
- .default_ifmt = IPU_PIX_FMT_RGB565,
+ .ipu_id = 0,
+ .disp_id = 0,
+ .default_ifmt = IPU_PIX_FMT_RGB565,
};
static struct fsl_mxc_ldb_platform_data ldb_data = {
- .ipu_id = 0,
- .disp_id = 1,
- .ext_ref = 1,
- .mode = LDB_SEP0,
- .sec_ipu_id = 1,
- .sec_disp_id = 0,
+ .ipu_id = 0,
+ .disp_id = 1,
+ .ext_ref = 1,
+ .mode = LDB_SEP0,
+ .sec_ipu_id = 1,
+ .sec_disp_id = 0,
};
static struct imx_ipuv3_platform_data ipu_data[] = {
{
- .rev = 4,
- .csi_clk[0] = "ccm_clk0",
+ .rev = 4,
+ .csi_clk[0] = "ccm_clk0",
}, {
- .rev = 4,
- .csi_clk[0] = "ccm_clk0",
+ .rev = 4,
+ .csi_clk[0] = "ccm_clk0",
},
};
static struct platform_pwm_backlight_data mx6_arm2_pwm_backlight_data = {
- .pwm_id = 0,
- .max_brightness = 255,
- .dft_brightness = 128,
- .pwm_period_ns = 50000,
+ .pwm_id = 0,
+ .max_brightness = 255,
+ .dft_brightness = 128,
+ .pwm_period_ns = 50000,
};
static struct android_pmem_platform_data android_pmem_data = {
@@ -1100,50 +907,50 @@ static struct android_pmem_platform_data android_pmem_gpu_data = {
.size = SZ_32M,
};
-static struct gpio mx6q_flexcan_gpios[] = {
- { MX6Q_ARM2_CAN1_EN, GPIOF_OUT_INIT_LOW, "flexcan1-en" },
- { MX6Q_ARM2_CAN1_STBY, GPIOF_OUT_INIT_LOW, "flexcan1-stby" },
- { MX6Q_ARM2_CAN2_EN, GPIOF_OUT_INIT_LOW, "flexcan2-en" },
+static struct gpio mx6_flexcan_gpios[] = {
+ { MX6_ARM2_CAN1_EN, GPIOF_OUT_INIT_LOW, "flexcan1-en" },
+ { MX6_ARM2_CAN1_STBY, GPIOF_OUT_INIT_LOW, "flexcan1-stby" },
+ { MX6_ARM2_CAN2_EN, GPIOF_OUT_INIT_LOW, "flexcan2-en" },
};
-static void mx6q_flexcan0_switch(int enable)
+static void mx6_flexcan0_switch(int enable)
{
if (enable) {
- gpio_set_value(MX6Q_ARM2_CAN1_EN, 1);
- gpio_set_value(MX6Q_ARM2_CAN1_STBY, 1);
+ gpio_set_value(MX6_ARM2_CAN1_EN, 1);
+ gpio_set_value(MX6_ARM2_CAN1_STBY, 1);
} else {
- gpio_set_value(MX6Q_ARM2_CAN1_EN, 0);
- gpio_set_value(MX6Q_ARM2_CAN1_STBY, 0);
+ gpio_set_value(MX6_ARM2_CAN1_EN, 0);
+ gpio_set_value(MX6_ARM2_CAN1_STBY, 0);
}
}
-static void mx6q_flexcan1_switch(int enable)
+static void mx6_flexcan1_switch(int enable)
{
if (enable) {
- gpio_set_value(MX6Q_ARM2_CAN2_EN, 1);
- gpio_set_value_cansleep(MX6Q_ARM2_CAN2_STBY, 1);
+ gpio_set_value(MX6_ARM2_CAN2_EN, 1);
+ gpio_set_value_cansleep(MX6_ARM2_CAN2_STBY, 1);
} else {
- gpio_set_value(MX6Q_ARM2_CAN2_EN, 0);
- gpio_set_value_cansleep(MX6Q_ARM2_CAN2_STBY, 0);
+ gpio_set_value(MX6_ARM2_CAN2_EN, 0);
+ gpio_set_value_cansleep(MX6_ARM2_CAN2_STBY, 0);
}
}
static const struct flexcan_platform_data
- mx6q_arm2_flexcan_pdata[] __initconst = {
+ mx6_arm2_flexcan_pdata[] __initconst = {
{
- .transceiver_switch = mx6q_flexcan0_switch,
+ .transceiver_switch = mx6_flexcan0_switch,
}, {
- .transceiver_switch = mx6q_flexcan1_switch,
+ .transceiver_switch = mx6_flexcan1_switch,
}
};
static struct mipi_csi2_platform_data mipi_csi2_pdata = {
- .ipu_id = 0,
- .csi_id = 0,
- .v_channel = 0,
- .lanes = 2,
- .dphy_clk = "mipi_pllref_clk",
- .pixel_clk = "emi_clk",
+ .ipu_id = 0,
+ .csi_id = 0,
+ .v_channel = 0,
+ .lanes = 2,
+ .dphy_clk = "mipi_pllref_clk",
+ .pixel_clk = "emi_clk",
};
static void arm2_suspend_enter(void)
@@ -1155,22 +962,22 @@ static void arm2_suspend_exit(void)
{
/* resmue resore */
}
-static const struct pm_platform_data mx6q_arm2_pm_data __initconst = {
- .name = "imx_pm",
- .suspend_enter = arm2_suspend_enter,
- .suspend_exit = arm2_suspend_exit,
+static const struct pm_platform_data mx6_arm2_pm_data __initconst = {
+ .name = "imx_pm",
+ .suspend_enter = arm2_suspend_enter,
+ .suspend_exit = arm2_suspend_exit,
};
static struct mxc_audio_platform_data sab_audio_data = {
- .sysclk = 16934400,
+ .sysclk = 16934400,
};
static struct platform_device sab_audio_device = {
- .name = "imx-cs42888",
+ .name = "imx-cs42888",
};
static struct imx_esai_platform_data sab_esai_pdata = {
- .flags = IMX_ESAI_NET,
+ .flags = IMX_ESAI_NET,
};
static struct regulator_consumer_supply arm2_vmmc_consumers[] = {
@@ -1185,16 +992,16 @@ static struct regulator_init_data arm2_vmmc_init = {
};
static struct fixed_voltage_config arm2_vmmc_reg_config = {
- .supply_name = "vmmc",
- .microvolts = 3300000,
- .gpio = -1,
- .init_data = &arm2_vmmc_init,
+ .supply_name = "vmmc",
+ .microvolts = 3300000,
+ .gpio = -1,
+ .init_data = &arm2_vmmc_init,
};
static struct platform_device arm2_vmmc_reg_devices = {
- .name = "reg-fixed-voltage",
- .id = 0,
- .dev = {
+ .name = "reg-fixed-voltage",
+ .id = 0,
+ .dev = {
.platform_data = &arm2_vmmc_reg_config,
},
};
@@ -1202,43 +1009,43 @@ static struct platform_device arm2_vmmc_reg_devices = {
#ifdef CONFIG_SND_SOC_CS42888
static struct regulator_consumer_supply cs42888_arm2_consumer_va = {
- .supply = "VA",
- .dev_name = "0-0048",
+ .supply = "VA",
+ .dev_name = "0-0048",
};
static struct regulator_consumer_supply cs42888_arm2_consumer_vd = {
- .supply = "VD",
- .dev_name = "0-0048",
+ .supply = "VD",
+ .dev_name = "0-0048",
};
static struct regulator_consumer_supply cs42888_arm2_consumer_vls = {
- .supply = "VLS",
- .dev_name = "0-0048",
+ .supply = "VLS",
+ .dev_name = "0-0048",
};
static struct regulator_consumer_supply cs42888_arm2_consumer_vlc = {
- .supply = "VLC",
- .dev_name = "0-0048",
+ .supply = "VLC",
+ .dev_name = "0-0048",
};
static struct regulator_init_data cs42888_arm2_va_reg_initdata = {
- .num_consumer_supplies = 1,
- .consumer_supplies = &cs42888_arm2_consumer_va,
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cs42888_arm2_consumer_va,
};
static struct regulator_init_data cs42888_arm2_vd_reg_initdata = {
- .num_consumer_supplies = 1,
- .consumer_supplies = &cs42888_arm2_consumer_vd,
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cs42888_arm2_consumer_vd,
};
static struct regulator_init_data cs42888_arm2_vls_reg_initdata = {
- .num_consumer_supplies = 1,
- .consumer_supplies = &cs42888_arm2_consumer_vls,
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cs42888_arm2_consumer_vls,
};
static struct regulator_init_data cs42888_arm2_vlc_reg_initdata = {
- .num_consumer_supplies = 1,
- .consumer_supplies = &cs42888_arm2_consumer_vlc,
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &cs42888_arm2_consumer_vlc,
};
static struct fixed_voltage_config cs42888_arm2_va_reg_config = {
@@ -1306,33 +1113,33 @@ static struct platform_device cs42888_arm2_vlc_reg_devices = {
#ifdef CONFIG_SND_SOC_SGTL5000
static struct regulator_consumer_supply sgtl5000_arm2_consumer_vdda = {
- .supply = "VDDA",
- .dev_name = "1-000a",
+ .supply = "VDDA",
+ .dev_name = "1-000a",
};
static struct regulator_consumer_supply sgtl5000_arm2_consumer_vddio = {
- .supply = "VDDIO",
- .dev_name = "1-000a",
+ .supply = "VDDIO",
+ .dev_name = "1-000a",
};
static struct regulator_consumer_supply sgtl5000_arm2_consumer_vddd = {
- .supply = "VDDD",
- .dev_name = "1-000a",
+ .supply = "VDDD",
+ .dev_name = "1-000a",
};
static struct regulator_init_data sgtl5000_arm2_vdda_reg_initdata = {
- .num_consumer_supplies = 1,
- .consumer_supplies = &sgtl5000_arm2_consumer_vdda,
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sgtl5000_arm2_consumer_vdda,
};
static struct regulator_init_data sgtl5000_arm2_vddio_reg_initdata = {
- .num_consumer_supplies = 1,
- .consumer_supplies = &sgtl5000_arm2_consumer_vddio,
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sgtl5000_arm2_consumer_vddio,
};
static struct regulator_init_data sgtl5000_arm2_vddd_reg_initdata = {
- .num_consumer_supplies = 1,
- .consumer_supplies = &sgtl5000_arm2_consumer_vddd,
+ .num_consumer_supplies = 1,
+ .consumer_supplies = &sgtl5000_arm2_consumer_vddd,
};
static struct fixed_voltage_config sgtl5000_arm2_vdda_reg_config = {
@@ -1408,7 +1215,7 @@ static struct platform_device mx6_arm2_audio_device = {
.name = "imx-sgtl5000",
};
-static int __init imx6q_init_audio(void)
+static int __init mx6_arm2_init_audio(void)
{
struct clk *pll3_pfd, *esai_clk;
mxc_register_device(&sab_audio_device, &sab_audio_data);
@@ -1426,10 +1233,10 @@ static int __init imx6q_init_audio(void)
clk_set_rate(esai_clk, 101647058);
#ifdef CONFIG_SND_SOC_CS42888
- platform_device_register(&cs42888_arm2_va_reg_devices);
- platform_device_register(&cs42888_arm2_vd_reg_devices);
- platform_device_register(&cs42888_arm2_vls_reg_devices);
- platform_device_register(&cs42888_arm2_vlc_reg_devices);
+ platform_device_register(&cs42888_arm2_va_reg_devices);
+ platform_device_register(&cs42888_arm2_vd_reg_devices);
+ platform_device_register(&cs42888_arm2_vls_reg_devices);
+ platform_device_register(&cs42888_arm2_vlc_reg_devices);
#endif
if (sgtl5000_en) {
@@ -1438,8 +1245,17 @@ static int __init imx6q_init_audio(void)
&mx6_arm2_audio_data);
imx6q_add_imx_ssi(1, &mx6_arm2_ssi_pdata);
- mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_audmux_pads,
- ARRAY_SIZE(mx6q_arm2_audmux_pads));
+ /*
+ * AUDMUX3 and CSI0_Camera use the same pin
+ * MX6x_PAD_CSI0_DAT5
+ */
+ if (cpu_is_mx6q()) {
+ mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_audmux_pads,
+ ARRAY_SIZE(mx6q_arm2_audmux_pads));
+ } else if (cpu_is_mx6dl()) {
+ mxc_iomux_v3_setup_multiple_pads(mx6dl_arm2_audmux_pads,
+ ARRAY_SIZE(mx6dl_arm2_audmux_pads));
+ }
#ifdef CONFIG_SND_SOC_SGTL5000
platform_device_register(&sgtl5000_arm2_vdda_reg_devices);
@@ -1459,36 +1275,36 @@ static int __init early_use_esai_record(char *p)
early_param("esai_record", early_use_esai_record);
-static struct mxc_mlb_platform_data mx6q_arm2_mlb150_data = {
- .reg_nvcc = NULL,
- .mlb_clk = "mlb150_clk",
- .mlb_pll_clk = "pll6",
+static struct mxc_mlb_platform_data mx6_arm2_mlb150_data = {
+ .reg_nvcc = NULL,
+ .mlb_clk = "mlb150_clk",
+ .mlb_pll_clk = "pll6",
};
static struct mxc_dvfs_platform_data arm2_dvfscore_data = {
- .reg_id = "cpu_vddgp",
- .clk1_id = "cpu_clk",
- .clk2_id = "gpc_dvfs_clk",
- .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
- .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
- .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
- .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
- .prediv_mask = 0x1F800,
- .prediv_offset = 11,
- .prediv_val = 3,
- .div3ck_mask = 0xE0000000,
- .div3ck_offset = 29,
- .div3ck_val = 2,
- .emac_val = 0x08,
- .upthr_val = 25,
- .dnthr_val = 9,
- .pncthr_val = 33,
- .upcnt_val = 10,
- .dncnt_val = 10,
- .delay_time = 80,
-};
-
-static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ .reg_id = "cpu_vddgp",
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_offset = MXC_GPC_CNTR_OFFSET,
+ .ccm_cdcr_offset = MXC_CCM_CDCR_OFFSET,
+ .ccm_cacrr_offset = MXC_CCM_CACRR_OFFSET,
+ .ccm_cdhipr_offset = MXC_CCM_CDHIPR_OFFSET,
+ .prediv_mask = 0x1F800,
+ .prediv_offset = 11,
+ .prediv_val = 3,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x08,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 10,
+ .dncnt_val = 10,
+ .delay_time = 80,
+};
+
+static void __init mx6_arm2_fixup(struct machine_desc *desc, struct tag *tags,
char **cmdline, struct meminfo *mi)
{
char *str;
@@ -1545,8 +1361,8 @@ static int spdif_clk_set_rate(struct clk *clk, unsigned long rate)
}
static struct mxc_spdif_platform_data mxc_spdif_data = {
- .spdif_tx = 1, /* enable tx */
- .spdif_rx = 1, /* enable rx */
+ .spdif_tx = 1, /* enable tx */
+ .spdif_rx = 1, /* enable rx */
/*
* spdif0_clk will be 454.7MHz divided by ccm dividers.
*
@@ -1554,58 +1370,133 @@ static struct mxc_spdif_platform_data mxc_spdif_data = {
* 48KHz: 454.7MHz / 4 (ccm) / 37 (spdif) = 48,004 Hz ~ 0.01% error
* 32KHz: 454.7MHz / 6 (ccm) / 37 (spdif) = 32,003 Hz ~ 0.01% error
*/
- .spdif_clk_44100 = 1, /* tx clk from spdif0_clk_root */
- .spdif_clk_48000 = 1, /* tx clk from spdif0_clk_root */
- .spdif_div_44100 = 23,
- .spdif_div_48000 = 37,
- .spdif_div_32000 = 37,
- .spdif_rx_clk = 0, /* rx clk from spdif stream */
- .spdif_clk_set_rate = spdif_clk_set_rate,
- .spdif_clk = NULL, /* spdif bus clk */
+ .spdif_clk_44100 = 1, /* tx clk from spdif0_clk_root */
+ .spdif_clk_48000 = 1, /* tx clk from spdif0_clk_root */
+ .spdif_div_44100 = 23,
+ .spdif_div_48000 = 37,
+ .spdif_div_32000 = 37,
+ .spdif_rx_clk = 0, /* rx clk from spdif stream */
+ .spdif_clk_set_rate = spdif_clk_set_rate,
+ .spdif_clk = NULL, /* spdif bus clk */
};
/*!
* Board specific initialization.
*/
-static void __init mx6_board_init(void)
+static void __init mx6_arm2_init(void)
{
int i;
int ret;
- mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_pads,
- ARRAY_SIZE(mx6q_arm2_pads));
+ iomux_v3_cfg_t *common_pads = NULL;
+ iomux_v3_cfg_t *esai_rec_pads = NULL;
+ iomux_v3_cfg_t *spdif_pads = NULL;
+ iomux_v3_cfg_t *flexcan_pads = NULL;
+ iomux_v3_cfg_t *i2c3_pads = NULL;
+
+ int common_pads_cnt;
+ int esai_rec_pads_cnt;
+ int spdif_pads_cnt;
+ int flexcan_pads_cnt;
+ int i2c3_pads_cnt;
- if (esai_record)
- mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_esai_record_pads,
- ARRAY_SIZE(mx6q_arm2_esai_record_pads));
/*
- * S/PDIF in and i2c3 are mutually exclusive because both
- * use GPIO_16.
+ * common pads: pads are non-shared with others on this board
+ * feature_pds: pads are shared with others on this board
+ */
+
+ if (cpu_is_mx6q()) {
+ common_pads = mx6q_arm2_pads;
+ esai_rec_pads = mx6q_arm2_esai_record_pads;
+ spdif_pads = mx6q_arm2_spdif_pads;
+ flexcan_pads = mx6q_arm2_can_pads;
+ i2c3_pads = mx6q_arm2_i2c3_pads;
+
+ common_pads_cnt = ARRAY_SIZE(mx6q_arm2_pads);
+ esai_rec_pads_cnt = ARRAY_SIZE(mx6q_arm2_esai_record_pads);
+ spdif_pads_cnt = ARRAY_SIZE(mx6q_arm2_spdif_pads);
+ flexcan_pads_cnt = ARRAY_SIZE(mx6q_arm2_can_pads);
+ i2c3_pads_cnt = ARRAY_SIZE(mx6q_arm2_i2c3_pads);
+ } else if (cpu_is_mx6dl()) {
+ common_pads = mx6dl_arm2_pads;
+ esai_rec_pads = mx6dl_arm2_esai_record_pads;
+ spdif_pads = mx6dl_arm2_spdif_pads;
+ flexcan_pads = mx6dl_arm2_can_pads;
+ i2c3_pads = mx6dl_arm2_i2c3_pads;
+
+ common_pads_cnt = ARRAY_SIZE(mx6dl_arm2_pads);
+ esai_rec_pads_cnt = ARRAY_SIZE(mx6dl_arm2_esai_record_pads);
+ spdif_pads_cnt = ARRAY_SIZE(mx6dl_arm2_spdif_pads);
+ flexcan_pads_cnt = ARRAY_SIZE(mx6dl_arm2_can_pads);
+ i2c3_pads_cnt = ARRAY_SIZE(mx6dl_arm2_i2c3_pads);
+ }
+
+ BUG_ON(!common_pads);
+ mxc_iomux_v3_setup_multiple_pads(common_pads, common_pads_cnt);
+
+ if (esai_record) {
+ BUG_ON(!esai_rec_pads);
+ mxc_iomux_v3_setup_multiple_pads(esai_rec_pads,
+ esai_rec_pads_cnt);
+ }
+
+ /*
+ * IEEE-1588 ts_clk, S/PDIF in and i2c3 are mutually exclusive
+ * because all of them use GPIO_16.
* S/PDIF out and can1 stby are mutually exclusive because both
* use GPIO_17.
*/
+#ifndef CONFIG_FEC_1588
if (spdif_en) {
- mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_spdif_pads,
- ARRAY_SIZE(mx6q_arm2_spdif_pads));
+ BUG_ON(!spdif_pads);
+ mxc_iomux_v3_setup_multiple_pads(spdif_pads, spdif_pads_cnt);
} else {
- mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_i2c3_pads,
- ARRAY_SIZE(mx6q_arm2_i2c3_pads));
- if (flexcan_en)
- mxc_iomux_v3_setup_multiple_pads(mx6q_arm2_can_pads,
- ARRAY_SIZE(mx6q_arm2_can_pads));
+ BUG_ON(!i2c3_pads);
+ mxc_iomux_v3_setup_multiple_pads(i2c3_pads, i2c3_pads_cnt);
}
+#else
+ /* Set GPIO_16 input for IEEE-1588 ts_clk and RMII reference clock
+ * For MX6 GPR1 bit21 meaning:
+ * Bit21: 0 - GPIO_16 pad output
+ * 1 - GPIO_16 pad input
+ */
+ mxc_iomux_set_gpr_register(1, 21, 1, 1);
+#endif
+
+ if (!spdif_en && flexcan_en) {
+ BUG_ON(!flexcan_pads);
+ mxc_iomux_v3_setup_multiple_pads(flexcan_pads,
+ flexcan_pads_cnt);
+ }
+
+ /*
+ * the following is the common devices support on the shared ARM2 boards
+ * Since i.MX6DQ/DL share the same memory/Register layout, we don't
+ * need to diff the i.MX6DQ or i.MX6DL here. We can simply use the
+ * mx6q_add_features() for the shared devices. For which only exist
+ * on each indivual SOC, we can use cpu_is_mx6q/6dl() to diff it.
+ */
gp_reg_id = arm2_dvfscore_data.reg_id;
- mx6q_arm2_init_uart();
+ mx6_arm2_init_uart();
imx6q_add_mipi_csi2(&mipi_csi2_pdata);
imx6q_add_mxc_hdmi_core(&hdmi_core_data);
imx6q_add_ipuv3(0, &ipu_data[0]);
- imx6q_add_ipuv3(1, &ipu_data[1]);
-
- for (i = 0; i < ARRAY_SIZE(sabr_fb_data); i++)
- imx6q_add_ipuv3fb(i, &sabr_fb_data[i]);
+ if (cpu_is_mx6q())
+ imx6q_add_ipuv3(1, &ipu_data[1]);
+
+ if (cpu_is_mx6dl()) {
+ mipi_dsi_pdata.ipu_id = 0;
+ mipi_dsi_pdata.disp_id = 1;
+ ldb_data.ipu_id = 0;
+ ldb_data.disp_id = 0;
+ for (i = 0; i < ARRAY_SIZE(sabr_fb_data) / 2; i++)
+ imx6q_add_ipuv3fb(i, &sabr_fb_data[i]);
+ } else
+ for (i = 0; i < ARRAY_SIZE(sabr_fb_data); i++)
+ imx6q_add_ipuv3fb(i, &sabr_fb_data[i]);
imx6q_add_mipi_dsi(&mipi_dsi_pdata);
imx6q_add_lcdif(&lcdif_data);
@@ -1615,37 +1506,38 @@ static void __init mx6_board_init(void)
imx6q_add_imx_snvs_rtc();
- imx6q_add_imx_i2c(0, &mx6q_arm2_i2c0_data);
- imx6q_add_imx_i2c(1, &mx6q_arm2_i2c1_data);
+ imx6q_add_imx_i2c(0, &mx6_arm2_i2c0_data);
+ imx6q_add_imx_i2c(1, &mx6_arm2_i2c1_data);
i2c_register_board_info(0, mxc_i2c0_board_info,
ARRAY_SIZE(mxc_i2c0_board_info));
i2c_register_board_info(1, mxc_i2c1_board_info,
ARRAY_SIZE(mxc_i2c1_board_info));
if (!spdif_en) {
- imx6q_add_imx_i2c(2, &mx6q_arm2_i2c2_data);
+ imx6q_add_imx_i2c(2, &mx6_arm2_i2c2_data);
i2c_register_board_info(2, mxc_i2c2_board_info,
ARRAY_SIZE(mxc_i2c2_board_info));
}
/* SPI */
- imx6q_add_ecspi(0, &mx6q_arm2_spi_data);
+ imx6q_add_ecspi(0, &mx6_arm2_spi_data);
spi_device_init();
imx6q_add_mxc_hdmi(&hdmi_data);
- imx6q_add_anatop_thermal_imx(1, &mx6q_arm2_anatop_thermal_data);
+ imx6q_add_anatop_thermal_imx(1, &mx6_arm2_anatop_thermal_data);
if (!esai_record)
imx6_init_fec(fec_data);
- imx6q_add_pm_imx(0, &mx6q_arm2_pm_data);
- imx6q_add_sdhci_usdhc_imx(3, &mx6q_arm2_sd4_data);
- imx6q_add_sdhci_usdhc_imx(2, &mx6q_arm2_sd3_data);
- imx_add_viv_gpu(&imx6_gpu_data, &imx6q_gpu_pdata);
- imx6q_arm2_init_usb();
- imx6q_add_ahci(0, &mx6q_arm2_sata_data);
+ imx6q_add_pm_imx(0, &mx6_arm2_pm_data);
+ imx6q_add_sdhci_usdhc_imx(3, &mx6_arm2_sd4_data);
+ imx6q_add_sdhci_usdhc_imx(2, &mx6_arm2_sd3_data);
+ imx_add_viv_gpu(&imx6_gpu_data, &imx6_gpu_pdata);
+ if (cpu_is_mx6q())
+ imx6q_add_ahci(0, &mx6_arm2_sata_data);
imx6q_add_vpu();
- imx6q_init_audio();
+ mx6_arm2_init_usb();
+ mx6_arm2_init_audio();
platform_device_register(&arm2_vmmc_reg_devices);
mx6_cpu_regulator_init();
@@ -1654,23 +1546,23 @@ static void __init mx6_board_init(void)
imx6q_add_asrc(&imx_asrc_data);
/* DISP0 Reset - Assert for i2c disabled mode */
- gpio_request(MX6Q_ARM2_DISP0_RESET, "disp0-reset");
- gpio_direction_output(MX6Q_ARM2_DISP0_RESET, 0);
+ gpio_request(MX6_ARM2_DISP0_RESET, "disp0-reset");
+ gpio_direction_output(MX6_ARM2_DISP0_RESET, 0);
/* DISP0 I2C enable */
- gpio_request(MX6Q_ARM2_DISP0_I2C_EN, "disp0-i2c");
- gpio_direction_output(MX6Q_ARM2_DISP0_I2C_EN, 0);
+ gpio_request(MX6_ARM2_DISP0_I2C_EN, "disp0-i2c");
+ gpio_direction_output(MX6_ARM2_DISP0_I2C_EN, 0);
- gpio_request(MX6Q_ARM2_DISP0_PWR, "disp0-pwr");
- gpio_direction_output(MX6Q_ARM2_DISP0_PWR, 1);
+ gpio_request(MX6_ARM2_DISP0_PWR, "disp0-pwr");
+ gpio_direction_output(MX6_ARM2_DISP0_PWR, 1);
- gpio_request(MX6Q_ARM2_LDB_BACKLIGHT, "ldb-backlight");
- gpio_direction_output(MX6Q_ARM2_LDB_BACKLIGHT, 1);
+ gpio_request(MX6_ARM2_LDB_BACKLIGHT, "ldb-backlight");
+ gpio_direction_output(MX6_ARM2_LDB_BACKLIGHT, 1);
imx6q_add_otp();
imx6q_add_viim();
imx6q_add_imx2_wdt(0, NULL);
imx6q_add_dma();
- imx6q_add_gpmi(&mx6q_gpmi_nfc_platform_data);
+ imx6q_add_gpmi(&mx6_gpmi_nand_platform_data);
imx6q_add_dvfs_core(&arm2_dvfscore_data);
@@ -1688,13 +1580,13 @@ static void __init mx6_board_init(void)
imx6q_add_spdif_dai();
imx6q_add_spdif_audio_device();
} else if (flexcan_en) {
- ret = gpio_request_array(mx6q_flexcan_gpios,
- ARRAY_SIZE(mx6q_flexcan_gpios));
+ ret = gpio_request_array(mx6_flexcan_gpios,
+ ARRAY_SIZE(mx6_flexcan_gpios));
if (ret) {
pr_err("failed to request flexcan-gpios: %d\n", ret);
} else {
- imx6q_add_flexcan0(&mx6q_arm2_flexcan_pdata[0]);
- imx6q_add_flexcan1(&mx6q_arm2_flexcan_pdata[1]);
+ imx6q_add_flexcan0(&mx6_arm2_flexcan_pdata[0]);
+ imx6q_add_flexcan1(&mx6_arm2_flexcan_pdata[1]);
}
}
@@ -1703,7 +1595,12 @@ static void __init mx6_board_init(void)
imx6q_add_perfmon(0);
imx6q_add_perfmon(1);
imx6q_add_perfmon(2);
- imx6q_add_mlb150(&mx6q_arm2_mlb150_data);
+ imx6q_add_mlb150(&mx6_arm2_mlb150_data);
+
+ if (cpu_is_mx6dl()) {
+ imx6dl_add_imx_pxp();
+ imx6dl_add_imx_pxp_client();
+ }
}
extern void __iomem *twd_base;
@@ -1724,16 +1621,16 @@ static struct sys_timer mxc_timer = {
.init = mx6_timer_init,
};
-static void __init mx6q_reserve(void)
+static void __init mx6_arm2_reserve(void)
{
phys_addr_t phys;
- if (imx6q_gpu_pdata.reserved_mem_size) {
- phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size,
- SZ_4K, SZ_2G);
- memblock_free(phys, imx6q_gpu_pdata.reserved_mem_size);
- memblock_remove(phys, imx6q_gpu_pdata.reserved_mem_size);
- imx6q_gpu_pdata.reserved_mem_base = phys;
+ if (imx6_gpu_pdata.reserved_mem_size) {
+ phys = memblock_alloc_base(
+ imx6_gpu_pdata.reserved_mem_size, SZ_4K, SZ_2G);
+ memblock_free(phys, imx6_gpu_pdata.reserved_mem_size);
+ memblock_remove(phys, imx6_gpu_pdata.reserved_mem_size);
+ imx6_gpu_pdata.reserved_mem_base = phys;
}
if (android_pmem_data.size) {
@@ -1751,16 +1648,12 @@ static void __init mx6q_reserve(void)
}
}
-/*
- * initialize __mach_desc_MX6Q_ARM2 data structure.
- */
-MACHINE_START(MX6Q_ARM2, "Freescale i.MX 6Quad Armadillo2 Board")
- /* Maintainer: Freescale Semiconductor, Inc. */
- .boot_params = MX6_PHYS_OFFSET + 0x100,
- .fixup = fixup_mxc_board,
- .map_io = mx6_map_io,
- .init_irq = mx6_init_irq,
- .init_machine = mx6_board_init,
- .timer = &mxc_timer,
- .reserve = mx6q_reserve,
+MACHINE_START(MX6Q_ARM2, "Freescale i.MX 6Quad/Solo/DualLite Armadillo2 Board")
+ .boot_params = MX6_PHYS_OFFSET + 0x100,
+ .fixup = mx6_arm2_fixup,
+ .map_io = mx6_map_io,
+ .init_irq = mx6_init_irq,
+ .init_machine = mx6_arm2_init,
+ .timer = &mxc_timer,
+ .reserve = mx6_arm2_reserve,
MACHINE_END
diff --git a/arch/arm/mach-mx6/board-mx6q_arm2.h b/arch/arm/mach-mx6/board-mx6q_arm2.h
new file mode 100644
index 000000000000..8c3277d869e1
--- /dev/null
+++ b/arch/arm/mach-mx6/board-mx6q_arm2.h
@@ -0,0 +1,317 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <mach/iomux-mx6q.h>
+
+static iomux_v3_cfg_t mx6q_arm2_pads[] = {
+
+ /* UART4 for debug */
+ MX6Q_PAD_KEY_COL0__UART4_TXD,
+ MX6Q_PAD_KEY_ROW0__UART4_RXD,
+ /* USB HSIC ports use the same pin with ENET */
+#ifdef CONFIG_USB_EHCI_ARC_HSIC
+ /* USB H2 strobe/data pin */
+ MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE,
+ MX6Q_PAD_RGMII_TXC__USBOH3_H2_DATA,
+
+ /* USB H3 strobe/data pin */
+ MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE,
+ MX6Q_PAD_RGMII_RX_CTL__USBOH3_H3_DATA,
+ /* ENET */
+#else
+ MX6Q_PAD_KEY_COL1__ENET_MDIO,
+ MX6Q_PAD_KEY_COL2__ENET_MDC,
+ MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC,
+ MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0,
+ MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1,
+ MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2,
+ MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3,
+ MX6Q_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL,
+ MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK,
+ MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC,
+ MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0,
+ MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1,
+ MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2,
+ MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3,
+ MX6Q_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL,
+#ifdef CONFIG_FEC_1588
+ MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT,
+#endif
+#endif
+ /* MCLK for csi0 */
+ MX6Q_PAD_GPIO_0__CCM_CLKO,
+ MX6Q_PAD_GPIO_3__CCM_CLKO2,
+
+ /* SD1 */
+ MX6Q_PAD_SD1_CLK__USDHC1_CLK,
+ MX6Q_PAD_SD1_CMD__USDHC1_CMD,
+ MX6Q_PAD_SD1_DAT0__USDHC1_DAT0,
+ MX6Q_PAD_SD1_DAT1__USDHC1_DAT1,
+ MX6Q_PAD_SD1_DAT2__USDHC1_DAT2,
+ MX6Q_PAD_SD1_DAT3__USDHC1_DAT3,
+ /* SD2 */
+ MX6Q_PAD_SD2_CLK__USDHC2_CLK,
+ MX6Q_PAD_SD2_CMD__USDHC2_CMD,
+ MX6Q_PAD_SD2_DAT0__USDHC2_DAT0,
+ MX6Q_PAD_SD2_DAT1__USDHC2_DAT1,
+ MX6Q_PAD_SD2_DAT2__USDHC2_DAT2,
+ MX6Q_PAD_SD2_DAT3__USDHC2_DAT3,
+ /* SD3 */
+ MX6Q_PAD_SD3_CLK__USDHC3_CLK_50MHZ,
+ MX6Q_PAD_SD3_CMD__USDHC3_CMD_50MHZ,
+ MX6Q_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ,
+ MX6Q_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ,
+ MX6Q_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ,
+ MX6Q_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ,
+ MX6Q_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ,
+ MX6Q_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ,
+ MX6Q_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ,
+ MX6Q_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ,
+ MX6Q_PAD_SD3_RST__USDHC3_RST,
+ /* SD3 VSelect */
+ MX6Q_PAD_GPIO_18__USDHC3_VSELECT,
+ /* SD3_CD and SD3_WP */
+ MX6Q_PAD_NANDF_CS0__GPIO_6_11,
+ MX6Q_PAD_NANDF_CS1__GPIO_6_14,
+ /* SD4 */
+ MX6Q_PAD_SD4_CLK__USDHC4_CLK_50MHZ,
+ MX6Q_PAD_SD4_CMD__USDHC4_CMD_50MHZ,
+ MX6Q_PAD_SD4_DAT0__USDHC4_DAT0_50MHZ,
+ MX6Q_PAD_SD4_DAT1__USDHC4_DAT1_50MHZ,
+ MX6Q_PAD_SD4_DAT2__USDHC4_DAT2_50MHZ,
+ MX6Q_PAD_SD4_DAT3__USDHC4_DAT3_50MHZ,
+ MX6Q_PAD_SD4_DAT4__USDHC4_DAT4_50MHZ,
+ MX6Q_PAD_SD4_DAT5__USDHC4_DAT5_50MHZ,
+ MX6Q_PAD_SD4_DAT6__USDHC4_DAT6_50MHZ,
+ MX6Q_PAD_SD4_DAT7__USDHC4_DAT7_50MHZ,
+ MX6Q_PAD_NANDF_ALE__USDHC4_RST,
+ /* eCSPI1 */
+ MX6Q_PAD_EIM_EB2__ECSPI1_SS0,
+ MX6Q_PAD_EIM_D16__ECSPI1_SCLK,
+ MX6Q_PAD_EIM_D17__ECSPI1_MISO,
+ MX6Q_PAD_EIM_D18__ECSPI1_MOSI,
+ MX6Q_PAD_EIM_D19__ECSPI1_SS1,
+ MX6Q_PAD_EIM_EB2__GPIO_2_30, /*SS0*/
+ MX6Q_PAD_EIM_D19__GPIO_3_19, /*SS1*/
+
+ /* ESAI */
+ MX6Q_PAD_ENET_RXD0__ESAI1_HCKT,
+ MX6Q_PAD_ENET_CRS_DV__ESAI1_SCKT,
+ MX6Q_PAD_ENET_RXD1__ESAI1_FST,
+ MX6Q_PAD_ENET_TX_EN__ESAI1_TX3_RX2,
+ MX6Q_PAD_ENET_TXD1__ESAI1_TX2_RX3,
+ MX6Q_PAD_ENET_TXD0__ESAI1_TX4_RX1,
+ MX6Q_PAD_ENET_MDC__ESAI1_TX5_RX0,
+ MX6Q_PAD_NANDF_CS2__ESAI1_TX0,
+ MX6Q_PAD_NANDF_CS3__ESAI1_TX1,
+
+ /* I2C1 */
+ MX6Q_PAD_CSI0_DAT8__I2C1_SDA,
+ MX6Q_PAD_CSI0_DAT9__I2C1_SCL,
+
+ /* I2C2 */
+ MX6Q_PAD_KEY_COL3__I2C2_SCL,
+ MX6Q_PAD_KEY_ROW3__I2C2_SDA,
+
+ /* DISPLAY */
+ MX6Q_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK,
+ MX6Q_PAD_DI0_PIN15__IPU1_DI0_PIN15,
+ MX6Q_PAD_DI0_PIN2__IPU1_DI0_PIN2,
+ MX6Q_PAD_DI0_PIN3__IPU1_DI0_PIN3,
+ MX6Q_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0,
+ MX6Q_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1,
+ MX6Q_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2,
+ MX6Q_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3,
+ MX6Q_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4,
+ MX6Q_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5,
+ MX6Q_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6,
+ MX6Q_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7,
+ MX6Q_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8,
+ MX6Q_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9,
+ MX6Q_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10,
+ MX6Q_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11,
+ MX6Q_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12,
+ MX6Q_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13,
+ MX6Q_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14,
+ MX6Q_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15,
+ MX6Q_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16,
+ MX6Q_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17,
+ MX6Q_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18,
+ MX6Q_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19,
+ MX6Q_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20,
+ MX6Q_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21,
+ MX6Q_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22,
+ MX6Q_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23,
+
+ MX6Q_PAD_EIM_D24__GPIO_3_24,
+
+ /* UART2 */
+ MX6Q_PAD_EIM_D26__UART2_RXD,
+ MX6Q_PAD_EIM_D27__UART2_TXD,
+ MX6Q_PAD_EIM_D28__UART2_RTS,
+ MX6Q_PAD_EIM_D29__UART2_CTS,
+
+ /* PWM1 */
+ MX6Q_PAD_GPIO_9__PWM1_PWMO,
+
+ /* DISP0 DET */
+ MX6Q_PAD_EIM_D31__GPIO_3_31,
+
+ /* DISP0 RESET */
+ MX6Q_PAD_EIM_WAIT__GPIO_5_0,
+
+ /* HDMI */
+ MX6Q_PAD_EIM_A25__HDMI_TX_CEC_LINE,
+ MX6Q_PAD_SD1_DAT1__HDMI_TX_OPHYDTB_0,
+ MX6Q_PAD_SD1_DAT0__HDMI_TX_OPHYDTB_1,
+
+ /* USBOTG ID pin */
+ MX6Q_PAD_GPIO_1__USBOTG_ID,
+
+ /* MLB150 */
+ MX6Q_PAD_GPIO_3__MLB_MLBCLK,
+ MX6Q_PAD_GPIO_6__MLB_MLBSIG,
+ MX6Q_PAD_GPIO_2__MLB_MLBDAT,
+};
+
+static iomux_v3_cfg_t mx6q_arm2_i2c3_pads[] = {
+ MX6Q_PAD_GPIO_5__I2C3_SCL,
+ MX6Q_PAD_GPIO_16__I2C3_SDA,
+};
+
+static iomux_v3_cfg_t mx6q_arm2_spdif_pads[] = {
+ /* SPDIF */
+ MX6Q_PAD_GPIO_16__SPDIF_IN1,
+ MX6Q_PAD_GPIO_17__SPDIF_OUT1,
+};
+
+static iomux_v3_cfg_t mx6q_arm2_can_pads[] = {
+ /* CAN1 */
+ MX6Q_PAD_GPIO_7__CAN1_TXCAN,
+ MX6Q_PAD_KEY_ROW2__CAN1_RXCAN,
+ MX6Q_PAD_GPIO_17__GPIO_7_12, /* CAN1 STBY */
+ MX6Q_PAD_GPIO_18__GPIO_7_13, /* CAN1 EN */
+
+ /* CAN2 */
+ MX6Q_PAD_KEY_COL4__CAN2_TXCAN,
+ MX6Q_PAD_KEY_ROW4__CAN2_RXCAN,
+ MX6Q_PAD_CSI0_DAT6__GPIO_5_24, /* CAN2 EN */
+};
+
+static iomux_v3_cfg_t mx6q_arm2_esai_record_pads[] = {
+ MX6Q_PAD_ENET_RX_ER__ESAI1_HCKR,
+ MX6Q_PAD_ENET_MDIO__ESAI1_SCKR,
+ MX6Q_PAD_ENET_REF_CLK__ESAI1_FSR,
+};
+
+static iomux_v3_cfg_t mx6q_arm2_csi0_sensor_pads[] = {
+ MX6Q_PAD_GPIO_0__CCM_CLKO,
+ /* ipu1 csi0 */
+ MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
+ MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
+ MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
+ MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
+ MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
+ MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
+ MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
+ MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
+ MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
+ MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
+ MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
+ /* camera reset */
+ MX6Q_PAD_GPIO_19__GPIO_4_5,
+ /* camera powerdown */
+ MX6Q_PAD_CSI0_DAT5__GPIO_5_23,
+};
+
+static iomux_v3_cfg_t mx6q_arm2_csi0_tvin_pads[] = {
+ /* ipu1 csi0 */
+ MX6Q_PAD_CSI0_DAT12__IPU1_CSI0_D_12,
+ MX6Q_PAD_CSI0_DAT13__IPU1_CSI0_D_13,
+ MX6Q_PAD_CSI0_DAT14__IPU1_CSI0_D_14,
+ MX6Q_PAD_CSI0_DAT15__IPU1_CSI0_D_15,
+ MX6Q_PAD_CSI0_DAT16__IPU1_CSI0_D_16,
+ MX6Q_PAD_CSI0_DAT17__IPU1_CSI0_D_17,
+ MX6Q_PAD_CSI0_DAT18__IPU1_CSI0_D_18,
+ MX6Q_PAD_CSI0_DAT19__IPU1_CSI0_D_19,
+ MX6Q_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC,
+ MX6Q_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC,
+ MX6Q_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK,
+ /* camera reset */
+ MX6Q_PAD_CSI0_DAT7__GPIO_5_25,
+ /* camera powerdown */
+ MX6Q_PAD_CSI0_DAT5__GPIO_5_23,
+};
+
+static iomux_v3_cfg_t mx6q_arm2_mipi_sensor_pads[] = {
+ MX6Q_PAD_CSI0_MCLK__CCM_CLKO,
+};
+
+static iomux_v3_cfg_t mx6q_arm2_audmux_pads[] = {
+
+ /* AUDMUX */
+ MX6Q_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC,
+ MX6Q_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD,
+ MX6Q_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS,
+ MX6Q_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD,
+};
+
+#define MX6Q_USDHC_PAD_SETTING(id, speed) \
+mx6q_sd##id##_##speed##mhz[] = { \
+ MX6Q_PAD_SD##id##_CLK__USDHC##id##_CLK_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_CMD__USDHC##id##_CMD_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT0__USDHC##id##_DAT0_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT1__USDHC##id##_DAT1_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT2__USDHC##id##_DAT2_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT3__USDHC##id##_DAT3_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT4__USDHC##id##_DAT4_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT5__USDHC##id##_DAT5_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT6__USDHC##id##_DAT6_##speed##MHZ, \
+ MX6Q_PAD_SD##id##_DAT7__USDHC##id##_DAT7_##speed##MHZ, \
+}
+
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 50);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 100);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(3, 200);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(4, 50);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(4, 100);
+static iomux_v3_cfg_t MX6Q_USDHC_PAD_SETTING(4, 200);
+
+
+/* The GPMI is conflicted with SD3, so init this in the driver. */
+static iomux_v3_cfg_t mx6q_gpmi_nand[] __initdata = {
+ MX6Q_PAD_NANDF_CLE__RAWNAND_CLE,
+ MX6Q_PAD_NANDF_ALE__RAWNAND_ALE,
+ MX6Q_PAD_NANDF_CS0__RAWNAND_CE0N,
+ MX6Q_PAD_NANDF_CS1__RAWNAND_CE1N,
+ MX6Q_PAD_NANDF_CS2__RAWNAND_CE2N,
+ MX6Q_PAD_NANDF_CS3__RAWNAND_CE3N,
+ MX6Q_PAD_NANDF_RB0__RAWNAND_READY0,
+ MX6Q_PAD_SD4_DAT0__RAWNAND_DQS,
+ MX6Q_PAD_NANDF_D0__RAWNAND_D0,
+ MX6Q_PAD_NANDF_D1__RAWNAND_D1,
+ MX6Q_PAD_NANDF_D2__RAWNAND_D2,
+ MX6Q_PAD_NANDF_D3__RAWNAND_D3,
+ MX6Q_PAD_NANDF_D4__RAWNAND_D4,
+ MX6Q_PAD_NANDF_D5__RAWNAND_D5,
+ MX6Q_PAD_NANDF_D6__RAWNAND_D6,
+ MX6Q_PAD_NANDF_D7__RAWNAND_D7,
+ MX6Q_PAD_SD4_CMD__RAWNAND_RDN,
+ MX6Q_PAD_SD4_CLK__RAWNAND_WRN,
+ MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN,
+};
diff --git a/arch/arm/mach-mx6/board-mx6q_sabreauto.c b/arch/arm/mach-mx6/board-mx6q_sabreauto.c
index 5938b9a7ddf3..8b582d566539 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabreauto.c
+++ b/arch/arm/mach-mx6/board-mx6q_sabreauto.c
@@ -498,15 +498,15 @@ static iomux_v3_cfg_t mx6q_gpmi_nand[] __initdata = {
MX6Q_PAD_NANDF_WP_B__RAWNAND_RESETN,
};
-static int gpmi_nfc_platform_init(void)
+static int gpmi_nand_platform_init(void)
{
return mxc_iomux_v3_setup_multiple_pads(mx6q_gpmi_nand,
ARRAY_SIZE(mx6q_gpmi_nand));
}
-static const struct gpmi_nfc_platform_data
-mx6q_gpmi_nfc_platform_data __initconst = {
- .platform_init = gpmi_nfc_platform_init,
+static const struct gpmi_nand_platform_data
+mx6q_gpmi_nand_platform_data __initconst = {
+ .platform_init = gpmi_nand_platform_init,
.min_prop_delay_in_ns = 5,
.max_prop_delay_in_ns = 9,
.max_chip_count = 1,
@@ -1349,31 +1349,10 @@ static inline void __init mx6q_csi0_io_init(void)
mxc_iomux_set_gpr_register(1, 19, 1, 1);
}
-static int spdif_clk_set_rate(struct clk *clk, unsigned long rate)
-{
- unsigned long rate_actual;
- rate_actual = clk_round_rate(clk, rate);
- clk_set_rate(clk, rate_actual);
- return 0;
-}
-
static struct mxc_spdif_platform_data mxc_spdif_data = {
.spdif_tx = 0, /* disable tx */
.spdif_rx = 1, /* enable rx */
- /*
- * spdif0_clk will be 454.7MHz divided by ccm dividers.
- *
- * 44.1KHz: 454.7MHz / 7 (ccm) / 23 (spdif) = 44,128 Hz ~ 0.06% error
- * 48KHz: 454.7MHz / 4 (ccm) / 37 (spdif) = 48,004 Hz ~ 0.01% error
- * 32KHz: 454.7MHz / 6 (ccm) / 37 (spdif) = 32,003 Hz ~ 0.01% error
- */
- .spdif_clk_44100 = 1, /* tx clk from spdif0_clk_root */
- .spdif_clk_48000 = 1, /* tx clk from spdif0_clk_root */
- .spdif_div_44100 = 23,
- .spdif_div_48000 = 37,
- .spdif_div_32000 = 37,
.spdif_rx_clk = 0, /* rx clk from spdif stream */
- .spdif_clk_set_rate = spdif_clk_set_rate,
.spdif_clk = NULL, /* spdif bus clk */
};
@@ -1498,7 +1477,7 @@ static void __init mx6_board_init(void)
imx6q_add_viim();
imx6q_add_imx2_wdt(0, NULL);
imx6q_add_dma();
- imx6q_add_gpmi(&mx6q_gpmi_nfc_platform_data);
+ imx6q_add_gpmi(&mx6q_gpmi_nand_platform_data);
imx6q_add_dvfs_core(&sabreauto_dvfscore_data);
diff --git a/arch/arm/mach-mx6/board-mx6q_sabresd.c b/arch/arm/mach-mx6/board-mx6q_sabresd.c
index 877609ebad63..66e93e414bc8 100644
--- a/arch/arm/mach-mx6/board-mx6q_sabresd.c
+++ b/arch/arm/mach-mx6/board-mx6q_sabresd.c
@@ -101,6 +101,7 @@
#define MX6Q_SABRESD_eCOMPASS_INT IMX_GPIO_NR(3, 16)
#define MX6Q_SABRESD_ALS_INT IMX_GPIO_NR(3, 9)
#define MX6Q_SABRESD_MPCIE_3V3_EN IMX_GPIO_NR(1, 6)
+
#define MX6Q_SABRESD_CHARGE_FLT_1_B IMX_GPIO_NR(5, 2)
#define MX6Q_SABRESD_CHARGE_CHG_1_B IMX_GPIO_NR(3, 23)
#define MX6Q_SABRESD_CHARGE_FLT_2_B IMX_GPIO_NR(3, 14)
@@ -1249,6 +1250,7 @@ static void __init mx6_sabresd_board_init(void)
mxc_register_device(&mxc_android_pmem_gpu_device,
&android_pmem_gpu_data);
imx6q_add_device_buttons();
+
/* enable sensor 3v3 and 1v8 */
gpio_request(MX6Q_SABRESD_SENSOR_EN, "sensor-en");
gpio_direction_output(MX6Q_SABRESD_SENSOR_EN, 1);
diff --git a/arch/arm/mach-mx6/clock.c b/arch/arm/mach-mx6/clock.c
index 403664a62168..578118103299 100644
--- a/arch/arm/mach-mx6/clock.c
+++ b/arch/arm/mach-mx6/clock.c
@@ -344,9 +344,6 @@ static int pfd_set_rate(struct clk *clk, unsigned long rate)
__raw_writel(frac << clk->enable_shift,
(int)clk->enable_reg + 4);
- tmp = (u64)clk_get_rate(clk->parent) * 18;
- do_div(tmp, frac);
-
if (apbh_dma_clk.usecount == 0)
apbh_dma_clk.disable(&apbh_dma_clk);
return 0;
@@ -1746,7 +1743,6 @@ static struct clk vdoa_clk = {
static unsigned long _clk_gpt_get_rate(struct clk *clk)
{
- u32 reg;
unsigned long rate;
if (mx6q_revision() == IMX_CHIP_REVISION_1_0)
@@ -3489,7 +3485,7 @@ static int _clk_enet_enable(struct clk *clk)
/* Enable ENET ref clock */
reg = __raw_readl(PLL8_ENET_BASE_ADDR);
reg &= ~ANADIG_PLL_BYPASS;
- reg &= ~ANADIG_PLL_ENABLE;
+ reg |= ANADIG_PLL_ENABLE;
__raw_writel(reg, PLL8_ENET_BASE_ADDR);
_clk_enable(clk);
@@ -3505,7 +3501,7 @@ static void _clk_enet_disable(struct clk *clk)
/* Enable ENET ref clock */
reg = __raw_readl(PLL8_ENET_BASE_ADDR);
reg |= ANADIG_PLL_BYPASS;
- reg |= ANADIG_PLL_ENABLE;
+ reg &= ~ANADIG_PLL_ENABLE;
__raw_writel(reg, PLL8_ENET_BASE_ADDR);
}
@@ -4338,10 +4334,13 @@ static int _clk_gpu2d_core_set_parent(struct clk *clk, struct clk *parent)
u32 reg = __raw_readl(MXC_CCM_CBCMR) &
~MXC_CCM_CBCMR_GPU2D_CLK_SEL_MASK;
- mux = _get_mux6(parent, &axi_clk, &pll3_usb_otg_main_clk,
- &pll2_pfd_352M, &pll2_pfd_400M, NULL, NULL);
- reg |= (mux << MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET);
- __raw_writel(reg, MXC_CCM_CBCMR);
+ /*on mx6dl, 2d core clock sources from 3d shader core clock*/
+ if (!cpu_is_mx6dl()) {
+ mux = _get_mux6(parent, &axi_clk, &pll3_usb_otg_main_clk,
+ &pll2_pfd_352M, &pll2_pfd_400M, NULL, NULL);
+ reg |= (mux << MXC_CCM_CBCMR_GPU2D_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+ }
return 0;
}
@@ -4478,11 +4477,11 @@ static struct clk gpu3d_shader_clk = {
};
/* set the parent by the ipcg table */
-static struct clk gpmi_nfc_clk[] = {
+static struct clk gpmi_nand_clk[] = {
{ /* gpmi_io_clk */
__INIT_CLK_DEBUG(gpmi_io_clk)
.parent = &enfc_clk,
- .secondary = &gpmi_nfc_clk[1],
+ .secondary = &gpmi_nand_clk[1],
.enable = _clk_enable,
.enable_reg = MXC_CCM_CCGR4,
.enable_shift = MXC_CCM_CCGRx_CG14_OFFSET,
@@ -4491,7 +4490,7 @@ static struct clk gpmi_nfc_clk[] = {
{ /* gpmi_apb_clk */
__INIT_CLK_DEBUG(gpmi_apb_clk)
.parent = &usdhc3_clk,
- .secondary = &gpmi_nfc_clk[2],
+ .secondary = &gpmi_nand_clk[2],
.enable = _clk_enable,
.enable_reg = MXC_CCM_CCGR4,
.enable_shift = MXC_CCM_CCGRx_CG15_OFFSET,
@@ -4500,7 +4499,7 @@ static struct clk gpmi_nfc_clk[] = {
{ /* bch_clk */
__INIT_CLK_DEBUG(gpmi_bch_clk)
.parent = &usdhc4_clk,
- .secondary = &gpmi_nfc_clk[3],
+ .secondary = &gpmi_nand_clk[3],
.enable = _clk_enable,
.enable_reg = MXC_CCM_CCGR4,
.enable_shift = MXC_CCM_CCGRx_CG13_OFFSET,
@@ -4509,7 +4508,7 @@ static struct clk gpmi_nfc_clk[] = {
{ /* bch_apb_clk */
__INIT_CLK_DEBUG(gpmi_bch_apb_clk)
.parent = &usdhc3_clk,
- .secondary = &gpmi_nfc_clk[4],
+ .secondary = &gpmi_nand_clk[4],
.enable = _clk_enable,
.enable_reg = MXC_CCM_CCGR4,
.enable_shift = MXC_CCM_CCGRx_CG12_OFFSET,
@@ -4565,7 +4564,48 @@ static int _clk_pcie_enable(struct clk *clk)
{
unsigned int reg;
- /* Enable SATA ref clock */
+ /* Clear Power Down and Enable PLLs */
+ reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+ reg &= ~ANADIG_PLL_ENET_POWER_DOWN;
+ __raw_writel(reg, PLL8_ENET_BASE_ADDR);
+
+ reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+ reg |= ANADIG_PLL_ENET_EN;
+ __raw_writel(reg, PLL8_ENET_BASE_ADDR);
+
+ /* Waiting for the PLL is locked */
+ if (!WAIT(ANADIG_PLL_ENET_LOCK & __raw_readl(PLL8_ENET_BASE_ADDR),
+ SPIN_DELAY))
+ panic("pll8 lock failed\n");
+
+ /* Disable the bypass */
+ reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+ reg &= ~ANADIG_PLL_ENET_BYPASS;
+ __raw_writel(reg, PLL8_ENET_BASE_ADDR);
+
+ /*
+ * Enable SATA ref clock.
+ * PCIe needs both sides to have the same source of refernce clock,
+ * The SATA reference clock is taken out on clk out
+ */
+ reg = __raw_readl(PLL8_ENET_BASE_ADDR);
+ reg |= ANADIG_PLL_ENET_EN_SATA;
+ __raw_writel(reg, PLL8_ENET_BASE_ADDR);
+
+ /* Activate LVDS CLK1 (the MiniPCIe slot clock input) */
+ reg = __raw_readl(ANADIG_MISC1_REG);
+ reg &= ~ANATOP_LVDS_CLK1_IBEN_MASK;
+ __raw_writel(reg, ANADIG_MISC1_REG);
+
+ reg = __raw_readl(ANADIG_MISC1_REG);
+ reg |= ANATOP_LVDS_CLK1_SRC_SATA;
+ __raw_writel(reg, ANADIG_MISC1_REG);
+
+ reg = __raw_readl(ANADIG_MISC1_REG);
+ reg |= ANATOP_LVDS_CLK1_OBEN_MASK;
+ __raw_writel(reg, ANADIG_MISC1_REG);
+
+ /* Enable PCIE ref clock */
reg = __raw_readl(PLL8_ENET_BASE_ADDR);
reg |= ANADIG_PLL_ENET_EN_PCIE;
__raw_writel(reg, PLL8_ENET_BASE_ADDR);
@@ -5044,11 +5084,11 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, "gpu2d_clk", gpu2d_core_clk[0]),
_REGISTER_CLOCK(NULL, "gpu3d_shader_clk", gpu3d_shader_clk),
_REGISTER_CLOCK(NULL, "gpt", gpt_clk[0]),
- _REGISTER_CLOCK("imx6q-gpmi-nfc.0", NULL, gpmi_nfc_clk[0]),
- _REGISTER_CLOCK(NULL, "gpmi-apb", gpmi_nfc_clk[1]),
- _REGISTER_CLOCK(NULL, "bch", gpmi_nfc_clk[2]),
- _REGISTER_CLOCK(NULL, "bch-apb", gpmi_nfc_clk[3]),
- _REGISTER_CLOCK(NULL, "pl301_mx6qperl-bch", gpmi_nfc_clk[4]),
+ _REGISTER_CLOCK("imx6q-gpmi-nand.0", NULL, gpmi_nand_clk[0]),
+ _REGISTER_CLOCK(NULL, "gpmi-apb", gpmi_nand_clk[1]),
+ _REGISTER_CLOCK(NULL, "bch", gpmi_nand_clk[2]),
+ _REGISTER_CLOCK(NULL, "bch-apb", gpmi_nand_clk[3]),
+ _REGISTER_CLOCK(NULL, "pl301_mx6qperl-bch", gpmi_nand_clk[4]),
_REGISTER_CLOCK("mxc_pwm.0", NULL, pwm_clk[0]),
_REGISTER_CLOCK("mxc_pwm.1", NULL, pwm_clk[1]),
_REGISTER_CLOCK("mxc_pwm.2", NULL, pwm_clk[2]),
@@ -5070,6 +5110,7 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK(NULL, NULL, aips_tz1_clk),
_REGISTER_CLOCK(NULL, "clko_clk", clko_clk),
_REGISTER_CLOCK(NULL, "clko2_clk", clko2_clk),
+ _REGISTER_CLOCK(NULL, "pxp_axi", ipu2_clk),
_REGISTER_CLOCK("mxs-perfmon.0", "perfmon", perfmon0_clk),
_REGISTER_CLOCK("mxs-perfmon.1", "perfmon", perfmon1_clk),
_REGISTER_CLOCK("mxs-perfmon.2", "perfmon", perfmon2_clk),
@@ -5083,7 +5124,8 @@ static void clk_tree_init(void)
reg = __raw_readl(MMDC_MDMISC_OFFSET);
if ((reg & MMDC_MDMISC_DDR_TYPE_MASK) ==
- (0x1 << MMDC_MDMISC_DDR_TYPE_OFFSET)) {
+ (0x1 << MMDC_MDMISC_DDR_TYPE_OFFSET) ||
+ cpu_is_mx6dl()) {
clk_set_parent(&periph_clk, &pll2_pfd_400M);
printk(KERN_INFO "Set periph_clk's parent to pll2_pfd_400M!\n");
}
@@ -5116,7 +5158,7 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
clk_tree_init();
- if (pll2_pfd_400M.usecount == 0)
+ if (pll2_pfd_400M.usecount == 0 && cpu_is_mx6q())
pll2_pfd_400M.disable(&pll2_pfd_400M);
pll2_pfd_352M.disable(&pll2_pfd_352M);
pll2_pfd_594M.disable(&pll2_pfd_594M);
@@ -5158,6 +5200,13 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
clk_set_rate(&gpu3d_shader_clk, 594000000);
clk_set_parent(&gpu3d_core_clk[0], &mmdc_ch0_axi_clk[0]);
clk_set_rate(&gpu3d_core_clk[0], 528000000);
+ if (cpu_is_mx6dl()) {
+ /*on mx6dl, 2d core clock sources from 3d shader core clock*/
+ clk_set_parent(&gpu2d_core_clk[0], &gpu3d_shader_clk);
+ /* on mx6dl gpu2d_axi_clk source from mmdc0 directly */
+ clk_set_parent(&gpu2d_axi_clk, &mmdc_ch0_axi_clk[0]);
+ gpu2d_axi_clk.secondary = NULL;
+ }
/* PCLK camera - J5 */
clk_set_parent(&clko2_clk, &osc_clk);
@@ -5216,6 +5265,10 @@ int __init mx6_clocks_init(unsigned long ckil, unsigned long osc,
/* S/PDIF */
clk_set_parent(&spdif0_clk[0], &pll3_pfd_454M);
+ /* pxp & epdc */
+ clk_set_parent(&ipu2_clk, &pll2_pfd_400M);
+ clk_set_rate(&ipu2_clk, 200000000);
+
if (mx6q_revision() == IMX_CHIP_REVISION_1_0) {
gpt_clk[0].parent = &ipg_perclk;
gpt_clk[0].get_rate = NULL;
diff --git a/arch/arm/mach-mx6/cpu_op-mx6.c b/arch/arm/mach-mx6/cpu_op-mx6.c
index 40ee552c6b04..781e9063fac0 100644
--- a/arch/arm/mach-mx6/cpu_op-mx6.c
+++ b/arch/arm/mach-mx6/cpu_op-mx6.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -23,26 +23,22 @@ extern void (*set_num_cpu_op)(int num);
extern u32 arm_max_freq;
static int num_cpu_op;
-/* working point(wp): 0 - 1GHzMHz; 1 - 800MHz, 3 - 400MHz, 4 - 160MHz */
+/* working point(wp): 0 - 1GHzMHz; 1 - 800MHz, 2 - 624MHz 3 - 400MHz, 4 - 200MHz */
static struct cpu_op mx6_cpu_op_1G[] = {
{
.pll_rate = 996000000,
.cpu_rate = 996000000,
- .pdf = 0,
- .mfi = 10,
- .mfd = 11,
- .mfn = 5,
.cpu_podf = 0,
.cpu_voltage = 1225000,},
{
.pll_rate = 792000000,
.cpu_rate = 792000000,
- .pdf = 0,
- .mfi = 8,
- .mfd = 2,
- .mfn = 1,
.cpu_podf = 0,
.cpu_voltage = 1100000,},
+ {
+ .pll_rate = 624000000,
+ .cpu_rate = 624000000,
+ .cpu_voltage = 11000000,},
{
.pll_rate = 792000000,
.cpu_rate = 396000000,
@@ -59,10 +55,6 @@ static struct cpu_op mx6_cpu_op[] = {
{
.pll_rate = 792000000,
.cpu_rate = 792000000,
- .pdf = 0,
- .mfi = 8,
- .mfd = 2,
- .mfn = 1,
.cpu_podf = 0,
.cpu_voltage = 1100000,},
{
@@ -77,6 +69,48 @@ static struct cpu_op mx6_cpu_op[] = {
.cpu_voltage = 850000,},
};
+/* working point(wp): 0 - 1GHzMHz; 1 - 800MHz, 3 - 400MHz, 4 - 200MHz */
+static struct cpu_op mx6dl_cpu_op_1G[] = {
+ {
+ .pll_rate = 996000000,
+ .cpu_rate = 996000000,
+ .cpu_podf = 0,
+ .cpu_voltage = 1225000,},
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 792000000,
+ .cpu_podf = 0,
+ .cpu_voltage = 1100000,},
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 396000000,
+ .cpu_podf = 1,
+ .cpu_voltage = 1000000,},
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 198000000,
+ .cpu_podf = 3,
+ .cpu_voltage = 1000000,},
+};
+
+static struct cpu_op mx6dl_cpu_op[] = {
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 792000000,
+ .cpu_podf = 0,
+ .cpu_voltage = 1100000,},
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 396000000,
+ .cpu_podf = 1,
+ .cpu_voltage = 1000000,},
+ {
+ .pll_rate = 792000000,
+ .cpu_rate = 198000000,
+ .cpu_podf = 3,
+ .cpu_voltage = 1000000,},
+};
+
static struct dvfs_op dvfs_core_setpoint_1G[] = {
{33, 14, 33, 10, 128, 0x10}, /* 1GHz*/
{30, 12, 33, 100, 200, 0x10}, /* 800MHz */
@@ -101,12 +135,22 @@ static struct dvfs_op *mx6_get_dvfs_core_table(int *wp)
struct cpu_op *mx6_get_cpu_op(int *op)
{
- if (arm_max_freq == CPU_AT_1GHz) {
- *op = num_cpu_op = ARRAY_SIZE(mx6_cpu_op_1G);
- return mx6_cpu_op_1G;
+ if (cpu_is_mx6dl()) {
+ if (arm_max_freq == CPU_AT_1GHz) {
+ *op = num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op_1G);
+ return mx6dl_cpu_op_1G;
+ } else {
+ *op = num_cpu_op = ARRAY_SIZE(mx6dl_cpu_op);
+ return mx6dl_cpu_op;
+ }
} else {
- *op = num_cpu_op = ARRAY_SIZE(mx6_cpu_op);
- return mx6_cpu_op;
+ if (arm_max_freq == CPU_AT_1GHz) {
+ *op = num_cpu_op = ARRAY_SIZE(mx6_cpu_op_1G);
+ return mx6_cpu_op_1G;
+ } else {
+ *op = num_cpu_op = ARRAY_SIZE(mx6_cpu_op);
+ return mx6_cpu_op;
+ }
}
}
diff --git a/arch/arm/mach-mx6/crm_regs.h b/arch/arm/mach-mx6/crm_regs.h
index 0e29ea83f1df..6dbdeafa0dba 100644
--- a/arch/arm/mach-mx6/crm_regs.h
+++ b/arch/arm/mach-mx6/crm_regs.h
@@ -47,6 +47,10 @@
#define PFD_480_BASE_ADDR (MXC_PLL_BASE + 0xF0)
#define PFD_528_BASE_ADDR (MXC_PLL_BASE + 0x100)
#define ANADIG_REG_CORE (MXC_PLL_BASE + 0x140)
+#define ANADIG_MISC1_REG (MXC_PLL_BASE + 0x160)
+#define ANATOP_LVDS_CLK1_SRC_SATA 0xB
+#define ANATOP_LVDS_CLK1_OBEN_MASK 0x400
+#define ANATOP_LVDS_CLK1_IBEN_MASK 0x1000
#define ANA_MISC2_BASE_ADDR (MXC_PLL_BASE + 0x170)
#define PLL_SETREG_OFFSET 0x4
diff --git a/arch/arm/mach-mx6/devices-imx6q.h b/arch/arm/mach-mx6/devices-imx6q.h
index ce6b50dc641f..ab245158cfb7 100644
--- a/arch/arm/mach-mx6/devices-imx6q.h
+++ b/arch/arm/mach-mx6/devices-imx6q.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -198,3 +198,13 @@ extern const struct imx_mxc_mlb_data imx6q_mxc_mlb150_data __initconst;
#define imx6q_add_mlb150(pdata) \
imx_add_mlb(pdata)
+extern const struct imx_pxp_data imx6dl_pxp_data __initconst;
+#define imx6dl_add_imx_pxp() \
+ imx_add_imx_pxp(&imx6dl_pxp_data)
+
+#define imx6dl_add_imx_pxp_client() \
+ imx_add_imx_pxp_client()
+
+extern const struct imx_epdc_data imx6dl_epdc_data __initconst;
+#define imx6dl_add_imx_epdc(pdata) \
+ imx_add_imx_epdc(&imx6dl_epdc_data, pdata)
diff --git a/arch/arm/mach-mx6/mm.c b/arch/arm/mach-mx6/mm.c
index fa1c78be532f..e4daaf1fb415 100644
--- a/arch/arm/mach-mx6/mm.c
+++ b/arch/arm/mach-mx6/mm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -57,6 +57,19 @@ static struct map_desc mx6_io_desc[] __initdata = {
.type = MT_DEVICE},
};
+static void mx6_set_cpu_type(void)
+{
+ u32 cpu_type = readl(IO_ADDRESS(ANATOP_BASE_ADDR + 0x260));
+
+ cpu_type >>= 16;
+ if (cpu_type == 0x63)
+ mxc_set_cpu_type(MXC_CPU_MX6Q);
+ else if (cpu_type == 0x61)
+ mxc_set_cpu_type(MXC_CPU_MX6DL);
+ else
+ pr_err("Unknown CPU type: %x\n", cpu_type);
+}
+
/*!
* This function initializes the memory map. It is called during the
* system startup to create static physical to virtual memory map for
@@ -67,6 +80,7 @@ void __init mx6_map_io(void)
iotable_init(mx6_io_desc, ARRAY_SIZE(mx6_io_desc));
mxc_iomux_v3_init(IO_ADDRESS(MX6Q_IOMUXC_BASE_ADDR));
mxc_arch_reset_init(IO_ADDRESS(MX6Q_WDOG1_BASE_ADDR));
+ mx6_set_cpu_type();
}
#ifdef CONFIG_CACHE_L2X0
int mxc_init_l2x0(void)
diff --git a/arch/arm/mach-mx6/pcie.c b/arch/arm/mach-mx6/pcie.c
new file mode 100644
index 000000000000..9959bbceaa4d
--- /dev/null
+++ b/arch/arm/mach-mx6/pcie.c
@@ -0,0 +1,484 @@
+/*
+ * arch/arm/mach-mx6/pcie.c
+ *
+ * PCIe host controller driver for IMX6 SOCs
+ *
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * Bits taken from arch/arm/mach-dove/pcie.c
+ *
+ * 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 <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+
+#include <asm/sizes.h>
+
+#include "crm_regs.h"
+
+/* Register Definitions */
+#define PRT_LOG_R_BaseAddress 0x700
+
+/* Register DB_R0 */
+/* Debug Register 0 */
+#define DB_R0 (PRT_LOG_R_BaseAddress + 0x28)
+#define DB_R0_RegisterSize 32
+#define DB_R0_RegisterResetValue 0x0
+#define DB_R0_RegisterResetMask 0xFFFFFFFF
+/* End of Register Definition for DB_R0 */
+
+/* Register DB_R1 */
+/* Debug Register 1 */
+#define DB_R1 (PRT_LOG_R_BaseAddress + 0x2c)
+#define DB_R1_RegisterSize 32
+#define DB_R1_RegisterResetValue 0x0
+#define DB_R1_RegisterResetMask 0xFFFFFFFF
+/* End of Register Definition for DB_R1 */
+
+#define ATU_R_BaseAddress 0x900
+#define ATU_VIEWPORT_R (ATU_R_BaseAddress + 0x0)
+#define ATU_REGION_CTRL1_R (ATU_R_BaseAddress + 0x4)
+#define ATU_REGION_CTRL2_R (ATU_R_BaseAddress + 0x8)
+#define ATU_REGION_LOWBASE_R (ATU_R_BaseAddress + 0xC)
+#define ATU_REGION_UPBASE_R (ATU_R_BaseAddress + 0x10)
+#define ATU_REGION_LIMIT_ADDR_R (ATU_R_BaseAddress + 0x14)
+#define ATU_REGION_LOW_TRGT_ADDR_R (ATU_R_BaseAddress + 0x18)
+#define ATU_REGION_UP_TRGT_ADDR_R (ATU_R_BaseAddress + 0x1C)
+
+/* GPR1: iomuxc_gpr1_pcie_ref_clk_en(iomuxc_gpr1[16]) */
+#define iomuxc_gpr1_pcie_ref_clk_en (1 << 16)
+/* GPR1: iomuxc_gpr1_test_powerdown(iomuxc_gpr1_18) */
+#define iomuxc_gpr1_test_powerdown (1 << 18)
+
+/* GPR12: iomuxc_gpr12_los_level(iomuxc_gpr12[8:4]) */
+#define iomuxc_gpr12_los_level (0x1F << 4)
+/* GPR12: iomuxc_gpr12_app_ltssm_enable(iomuxc_gpr12[10]) */
+#define iomuxc_gpr12_app_ltssm_enable (1 << 10)
+/* GPR12: iomuxc_gpr12_device_type(iomuxc_gpr12[15:12]) */
+#define iomuxc_gpr12_device_type (0xF << 12)
+
+/* GPR8: iomuxc_gpr8_tx_deemph_gen1(iomuxc_gpr8[5:0]) */
+#define iomuxc_gpr8_tx_deemph_gen1 (0x3F << 0)
+/* GPR8: iomuxc_gpr8_tx_deemph_gen2_3p5db(iomuxc_gpr8[11:6]) */
+#define iomuxc_gpr8_tx_deemph_gen2_3p5db (0x3F << 6)
+/* GPR8: iomuxc_gpr8_tx_deemph_gen2_6db(iomuxc_gpr8[17:12]) */
+#define iomuxc_gpr8_tx_deemph_gen2_6db (0x3F << 12)
+/* GPR8: iomuxc_gpr8_tx_swing_full(iomuxc_gpr8[24:18]) */
+#define iomuxc_gpr8_tx_swing_full (0x7F << 18)
+/* GPR8: iomuxc_gpr8_tx_swing_low(iomuxc_gpr8[31:25]) */
+#define iomuxc_gpr8_tx_swing_low (0x7F << 25)
+
+/* End of Register Definitions */
+
+#define PCIE_DBI_BASE_ADDR (PCIE_ARB_END_ADDR - SZ_16K + 1)
+
+#define PCIE_CONF_BUS(b) (((b) & 0xFF) << 16)
+#define PCIE_CONF_DEV(d) (((d) & 0x1F) << 11)
+#define PCIE_CONF_FUNC(f) (((f) & 0x7) << 8)
+
+enum {
+ MemRdWr = 0,
+ MemRdLk = 1,
+ IORdWr = 2,
+ CfgRdWr0 = 4,
+ CfgRdWr1 = 5
+};
+
+struct imx_pcie_port {
+ u8 index;
+ u8 root_bus_nr;
+ void __iomem *base;
+ void __iomem *dbi_base;
+ spinlock_t conf_lock;
+
+ char io_space_name[16];
+ char mem_space_name[16];
+
+ struct resource res[2];
+};
+
+static struct imx_pcie_port imx_pcie_port[1];
+static int num_pcie_ports;
+
+/* IMX PCIE GPR configure routines */
+static inline void imx_pcie_clrset(u32 mask, u32 val, void __iomem *addr)
+{
+ writel(((readl(addr) & ~mask) | (val & mask)), addr);
+}
+
+static struct imx_pcie_port *bus_to_port(int bus)
+{
+ int i;
+
+ for (i = num_pcie_ports - 1; i >= 0; i--) {
+ int rbus = imx_pcie_port[i].root_bus_nr;
+ if (rbus != -1 && rbus <= bus)
+ break;
+ }
+
+ return i >= 0 ? imx_pcie_port + i : NULL;
+}
+
+static int __init imx_pcie_setup(int nr, struct pci_sys_data *sys)
+{
+ struct imx_pcie_port *pp;
+
+ if (nr >= num_pcie_ports)
+ return 0;
+
+ pp = &imx_pcie_port[nr];
+ pp->root_bus_nr = sys->busnr;
+
+ /*
+ * IORESOURCE_IO
+ */
+ snprintf(pp->io_space_name, sizeof(pp->io_space_name),
+ "PCIe %d I/O", pp->index);
+ pp->io_space_name[sizeof(pp->io_space_name) - 1] = 0;
+ pp->res[0].name = pp->io_space_name;
+ if (pp->index == 0) {
+ pp->res[0].start = PCIE_ARB_BASE_ADDR;
+ pp->res[0].end = pp->res[0].start + SZ_64K - 1;
+ }
+ pp->res[0].flags = IORESOURCE_IO;
+ if (request_resource(&ioport_resource, &pp->res[0]))
+ panic("Request PCIe IO resource failed\n");
+ sys->resource[0] = &pp->res[0];
+
+ /*
+ * IORESOURCE_MEM
+ */
+ snprintf(pp->mem_space_name, sizeof(pp->mem_space_name),
+ "PCIe %d MEM", pp->index);
+ pp->mem_space_name[sizeof(pp->mem_space_name) - 1] = 0;
+ pp->res[1].name = pp->mem_space_name;
+ if (pp->index == 0) {
+ pp->res[1].start = PCIE_ARB_BASE_ADDR + SZ_64K;
+ pp->res[1].end = pp->res[1].start + SZ_16M - SZ_128K - 1;
+ }
+ pp->res[1].flags = IORESOURCE_MEM;
+ if (request_resource(&iomem_resource, &pp->res[1]))
+ panic("Request PCIe Memory resource failed\n");
+ sys->resource[1] = &pp->res[1];
+
+ sys->resource[2] = NULL;
+
+ return 1;
+}
+
+static void __init imx_pcie_preinit(void)
+{
+ pcibios_setup("debug");
+}
+
+static int imx_pcie_link_up(void __iomem *dbi_base)
+{
+ /* Check the pcie link up or link down */
+ u32 rc, iterations = 0x100000;
+
+ do {
+ /* link is debug bit 36 debug 1 start in bit 32 */
+ rc = readl(dbi_base + DB_R1) & (0x1 << (36-32)) ;
+ iterations--;
+ if ((iterations % 0x100000) == 0)
+ pr_info("link up failed!\n");
+ } while (!rc && iterations);
+
+ if (!rc)
+ return 0;
+ return 1;
+}
+
+static int pcie_valid_config(struct imx_pcie_port *pp, int bus_num, int dev)
+{
+ /*If there is no link, then there is no device*/
+ if (bus_num != pp->root_bus_nr) {
+ if (!imx_pcie_link_up(pp->dbi_base))
+ return 0;
+ }
+
+ /*
+ * Don't go out when trying to access nonexisting devices
+ * on the local bus.
+ * We have only one slot on the root port.
+ */
+ if (bus_num == pp->root_bus_nr && dev > 0)
+ return 0;
+
+ return 1;
+}
+
+static void imx_pcie_regions_setup(void __iomem *dbi_base)
+{
+ /*
+ * i.MX6 defines 16MB in the AXI address map for PCIe.
+ *
+ * That address space excepted the pcie registers is
+ * split and defined into different regions by iATU,
+ * with sizes and offsets as follows:
+ *
+ * 0x0100_0000 --- 0x0100_FFFF 64KB IORESOURCE_IO
+ * 0x0101_0000 --- 0x01FE_FFFF 16MB - 128KB IORESOURCE_MEM
+ * 0x01FF_0000 --- 0x01FF_FFFF 64KB Cfg + Registers
+ */
+
+ /* CMD reg:I/O space, MEM space, and Bus Master Enable */
+ writel(readl(dbi_base + PCI_COMMAND)
+ | PCI_COMMAND_IO
+ | PCI_COMMAND_MEMORY
+ | PCI_COMMAND_MASTER,
+ dbi_base + PCI_COMMAND);
+ /*
+ * region0 outbound used to access target cfg
+ */
+ writel(0, dbi_base + ATU_VIEWPORT_R);
+ writel(PCIE_ARB_END_ADDR - SZ_64K + 1, dbi_base + ATU_REGION_LOWBASE_R);
+ writel(0, dbi_base + ATU_REGION_UPBASE_R);
+ writel(PCIE_ARB_END_ADDR, dbi_base + ATU_REGION_LIMIT_ADDR_R);
+ writel(0, dbi_base + ATU_REGION_LOW_TRGT_ADDR_R);
+ writel(0, dbi_base + ATU_REGION_UP_TRGT_ADDR_R);
+ writel(CfgRdWr0, dbi_base + ATU_REGION_CTRL1_R);
+ writel((1<<31), dbi_base + ATU_REGION_CTRL2_R);
+
+ /*
+ * region1 outbound used to as IORESOURCE_IO
+ */
+ writel(1, dbi_base + ATU_VIEWPORT_R);
+ writel(0, dbi_base + ATU_REGION_LOWBASE_R);
+ writel(0, dbi_base + ATU_REGION_UPBASE_R);
+ writel(SZ_64K - 1, dbi_base + ATU_REGION_LIMIT_ADDR_R);
+ writel(0, dbi_base + ATU_REGION_LOW_TRGT_ADDR_R);
+ writel(0, dbi_base + ATU_REGION_UP_TRGT_ADDR_R);
+ writel(IORdWr, dbi_base + ATU_REGION_CTRL1_R);
+ writel((1<<31), dbi_base + ATU_REGION_CTRL2_R);
+
+ /*
+ * region2 outbound used to as IORESOURCE_MEM
+ */
+ writel(2, dbi_base + ATU_VIEWPORT_R);
+ writel(0, dbi_base + ATU_REGION_LOWBASE_R);
+ writel(0, dbi_base + ATU_REGION_UPBASE_R);
+ writel(SZ_16M - SZ_128K - 1, dbi_base + ATU_REGION_LIMIT_ADDR_R);
+ writel(0, dbi_base + ATU_REGION_LOW_TRGT_ADDR_R);
+ writel(0, dbi_base + ATU_REGION_UP_TRGT_ADDR_R);
+ writel(MemRdWr, dbi_base + ATU_REGION_CTRL1_R);
+ writel((1<<31), dbi_base + ATU_REGION_CTRL2_R);
+}
+
+static int imx_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
+ int size, u32 *val)
+{
+ struct imx_pcie_port *pp = bus_to_port(bus->number);
+ unsigned long flags;
+ u32 va_address;
+
+ if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0) {
+ *val = 0xFFFFFFFF;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+
+ spin_lock_irqsave(&pp->conf_lock, flags);
+
+ va_address = (u32)pp->base +
+ PCIE_CONF_BUS(bus->number) +
+ PCIE_CONF_DEV(PCI_SLOT(devfn)) +
+ PCIE_CONF_FUNC(PCI_FUNC(devfn)) +
+ (where & ~0x3);
+
+ *val = readl(va_address);
+
+ if (size == 1)
+ *val = (*val >> (8 * (where & 3))) & 0xFF;
+ else if (size == 2)
+ *val = (*val >> (8 * (where & 3))) & 0xFFFF;
+
+ spin_unlock_irqrestore(&pp->conf_lock, flags);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int imx_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
+ int where, int size, u32 val)
+{
+ struct imx_pcie_port *pp = bus_to_port(bus->number);
+ unsigned long flags;
+ u32 va_address = 0, mask = 0, tmp = 0;
+ int ret = PCIBIOS_SUCCESSFUL;
+
+ if (pcie_valid_config(pp, bus->number, PCI_SLOT(devfn)) == 0)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ spin_lock_irqsave(&pp->conf_lock, flags);
+
+ va_address = (u32)pp->base +
+ PCIE_CONF_BUS(bus->number) +
+ PCIE_CONF_DEV(PCI_SLOT(devfn)) +
+ PCIE_CONF_FUNC(PCI_FUNC(devfn)) +
+ (where & ~0x3);
+
+ if (size == 4) {
+ writel(val, va_address);
+ goto exit;
+ }
+
+ if (size == 2)
+ mask = ~(0xFFFF << ((where & 0x3) * 8));
+ else if (size == 1)
+ mask = ~(0xFF << ((where & 0x3) * 8));
+ else
+ ret = PCIBIOS_BAD_REGISTER_NUMBER;
+
+ tmp = readl(va_address) & mask;
+ tmp |= val << ((where & 0x3) * 8);
+ writel(tmp, va_address);
+exit:
+ spin_unlock_irqrestore(&pp->conf_lock, flags);
+
+ return ret;
+}
+
+static struct pci_ops imx_pcie_ops = {
+ .read = imx_pcie_rd_conf,
+ .write = imx_pcie_wr_conf,
+};
+
+static struct pci_bus __init *
+imx_pcie_scan_bus(int nr, struct pci_sys_data *sys)
+{
+ struct pci_bus *bus;
+
+ if (nr < num_pcie_ports) {
+ bus = pci_scan_bus(sys->busnr, &imx_pcie_ops, sys);
+ } else {
+ bus = NULL;
+ BUG();
+ }
+
+ return bus;
+}
+
+static int __init imx_pcie_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return MXC_INT_PCIE_0;
+}
+
+static struct hw_pci imx_pci __initdata = {
+ .nr_controllers = 1,
+ .swizzle = pci_std_swizzle,
+ .setup = imx_pcie_setup,
+ .preinit = imx_pcie_preinit,
+ .scan = imx_pcie_scan_bus,
+ .map_irq = imx_pcie_map_irq,
+};
+
+static void imx_pcie_enable_controller(void)
+{
+ struct clk *pcie_clk;
+
+ imx_pcie_clrset(iomuxc_gpr1_test_powerdown, 0 << 18, IOMUXC_GPR1);
+
+ /* enable the clks */
+ pcie_clk = clk_get(NULL, "pcie_clk");
+ if (IS_ERR(pcie_clk))
+ pr_err("no pcie clock.\n");
+
+ if (clk_enable(pcie_clk)) {
+ pr_err("can't enable pcie clock.\n");
+ clk_put(pcie_clk);
+ }
+}
+
+static void card_reset(void)
+{
+ /* Add one reset to the pcie external device */
+}
+
+static void __init add_pcie_port(void __iomem *base, void __iomem *dbi_base)
+{
+ if (imx_pcie_link_up(dbi_base)) {
+ struct imx_pcie_port *pp = &imx_pcie_port[num_pcie_ports++];
+
+ pr_info("IMX PCIe port: link up.\n");
+
+ pp->index = 0;
+ pp->root_bus_nr = -1;
+ pp->base = base;
+ pp->dbi_base = dbi_base;
+ spin_lock_init(&pp->conf_lock);
+ memset(pp->res, 0, sizeof(pp->res));
+ } else
+ pr_info("IMX PCIe port: link down!\n");
+}
+
+static int __init imx_pcie_init(void)
+{
+ void __iomem *base, *dbi_base;
+
+ base = ioremap_nocache(PCIE_ARB_END_ADDR - SZ_64K + 1, SZ_32K);
+ if (!base) {
+ pr_err("error with ioremap in function %s\n", __func__);
+ return -EIO;
+ }
+
+ dbi_base = ioremap_nocache(PCIE_DBI_BASE_ADDR, SZ_16K);
+ if (!dbi_base) {
+ pr_err("error with ioremap in function %s\n", __func__);
+ iounmap(base);
+ return -EIO;
+ }
+
+ /* FIXME the field name should be aligned to RM */
+ imx_pcie_clrset(iomuxc_gpr12_app_ltssm_enable, 0 << 10, IOMUXC_GPR12);
+
+ /* configure constant input signal to the pcie ctrl and phy */
+ imx_pcie_clrset(iomuxc_gpr12_device_type, PCI_EXP_TYPE_ROOT_PORT << 12,
+ IOMUXC_GPR12);
+ imx_pcie_clrset(iomuxc_gpr12_los_level, 9 << 4, IOMUXC_GPR12);
+ imx_pcie_clrset(iomuxc_gpr8_tx_deemph_gen1, 21 << 0, IOMUXC_GPR8);
+ imx_pcie_clrset(iomuxc_gpr8_tx_deemph_gen2_3p5db, 21 << 6, IOMUXC_GPR8);
+ imx_pcie_clrset(iomuxc_gpr8_tx_deemph_gen2_6db, 32 << 12, IOMUXC_GPR8);
+ imx_pcie_clrset(iomuxc_gpr8_tx_swing_full, 115 << 18, IOMUXC_GPR8);
+ imx_pcie_clrset(iomuxc_gpr8_tx_swing_low, 115 << 25, IOMUXC_GPR8);
+
+ /* Enable the pwr, clks and so on */
+ imx_pcie_enable_controller();
+
+ imx_pcie_clrset(iomuxc_gpr1_pcie_ref_clk_en, 1 << 16, IOMUXC_GPR1);
+
+ /* togle the external card's reset */
+ card_reset() ;
+
+ usleep_range(3000, 4000);
+ imx_pcie_regions_setup(dbi_base);
+ usleep_range(3000, 4000);
+
+ /* start link up */
+ imx_pcie_clrset(iomuxc_gpr12_app_ltssm_enable, 1 << 10, IOMUXC_GPR12);
+
+ /* add the pcie port */
+ add_pcie_port(base, dbi_base);
+
+ pci_common_init(&imx_pci);
+ pr_info("pcie init successful\n");
+ return 0;
+}
+subsys_initcall(imx_pcie_init);
diff --git a/arch/arm/mach-mx6/system.c b/arch/arm/mach-mx6/system.c
index efc838e08078..185be00db482 100644
--- a/arch/arm/mach-mx6/system.c
+++ b/arch/arm/mach-mx6/system.c
@@ -243,7 +243,7 @@ static int __mxs_reset_block(void __iomem *hwreg, int just_enable)
return 0;
}
-int mxs_reset_block(void __iomem *hwreg, int just_enable)
+static int _mxs_reset_block(void __iomem *hwreg, int just_enable)
{
int try = 10;
int r;
@@ -256,4 +256,9 @@ int mxs_reset_block(void __iomem *hwreg, int just_enable)
}
return r;
}
+
+int mxs_reset_block(void __iomem *hwreg)
+{
+ return _mxs_reset_block(hwreg, false);
+}
EXPORT_SYMBOL(mxs_reset_block);
diff --git a/arch/arm/mach-mx6/usb_dr.c b/arch/arm/mach-mx6/usb_dr.c
index 4c7c21dd2f56..21cf3d80699a 100644
--- a/arch/arm/mach-mx6/usb_dr.c
+++ b/arch/arm/mach-mx6/usb_dr.c
@@ -395,6 +395,19 @@ static void host_wakeup_handler(struct fsl_usb2_platform_data *pdata)
#ifdef CONFIG_USB_GADGET_ARC
/* Beginning of device related operation for DR port */
+static void _gadget_discharge_dp(bool enable)
+{
+ void __iomem *phy_reg = MX6_IO_ADDRESS(USB_PHY0_BASE_ADDR);
+ if (enable) {
+ __raw_writel(BF_USBPHY_DEBUG_ENHSTPULLDOWN(0x2), phy_reg + HW_USBPHY_DEBUG_SET);
+ __raw_writel(BF_USBPHY_DEBUG_HSTPULLDOWN(0x2), phy_reg + HW_USBPHY_DEBUG_SET);
+ } else {
+ __raw_writel(BF_USBPHY_DEBUG_ENHSTPULLDOWN(0x2), phy_reg + HW_USBPHY_DEBUG_CLR);
+ __raw_writel(BF_USBPHY_DEBUG_HSTPULLDOWN(0x2), phy_reg + HW_USBPHY_DEBUG_CLR);
+ }
+
+}
+
static void _device_phy_lowpower_suspend(struct fsl_usb2_platform_data *pdata, bool enable)
{
__phy_lowpower_suspend(pdata, enable, ENABLED_BY_DEVICE);
@@ -489,6 +502,7 @@ void __init mx6_usb_dr_init(void)
dr_utmi_config.platform_resume = NULL;
dr_utmi_config.phy_lowpower_suspend = _device_phy_lowpower_suspend;
dr_utmi_config.is_wakeup_event = _is_device_wakeup;
+ dr_utmi_config.gadget_discharge_dp = _gadget_discharge_dp;
dr_utmi_config.wakeup_pdata = &dr_wakeup_config;
dr_utmi_config.wakeup_handler = device_wakeup_handler;
pdev = imx6q_add_fsl_usb2_udc(&dr_utmi_config);
diff --git a/arch/arm/mach-mx6/usb_h2.c b/arch/arm/mach-mx6/usb_h2.c
index edbad95a82ad..4e78ad3a0cf9 100644
--- a/arch/arm/mach-mx6/usb_h2.c
+++ b/arch/arm/mach-mx6/usb_h2.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,6 +30,7 @@
#include <mach/arc_otg.h>
#include <mach/hardware.h>
#include <mach/iomux-mx6q.h>
+#include <mach/iomux-mx6dl.h>
#include "devices-imx6q.h"
#include "regs-anadig.h"
#include "usb.h"
@@ -43,11 +44,17 @@ static struct fsl_usb2_platform_data usbh2_config;
static void usbh2_internal_phy_clock_gate(bool on)
{
if (on) {
+ /* must turn on the 480M clock, otherwise
+ * there will be a 10ms delay before host
+ * controller send out resume signal*/
USB_H2_CTRL |= UCTRL_UTMI_ON_CLOCK;
USB_UH2_HSIC_CTRL |= HSIC_CLK_ON;
} else {
USB_UH2_HSIC_CTRL &= ~HSIC_CLK_ON;
- USB_H2_CTRL &= ~UCTRL_UTMI_ON_CLOCK;
+ /* can't turn off this clock, otherwise
+ * there will be a 10ms delay before host
+ * controller send out resume signal*/
+ /*USB_H2_CTRL &= ~UCTRL_UTMI_ON_CLOCK*/;
}
}
@@ -113,6 +120,10 @@ void mx6_set_host2_vbus_func(driver_vbus_func driver_vbus)
static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable)
{
pr_debug("host2, %s, enable is %d\n", __func__, enable);
+ /* for HSIC, no disconnect nor connect
+ * we need to disable the WKDS, WKCN */
+ UH2_PORTSC1 &= ~(PORTSC_WKDC | PORTSC_WKCN);
+
if (enable) {
USB_H2_CTRL |= (UCTRL_OWIE);
} else {
@@ -169,7 +180,19 @@ static void hsic_start(void)
{
pr_debug("%s\n", __func__);
/* strobe 47K pull up */
- mxc_iomux_v3_setup_pad(MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE_START);
+ if (cpu_is_mx6q())
+ mxc_iomux_v3_setup_pad(
+ MX6Q_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE_START);
+ else if (cpu_is_mx6dl())
+ mxc_iomux_v3_setup_pad(
+ MX6DL_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE_START);
+}
+
+static void hsic_device_connected(void)
+{
+ pr_debug("%s\n", __func__);
+ if (!(USB_UH2_HSIC_CTRL & HSIC_DEV_CONN))
+ USB_UH2_HSIC_CTRL |= HSIC_DEV_CONN;
}
static struct fsl_usb2_platform_data usbh2_config = {
@@ -186,6 +209,7 @@ static struct fsl_usb2_platform_data usbh2_config = {
.wakeup_handler = h2_wakeup_handler,
.transceiver = "hsic_xcvr",
.hsic_post_ops = hsic_start,
+ .hsic_device_connected = hsic_device_connected,
};
static struct fsl_usb2_wakeup_platform_data usbh2_wakeup_config = {
@@ -211,4 +235,8 @@ void __init mx6_usb_h2_init(void)
*/
__raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS,
anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET);
+ /* must change the clkgate delay to 2 or 3 to avoid
+ * 24M OSCI clock not stable issue */
+ __raw_writel(BF_ANADIG_ANA_MISC0_CLKGATE_DELAY(3),
+ anatop_base_addr + HW_ANADIG_ANA_MISC0);
}
diff --git a/arch/arm/mach-mx6/usb_h3.c b/arch/arm/mach-mx6/usb_h3.c
index 43c2b1208eed..46ffc74cce3a 100644
--- a/arch/arm/mach-mx6/usb_h3.c
+++ b/arch/arm/mach-mx6/usb_h3.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -30,6 +30,7 @@
#include <mach/arc_otg.h>
#include <mach/hardware.h>
#include <mach/iomux-mx6q.h>
+#include <mach/iomux-mx6dl.h>
#include "devices-imx6q.h"
#include "regs-anadig.h"
#include "usb.h"
@@ -43,11 +44,17 @@ static struct fsl_usb2_platform_data usbh3_config;
static void usbh3_internal_phy_clock_gate(bool on)
{
if (on) {
+ /* must turn on the 480M clock, otherwise
+ * there will be a 10ms delay before host
+ * controller send out resume signal*/
USB_H3_CTRL |= UCTRL_UTMI_ON_CLOCK;
USB_UH3_HSIC_CTRL |= HSIC_CLK_ON;
} else {
USB_UH3_HSIC_CTRL &= ~HSIC_CLK_ON;
- USB_H3_CTRL &= ~UCTRL_UTMI_ON_CLOCK;
+ /* can't turn off this clock, otherwise
+ * there will be a 10ms delay before host
+ * controller send out resume signal*/
+ /*USB_H3_CTRL &= ~UCTRL_UTMI_ON_CLOCK;*/
}
}
@@ -114,6 +121,10 @@ void mx6_set_host3_vbus_func(driver_vbus_func driver_vbus)
static void _wake_up_enable(struct fsl_usb2_platform_data *pdata, bool enable)
{
pr_debug("host3, %s, enable is %d\n", __func__, enable);
+ /* for HSIC, no disconnect nor connect
+ * we need to disable the WKDS, WKCN */
+ UH3_PORTSC1 &= ~(PORTSC_WKDC | PORTSC_WKCN);
+
if (enable) {
USB_H3_CTRL |= (UCTRL_OWIE);
} else {
@@ -170,7 +181,19 @@ static void hsic_start(void)
{
pr_debug("%s", __func__);
/* strobe 47K pull up */
- mxc_iomux_v3_setup_pad(MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE_START);
+ if (cpu_is_mx6q())
+ mxc_iomux_v3_setup_pad(
+ MX6Q_PAD_RGMII_RXC__USBOH3_H3_STROBE_START);
+ else if (cpu_is_mx6dl())
+ mxc_iomux_v3_setup_pad(
+ MX6DL_PAD_RGMII_RXC__USBOH3_H3_STROBE_START);
+}
+
+static void hsic_device_connected(void)
+{
+ pr_debug("%s\n", __func__);
+ if (!(USB_UH3_HSIC_CTRL & HSIC_DEV_CONN))
+ USB_UH3_HSIC_CTRL |= HSIC_DEV_CONN;
}
static struct fsl_usb2_platform_data usbh3_config = {
@@ -187,6 +210,7 @@ static struct fsl_usb2_platform_data usbh3_config = {
.wakeup_handler = usbh3_wakeup_handler,
.transceiver = "hsic_xcvr",
.hsic_post_ops = hsic_start,
+ .hsic_device_connected = hsic_device_connected,
};
static struct fsl_usb2_wakeup_platform_data usbh3_wakeup_config = {
@@ -213,4 +237,8 @@ void __init mx6_usb_h3_init(void)
*/
__raw_writel(BM_ANADIG_USB1_PLL_480_CTRL_EN_USB_CLKS,
anatop_base_addr + HW_ANADIG_USB1_PLL_480_CTRL_SET);
+ /* must change the clkgate delay to 2 or 3 to avoid
+ * 24M OSCI clock not stable issue */
+ __raw_writel(BF_ANADIG_ANA_MISC0_CLKGATE_DELAY(3),
+ anatop_base_addr + HW_ANADIG_ANA_MISC0);
}
diff --git a/arch/arm/plat-mxc/audmux-v2.c b/arch/arm/plat-mxc/audmux-v2.c
index c7270196718d..8933cacb8cb3 100644
--- a/arch/arm/plat-mxc/audmux-v2.c
+++ b/arch/arm/plat-mxc/audmux-v2.c
@@ -189,7 +189,7 @@ static int mxc_audmux_v2_init(void)
int ret;
#if defined(CONFIG_ARCH_MX6)
- if (cpu_is_mx6q()) {
+ if (cpu_is_mx6q() || cpu_is_mx6dl()) {
audmux_base = MX6_IO_ADDRESS(MX6Q_AUDMUX_BASE_ADDR);
ret = 0;
}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-dma.c b/arch/arm/plat-mxc/devices/platform-imx-dma.c
index 9b8715244e29..9f99aa481526 100755
--- a/arch/arm/plat-mxc/devices/platform-imx-dma.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-dma.c
@@ -259,7 +259,7 @@ static int __init imxXX_add_imx_dma(void)
} else
#endif
#if defined(CONFIG_SOC_IMX6Q)
- if (cpu_is_mx6q()) {
+ if (cpu_is_mx6q() || cpu_is_mx6dl()) {
int to_version = 1;
imx6q_imx_sdma_data.pdata.to_version = to_version;
if (to_version == 1)
diff --git a/arch/arm/plat-mxc/devices/platform-imx-gpmi-nfc.c b/arch/arm/plat-mxc/devices/platform-imx-gpmi-nfc.c
index bc0c6ab47fd8..a1e297d5c35d 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-gpmi-nfc.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-gpmi-nfc.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -17,9 +17,9 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+#include <linux/mtd/gpmi-nand.h>
#include <asm/sizes.h>
#include <mach/hardware.h>
-#include <mach/gpmi-nfc.h>
#include <mach/devices-common.h>
#ifdef CONFIG_SOC_IMX50
@@ -67,42 +67,42 @@ imx_add_gpmi(const struct gpmi_nfc_platform_data *platform_data)
#ifdef CONFIG_SOC_IMX6Q
struct platform_device *__init
-imx_add_gpmi(const struct gpmi_nfc_platform_data *platform_data)
+imx_add_gpmi(const struct gpmi_nand_platform_data *platform_data)
{
struct resource res[] = {
{ /* GPMI */
- .name = GPMI_NFC_GPMI_REGS_ADDR_RES_NAME,
+ .name = GPMI_NAND_GPMI_REGS_ADDR_RES_NAME,
.flags = IORESOURCE_MEM,
.start = MX6Q_GPMI_BASE_ADDR,
.end = MX6Q_GPMI_BASE_ADDR + SZ_8K - 1,
}, {
- .name = GPMI_NFC_GPMI_INTERRUPT_RES_NAME,
+ .name = GPMI_NAND_GPMI_INTERRUPT_RES_NAME,
.flags = IORESOURCE_IRQ,
.start = MXC_INT_RAWNAND_GPMI,
.end = MXC_INT_RAWNAND_GPMI,
}, { /* BCH */
- .name = GPMI_NFC_BCH_REGS_ADDR_RES_NAME,
+ .name = GPMI_NAND_BCH_REGS_ADDR_RES_NAME,
.flags = IORESOURCE_MEM,
.start = MX6Q_BCH_BASE_ADDR,
.end = MX6Q_BCH_BASE_ADDR + SZ_8K - 1,
}, {
- .name = GPMI_NFC_BCH_INTERRUPT_RES_NAME,
+ .name = GPMI_NAND_BCH_INTERRUPT_RES_NAME,
.flags = IORESOURCE_IRQ,
.start = MXC_INT_RAWNAND_BCH,
.end = MXC_INT_RAWNAND_BCH,
}, { /* DMA */
- .name = GPMI_NFC_DMA_CHANNELS_RES_NAME,
+ .name = GPMI_NAND_DMA_CHANNELS_RES_NAME,
.flags = IORESOURCE_DMA,
.start = MX6Q_DMA_CHANNEL_AHB_APBH_GPMI0,
.end = MX6Q_DMA_CHANNEL_AHB_APBH_GPMI7,
}, {
- .name = GPMI_NFC_DMA_INTERRUPT_RES_NAME,
+ .name = GPMI_NAND_DMA_INTERRUPT_RES_NAME,
.flags = IORESOURCE_IRQ,
.start = MXC_INT_APBHDMA_DMA,
.end = MXC_INT_APBHDMA_DMA,
}, };
- return imx_add_platform_device_dmamask("imx6q-gpmi-nfc", 0,
+ return imx_add_platform_device_dmamask("imx6q-gpmi-nand", 0,
res, ARRAY_SIZE(res), platform_data,
sizeof(*platform_data), DMA_BIT_MASK(32));
}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-perfmon.c b/arch/arm/plat-mxc/devices/platform-imx-perfmon.c
index 25d1bf582de2..56e262b39f11 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-perfmon.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-perfmon.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -86,8 +86,11 @@ static void platform_perfmon_init(void)
if (init)
return;
- /* GPR11 bit[16] is the clock enable bit for perfmon */
- mxc_iomux_set_gpr_register(11, 16, 1, 1);
+ if (mx6q_revision() == IMX_CHIP_REVISION_1_0 || cpu_is_mx6dl())
+ /* GPR11 bit[16] must be set for TO1.0(6q & 6dl), it's a bug */
+ mxc_iomux_set_gpr_register(11, 16, 1, 1);
+
+ mxc_iomux_set_gpr_register(11, 0, 1, 1);
init = true;
}
@@ -96,8 +99,7 @@ static void platform_perfmon_exit(void)
if (!init)
return;
- /* GPR11 bit[16] is the clock enable bit for perfmon */
- mxc_iomux_set_gpr_register(11, 16, 1, 0);
+ mxc_iomux_set_gpr_register(11, 0, 1, 0);
init = false;
}
diff --git a/arch/arm/plat-mxc/devices/platform-imx-pxp.c b/arch/arm/plat-mxc/devices/platform-imx-pxp.c
index 51030c57ca83..3ae3e4880e1d 100644
--- a/arch/arm/plat-mxc/devices/platform-imx-pxp.c
+++ b/arch/arm/plat-mxc/devices/platform-imx-pxp.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -22,7 +22,7 @@
#include <mach/hardware.h>
#include <mach/devices-common.h>
-#define imx5_pxp_data_entry_single(soc, size) \
+#define imx_pxp_data_entry_single(soc, size) \
{ \
.iobase = soc ## _EPXP_BASE_ADDR, \
.irq = soc ## _INT_EPXP, \
@@ -31,7 +31,12 @@
#ifdef CONFIG_SOC_IMX50
const struct imx_pxp_data imx50_pxp_data __initconst =
- imx5_pxp_data_entry_single(MX50, SZ_4K);
+ imx_pxp_data_entry_single(MX50, SZ_4K);
+#endif
+
+#ifdef CONFIG_SOC_IMX6Q
+const struct imx_pxp_data imx6dl_pxp_data __initconst =
+ imx_pxp_data_entry_single(MX6DL, SZ_16K);
#endif
struct platform_device *__init imx_add_imx_pxp(
diff --git a/arch/arm/plat-mxc/devices/platform-imx_vpu.c b/arch/arm/plat-mxc/devices/platform-imx_vpu.c
index ed30bc7882b8..c36439138778 100755
--- a/arch/arm/plat-mxc/devices/platform-imx_vpu.c
+++ b/arch/arm/plat-mxc/devices/platform-imx_vpu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
* Jason Chen <jason.chen@freescale.com>
*
* This program is free software; you can redistribute it and/or modify it under
@@ -167,6 +167,9 @@ struct platform_device *__init imx_add_vpu(
pdata.iram_enable = data->iram_enable;
pdata.iram_size = data->iram_size;
+ if (cpu_is_mx6dl())
+ pdata.iram_enable = false;
+
return imx_add_platform_device("mxc_vpu", -1,
res, ARRAY_SIZE(res), &pdata, sizeof(pdata));
}
diff --git a/arch/arm/plat-mxc/devices/platform-viv_gpu.c b/arch/arm/plat-mxc/devices/platform-viv_gpu.c
index b11efe0de1cf..dad9d5a2df3b 100644
--- a/arch/arm/plat-mxc/devices/platform-viv_gpu.c
+++ b/arch/arm/plat-mxc/devices/platform-viv_gpu.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -36,6 +36,7 @@ struct platform_device *__init imx_add_viv_gpu(
const struct imx_viv_gpu_data *data,
const struct viv_gpu_platform_data *pdata)
{
+ u32 res_count = 0;
struct resource res[] = {
{
.name = "iobase_3d",
@@ -70,8 +71,15 @@ struct platform_device *__init imx_add_viv_gpu(
},
};
+ if (cpu_is_mx6q())
+ res_count = ARRAY_SIZE(res);
+ else if (cpu_is_mx6dl())
+ /* No openVG on i.mx6 Solo/DL */
+ res_count = ARRAY_SIZE(res) - 2;
+ BUG_ON(!res_count);
+
return imx_add_platform_device_dmamask("galcore", 0,
- res, ARRAY_SIZE(res),
+ res, res_count,
pdata, sizeof(*pdata),
DMA_BIT_MASK(32));
}
diff --git a/arch/arm/plat-mxc/dvfs_core.c b/arch/arm/plat-mxc/dvfs_core.c
index cacd3cca7dd5..d52f7b6eb039 100755
--- a/arch/arm/plat-mxc/dvfs_core.c
+++ b/arch/arm/plat-mxc/dvfs_core.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -427,7 +427,7 @@ static int set_cpu_freq(int op)
{
int ret = 0;
- if (cpu_is_mx6q())
+ if (cpu_is_mx6q() || cpu_is_mx6dl())
ret = mx6_set_cpu_freq(op);
else
ret = mx5_set_cpu_freq(op);
@@ -476,7 +476,7 @@ static int start_dvfs(void)
/* GPCIRQ=1, select ARM IRQ */
reg |= MXC_GPCCNTR_GPCIRQ_ARM;
/* ADU=1, select ARM domain */
- if (!cpu_is_mx6q())
+ if (!(cpu_is_mx6q() || cpu_is_mx6dl()))
reg |= MXC_GPCCNTR_ADU;
__raw_writel(reg, gpc_base + dvfs_data->gpc_cntr_offset);
@@ -509,7 +509,7 @@ static int start_dvfs(void)
__raw_writel(reg, dvfs_data->membase + MXC_DVFSCORE_CNTR);
/* Enable DVFS */
- if (cpu_is_mx6q()) {
+ if (cpu_is_mx6q() || cpu_is_mx6dl()) {
unsigned long cpu_wfi = 0;
int num_cpus = num_possible_cpus();
reg = __raw_readl(dvfs_data->membase + MXC_DVFSCORE_EMAC);
@@ -947,7 +947,7 @@ static int __devinit mxc_dvfs_core_probe(struct platform_device *pdev)
printk(KERN_ERR "%s: failed to get cpu clock\n", __func__);
return PTR_ERR(cpu_clk);
}
- if (!cpu_is_mx6q()) {
+ if (!(cpu_is_mx6q() || cpu_is_mx6dl())) {
dvfs_clk = clk_get(NULL, dvfs_data->clk2_id);
if (IS_ERR(dvfs_clk)) {
printk(KERN_ERR "%s: failed to get dvfs clock\n", __func__);
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index 40f9799ed0d3..f84aa75cdbba 100755
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -345,7 +345,8 @@ int mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
BUG_ON(gpiochip_add(&port[i].chip) < 0);
if (cpu_is_mx1() || cpu_is_mx3() || cpu_is_mx25() ||
- cpu_is_mx51() || cpu_is_mx53() || cpu_is_mx6q()) {
+ cpu_is_mx51() || cpu_is_mx53() || cpu_is_mx6q() ||
+ cpu_is_mx6dl()) {
/* setup one handler for each entry */
irq_set_chained_handler(port[i].irq,
mx3_gpio_irq_handler);
diff --git a/arch/arm/plat-mxc/include/mach/arc_otg.h b/arch/arm/plat-mxc/include/mach/arc_otg.h
index b5bd8c31a4b2..bdb6b252b356 100755
--- a/arch/arm/plat-mxc/include/mach/arc_otg.h
+++ b/arch/arm/plat-mxc/include/mach/arc_otg.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -248,6 +248,8 @@ extern void __iomem *imx_otg_base;
#define PORTSC_PTW (1 << 28) /* UTMI width */
#define PORTSC_HSIC_MODE (1 << 25) /* Only for HSIC */
#define PORTSC_PHCD (1 << 23) /* Low Power Suspend */
+#define PORTSC_WKDC (1 << 21) /* wakeup on discnt*/
+#define PORTSC_WKCN (1 << 20) /* wakeup on connect*/
#define PORTSC_PORT_POWER (1 << 12) /* port power */
#define PORTSC_LS_MASK (3 << 10) /* Line State mask */
#define PORTSC_LS_SE0 (0 << 10) /* SE0 */
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index a8d1982b1b08..62489695af0f 100755
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -87,4 +87,5 @@ extern int mx53_revision(void);
extern int mx50_revision(void);
extern int mx53_display_revision(void);
extern unsigned long mx6_timer_rate(void);
+extern int mxs_reset_block(void __iomem *);
#endif
diff --git a/arch/arm/plat-mxc/include/mach/devices-common.h b/arch/arm/plat-mxc/include/mach/devices-common.h
index 8538d5b658c2..2f5f04c39638 100755
--- a/arch/arm/plat-mxc/include/mach/devices-common.h
+++ b/arch/arm/plat-mxc/include/mach/devices-common.h
@@ -621,10 +621,10 @@ struct platform_device *__init imx_add_fsl_usb2_wakeup(
const struct imx_fsl_usb2_wakeup_data *data,
const struct fsl_usb2_wakeup_platform_data *pdata);
-/* gpmi-nfc */
-#include <mach/gpmi-nfc.h>
+/* gpmi-nand*/
+#include <linux/mtd/gpmi-nand.h>
struct platform_device *__init imx_add_gpmi(
- const struct gpmi_nfc_platform_data *data);
+ const struct gpmi_nand_platform_data *data);
struct imx_rngb_data {
resource_size_t iobase;
diff --git a/arch/arm/plat-mxc/include/mach/dma.h b/arch/arm/plat-mxc/include/mach/dma.h
index 321ced11c71d..ee3b962eeb4d 100644
--- a/arch/arm/plat-mxc/include/mach/dma.h
+++ b/arch/arm/plat-mxc/include/mach/dma.h
@@ -71,6 +71,11 @@ static inline int imx_dma_is_ipu(struct dma_chan *chan)
return !strcmp(dev_name(chan->device->dev), "ipu-core");
}
+static inline int imx_dma_is_pxp(struct dma_chan *chan)
+{
+ return !strcmp(dev_name(chan->device->dev), "imx-pxp");
+}
+
static inline int imx_dma_is_general_purpose(struct dma_chan *chan)
{
return !strcmp(dev_name(chan->device->dev), "imx-sdma") ||
diff --git a/arch/arm/plat-mxc/include/mach/fsl_usb.h b/arch/arm/plat-mxc/include/mach/fsl_usb.h
index c471064a5fda..0b47a7d5bcaa 100755
--- a/arch/arm/plat-mxc/include/mach/fsl_usb.h
+++ b/arch/arm/plat-mxc/include/mach/fsl_usb.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -98,7 +98,7 @@ static inline void fsl_platform_set_ahb_burst(struct usb_hcd *hcd)
}
/* Increase TX fifo threshold for in Hostx */
- if (cpu_is_mx6q()) {
+ if (cpu_is_mx6()) {
temp = readl(hcd->regs + FSL_SOC_USB_TXFILLTUNING);
/* Change TX FIFO threshold to be 0x08 */
writel((temp & (~(0x3f << 16))) | (0x08 << 16),
diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
index ef964551b0ea..e1c523443ca8 100755
--- a/arch/arm/plat-mxc/include/mach/hardware.h
+++ b/arch/arm/plat-mxc/include/mach/hardware.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2011 Freescale Semiconductor, Inc.
+ * Copyright 2004-2012 Freescale Semiconductor, Inc.
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de
*
* This program is free software; you can redistribute it and/or
@@ -138,4 +138,9 @@
.type = _type, \
}
+/* macro to get at IO space when running virtually */
+#define PCIBIOS_MIN_IO 0x00000000
+#define PCIBIOS_MIN_MEM 0x00000000
+#define pcibios_assign_all_busses() 0
+
#endif /* __ASM_ARCH_MXC_HARDWARE_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx6dl.h b/arch/arm/plat-mxc/include/mach/iomux-mx6dl.h
new file mode 100644
index 000000000000..b32cc00859ba
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx6dl.h
@@ -0,0 +1,3797 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Auto Generate file, please don't edit it
+ *
+ */
+
+#ifndef __MACH_IOMUX_MX6DL_H__
+#define __MACH_IOMUX_MX6DL_H__
+
+#include <mach/iomux-v3.h>
+
+#define MX6DL_HIGH_DRV PAD_CTL_DSE_120ohm
+#define MX6DL_DISP_PAD_CLT MX6DL_HIGH_DRV
+
+#define MX6DL_CCM_CLK0_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6DL_MLB150_PAD_CTRL (PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST) \
+
+#define MX6DL_UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6DL_USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_LOW | \
+ PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6DL_USDHC_PAD_CTRL_100MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6DL_USDHC_PAD_CTRL_200MHZ (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_HIGH | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
+
+#define MX6DL_ENET_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+
+#define MX6DL_I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | \
+ PAD_CTL_HYS | PAD_CTL_ODE)
+
+#define MX6DL_ESAI_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_PUS_100K_UP | PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define MX6DL_USB_HSIC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define MX6DL_ECSPI_PAD_CTRL (PAD_CTL_SRE_FAST | PAD_CTL_SPEED_MED | \
+ PAD_CTL_DSE_40ohm | PAD_CTL_HYS)
+
+#define MX6DL_GPMI_PAD_CTRL0 (PAD_CTL_PKE | PAD_CTL_PUE | PAD_CTL_PUS_100K_UP)
+#define MX6DL_GPMI_PAD_CTRL1 (PAD_CTL_DSE_40ohm | PAD_CTL_SPEED_MED | PAD_CTL_SRE_FAST)
+#define MX6DL_GPMI_PAD_CTRL2 (MX6DL_GPMI_PAD_CTRL0 | MX6DL_GPMI_PAD_CTRL1)
+#define MX6DL_SPDIF_OUT_PAD_CTRL (PAD_CTL_DSE_120ohm | PAD_CTL_SRE_FAST)
+
+#define MX6DL_PAD_CSI0_DAT10__IPU1_CSI0_D_10 \
+ IOMUX_PAD(0x0360, 0x004C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT10__AUDMUX_AUD3_RXC \
+ IOMUX_PAD(0x0360, 0x004C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT10__ECSPI2_MISO \
+ IOMUX_PAD(0x0360, 0x004C, 2, 0x07F8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT10__UART1_TXD \
+ IOMUX_PAD(0x0360, 0x004C, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT10__UART1_RXD \
+ IOMUX_PAD(0x0360, 0x004C, 3, 0x08FC, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT10__SDMA_DEBUG_PC_4 \
+ IOMUX_PAD(0x0360, 0x004C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT10__GPIO_5_28 \
+ IOMUX_PAD(0x0360, 0x004C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT10__MMDC_MMDC_DEBUG_33 \
+ IOMUX_PAD(0x0360, 0x004C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT10__SIMBA_TRACE_7 \
+ IOMUX_PAD(0x0360, 0x004C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT11__IPU1_CSI0_D_11 \
+ IOMUX_PAD(0x0364, 0x0050, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT11__AUDMUX_AUD3_RXFS \
+ IOMUX_PAD(0x0364, 0x0050, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT11__ECSPI2_SS0 \
+ IOMUX_PAD(0x0364, 0x0050, 2, 0x0800, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT11__UART1_TXD \
+ IOMUX_PAD(0x0364, 0x0050, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT11__UART1_RXD \
+ IOMUX_PAD(0x0364, 0x0050, 3, 0x08FC, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT11__SDMA_DEBUG_PC_5 \
+ IOMUX_PAD(0x0364, 0x0050, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT11__GPIO_5_29 \
+ IOMUX_PAD(0x0364, 0x0050, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT11__MMDC_MMDC_DEBUG_34 \
+ IOMUX_PAD(0x0364, 0x0050, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT11__SIMBA_TRACE_8 \
+ IOMUX_PAD(0x0364, 0x0050, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT12__IPU1_CSI0_D_12 \
+ IOMUX_PAD(0x0368, 0x0054, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT12__WEIM_WEIM_D_8 \
+ IOMUX_PAD(0x0368, 0x0054, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT12__PCIE_CTRL_DIAG_STATUS_BUS_MUX_16 \
+ IOMUX_PAD(0x0368, 0x0054, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT12__UART4_TXD \
+ IOMUX_PAD(0x0368, 0x0054, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT12__UART4_RXD \
+ IOMUX_PAD(0x0368, 0x0054, 3, 0x0914, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT12__SDMA_DEBUG_PC_6 \
+ IOMUX_PAD(0x0368, 0x0054, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT12__GPIO_5_30 \
+ IOMUX_PAD(0x0368, 0x0054, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT12__MMDC_MMDC_DEBUG_35 \
+ IOMUX_PAD(0x0368, 0x0054, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT12__SIMBA_TRACE_9 \
+ IOMUX_PAD(0x0368, 0x0054, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT13__IPU1_CSI0_D_13 \
+ IOMUX_PAD(0x036C, 0x0058, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT13__WEIM_WEIM_D_9 \
+ IOMUX_PAD(0x036C, 0x0058, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT13__PCIE_CTRL_DIAG_STATUS_BUS_MUX_17 \
+ IOMUX_PAD(0x036C, 0x0058, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT13__UART4_TXD \
+ IOMUX_PAD(0x036C, 0x0058, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT13__UART4_RXD \
+ IOMUX_PAD(0x036C, 0x0058, 3, 0x0914, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT13__SDMA_DEBUG_PC_7 \
+ IOMUX_PAD(0x036C, 0x0058, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT13__GPIO_5_31 \
+ IOMUX_PAD(0x036C, 0x0058, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT13__MMDC_MMDC_DEBUG_36 \
+ IOMUX_PAD(0x036C, 0x0058, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT13__SIMBA_TRACE_10 \
+ IOMUX_PAD(0x036C, 0x0058, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT14__IPU1_CSI0_D_14 \
+ IOMUX_PAD(0x0370, 0x005C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT14__WEIM_WEIM_D_10 \
+ IOMUX_PAD(0x0370, 0x005C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT14__PCIE_CTRL_DIAG_STATUS_BUS_MUX_18 \
+ IOMUX_PAD(0x0370, 0x005C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT14__UART5_TXD \
+ IOMUX_PAD(0x0370, 0x005C, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT14__UART5_RXD \
+ IOMUX_PAD(0x0370, 0x005C, 3, 0x091C, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT14__SDMA_DEBUG_PC_8 \
+ IOMUX_PAD(0x0370, 0x005C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT14__GPIO_6_0 \
+ IOMUX_PAD(0x0370, 0x005C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT14__MMDC_MMDC_DEBUG_37 \
+ IOMUX_PAD(0x0370, 0x005C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT14__SIMBA_TRACE_11 \
+ IOMUX_PAD(0x0370, 0x005C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT15__IPU1_CSI0_D_15 \
+ IOMUX_PAD(0x0374, 0x0060, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT15__WEIM_WEIM_D_11 \
+ IOMUX_PAD(0x0374, 0x0060, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT15__PCIE_CTRL_DIAG_STATUS_BUS_MUX_19 \
+ IOMUX_PAD(0x0374, 0x0060, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT15__UART5_TXD \
+ IOMUX_PAD(0x0374, 0x0060, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT15__UART5_RXD \
+ IOMUX_PAD(0x0374, 0x0060, 3, 0x091C, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT15__SDMA_DEBUG_PC_9 \
+ IOMUX_PAD(0x0374, 0x0060, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT15__GPIO_6_1 \
+ IOMUX_PAD(0x0374, 0x0060, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT15__MMDC_MMDC_DEBUG_38 \
+ IOMUX_PAD(0x0374, 0x0060, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT15__SIMBA_TRACE_12 \
+ IOMUX_PAD(0x0374, 0x0060, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT16__IPU1_CSI0_D_16 \
+ IOMUX_PAD(0x0378, 0x0064, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT16__WEIM_WEIM_D_12 \
+ IOMUX_PAD(0x0378, 0x0064, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT16__PCIE_CTRL_DIAG_STATUS_BUS_MUX_20 \
+ IOMUX_PAD(0x0378, 0x0064, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT16__UART4_CTS \
+ IOMUX_PAD(0x0378, 0x0064, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT16__UART4_RTS \
+ IOMUX_PAD(0x0378, 0x0064, 3, 0x0910, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT16__SDMA_DEBUG_PC_10 \
+ IOMUX_PAD(0x0378, 0x0064, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT16__GPIO_6_2 \
+ IOMUX_PAD(0x0378, 0x0064, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT16__MMDC_MMDC_DEBUG_39 \
+ IOMUX_PAD(0x0378, 0x0064, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT16__SIMBA_TRACE_13 \
+ IOMUX_PAD(0x0378, 0x0064, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT17__IPU1_CSI0_D_17 \
+ IOMUX_PAD(0x037C, 0x0068, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT17__WEIM_WEIM_D_13 \
+ IOMUX_PAD(0x037C, 0x0068, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT17__PCIE_CTRL_DIAG_STATUS_BUS_MUX_21 \
+ IOMUX_PAD(0x037C, 0x0068, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT17__UART4_CTS \
+ IOMUX_PAD(0x037C, 0x0068, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT17__UART4_RTS \
+ IOMUX_PAD(0x037C, 0x0068, 3, 0x0910, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT17__SDMA_DEBUG_PC_11 \
+ IOMUX_PAD(0x037C, 0x0068, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT17__GPIO_6_3 \
+ IOMUX_PAD(0x037C, 0x0068, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT17__MMDC_MMDC_DEBUG_40 \
+ IOMUX_PAD(0x037C, 0x0068, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT17__SIMBA_TRACE_14 \
+ IOMUX_PAD(0x037C, 0x0068, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT18__IPU1_CSI0_D_18 \
+ IOMUX_PAD(0x0380, 0x006C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT18__WEIM_WEIM_D_14 \
+ IOMUX_PAD(0x0380, 0x006C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT18__PCIE_CTRL_DIAG_STATUS_BUS_MUX_22 \
+ IOMUX_PAD(0x0380, 0x006C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT18__UART5_CTS \
+ IOMUX_PAD(0x0380, 0x006C, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT18__UART5_RTS \
+ IOMUX_PAD(0x0380, 0x006C, 3, 0x0918, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT18__SDMA_DEBUG_PC_12 \
+ IOMUX_PAD(0x0380, 0x006C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT18__GPIO_6_4 \
+ IOMUX_PAD(0x0380, 0x006C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT18__MMDC_MMDC_DEBUG_41 \
+ IOMUX_PAD(0x0380, 0x006C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT18__SIMBA_TRACE_15 \
+ IOMUX_PAD(0x0380, 0x006C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT19__IPU1_CSI0_D_19 \
+ IOMUX_PAD(0x0384, 0x0070, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT19__WEIM_WEIM_D_15 \
+ IOMUX_PAD(0x0384, 0x0070, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT19__PCIE_CTRL_DIAG_STATUS_BUS_MUX_23 \
+ IOMUX_PAD(0x0384, 0x0070, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT19__UART5_CTS \
+ IOMUX_PAD(0x0384, 0x0070, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT19__UART5_RTS \
+ IOMUX_PAD(0x0384, 0x0070, 3, 0x0918, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT19__SDMA_DEBUG_PC_13 \
+ IOMUX_PAD(0x0384, 0x0070, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT19__GPIO_6_5 \
+ IOMUX_PAD(0x0384, 0x0070, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT19__MMDC_MMDC_DEBUG_42 \
+ IOMUX_PAD(0x0384, 0x0070, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT19__ANATOP_ANATOP_TESTO_9 \
+ IOMUX_PAD(0x0384, 0x0070, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT4__IPU1_CSI0_D_4 \
+ IOMUX_PAD(0x0388, 0x0074, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT4__WEIM_WEIM_D_2 \
+ IOMUX_PAD(0x0388, 0x0074, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT4__ECSPI1_SCLK \
+ IOMUX_PAD(0x0388, 0x0074, 2, 0x07D8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT4__KPP_COL_5 \
+ IOMUX_PAD(0x0388, 0x0074, 3, 0x08C0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT4__AUDMUX_AUD3_TXC \
+ IOMUX_PAD(0x0388, 0x0074, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT4__GPIO_5_22 \
+ IOMUX_PAD(0x0388, 0x0074, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT4__MMDC_MMDC_DEBUG_43 \
+ IOMUX_PAD(0x0388, 0x0074, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT4__SIMBA_TRACE_1 \
+ IOMUX_PAD(0x0388, 0x0074, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT5__IPU1_CSI0_D_5 \
+ IOMUX_PAD(0x038C, 0x0078, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT5__WEIM_WEIM_D_3 \
+ IOMUX_PAD(0x038C, 0x0078, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT5__ECSPI1_MOSI \
+ IOMUX_PAD(0x038C, 0x0078, 2, 0x07E0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT5__KPP_ROW_5 \
+ IOMUX_PAD(0x038C, 0x0078, 3, 0x08CC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT5__AUDMUX_AUD3_TXD \
+ IOMUX_PAD(0x038C, 0x0078, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT5__GPIO_5_23 \
+ IOMUX_PAD(0x038C, 0x0078, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT5__MMDC_MMDC_DEBUG_44 \
+ IOMUX_PAD(0x038C, 0x0078, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT5__SIMBA_TRACE_2 \
+ IOMUX_PAD(0x038C, 0x0078, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT6__IPU1_CSI0_D_6 \
+ IOMUX_PAD(0x0390, 0x007C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT6__WEIM_WEIM_D_4 \
+ IOMUX_PAD(0x0390, 0x007C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT6__ECSPI1_MISO \
+ IOMUX_PAD(0x0390, 0x007C, 2, 0x07DC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT6__KPP_COL_6 \
+ IOMUX_PAD(0x0390, 0x007C, 3, 0x08C4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT6__AUDMUX_AUD3_TXFS \
+ IOMUX_PAD(0x0390, 0x007C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT6__GPIO_5_24 \
+ IOMUX_PAD(0x0390, 0x007C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT6__MMDC_MMDC_DEBUG_45 \
+ IOMUX_PAD(0x0390, 0x007C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT6__SIMBA_TRACE_3 \
+ IOMUX_PAD(0x0390, 0x007C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT7__IPU1_CSI0_D_7 \
+ IOMUX_PAD(0x0394, 0x0080, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT7__WEIM_WEIM_D_5 \
+ IOMUX_PAD(0x0394, 0x0080, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT7__ECSPI1_SS0 \
+ IOMUX_PAD(0x0394, 0x0080, 2, 0x07E4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT7__KPP_ROW_6 \
+ IOMUX_PAD(0x0394, 0x0080, 3, 0x08D0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT7__AUDMUX_AUD3_RXD \
+ IOMUX_PAD(0x0394, 0x0080, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT7__GPIO_5_25 \
+ IOMUX_PAD(0x0394, 0x0080, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT7__MMDC_MMDC_DEBUG_46 \
+ IOMUX_PAD(0x0394, 0x0080, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT7__SIMBA_TRACE_4 \
+ IOMUX_PAD(0x0394, 0x0080, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT8__IPU1_CSI0_D_8 \
+ IOMUX_PAD(0x0398, 0x0084, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT8__WEIM_WEIM_D_6 \
+ IOMUX_PAD(0x0398, 0x0084, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT8__ECSPI2_SCLK \
+ IOMUX_PAD(0x0398, 0x0084, 2, 0x07F4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT8__KPP_COL_7 \
+ IOMUX_PAD(0x0398, 0x0084, 3, 0x08C8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT8__I2C1_SDA \
+ IOMUX_PAD(0x0398, 0x0084, 4 | IOMUX_CONFIG_SION, 0x086C, 0, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT8__GPIO_5_26 \
+ IOMUX_PAD(0x0398, 0x0084, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT8__MMDC_MMDC_DEBUG_47 \
+ IOMUX_PAD(0x0398, 0x0084, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT8__SIMBA_TRACE_5 \
+ IOMUX_PAD(0x0398, 0x0084, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DAT9__IPU1_CSI0_D_9 \
+ IOMUX_PAD(0x039C, 0x0088, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT9__WEIM_WEIM_D_7 \
+ IOMUX_PAD(0x039C, 0x0088, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT9__ECSPI2_MOSI \
+ IOMUX_PAD(0x039C, 0x0088, 2, 0x07FC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT9__KPP_ROW_7 \
+ IOMUX_PAD(0x039C, 0x0088, 3, 0x08D4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT9__I2C1_SCL \
+ IOMUX_PAD(0x039C, 0x0088, 4 | IOMUX_CONFIG_SION, 0x0868, 0, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT9__GPIO_5_27 \
+ IOMUX_PAD(0x039C, 0x0088, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT9__MMDC_MMDC_DEBUG_48 \
+ IOMUX_PAD(0x039C, 0x0088, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DAT9__SIMBA_TRACE_6 \
+ IOMUX_PAD(0x039C, 0x0088, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_DATA_EN__IPU1_CSI0_DATA_EN \
+ IOMUX_PAD(0x03A0, 0x008C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DATA_EN__WEIM_WEIM_D_0 \
+ IOMUX_PAD(0x03A0, 0x008C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DATA_EN__PCIE_CTRL_DIAG_STATUS_BUS_MUX_14 \
+ IOMUX_PAD(0x03A0, 0x008C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DATA_EN__SDMA_DEBUG_PC_2 \
+ IOMUX_PAD(0x03A0, 0x008C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DATA_EN__GPIO_5_20 \
+ IOMUX_PAD(0x03A0, 0x008C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DATA_EN__MMDC_MMDC_DEBUG_31 \
+ IOMUX_PAD(0x03A0, 0x008C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_DATA_EN__SIMBA_TRCLK \
+ IOMUX_PAD(0x03A0, 0x008C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_MCLK__IPU1_CSI0_HSYNC \
+ IOMUX_PAD(0x03A4, 0x0090, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_MCLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_13 \
+ IOMUX_PAD(0x03A4, 0x0090, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_MCLK__CCM_CLKO \
+ IOMUX_PAD(0x03A4, 0x0090, 3, 0x0000, 0, MX6DL_CCM_CLK0_PAD_CTRL)
+#define MX6DL_PAD_CSI0_MCLK__SDMA_DEBUG_PC_1 \
+ IOMUX_PAD(0x03A4, 0x0090, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_MCLK__GPIO_5_19 \
+ IOMUX_PAD(0x03A4, 0x0090, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_MCLK__MMDC_MMDC_DEBUG_30 \
+ IOMUX_PAD(0x03A4, 0x0090, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_MCLK__SIMBA_TRCTL \
+ IOMUX_PAD(0x03A4, 0x0090, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_PIXCLK__IPU1_CSI0_PIXCLK \
+ IOMUX_PAD(0x03A8, 0x0094, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_PIXCLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_12 \
+ IOMUX_PAD(0x03A8, 0x0094, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_PIXCLK__SDMA_DEBUG_PC_0 \
+ IOMUX_PAD(0x03A8, 0x0094, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_PIXCLK__GPIO_5_18 \
+ IOMUX_PAD(0x03A8, 0x0094, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_PIXCLK__MMDC_MMDC_DEBUG_29 \
+ IOMUX_PAD(0x03A8, 0x0094, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_PIXCLK__SIMBA_EVENTO \
+ IOMUX_PAD(0x03A8, 0x0094, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_CSI0_VSYNC__IPU1_CSI0_VSYNC \
+ IOMUX_PAD(0x03AC, 0x0098, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_VSYNC__WEIM_WEIM_D_1 \
+ IOMUX_PAD(0x03AC, 0x0098, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_VSYNC__PCIE_CTRL_DIAG_STATUS_BUS_MUX_15 \
+ IOMUX_PAD(0x03AC, 0x0098, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_VSYNC__SDMA_DEBUG_PC_3 \
+ IOMUX_PAD(0x03AC, 0x0098, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_VSYNC__GPIO_5_21 \
+ IOMUX_PAD(0x03AC, 0x0098, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_VSYNC__MMDC_MMDC_DEBUG_32 \
+ IOMUX_PAD(0x03AC, 0x0098, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_CSI0_VSYNC__SIMBA_TRACE_0 \
+ IOMUX_PAD(0x03AC, 0x0098, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DI0_DISP_CLK__IPU1_DI0_DISP_CLK \
+ IOMUX_PAD(0x03B0, 0x009C, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DI0_DISP_CLK__LCDIF_CLK \
+ IOMUX_PAD(0x03B0, 0x009C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_DISP_CLK__MIPI_CORE_DPHY_TEST_OUT_28 \
+ IOMUX_PAD(0x03B0, 0x009C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_DISP_CLK__SDMA_DEBUG_CORE_STATE_0 \
+ IOMUX_PAD(0x03B0, 0x009C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_DISP_CLK__GPIO_4_16 \
+ IOMUX_PAD(0x03B0, 0x009C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_DISP_CLK__MMDC_MMDC_DEBUG_0 \
+ IOMUX_PAD(0x03B0, 0x009C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_DISP_CLK__TPSMP_HDATA_DIR \
+ IOMUX_PAD(0x03B0, 0x009C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_DISP_CLK__LCDIF_WR_RWN \
+ IOMUX_PAD(0x03B0, 0x009C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DI0_PIN15__IPU1_DI0_PIN15 \
+ IOMUX_PAD(0x03B4, 0x00A0, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DI0_PIN15__LCDIF_ENABLE \
+ IOMUX_PAD(0x03B4, 0x00A0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN15__AUDMUX_AUD6_TXC \
+ IOMUX_PAD(0x03B4, 0x00A0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN15__MIPI_CORE_DPHY_TEST_OUT_29 \
+ IOMUX_PAD(0x03B4, 0x00A0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN15__SDMA_DEBUG_CORE_STATE_1 \
+ IOMUX_PAD(0x03B4, 0x00A0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN15__GPIO_4_17 \
+ IOMUX_PAD(0x03B4, 0x00A0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN15__MMDC_MMDC_DEBUG_1 \
+ IOMUX_PAD(0x03B4, 0x00A0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN15__PL301_SIM_MX6DL_PER1_HSIZE_0 \
+ IOMUX_PAD(0x03B4, 0x00A0, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN15__LCDIF_RD_E \
+ IOMUX_PAD(0x03B4, 0x00A0, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DI0_PIN2__IPU1_DI0_PIN2 \
+ IOMUX_PAD(0x03B8, 0x00A4, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DI0_PIN2__LCDIF_HSYNC \
+ IOMUX_PAD(0x03B8, 0x00A4, 1, 0x08D8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN2__AUDMUX_AUD6_TXD \
+ IOMUX_PAD(0x03B8, 0x00A4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN2__MIPI_CORE_DPHY_TEST_OUT_30 \
+ IOMUX_PAD(0x03B8, 0x00A4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN2__SDMA_DEBUG_CORE_STATE_2 \
+ IOMUX_PAD(0x03B8, 0x00A4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN2__GPIO_4_18 \
+ IOMUX_PAD(0x03B8, 0x00A4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN2__MMDC_MMDC_DEBUG_2 \
+ IOMUX_PAD(0x03B8, 0x00A4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN2__PL301_SIM_MX6DL_PER1_HADDR_9 \
+ IOMUX_PAD(0x03B8, 0x00A4, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN2__LCDIF_RS \
+ IOMUX_PAD(0x03B8, 0x00A4, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DI0_PIN3__IPU1_DI0_PIN3 \
+ IOMUX_PAD(0x03BC, 0x00A8, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DI0_PIN3__LCDIF_VSYNC \
+ IOMUX_PAD(0x03BC, 0x00A8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN3__AUDMUX_AUD6_TXFS \
+ IOMUX_PAD(0x03BC, 0x00A8, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN3__MIPI_CORE_DPHY_TEST_OUT_31 \
+ IOMUX_PAD(0x03BC, 0x00A8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN3__SDMA_DEBUG_CORE_STATE_3 \
+ IOMUX_PAD(0x03BC, 0x00A8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN3__GPIO_4_19 \
+ IOMUX_PAD(0x03BC, 0x00A8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN3__MMDC_MMDC_DEBUG_3 \
+ IOMUX_PAD(0x03BC, 0x00A8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN3__PL301_SIM_MX6DL_PER1_HADDR_10 \
+ IOMUX_PAD(0x03BC, 0x00A8, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN3__LCDIF_CS \
+ IOMUX_PAD(0x03BC, 0x00A8, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DI0_PIN4__IPU1_DI0_PIN4 \
+ IOMUX_PAD(0x03C0, 0x00AC, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DI0_PIN4__LCDIF_BUSY \
+ IOMUX_PAD(0x03C0, 0x00AC, 1, 0x08D8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN4__AUDMUX_AUD6_RXD \
+ IOMUX_PAD(0x03C0, 0x00AC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN4__USDHC1_WP \
+ IOMUX_PAD(0x03C0, 0x00AC, 3, 0x092C, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN4__SDMA_DEBUG_YIELD \
+ IOMUX_PAD(0x03C0, 0x00AC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN4__GPIO_4_20 \
+ IOMUX_PAD(0x03C0, 0x00AC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN4__MMDC_MMDC_DEBUG_4 \
+ IOMUX_PAD(0x03C0, 0x00AC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN4__PL301_SIM_MX6DL_PER1_HADDR_11 \
+ IOMUX_PAD(0x03C0, 0x00AC, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DI0_PIN4__LCDIF_RESET \
+ IOMUX_PAD(0x03C0, 0x00AC, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT0__IPU1_DISP0_DAT_0 \
+ IOMUX_PAD(0x03C4, 0x00B0, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT0__LCDIF_DAT_0 \
+ IOMUX_PAD(0x03C4, 0x00B0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT0__ECSPI3_SCLK \
+ IOMUX_PAD(0x03C4, 0x00B0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT0__USDHC1_USDHC_DEBUG_0 \
+ IOMUX_PAD(0x03C4, 0x00B0, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT0__SDMA_DEBUG_CORE_RUN \
+ IOMUX_PAD(0x03C4, 0x00B0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT0__GPIO_4_21 \
+ IOMUX_PAD(0x03C4, 0x00B0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT0__MMDC_MMDC_DEBUG_5 \
+ IOMUX_PAD(0x03C4, 0x00B0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT0__PL301_SIM_MX6DL_PER1_HSIZE_1 \
+ IOMUX_PAD(0x03C4, 0x00B0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT1__IPU1_DISP0_DAT_1 \
+ IOMUX_PAD(0x03C8, 0x00B4, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT1__LCDIF_DAT_1 \
+ IOMUX_PAD(0x03C8, 0x00B4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT1__ECSPI3_MOSI \
+ IOMUX_PAD(0x03C8, 0x00B4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT1__USDHC1_USDHC_DEBUG_1 \
+ IOMUX_PAD(0x03C8, 0x00B4, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT1__SDMA_DEBUG_EVENT_CHANNEL_SEL \
+ IOMUX_PAD(0x03C8, 0x00B4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT1__GPIO_4_22 \
+ IOMUX_PAD(0x03C8, 0x00B4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT1__MMDC_MMDC_DEBUG_6 \
+ IOMUX_PAD(0x03C8, 0x00B4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT1__PL301_SIM_MX6DL_PER1_HADDR_12 \
+ IOMUX_PAD(0x03C8, 0x00B4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT10__IPU1_DISP0_DAT_10 \
+ IOMUX_PAD(0x03CC, 0x00B8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT10__LCDIF_DAT_10 \
+ IOMUX_PAD(0x03CC, 0x00B8, 1, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT10__USDHC1_USDHC_DEBUG_6 \
+ IOMUX_PAD(0x03CC, 0x00B8, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT10__SDMA_DEBUG_EVENT_CHANNEL_3 \
+ IOMUX_PAD(0x03CC, 0x00B8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT10__GPIO_4_31 \
+ IOMUX_PAD(0x03CC, 0x00B8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT10__MMDC_MMDC_DEBUG_15 \
+ IOMUX_PAD(0x03CC, 0x00B8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT10__PL301_SIM_MX6DL_PER1_HADDR_21 \
+ IOMUX_PAD(0x03CC, 0x00B8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT11__IPU1_DISP0_DAT_11 \
+ IOMUX_PAD(0x03D0, 0x00BC, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT11__LCDIF_DAT_11 \
+ IOMUX_PAD(0x03D0, 0x00BC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT11__USDHC1_USDHC_DEBUG_7 \
+ IOMUX_PAD(0x03D0, 0x00BC, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT11__SDMA_DEBUG_EVENT_CHANNEL_4 \
+ IOMUX_PAD(0x03D0, 0x00BC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT11__GPIO_5_5 \
+ IOMUX_PAD(0x03D0, 0x00BC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT11__MMDC_MMDC_DEBUG_16 \
+ IOMUX_PAD(0x03D0, 0x00BC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT11__PL301_SIM_MX6DL_PER1_HADDR_22 \
+ IOMUX_PAD(0x03D0, 0x00BC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT12__IPU1_DISP0_DAT_12 \
+ IOMUX_PAD(0x03D4, 0x00C0, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT12__LCDIF_DAT_12 \
+ IOMUX_PAD(0x03D4, 0x00C0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT12__SDMA_DEBUG_EVENT_CHANNEL_5 \
+ IOMUX_PAD(0x03D4, 0x00C0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT12__GPIO_5_6 \
+ IOMUX_PAD(0x03D4, 0x00C0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT12__MMDC_MMDC_DEBUG_17 \
+ IOMUX_PAD(0x03D4, 0x00C0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT12__PL301_SIM_MX6DL_PER1_HADDR_23 \
+ IOMUX_PAD(0x03D4, 0x00C0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT13__IPU1_DISP0_DAT_13 \
+ IOMUX_PAD(0x03D8, 0x00C4, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT13__LCDIF_DAT_13 \
+ IOMUX_PAD(0x03D8, 0x00C4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT13__AUDMUX_AUD5_RXFS \
+ IOMUX_PAD(0x03D8, 0x00C4, 3, 0x07BC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT13__SDMA_DEBUG_EVT_CHN_LINES_0 \
+ IOMUX_PAD(0x03D8, 0x00C4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT13__GPIO_5_7 \
+ IOMUX_PAD(0x03D8, 0x00C4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT13__MMDC_MMDC_DEBUG_18 \
+ IOMUX_PAD(0x03D8, 0x00C4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT13__PL301_SIM_MX6DL_PER1_HADDR_24 \
+ IOMUX_PAD(0x03D8, 0x00C4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT14__IPU1_DISP0_DAT_14 \
+ IOMUX_PAD(0x03DC, 0x00C8, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT14__LCDIF_DAT_14 \
+ IOMUX_PAD(0x03DC, 0x00C8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT14__AUDMUX_AUD5_RXC \
+ IOMUX_PAD(0x03DC, 0x00C8, 3, 0x07B8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT14__SDMA_DEBUG_EVT_CHN_LINES_1 \
+ IOMUX_PAD(0x03DC, 0x00C8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT14__GPIO_5_8 \
+ IOMUX_PAD(0x03DC, 0x00C8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT14__MMDC_MMDC_DEBUG_19 \
+ IOMUX_PAD(0x03DC, 0x00C8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT14__PL301_SIM_MX6DL_PER1_HSIZE_2 \
+ IOMUX_PAD(0x03DC, 0x00C8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT15__IPU1_DISP0_DAT_15 \
+ IOMUX_PAD(0x03E0, 0x00CC, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT15__LCDIF_DAT_15 \
+ IOMUX_PAD(0x03E0, 0x00CC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT15__ECSPI1_SS1 \
+ IOMUX_PAD(0x03E0, 0x00CC, 2, 0x07E8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT15__ECSPI2_SS1 \
+ IOMUX_PAD(0x03E0, 0x00CC, 3, 0x0804, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT15__SDMA_DEBUG_EVT_CHN_LINES_2 \
+ IOMUX_PAD(0x03E0, 0x00CC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT15__GPIO_5_9 \
+ IOMUX_PAD(0x03E0, 0x00CC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT15__MMDC_MMDC_DEBUG_20 \
+ IOMUX_PAD(0x03E0, 0x00CC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT15__PL301_SIM_MX6DL_PER1_HADDR_25 \
+ IOMUX_PAD(0x03E0, 0x00CC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT16__IPU1_DISP0_DAT_16 \
+ IOMUX_PAD(0x03E4, 0x00D0, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT16__LCDIF_DAT_16 \
+ IOMUX_PAD(0x03E4, 0x00D0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT16__ECSPI2_MOSI \
+ IOMUX_PAD(0x03E4, 0x00D0, 2, 0x07FC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT16__AUDMUX_AUD5_TXC \
+ IOMUX_PAD(0x03E4, 0x00D0, 3, 0x07C0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT16__SDMA_SDMA_EXT_EVENT_0 \
+ IOMUX_PAD(0x03E4, 0x00D0, 4, 0x08E8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT16__GPIO_5_10 \
+ IOMUX_PAD(0x03E4, 0x00D0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT16__MMDC_MMDC_DEBUG_21 \
+ IOMUX_PAD(0x03E4, 0x00D0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT16__PL301_SIM_MX6DL_PER1_HADDR_26 \
+ IOMUX_PAD(0x03E4, 0x00D0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT17__IPU1_DISP0_DAT_17 \
+ IOMUX_PAD(0x03E8, 0x00D4, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT17__LCDIF_DAT_17 \
+ IOMUX_PAD(0x03E8, 0x00D4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT17__ECSPI2_MISO \
+ IOMUX_PAD(0x03E8, 0x00D4, 2, 0x07F8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT17__AUDMUX_AUD5_TXD \
+ IOMUX_PAD(0x03E8, 0x00D4, 3, 0x07B4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT17__SDMA_SDMA_EXT_EVENT_1 \
+ IOMUX_PAD(0x03E8, 0x00D4, 4, 0x08EC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT17__GPIO_5_11 \
+ IOMUX_PAD(0x03E8, 0x00D4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT17__MMDC_MMDC_DEBUG_22 \
+ IOMUX_PAD(0x03E8, 0x00D4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT17__PL301_SIM_MX6DL_PER1_HADDR_27 \
+ IOMUX_PAD(0x03E8, 0x00D4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT18__IPU1_DISP0_DAT_18 \
+ IOMUX_PAD(0x03EC, 0x00D8, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT18__LCDIF_DAT_18 \
+ IOMUX_PAD(0x03EC, 0x00D8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT18__ECSPI2_SS0 \
+ IOMUX_PAD(0x03EC, 0x00D8, 2, 0x0800, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT18__AUDMUX_AUD5_TXFS \
+ IOMUX_PAD(0x03EC, 0x00D8, 3, 0x07C4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT18__AUDMUX_AUD4_RXFS \
+ IOMUX_PAD(0x03EC, 0x00D8, 4, 0x07A4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT18__GPIO_5_12 \
+ IOMUX_PAD(0x03EC, 0x00D8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT18__MMDC_MMDC_DEBUG_23 \
+ IOMUX_PAD(0x03EC, 0x00D8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT18__WEIM_WEIM_CS_2 \
+ IOMUX_PAD(0x03EC, 0x00D8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT19__IPU1_DISP0_DAT_19 \
+ IOMUX_PAD(0x03F0, 0x00DC, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT19__LCDIF_DAT_19 \
+ IOMUX_PAD(0x03F0, 0x00DC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT19__ECSPI2_SCLK \
+ IOMUX_PAD(0x03F0, 0x00DC, 2, 0x07F4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT19__AUDMUX_AUD5_RXD \
+ IOMUX_PAD(0x03F0, 0x00DC, 3, 0x07B0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT19__AUDMUX_AUD4_RXC \
+ IOMUX_PAD(0x03F0, 0x00DC, 4, 0x07A0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT19__GPIO_5_13 \
+ IOMUX_PAD(0x03F0, 0x00DC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT19__MMDC_MMDC_DEBUG_24 \
+ IOMUX_PAD(0x03F0, 0x00DC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT19__WEIM_WEIM_CS_3 \
+ IOMUX_PAD(0x03F0, 0x00DC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT2__IPU1_DISP0_DAT_2 \
+ IOMUX_PAD(0x03F4, 0x00E0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT2__LCDIF_DAT_2 \
+ IOMUX_PAD(0x03F4, 0x00E0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT2__ECSPI3_MISO \
+ IOMUX_PAD(0x03F4, 0x00E0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT2__USDHC1_USDHC_DEBUG_2 \
+ IOMUX_PAD(0x03F4, 0x00E0, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT2__SDMA_DEBUG_MODE \
+ IOMUX_PAD(0x03F4, 0x00E0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT2__GPIO_4_23 \
+ IOMUX_PAD(0x03F4, 0x00E0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT2__MMDC_MMDC_DEBUG_7 \
+ IOMUX_PAD(0x03F4, 0x00E0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT2__PL301_SIM_MX6DL_PER1_HADDR_13 \
+ IOMUX_PAD(0x03F4, 0x00E0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT20__IPU1_DISP0_DAT_20 \
+ IOMUX_PAD(0x03F8, 0x00E4, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT20__LCDIF_DAT_20 \
+ IOMUX_PAD(0x03F8, 0x00E4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT20__ECSPI1_SCLK \
+ IOMUX_PAD(0x03F8, 0x00E4, 2, 0x07D8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT20__AUDMUX_AUD4_TXC \
+ IOMUX_PAD(0x03F8, 0x00E4, 3, 0x07A8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT20__SDMA_DEBUG_EVT_CHN_LINES_7 \
+ IOMUX_PAD(0x03F8, 0x00E4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT20__GPIO_5_14 \
+ IOMUX_PAD(0x03F8, 0x00E4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT20__MMDC_MMDC_DEBUG_25 \
+ IOMUX_PAD(0x03F8, 0x00E4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT20__PL301_SIM_MX6DL_PER1_HADDR_28 \
+ IOMUX_PAD(0x03F8, 0x00E4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT21__IPU1_DISP0_DAT_21 \
+ IOMUX_PAD(0x03FC, 0x00E8, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT21__LCDIF_DAT_21 \
+ IOMUX_PAD(0x03FC, 0x00E8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT21__ECSPI1_MOSI \
+ IOMUX_PAD(0x03FC, 0x00E8, 2, 0x07E0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT21__AUDMUX_AUD4_TXD \
+ IOMUX_PAD(0x03FC, 0x00E8, 3, 0x079C, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT21__SDMA_DEBUG_BUS_DEVICE_0 \
+ IOMUX_PAD(0x03FC, 0x00E8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT21__GPIO_5_15 \
+ IOMUX_PAD(0x03FC, 0x00E8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT21__MMDC_MMDC_DEBUG_26 \
+ IOMUX_PAD(0x03FC, 0x00E8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT21__PL301_SIM_MX6DL_PER1_HADDR_29 \
+ IOMUX_PAD(0x03FC, 0x00E8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT22__IPU1_DISP0_DAT_22 \
+ IOMUX_PAD(0x0400, 0x00EC, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT22__LCDIF_DAT_22 \
+ IOMUX_PAD(0x0400, 0x00EC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT22__ECSPI1_MISO \
+ IOMUX_PAD(0x0400, 0x00EC, 2, 0x07DC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT22__AUDMUX_AUD4_TXFS \
+ IOMUX_PAD(0x0400, 0x00EC, 3, 0x07AC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT22__SDMA_DEBUG_BUS_DEVICE_1 \
+ IOMUX_PAD(0x0400, 0x00EC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT22__GPIO_5_16 \
+ IOMUX_PAD(0x0400, 0x00EC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT22__MMDC_MMDC_DEBUG_27 \
+ IOMUX_PAD(0x0400, 0x00EC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT22__PL301_SIM_MX6DL_PER1_HADDR_30 \
+ IOMUX_PAD(0x0400, 0x00EC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT23__IPU1_DISP0_DAT_23 \
+ IOMUX_PAD(0x0404, 0x00F0, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT23__LCDIF_DAT_23 \
+ IOMUX_PAD(0x0404, 0x00F0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT23__ECSPI1_SS0 \
+ IOMUX_PAD(0x0404, 0x00F0, 2, 0x07E4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT23__AUDMUX_AUD4_RXD \
+ IOMUX_PAD(0x0404, 0x00F0, 3, 0x0798, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT23__SDMA_DEBUG_BUS_DEVICE_2 \
+ IOMUX_PAD(0x0404, 0x00F0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT23__GPIO_5_17 \
+ IOMUX_PAD(0x0404, 0x00F0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT23__MMDC_MMDC_DEBUG_28 \
+ IOMUX_PAD(0x0404, 0x00F0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT23__PL301_SIM_MX6DL_PER1_HADDR_31 \
+ IOMUX_PAD(0x0404, 0x00F0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT3__IPU1_DISP0_DAT_3 \
+ IOMUX_PAD(0x0408, 0x00F4, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT3__LCDIF_DAT_3 \
+ IOMUX_PAD(0x0408, 0x00F4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT3__ECSPI3_SS0 \
+ IOMUX_PAD(0x0408, 0x00F4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT3__USDHC1_USDHC_DEBUG_3 \
+ IOMUX_PAD(0x0408, 0x00F4, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT3__SDMA_DEBUG_BUS_ERROR \
+ IOMUX_PAD(0x0408, 0x00F4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT3__GPIO_4_24 \
+ IOMUX_PAD(0x0408, 0x00F4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT3__MMDC_MMDC_DEBUG_8 \
+ IOMUX_PAD(0x0408, 0x00F4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT3__PL301_SIM_MX6DL_PER1_HADDR_14 \
+ IOMUX_PAD(0x0408, 0x00F4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT4__IPU1_DISP0_DAT_4 \
+ IOMUX_PAD(0x040C, 0x00F8, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT4__LCDIF_DAT_4 \
+ IOMUX_PAD(0x040C, 0x00F8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT4__ECSPI3_SS1 \
+ IOMUX_PAD(0x040C, 0x00F8, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT4__USDHC1_USDHC_DEBUG_4 \
+ IOMUX_PAD(0x040C, 0x00F8, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT4__SDMA_DEBUG_BUS_RWB \
+ IOMUX_PAD(0x040C, 0x00F8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT4__GPIO_4_25 \
+ IOMUX_PAD(0x040C, 0x00F8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT4__MMDC_MMDC_DEBUG_9 \
+ IOMUX_PAD(0x040C, 0x00F8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT4__PL301_SIM_MX6DL_PER1_HADDR_15 \
+ IOMUX_PAD(0x040C, 0x00F8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT5__IPU1_DISP0_DAT_5 \
+ IOMUX_PAD(0x0410, 0x00FC, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT5__LCDIF_DAT_5 \
+ IOMUX_PAD(0x0410, 0x00FC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT5__ECSPI3_SS2 \
+ IOMUX_PAD(0x0410, 0x00FC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT5__AUDMUX_AUD6_RXFS \
+ IOMUX_PAD(0x0410, 0x00FC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT5__SDMA_DEBUG_MATCHED_DMBUS \
+ IOMUX_PAD(0x0410, 0x00FC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT5__GPIO_4_26 \
+ IOMUX_PAD(0x0410, 0x00FC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT5__MMDC_MMDC_DEBUG_10 \
+ IOMUX_PAD(0x0410, 0x00FC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT5__PL301_SIM_MX6DL_PER1_HADDR_16 \
+ IOMUX_PAD(0x0410, 0x00FC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT6__IPU1_DISP0_DAT_6 \
+ IOMUX_PAD(0x0414, 0x0100, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT6__LCDIF_DAT_6 \
+ IOMUX_PAD(0x0414, 0x0100, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT6__ECSPI3_SS3 \
+ IOMUX_PAD(0x0414, 0x0100, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT6__AUDMUX_AUD6_RXC \
+ IOMUX_PAD(0x0414, 0x0100, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT6__SDMA_DEBUG_RTBUFFER_WRITE \
+ IOMUX_PAD(0x0414, 0x0100, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT6__GPIO_4_27 \
+ IOMUX_PAD(0x0414, 0x0100, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT6__MMDC_MMDC_DEBUG_11 \
+ IOMUX_PAD(0x0414, 0x0100, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT6__PL301_SIM_MX6DL_PER1_HADDR_17 \
+ IOMUX_PAD(0x0414, 0x0100, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT7__IPU1_DISP0_DAT_7 \
+ IOMUX_PAD(0x0418, 0x0104, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT7__LCDIF_DAT_7 \
+ IOMUX_PAD(0x0418, 0x0104, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT7__ECSPI3_RDY \
+ IOMUX_PAD(0x0418, 0x0104, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT7__USDHC1_USDHC_DEBUG_5 \
+ IOMUX_PAD(0x0418, 0x0104, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT7__SDMA_DEBUG_EVENT_CHANNEL_0 \
+ IOMUX_PAD(0x0418, 0x0104, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT7__GPIO_4_28 \
+ IOMUX_PAD(0x0418, 0x0104, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT7__MMDC_MMDC_DEBUG_12 \
+ IOMUX_PAD(0x0418, 0x0104, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT7__PL301_SIM_MX6DL_PER1_HADDR_18 \
+ IOMUX_PAD(0x0418, 0x0104, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT8__IPU1_DISP0_DAT_8 \
+ IOMUX_PAD(0x041C, 0x0108, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT8__LCDIF_DAT_8 \
+ IOMUX_PAD(0x041C, 0x0108, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT8__PWM1_PWMO \
+ IOMUX_PAD(0x041C, 0x0108, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT8__WDOG1_WDOG_B \
+ IOMUX_PAD(0x041C, 0x0108, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT8__SDMA_DEBUG_EVENT_CHANNEL_1 \
+ IOMUX_PAD(0x041C, 0x0108, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT8__GPIO_4_29 \
+ IOMUX_PAD(0x041C, 0x0108, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT8__MMDC_MMDC_DEBUG_13 \
+ IOMUX_PAD(0x041C, 0x0108, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT8__PL301_SIM_MX6DL_PER1_HADDR_19 \
+ IOMUX_PAD(0x041C, 0x0108, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DISP0_DAT9__IPU1_DISP0_DAT_9 \
+ IOMUX_PAD(0x0420, 0x010C, 0, 0x0000, 0, MX6DL_DISP_PAD_CLT)
+#define MX6DL_PAD_DISP0_DAT9__LCDIF_DAT_9 \
+ IOMUX_PAD(0x0420, 0x010C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT9__PWM2_PWMO \
+ IOMUX_PAD(0x0420, 0x010C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT9__WDOG2_WDOG_B \
+ IOMUX_PAD(0x0420, 0x010C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT9__SDMA_DEBUG_EVENT_CHANNEL_2 \
+ IOMUX_PAD(0x0420, 0x010C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT9__GPIO_4_30 \
+ IOMUX_PAD(0x0420, 0x010C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT9__MMDC_MMDC_DEBUG_14 \
+ IOMUX_PAD(0x0420, 0x010C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_DISP0_DAT9__PL301_SIM_MX6DL_PER1_HADDR_20 \
+ IOMUX_PAD(0x0420, 0x010C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A0__MMDC_DRAM_A_0 \
+ IOMUX_PAD(0x0424, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A1__MMDC_DRAM_A_1 \
+ IOMUX_PAD(0x0428, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A10__MMDC_DRAM_A_10 \
+ IOMUX_PAD(0x042C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A11__MMDC_DRAM_A_11 \
+ IOMUX_PAD(0x0430, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A12__MMDC_DRAM_A_12 \
+ IOMUX_PAD(0x0434, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A13__MMDC_DRAM_A_13 \
+ IOMUX_PAD(0x0438, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A14__MMDC_DRAM_A_14 \
+ IOMUX_PAD(0x043C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A15__MMDC_DRAM_A_15 \
+ IOMUX_PAD(0x0440, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A2__MMDC_DRAM_A_2 \
+ IOMUX_PAD(0x0444, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A3__MMDC_DRAM_A_3 \
+ IOMUX_PAD(0x0448, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A4__MMDC_DRAM_A_4 \
+ IOMUX_PAD(0x044C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A5__MMDC_DRAM_A_5 \
+ IOMUX_PAD(0x0450, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A6__MMDC_DRAM_A_6 \
+ IOMUX_PAD(0x0454, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A7__MMDC_DRAM_A_7 \
+ IOMUX_PAD(0x0458, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A8__MMDC_DRAM_A_8 \
+ IOMUX_PAD(0x045C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_A9__MMDC_DRAM_A_9 \
+ IOMUX_PAD(0x0460, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_CAS__MMDC_DRAM_CAS \
+ IOMUX_PAD(0x0464, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_CS0__MMDC_DRAM_CS_0 \
+ IOMUX_PAD(0x0468, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_CS1__MMDC_DRAM_CS_1 \
+ IOMUX_PAD(0x046C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D0__MMDC_DRAM_D_0 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D1__MMDC_DRAM_D_1 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D10__MMDC_DRAM_D_10 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D11__MMDC_DRAM_D_11 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D12__MMDC_DRAM_D_12 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D13__MMDC_DRAM_D_13 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D14__MMDC_DRAM_D_14 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D15__MMDC_DRAM_D_15 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D16__MMDC_DRAM_D_16 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D17__MMDC_DRAM_D_17 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D18__MMDC_DRAM_D_18 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D19__MMDC_DRAM_D_19 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D2__MMDC_DRAM_D_2 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D20__MMDC_DRAM_D_20 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D21__MMDC_DRAM_D_21 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D22__MMDC_DRAM_D_22 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D23__MMDC_DRAM_D_23 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D24__MMDC_DRAM_D_24 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D25__MMDC_DRAM_D_25 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D26__MMDC_DRAM_D_26 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D27__MMDC_DRAM_D_27 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D28__MMDC_DRAM_D_28 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D29__MMDC_DRAM_D_29 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D3__MMDC_DRAM_D_3 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D30__MMDC_DRAM_D_30 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D31__MMDC_DRAM_D_31 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D32__MMDC_DRAM_D_32 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D33__MMDC_DRAM_D_33 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D34__MMDC_DRAM_D_34 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D35__MMDC_DRAM_D_35 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D36__MMDC_DRAM_D_36 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D37__MMDC_DRAM_D_37 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D38__MMDC_DRAM_D_38 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D39__MMDC_DRAM_D_39 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D4__MMDC_DRAM_D_4 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D40__MMDC_DRAM_D_40 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D41__MMDC_DRAM_D_41 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D42__MMDC_DRAM_D_42 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D43__MMDC_DRAM_D_43 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D44__MMDC_DRAM_D_44 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D45__MMDC_DRAM_D_45 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D46__MMDC_DRAM_D_46 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D47__MMDC_DRAM_D_47 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D48__MMDC_DRAM_D_48 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D49__MMDC_DRAM_D_49 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D5__MMDC_DRAM_D_5 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D50__MMDC_DRAM_D_50 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D51__MMDC_DRAM_D_51 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D52__MMDC_DRAM_D_52 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D53__MMDC_DRAM_D_53 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D54__MMDC_DRAM_D_54 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D55__MMDC_DRAM_D_55 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D56__MMDC_DRAM_D_56 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D57__MMDC_DRAM_D_57 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D58__MMDC_DRAM_D_58 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D59__MMDC_DRAM_D_59 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D6__MMDC_DRAM_D_6 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D60__MMDC_DRAM_D_60 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D61__MMDC_DRAM_D_61 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D62__MMDC_DRAM_D_62 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D63__MMDC_DRAM_D_63 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D7__MMDC_DRAM_D_7 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D8__MMDC_DRAM_D_8 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_D9__MMDC_DRAM_D_9 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_DQM0__MMDC_DRAM_DQM_0 \
+ IOMUX_PAD(0x0470, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_DQM1__MMDC_DRAM_DQM_1 \
+ IOMUX_PAD(0x0474, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_DQM2__MMDC_DRAM_DQM_2 \
+ IOMUX_PAD(0x0478, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_DQM3__MMDC_DRAM_DQM_3 \
+ IOMUX_PAD(0x047C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_DQM4__MMDC_DRAM_DQM_4 \
+ IOMUX_PAD(0x0480, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_DQM5__MMDC_DRAM_DQM_5 \
+ IOMUX_PAD(0x0484, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_DQM6__MMDC_DRAM_DQM_6 \
+ IOMUX_PAD(0x0488, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_DQM7__MMDC_DRAM_DQM_7 \
+ IOMUX_PAD(0x048C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_RAS__MMDC_DRAM_RAS \
+ IOMUX_PAD(0x0490, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_RESET__MMDC_DRAM_RESET \
+ IOMUX_PAD(0x0494, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDBA0__MMDC_DRAM_SDBA_0 \
+ IOMUX_PAD(0x0498, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDBA1__MMDC_DRAM_SDBA_1 \
+ IOMUX_PAD(0x049C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDBA2__MMDC_DRAM_SDBA_2 \
+ IOMUX_PAD(0x04A0, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDCKE0__MMDC_DRAM_SDCKE_0 \
+ IOMUX_PAD(0x04A4, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDCKE1__MMDC_DRAM_SDCKE_1 \
+ IOMUX_PAD(0x04A8, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDCLK_0__MMDC_DRAM_SDCLK0 \
+ IOMUX_PAD(0x04AC, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDCLK_1__MMDC_DRAM_SDCLK1 \
+ IOMUX_PAD(0x04B0, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDODT0__MMDC_DRAM_ODT_0 \
+ IOMUX_PAD(0x04B4, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDODT1__MMDC_DRAM_ODT_1 \
+ IOMUX_PAD(0x04B8, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDQS0__MMDC_DRAM_SDQS_0 \
+ IOMUX_PAD(0x04BC, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDQS1__MMDC_DRAM_SDQS_1 \
+ IOMUX_PAD(0x04C0, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDQS2__MMDC_DRAM_SDQS_2 \
+ IOMUX_PAD(0x04C4, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDQS3__MMDC_DRAM_SDQS_3 \
+ IOMUX_PAD(0x04C8, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDQS4__MMDC_DRAM_SDQS_4 \
+ IOMUX_PAD(0x04CC, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDQS5__MMDC_DRAM_SDQS_5 \
+ IOMUX_PAD(0x04D0, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDQS6__MMDC_DRAM_SDQS_6 \
+ IOMUX_PAD(0x04D4, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDQS7__MMDC_DRAM_SDQS_7 \
+ IOMUX_PAD(0x04D8, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_DRAM_SDWE__MMDC_DRAM_SDWE \
+ IOMUX_PAD(0x04DC, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A16__WEIM_WEIM_A_16 \
+ IOMUX_PAD(0x04E0, 0x0110, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A16__IPU1_DI1_DISP_CLK \
+ IOMUX_PAD(0x04E0, 0x0110, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A16__IPU1_CSI1_PIXCLK \
+ IOMUX_PAD(0x04E0, 0x0110, 2, 0x08B8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A16__MIPI_CORE_DPHY_TEST_OUT_23 \
+ IOMUX_PAD(0x04E0, 0x0110, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A16__GPIO_2_22 \
+ IOMUX_PAD(0x04E0, 0x0110, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A16__TPSMP_HDATA_6 \
+ IOMUX_PAD(0x04E0, 0x0110, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A16__SRC_BT_CFG_16 \
+ IOMUX_PAD(0x04E0, 0x0110, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A16__EPDC_SDDO_0 \
+ IOMUX_PAD(0x04E0, 0x0110, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A17__WEIM_WEIM_A_17 \
+ IOMUX_PAD(0x04E4, 0x0114, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A17__IPU1_DISP1_DAT_12 \
+ IOMUX_PAD(0x04E4, 0x0114, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A17__IPU1_CSI1_D_12 \
+ IOMUX_PAD(0x04E4, 0x0114, 2, 0x0890, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A17__MIPI_CORE_DPHY_TEST_OUT_22 \
+ IOMUX_PAD(0x04E4, 0x0114, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A17__GPIO_2_21 \
+ IOMUX_PAD(0x04E4, 0x0114, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A17__TPSMP_HDATA_5 \
+ IOMUX_PAD(0x04E4, 0x0114, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A17__SRC_BT_CFG_17 \
+ IOMUX_PAD(0x04E4, 0x0114, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A17__EPDC_PWRSTAT \
+ IOMUX_PAD(0x04E4, 0x0114, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A18__WEIM_WEIM_A_18 \
+ IOMUX_PAD(0x04E8, 0x0118, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A18__IPU1_DISP1_DAT_13 \
+ IOMUX_PAD(0x04E8, 0x0118, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A18__IPU1_CSI1_D_13 \
+ IOMUX_PAD(0x04E8, 0x0118, 2, 0x0894, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A18__MIPI_CORE_DPHY_TEST_OUT_21 \
+ IOMUX_PAD(0x04E8, 0x0118, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A18__GPIO_2_20 \
+ IOMUX_PAD(0x04E8, 0x0118, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A18__TPSMP_HDATA_4 \
+ IOMUX_PAD(0x04E8, 0x0118, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A18__SRC_BT_CFG_18 \
+ IOMUX_PAD(0x04E8, 0x0118, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A18__EPDC_PWRCTRL_0 \
+ IOMUX_PAD(0x04E8, 0x0118, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A19__WEIM_WEIM_A_19 \
+ IOMUX_PAD(0x04EC, 0x011C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A19__IPU1_DISP1_DAT_14 \
+ IOMUX_PAD(0x04EC, 0x011C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A19__IPU1_CSI1_D_14 \
+ IOMUX_PAD(0x04EC, 0x011C, 2, 0x0898, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A19__MIPI_CORE_DPHY_TEST_OUT_20 \
+ IOMUX_PAD(0x04EC, 0x011C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A19__GPIO_2_19 \
+ IOMUX_PAD(0x04EC, 0x011C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A19__TPSMP_HDATA_3 \
+ IOMUX_PAD(0x04EC, 0x011C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A19__SRC_BT_CFG_19 \
+ IOMUX_PAD(0x04EC, 0x011C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A19__EPDC_PWRCTRL_1 \
+ IOMUX_PAD(0x04EC, 0x011C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A20__WEIM_WEIM_A_20 \
+ IOMUX_PAD(0x04F0, 0x0120, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A20__IPU1_DISP1_DAT_15 \
+ IOMUX_PAD(0x04F0, 0x0120, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A20__IPU1_CSI1_D_15 \
+ IOMUX_PAD(0x04F0, 0x0120, 2, 0x089C, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A20__MIPI_CORE_DPHY_TEST_OUT_19 \
+ IOMUX_PAD(0x04F0, 0x0120, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A20__GPIO_2_18 \
+ IOMUX_PAD(0x04F0, 0x0120, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A20__TPSMP_HDATA_2 \
+ IOMUX_PAD(0x04F0, 0x0120, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A20__SRC_BT_CFG_20 \
+ IOMUX_PAD(0x04F0, 0x0120, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A20__EPDC_PWRCTRL_2 \
+ IOMUX_PAD(0x04F0, 0x0120, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A21__WEIM_WEIM_A_21 \
+ IOMUX_PAD(0x04F4, 0x0124, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A21__IPU1_DISP1_DAT_16 \
+ IOMUX_PAD(0x04F4, 0x0124, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A21__IPU1_CSI1_D_16 \
+ IOMUX_PAD(0x04F4, 0x0124, 2, 0x08A0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A21__MIPI_CORE_DPHY_TEST_OUT_18 \
+ IOMUX_PAD(0x04F4, 0x0124, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A21__GPIO_2_17 \
+ IOMUX_PAD(0x04F4, 0x0124, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A21__TPSMP_HDATA_1 \
+ IOMUX_PAD(0x04F4, 0x0124, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A21__SRC_BT_CFG_21 \
+ IOMUX_PAD(0x04F4, 0x0124, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A21__EPDC_GDCLK \
+ IOMUX_PAD(0x04F4, 0x0124, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A22__WEIM_WEIM_A_22 \
+ IOMUX_PAD(0x04F8, 0x0128, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A22__IPU1_DISP1_DAT_17 \
+ IOMUX_PAD(0x04F8, 0x0128, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A22__IPU1_CSI1_D_17 \
+ IOMUX_PAD(0x04F8, 0x0128, 2, 0x08A4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A22__GPIO_2_16 \
+ IOMUX_PAD(0x04F8, 0x0128, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A22__TPSMP_HDATA_0 \
+ IOMUX_PAD(0x04F8, 0x0128, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A22__SRC_BT_CFG_22 \
+ IOMUX_PAD(0x04F8, 0x0128, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A22__EPDC_GDSP \
+ IOMUX_PAD(0x04F8, 0x0128, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A23__WEIM_WEIM_A_23 \
+ IOMUX_PAD(0x04FC, 0x012C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A23__IPU1_DISP1_DAT_18 \
+ IOMUX_PAD(0x04FC, 0x012C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A23__IPU1_CSI1_D_18 \
+ IOMUX_PAD(0x04FC, 0x012C, 2, 0x08A8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A23__IPU1_SISG_3 \
+ IOMUX_PAD(0x04FC, 0x012C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A23__GPIO_6_6 \
+ IOMUX_PAD(0x04FC, 0x012C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A23__PL301_SIM_MX6DL_PER1_HPROT_3 \
+ IOMUX_PAD(0x04FC, 0x012C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A23__SRC_BT_CFG_23 \
+ IOMUX_PAD(0x04FC, 0x012C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A23__EPDC_GDOE \
+ IOMUX_PAD(0x04FC, 0x012C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A24__WEIM_WEIM_A_24 \
+ IOMUX_PAD(0x0500, 0x0130, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A24__IPU1_DISP1_DAT_19 \
+ IOMUX_PAD(0x0500, 0x0130, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A24__IPU1_CSI1_D_19 \
+ IOMUX_PAD(0x0500, 0x0130, 2, 0x08AC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A24__IPU1_SISG_2 \
+ IOMUX_PAD(0x0500, 0x0130, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A24__GPIO_5_4 \
+ IOMUX_PAD(0x0500, 0x0130, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A24__PL301_SIM_MX6DL_PER1_HPROT_2 \
+ IOMUX_PAD(0x0500, 0x0130, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A24__SRC_BT_CFG_24 \
+ IOMUX_PAD(0x0500, 0x0130, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A24__EPDC_GDRL \
+ IOMUX_PAD(0x0500, 0x0130, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_A25__WEIM_WEIM_A_25 \
+ IOMUX_PAD(0x0504, 0x0134, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__ECSPI4_SS1 \
+ IOMUX_PAD(0x0504, 0x0134, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__ECSPI2_RDY \
+ IOMUX_PAD(0x0504, 0x0134, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__IPU1_DI1_PIN12 \
+ IOMUX_PAD(0x0504, 0x0134, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__IPU1_DI0_D1_CS \
+ IOMUX_PAD(0x0504, 0x0134, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__GPIO_5_2 \
+ IOMUX_PAD(0x0504, 0x0134, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__HDMI_TX_CEC_LINE \
+ IOMUX_PAD(0x0504, 0x0134, 6, 0x085C, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__PL301_SIM_MX6DL_PER1_HBURST_0 \
+ IOMUX_PAD(0x0504, 0x0134, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__EPDC_SDDO_15 \
+ IOMUX_PAD(0x0504, 0x0134, 8, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_A25__WEIM_ACLK_FREERUN \
+ IOMUX_PAD(0x0504, 0x0134, 9, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_BCLK__WEIM_WEIM_BCLK \
+ IOMUX_PAD(0x0508, 0x0138, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_BCLK__IPU1_DI1_PIN16 \
+ IOMUX_PAD(0x0508, 0x0138, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_BCLK__GPIO_6_31 \
+ IOMUX_PAD(0x0508, 0x0138, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_BCLK__TPSMP_HDATA_31 \
+ IOMUX_PAD(0x0508, 0x0138, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_BCLK__EPDC_SDCE_9 \
+ IOMUX_PAD(0x0508, 0x0138, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_CS0__WEIM_WEIM_CS_0 \
+ IOMUX_PAD(0x050C, 0x013C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS0__IPU1_DI1_PIN5 \
+ IOMUX_PAD(0x050C, 0x013C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS0__ECSPI2_SCLK \
+ IOMUX_PAD(0x050C, 0x013C, 2, 0x07F4, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS0__MIPI_CORE_DPHY_TEST_OUT_24 \
+ IOMUX_PAD(0x050C, 0x013C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS0__GPIO_2_23 \
+ IOMUX_PAD(0x050C, 0x013C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS0__TPSMP_HDATA_7 \
+ IOMUX_PAD(0x050C, 0x013C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS0__EPDC_SDDO_6 \
+ IOMUX_PAD(0x050C, 0x013C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_CS1__WEIM_WEIM_CS_1 \
+ IOMUX_PAD(0x0510, 0x0140, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS1__IPU1_DI1_PIN6 \
+ IOMUX_PAD(0x0510, 0x0140, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS1__ECSPI2_MOSI \
+ IOMUX_PAD(0x0510, 0x0140, 2, 0x07FC, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS1__MIPI_CORE_DPHY_TEST_OUT_25 \
+ IOMUX_PAD(0x0510, 0x0140, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS1__GPIO_2_24 \
+ IOMUX_PAD(0x0510, 0x0140, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS1__TPSMP_HDATA_8 \
+ IOMUX_PAD(0x0510, 0x0140, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_CS1__EPDC_SDDO_8 \
+ IOMUX_PAD(0x0510, 0x0140, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D16__WEIM_WEIM_D_16 \
+ IOMUX_PAD(0x0514, 0x0144, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D16__ECSPI1_SCLK \
+ IOMUX_PAD(0x0514, 0x0144, 1, 0x07D8, 2, MX6DL_ECSPI_PAD_CTRL)
+#define MX6DL_PAD_EIM_D16__IPU1_DI0_PIN5 \
+ IOMUX_PAD(0x0514, 0x0144, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D16__IPU1_CSI1_D_18 \
+ IOMUX_PAD(0x0514, 0x0144, 3, 0x08A8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D16__HDMI_TX_DDC_SDA \
+ IOMUX_PAD(0x0514, 0x0144, 4, 0x0864, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D16__GPIO_3_16 \
+ IOMUX_PAD(0x0514, 0x0144, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D16__I2C2_SDA \
+ IOMUX_PAD(0x0514, 0x0144, 6 | IOMUX_CONFIG_SION, 0x0874, 0, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_EIM_D16__TPSMP_HTRANS_0 \
+ IOMUX_PAD(0x0514, 0x0144, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D16__EPDC_SDDO_10 \
+ IOMUX_PAD(0x0514, 0x0144, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D17__WEIM_WEIM_D_17 \
+ IOMUX_PAD(0x0518, 0x0148, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D17__ECSPI1_MISO \
+ IOMUX_PAD(0x0518, 0x0148, 1, 0x07DC, 2, MX6DL_ECSPI_PAD_CTRL)
+#define MX6DL_PAD_EIM_D17__IPU1_DI0_PIN6 \
+ IOMUX_PAD(0x0518, 0x0148, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D17__IPU1_CSI1_PIXCLK \
+ IOMUX_PAD(0x0518, 0x0148, 3, 0x08B8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D17__DCIC1_DCIC_OUT \
+ IOMUX_PAD(0x0518, 0x0148, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D17__GPIO_3_17 \
+ IOMUX_PAD(0x0518, 0x0148, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D17__I2C3_SCL \
+ IOMUX_PAD(0x0518, 0x0148, 6 | IOMUX_CONFIG_SION, 0x0878, 0, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_EIM_D17__PL301_SIM_MX6DL_PER1_HBURST_1 \
+ IOMUX_PAD(0x0518, 0x0148, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D17__EPDC_VCOM_0 \
+ IOMUX_PAD(0x0518, 0x0148, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D18__WEIM_WEIM_D_18 \
+ IOMUX_PAD(0x051C, 0x014C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D18__ECSPI1_MOSI \
+ IOMUX_PAD(0x051C, 0x014C, 1, 0x07E0, 2, MX6DL_ECSPI_PAD_CTRL)
+#define MX6DL_PAD_EIM_D18__IPU1_DI0_PIN7 \
+ IOMUX_PAD(0x051C, 0x014C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D18__IPU1_CSI1_D_17 \
+ IOMUX_PAD(0x051C, 0x014C, 3, 0x08A4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D18__IPU1_DI1_D0_CS \
+ IOMUX_PAD(0x051C, 0x014C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D18__GPIO_3_18 \
+ IOMUX_PAD(0x051C, 0x014C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D18__I2C3_SDA \
+ IOMUX_PAD(0x051C, 0x014C, 6 | IOMUX_CONFIG_SION, 0x087C, 0, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_EIM_D18__PL301_SIM_MX6DL_PER1_HBURST_2 \
+ IOMUX_PAD(0x051C, 0x014C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D18__EPDC_VCOM_1 \
+ IOMUX_PAD(0x051C, 0x014C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D19__WEIM_WEIM_D_19 \
+ IOMUX_PAD(0x0520, 0x0150, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__ECSPI1_SS1 \
+ IOMUX_PAD(0x0520, 0x0150, 1, 0x07E8, 1, MX6DL_ECSPI_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__IPU1_DI0_PIN8 \
+ IOMUX_PAD(0x0520, 0x0150, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__IPU1_CSI1_D_16 \
+ IOMUX_PAD(0x0520, 0x0150, 3, 0x08A0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__UART1_CTS \
+ IOMUX_PAD(0x0520, 0x0150, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__UART1_RTS \
+ IOMUX_PAD(0x0520, 0x0150, 4, 0x08F8, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__GPIO_3_19 \
+ IOMUX_PAD(0x0520, 0x0150, 5, 0x0000, 0, MX6DL_ECSPI_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__EPIT1_EPITO \
+ IOMUX_PAD(0x0520, 0x0150, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__PL301_SIM_MX6DL_PER1_HRESP \
+ IOMUX_PAD(0x0520, 0x0150, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D19__EPDC_SDDO_12 \
+ IOMUX_PAD(0x0520, 0x0150, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D20__WEIM_WEIM_D_20 \
+ IOMUX_PAD(0x0524, 0x0154, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D20__ECSPI4_SS0 \
+ IOMUX_PAD(0x0524, 0x0154, 1, 0x0808, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D20__IPU1_DI0_PIN16 \
+ IOMUX_PAD(0x0524, 0x0154, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D20__IPU1_CSI1_D_15 \
+ IOMUX_PAD(0x0524, 0x0154, 3, 0x089C, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D20__UART1_CTS \
+ IOMUX_PAD(0x0524, 0x0154, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D20__UART1_RTS \
+ IOMUX_PAD(0x0524, 0x0154, 4, 0x08F8, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D20__GPIO_3_20 \
+ IOMUX_PAD(0x0524, 0x0154, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D20__EPIT2_EPITO \
+ IOMUX_PAD(0x0524, 0x0154, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D20__TPSMP_HTRANS_1 \
+ IOMUX_PAD(0x0524, 0x0154, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D21__WEIM_WEIM_D_21 \
+ IOMUX_PAD(0x0528, 0x0158, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D21__ECSPI4_SCLK \
+ IOMUX_PAD(0x0528, 0x0158, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D21__IPU1_DI0_PIN17 \
+ IOMUX_PAD(0x0528, 0x0158, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D21__IPU1_CSI1_D_11 \
+ IOMUX_PAD(0x0528, 0x0158, 3, 0x088C, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D21__USBOH3_USBOTG_OC \
+ IOMUX_PAD(0x0528, 0x0158, 4, 0x0920, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D21__GPIO_3_21 \
+ IOMUX_PAD(0x0528, 0x0158, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D21__I2C1_SCL \
+ IOMUX_PAD(0x0528, 0x0158, 6 | IOMUX_CONFIG_SION, 0x0868, 1, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_EIM_D21__SPDIF_IN1 \
+ IOMUX_PAD(0x0528, 0x0158, 7, 0x08F0, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D22__WEIM_WEIM_D_22 \
+ IOMUX_PAD(0x052C, 0x015C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D22__ECSPI4_MISO \
+ IOMUX_PAD(0x052C, 0x015C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D22__IPU1_DI0_PIN1 \
+ IOMUX_PAD(0x052C, 0x015C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D22__IPU1_CSI1_D_10 \
+ IOMUX_PAD(0x052C, 0x015C, 3, 0x0888, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D22__USBOH3_USBOTG_PWR \
+ IOMUX_PAD(0x052C, 0x015C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D22__GPIO_3_22 \
+ IOMUX_PAD(0x052C, 0x015C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D22__SPDIF_OUT1 \
+ IOMUX_PAD(0x052C, 0x015C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D22__PL301_SIM_MX6DL_PER1_HWRITE \
+ IOMUX_PAD(0x052C, 0x015C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D22__EPDC_SDCE_6 \
+ IOMUX_PAD(0x052C, 0x015C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D23__WEIM_WEIM_D_23 \
+ IOMUX_PAD(0x0530, 0x0160, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__IPU1_DI0_D0_CS \
+ IOMUX_PAD(0x0530, 0x0160, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__UART3_CTS \
+ IOMUX_PAD(0x0530, 0x0160, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__UART3_RTS \
+ IOMUX_PAD(0x0530, 0x0160, 2, 0x0908, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__UART1_DCD \
+ IOMUX_PAD(0x0530, 0x0160, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__IPU1_CSI1_DATA_EN \
+ IOMUX_PAD(0x0530, 0x0160, 4, 0x08B0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__GPIO_3_23 \
+ IOMUX_PAD(0x0530, 0x0160, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__IPU1_DI1_PIN2 \
+ IOMUX_PAD(0x0530, 0x0160, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__IPU1_DI1_PIN14 \
+ IOMUX_PAD(0x0530, 0x0160, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D23__EPDC_SDDO_11 \
+ IOMUX_PAD(0x0530, 0x0160, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D24__WEIM_WEIM_D_24 \
+ IOMUX_PAD(0x0534, 0x0164, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__ECSPI4_SS2 \
+ IOMUX_PAD(0x0534, 0x0164, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__UART3_TXD \
+ IOMUX_PAD(0x0534, 0x0164, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__UART3_RXD \
+ IOMUX_PAD(0x0534, 0x0164, 2, 0x090C, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__ECSPI1_SS2 \
+ IOMUX_PAD(0x0534, 0x0164, 3, 0x07EC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__ECSPI2_SS2 \
+ IOMUX_PAD(0x0534, 0x0164, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__GPIO_3_24 \
+ IOMUX_PAD(0x0534, 0x0164, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__AUDMUX_AUD5_RXFS \
+ IOMUX_PAD(0x0534, 0x0164, 6, 0x07BC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__UART1_DTR \
+ IOMUX_PAD(0x0534, 0x0164, 7, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D24__EPDC_SDCE_7 \
+ IOMUX_PAD(0x0534, 0x0164, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D25__WEIM_WEIM_D_25 \
+ IOMUX_PAD(0x0538, 0x0168, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__ECSPI4_SS3 \
+ IOMUX_PAD(0x0538, 0x0168, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__UART3_TXD \
+ IOMUX_PAD(0x0538, 0x0168, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__UART3_RXD \
+ IOMUX_PAD(0x0538, 0x0168, 2, 0x090C, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__ECSPI1_SS3 \
+ IOMUX_PAD(0x0538, 0x0168, 3, 0x07F0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__ECSPI2_SS3 \
+ IOMUX_PAD(0x0538, 0x0168, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__GPIO_3_25 \
+ IOMUX_PAD(0x0538, 0x0168, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__AUDMUX_AUD5_RXC \
+ IOMUX_PAD(0x0538, 0x0168, 6, 0x07B8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__UART1_DSR \
+ IOMUX_PAD(0x0538, 0x0168, 7, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D25__EPDC_SDCE_8 \
+ IOMUX_PAD(0x0538, 0x0168, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D26__WEIM_WEIM_D_26 \
+ IOMUX_PAD(0x053C, 0x016C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__IPU1_DI1_PIN11 \
+ IOMUX_PAD(0x053C, 0x016C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__IPU1_CSI0_D_1 \
+ IOMUX_PAD(0x053C, 0x016C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__IPU1_CSI1_D_14 \
+ IOMUX_PAD(0x053C, 0x016C, 3, 0x0898, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__UART2_TXD \
+ IOMUX_PAD(0x053C, 0x016C, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__UART2_RXD \
+ IOMUX_PAD(0x053C, 0x016C, 4, 0x0904, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__GPIO_3_26 \
+ IOMUX_PAD(0x053C, 0x016C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__IPU1_SISG_2 \
+ IOMUX_PAD(0x053C, 0x016C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__IPU1_DISP1_DAT_22 \
+ IOMUX_PAD(0x053C, 0x016C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D26__EPDC_SDOED \
+ IOMUX_PAD(0x053C, 0x016C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D27__WEIM_WEIM_D_27 \
+ IOMUX_PAD(0x0540, 0x0170, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__IPU1_DI1_PIN13 \
+ IOMUX_PAD(0x0540, 0x0170, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__IPU1_CSI0_D_0 \
+ IOMUX_PAD(0x0540, 0x0170, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__IPU1_CSI1_D_13 \
+ IOMUX_PAD(0x0540, 0x0170, 3, 0x0894, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__UART2_TXD \
+ IOMUX_PAD(0x0540, 0x0170, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__UART2_RXD \
+ IOMUX_PAD(0x0540, 0x0170, 4, 0x0904, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__GPIO_3_27 \
+ IOMUX_PAD(0x0540, 0x0170, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__IPU1_SISG_3 \
+ IOMUX_PAD(0x0540, 0x0170, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__IPU1_DISP1_DAT_23 \
+ IOMUX_PAD(0x0540, 0x0170, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D27__EPDC_SDOE \
+ IOMUX_PAD(0x0540, 0x0170, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D28__WEIM_WEIM_D_28 \
+ IOMUX_PAD(0x0544, 0x0174, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__I2C1_SDA \
+ IOMUX_PAD(0x0544, 0x0174, 1 | IOMUX_CONFIG_SION, 0x086C, 1, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__ECSPI4_MOSI \
+ IOMUX_PAD(0x0544, 0x0174, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__IPU1_CSI1_D_12 \
+ IOMUX_PAD(0x0544, 0x0174, 3, 0x0890, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__UART2_CTS \
+ IOMUX_PAD(0x0544, 0x0174, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__UART2_RTS \
+ IOMUX_PAD(0x0544, 0x0174, 4, 0x0900, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__GPIO_3_28 \
+ IOMUX_PAD(0x0544, 0x0174, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__IPU1_EXT_TRIG \
+ IOMUX_PAD(0x0544, 0x0174, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__IPU1_DI0_PIN13 \
+ IOMUX_PAD(0x0544, 0x0174, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D28__EPDC_PWRCTRL_3 \
+ IOMUX_PAD(0x0544, 0x0174, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D29__WEIM_WEIM_D_29 \
+ IOMUX_PAD(0x0548, 0x0178, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D29__IPU1_DI1_PIN15 \
+ IOMUX_PAD(0x0548, 0x0178, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D29__ECSPI4_SS0 \
+ IOMUX_PAD(0x0548, 0x0178, 2, 0x0808, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D29__UART2_CTS \
+ IOMUX_PAD(0x0548, 0x0178, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D29__UART2_RTS \
+ IOMUX_PAD(0x0548, 0x0178, 4, 0x0900, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D29__GPIO_3_29 \
+ IOMUX_PAD(0x0548, 0x0178, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D29__IPU1_CSI1_VSYNC \
+ IOMUX_PAD(0x0548, 0x0178, 6, 0x08BC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D29__IPU1_DI0_PIN14 \
+ IOMUX_PAD(0x0548, 0x0178, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D29__EPDC_PWRWAKE \
+ IOMUX_PAD(0x0548, 0x0178, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D30__WEIM_WEIM_D_30 \
+ IOMUX_PAD(0x054C, 0x017C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__IPU1_DISP1_DAT_21 \
+ IOMUX_PAD(0x054C, 0x017C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__IPU1_DI0_PIN11 \
+ IOMUX_PAD(0x054C, 0x017C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__IPU1_CSI0_D_3 \
+ IOMUX_PAD(0x054C, 0x017C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__UART3_CTS \
+ IOMUX_PAD(0x054C, 0x017C, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__UART3_RTS \
+ IOMUX_PAD(0x054C, 0x017C, 4, 0x0908, 1, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__GPIO_3_30 \
+ IOMUX_PAD(0x054C, 0x017C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__USBOH3_USBH1_OC \
+ IOMUX_PAD(0x054C, 0x017C, 6, 0x0924, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__PL301_SIM_MX6DL_PER1_HPROT_0 \
+ IOMUX_PAD(0x054C, 0x017C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D30__EPDC_SDOEZ \
+ IOMUX_PAD(0x054C, 0x017C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_D31__WEIM_WEIM_D_31 \
+ IOMUX_PAD(0x0550, 0x0180, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__IPU1_DISP1_DAT_20 \
+ IOMUX_PAD(0x0550, 0x0180, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__IPU1_DI0_PIN12 \
+ IOMUX_PAD(0x0550, 0x0180, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__IPU1_CSI0_D_2 \
+ IOMUX_PAD(0x0550, 0x0180, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__UART3_CTS \
+ IOMUX_PAD(0x0550, 0x0180, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__UART3_RTS \
+ IOMUX_PAD(0x0550, 0x0180, 4, 0x0908, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__GPIO_3_31 \
+ IOMUX_PAD(0x0550, 0x0180, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__USBOH3_USBH1_PWR \
+ IOMUX_PAD(0x0550, 0x0180, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__PL301_SIM_MX6DL_PER1_HPROT_1 \
+ IOMUX_PAD(0x0550, 0x0180, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__EPDC_SDCLK \
+ IOMUX_PAD(0x0550, 0x0180, 8, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_D31__WEIM_ACLK_FREERUN \
+ IOMUX_PAD(0x0550, 0x0180, 9, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA0__WEIM_WEIM_DA_A_0 \
+ IOMUX_PAD(0x0554, 0x0184, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA0__IPU1_DISP1_DAT_9 \
+ IOMUX_PAD(0x0554, 0x0184, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA0__IPU1_CSI1_D_9 \
+ IOMUX_PAD(0x0554, 0x0184, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA0__MIPI_CORE_DPHY_TEST_OUT_2 \
+ IOMUX_PAD(0x0554, 0x0184, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA0__GPIO_3_0 \
+ IOMUX_PAD(0x0554, 0x0184, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA0__TPSMP_HDATA_14 \
+ IOMUX_PAD(0x0554, 0x0184, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA0__SRC_BT_CFG_0 \
+ IOMUX_PAD(0x0554, 0x0184, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA0__EPDC_SDCLKN \
+ IOMUX_PAD(0x0554, 0x0184, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA1__WEIM_WEIM_DA_A_1 \
+ IOMUX_PAD(0x0558, 0x0188, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA1__IPU1_DISP1_DAT_8 \
+ IOMUX_PAD(0x0558, 0x0188, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA1__IPU1_CSI1_D_8 \
+ IOMUX_PAD(0x0558, 0x0188, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA1__MIPI_CORE_DPHY_TEST_OUT_3 \
+ IOMUX_PAD(0x0558, 0x0188, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA1__ANATOP_USBPHY1_TSTI_TX_LS_MODE \
+ IOMUX_PAD(0x0558, 0x0188, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA1__GPIO_3_1 \
+ IOMUX_PAD(0x0558, 0x0188, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA1__TPSMP_HDATA_15 \
+ IOMUX_PAD(0x0558, 0x0188, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA1__SRC_BT_CFG_1 \
+ IOMUX_PAD(0x0558, 0x0188, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA1__EPDC_SDLE \
+ IOMUX_PAD(0x0558, 0x0188, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA10__WEIM_WEIM_DA_A_10 \
+ IOMUX_PAD(0x055C, 0x018C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA10__IPU1_DI1_PIN15 \
+ IOMUX_PAD(0x055C, 0x018C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA10__IPU1_CSI1_DATA_EN \
+ IOMUX_PAD(0x055C, 0x018C, 2, 0x08B0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA10__MIPI_CORE_DPHY_TEST_OUT_12 \
+ IOMUX_PAD(0x055C, 0x018C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA10__GPIO_3_10 \
+ IOMUX_PAD(0x055C, 0x018C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA10__TPSMP_HDATA_24 \
+ IOMUX_PAD(0x055C, 0x018C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA10__SRC_BT_CFG_10 \
+ IOMUX_PAD(0x055C, 0x018C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA10__EPDC_SDDO_1 \
+ IOMUX_PAD(0x055C, 0x018C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA11__WEIM_WEIM_DA_A_11 \
+ IOMUX_PAD(0x0560, 0x0190, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA11__IPU1_DI1_PIN2 \
+ IOMUX_PAD(0x0560, 0x0190, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA11__IPU1_CSI1_HSYNC \
+ IOMUX_PAD(0x0560, 0x0190, 2, 0x08B4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA11__MIPI_CORE_DPHY_TEST_OUT_13 \
+ IOMUX_PAD(0x0560, 0x0190, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA11__SDMA_DEBUG_EVT_CHN_LINES_6 \
+ IOMUX_PAD(0x0560, 0x0190, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA11__GPIO_3_11 \
+ IOMUX_PAD(0x0560, 0x0190, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA11__TPSMP_HDATA_25 \
+ IOMUX_PAD(0x0560, 0x0190, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA11__SRC_BT_CFG_11 \
+ IOMUX_PAD(0x0560, 0x0190, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA11__EPDC_SDDO_3 \
+ IOMUX_PAD(0x0560, 0x0190, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA12__WEIM_WEIM_DA_A_12 \
+ IOMUX_PAD(0x0564, 0x0194, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA12__IPU1_DI1_PIN3 \
+ IOMUX_PAD(0x0564, 0x0194, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA12__IPU1_CSI1_VSYNC \
+ IOMUX_PAD(0x0564, 0x0194, 2, 0x08BC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA12__MIPI_CORE_DPHY_TEST_OUT_14 \
+ IOMUX_PAD(0x0564, 0x0194, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA12__SDMA_DEBUG_EVT_CHN_LINES_3 \
+ IOMUX_PAD(0x0564, 0x0194, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA12__GPIO_3_12 \
+ IOMUX_PAD(0x0564, 0x0194, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA12__TPSMP_HDATA_26 \
+ IOMUX_PAD(0x0564, 0x0194, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA12__SRC_BT_CFG_12 \
+ IOMUX_PAD(0x0564, 0x0194, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA12__EPDC_SDDO_2 \
+ IOMUX_PAD(0x0564, 0x0194, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA13__WEIM_WEIM_DA_A_13 \
+ IOMUX_PAD(0x0568, 0x0198, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA13__IPU1_DI1_D0_CS \
+ IOMUX_PAD(0x0568, 0x0198, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA13__CCM_DI1_EXT_CLK \
+ IOMUX_PAD(0x0568, 0x0198, 2, 0x07D0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA13__MIPI_CORE_DPHY_TEST_OUT_15 \
+ IOMUX_PAD(0x0568, 0x0198, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA13__SDMA_DEBUG_EVT_CHN_LINES_4 \
+ IOMUX_PAD(0x0568, 0x0198, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA13__GPIO_3_13 \
+ IOMUX_PAD(0x0568, 0x0198, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA13__TPSMP_HDATA_27 \
+ IOMUX_PAD(0x0568, 0x0198, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA13__SRC_BT_CFG_13 \
+ IOMUX_PAD(0x0568, 0x0198, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA13__EPDC_SDDO_13 \
+ IOMUX_PAD(0x0568, 0x0198, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA14__WEIM_WEIM_DA_A_14 \
+ IOMUX_PAD(0x056C, 0x019C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA14__IPU1_DI1_D1_CS \
+ IOMUX_PAD(0x056C, 0x019C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA14__CCM_DI0_EXT_CLK \
+ IOMUX_PAD(0x056C, 0x019C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA14__MIPI_CORE_DPHY_TEST_OUT_16 \
+ IOMUX_PAD(0x056C, 0x019C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA14__SDMA_DEBUG_EVT_CHN_LINES_5 \
+ IOMUX_PAD(0x056C, 0x019C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA14__GPIO_3_14 \
+ IOMUX_PAD(0x056C, 0x019C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA14__TPSMP_HDATA_28 \
+ IOMUX_PAD(0x056C, 0x019C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA14__SRC_BT_CFG_14 \
+ IOMUX_PAD(0x056C, 0x019C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA14__EPDC_SDDO_14 \
+ IOMUX_PAD(0x056C, 0x019C, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA15__WEIM_WEIM_DA_A_15 \
+ IOMUX_PAD(0x0570, 0x01A0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA15__IPU1_DI1_PIN1 \
+ IOMUX_PAD(0x0570, 0x01A0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA15__IPU1_DI1_PIN4 \
+ IOMUX_PAD(0x0570, 0x01A0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA15__MIPI_CORE_DPHY_TEST_OUT_17 \
+ IOMUX_PAD(0x0570, 0x01A0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA15__GPIO_3_15 \
+ IOMUX_PAD(0x0570, 0x01A0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA15__TPSMP_HDATA_29 \
+ IOMUX_PAD(0x0570, 0x01A0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA15__SRC_BT_CFG_15 \
+ IOMUX_PAD(0x0570, 0x01A0, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA15__EPDC_SDDO_9 \
+ IOMUX_PAD(0x0570, 0x01A0, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA2__WEIM_WEIM_DA_A_2 \
+ IOMUX_PAD(0x0574, 0x01A4, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA2__IPU1_DISP1_DAT_7 \
+ IOMUX_PAD(0x0574, 0x01A4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA2__IPU1_CSI1_D_7 \
+ IOMUX_PAD(0x0574, 0x01A4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA2__MIPI_CORE_DPHY_TEST_OUT_4 \
+ IOMUX_PAD(0x0574, 0x01A4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA2__ANATOP_USBPHY1_TSTI_TX_HS_MODE \
+ IOMUX_PAD(0x0574, 0x01A4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA2__GPIO_3_2 \
+ IOMUX_PAD(0x0574, 0x01A4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA2__TPSMP_HDATA_16 \
+ IOMUX_PAD(0x0574, 0x01A4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA2__SRC_BT_CFG_2 \
+ IOMUX_PAD(0x0574, 0x01A4, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA2__EPDC_BDR_0 \
+ IOMUX_PAD(0x0574, 0x01A4, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA3__WEIM_WEIM_DA_A_3 \
+ IOMUX_PAD(0x0578, 0x01A8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA3__IPU1_DISP1_DAT_6 \
+ IOMUX_PAD(0x0578, 0x01A8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA3__IPU1_CSI1_D_6 \
+ IOMUX_PAD(0x0578, 0x01A8, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA3__MIPI_CORE_DPHY_TEST_OUT_5 \
+ IOMUX_PAD(0x0578, 0x01A8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA3__ANATOP_USBPHY1_TSTI_TX_HIZ \
+ IOMUX_PAD(0x0578, 0x01A8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA3__GPIO_3_3 \
+ IOMUX_PAD(0x0578, 0x01A8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA3__TPSMP_HDATA_17 \
+ IOMUX_PAD(0x0578, 0x01A8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA3__SRC_BT_CFG_3 \
+ IOMUX_PAD(0x0578, 0x01A8, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA3__EPDC_BDR_1 \
+ IOMUX_PAD(0x0578, 0x01A8, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA4__WEIM_WEIM_DA_A_4 \
+ IOMUX_PAD(0x057C, 0x01AC, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA4__IPU1_DISP1_DAT_5 \
+ IOMUX_PAD(0x057C, 0x01AC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA4__IPU1_CSI1_D_5 \
+ IOMUX_PAD(0x057C, 0x01AC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA4__MIPI_CORE_DPHY_TEST_OUT_6 \
+ IOMUX_PAD(0x057C, 0x01AC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA4__ANATOP_USBPHY1_TSTI_TX_EN \
+ IOMUX_PAD(0x057C, 0x01AC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA4__GPIO_3_4 \
+ IOMUX_PAD(0x057C, 0x01AC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA4__TPSMP_HDATA_18 \
+ IOMUX_PAD(0x057C, 0x01AC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA4__SRC_BT_CFG_4 \
+ IOMUX_PAD(0x057C, 0x01AC, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA4__EPDC_SDCE_0 \
+ IOMUX_PAD(0x057C, 0x01AC, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA5__WEIM_WEIM_DA_A_5 \
+ IOMUX_PAD(0x0580, 0x01B0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA5__IPU1_DISP1_DAT_4 \
+ IOMUX_PAD(0x0580, 0x01B0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA5__IPU1_CSI1_D_4 \
+ IOMUX_PAD(0x0580, 0x01B0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA5__MIPI_CORE_DPHY_TEST_OUT_7 \
+ IOMUX_PAD(0x0580, 0x01B0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA5__ANATOP_USBPHY1_TSTI_TX_DP \
+ IOMUX_PAD(0x0580, 0x01B0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA5__GPIO_3_5 \
+ IOMUX_PAD(0x0580, 0x01B0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA5__TPSMP_HDATA_19 \
+ IOMUX_PAD(0x0580, 0x01B0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA5__SRC_BT_CFG_5 \
+ IOMUX_PAD(0x0580, 0x01B0, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA5__EPDC_SDCE_1 \
+ IOMUX_PAD(0x0580, 0x01B0, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA6__WEIM_WEIM_DA_A_6 \
+ IOMUX_PAD(0x0584, 0x01B4, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA6__IPU1_DISP1_DAT_3 \
+ IOMUX_PAD(0x0584, 0x01B4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA6__IPU1_CSI1_D_3 \
+ IOMUX_PAD(0x0584, 0x01B4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA6__MIPI_CORE_DPHY_TEST_OUT_8 \
+ IOMUX_PAD(0x0584, 0x01B4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA6__ANATOP_USBPHY1_TSTI_TX_DN \
+ IOMUX_PAD(0x0584, 0x01B4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA6__GPIO_3_6 \
+ IOMUX_PAD(0x0584, 0x01B4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA6__TPSMP_HDATA_20 \
+ IOMUX_PAD(0x0584, 0x01B4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA6__SRC_BT_CFG_6 \
+ IOMUX_PAD(0x0584, 0x01B4, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA6__EPDC_SDCE_2 \
+ IOMUX_PAD(0x0584, 0x01B4, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA7__WEIM_WEIM_DA_A_7 \
+ IOMUX_PAD(0x0588, 0x01B8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA7__IPU1_DISP1_DAT_2 \
+ IOMUX_PAD(0x0588, 0x01B8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA7__IPU1_CSI1_D_2 \
+ IOMUX_PAD(0x0588, 0x01B8, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA7__MIPI_CORE_DPHY_TEST_OUT_9 \
+ IOMUX_PAD(0x0588, 0x01B8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA7__GPIO_3_7 \
+ IOMUX_PAD(0x0588, 0x01B8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA7__TPSMP_HDATA_21 \
+ IOMUX_PAD(0x0588, 0x01B8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA7__SRC_BT_CFG_7 \
+ IOMUX_PAD(0x0588, 0x01B8, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA7__EPDC_SDCE_3 \
+ IOMUX_PAD(0x0588, 0x01B8, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA8__WEIM_WEIM_DA_A_8 \
+ IOMUX_PAD(0x058C, 0x01BC, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA8__IPU1_DISP1_DAT_1 \
+ IOMUX_PAD(0x058C, 0x01BC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA8__IPU1_CSI1_D_1 \
+ IOMUX_PAD(0x058C, 0x01BC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA8__MIPI_CORE_DPHY_TEST_OUT_10 \
+ IOMUX_PAD(0x058C, 0x01BC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA8__GPIO_3_8 \
+ IOMUX_PAD(0x058C, 0x01BC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA8__TPSMP_HDATA_22 \
+ IOMUX_PAD(0x058C, 0x01BC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA8__SRC_BT_CFG_8 \
+ IOMUX_PAD(0x058C, 0x01BC, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA8__EPDC_SDCE_4 \
+ IOMUX_PAD(0x058C, 0x01BC, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_DA9__WEIM_WEIM_DA_A_9 \
+ IOMUX_PAD(0x0590, 0x01C0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA9__IPU1_DISP1_DAT_0 \
+ IOMUX_PAD(0x0590, 0x01C0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA9__IPU1_CSI1_D_0 \
+ IOMUX_PAD(0x0590, 0x01C0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA9__MIPI_CORE_DPHY_TEST_OUT_11 \
+ IOMUX_PAD(0x0590, 0x01C0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA9__GPIO_3_9 \
+ IOMUX_PAD(0x0590, 0x01C0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA9__TPSMP_HDATA_23 \
+ IOMUX_PAD(0x0590, 0x01C0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA9__SRC_BT_CFG_9 \
+ IOMUX_PAD(0x0590, 0x01C0, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_DA9__EPDC_SDCE_5 \
+ IOMUX_PAD(0x0590, 0x01C0, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_EB0__WEIM_WEIM_EB_0 \
+ IOMUX_PAD(0x0594, 0x01C4, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB0__IPU1_DISP1_DAT_11 \
+ IOMUX_PAD(0x0594, 0x01C4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB0__IPU1_CSI1_D_11 \
+ IOMUX_PAD(0x0594, 0x01C4, 2, 0x088C, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB0__MIPI_CORE_DPHY_TEST_OUT_0 \
+ IOMUX_PAD(0x0594, 0x01C4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB0__CCM_PMIC_RDY \
+ IOMUX_PAD(0x0594, 0x01C4, 4, 0x07D4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB0__GPIO_2_28 \
+ IOMUX_PAD(0x0594, 0x01C4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB0__TPSMP_HDATA_12 \
+ IOMUX_PAD(0x0594, 0x01C4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB0__SRC_BT_CFG_27 \
+ IOMUX_PAD(0x0594, 0x01C4, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB0__EPDC_PWRCOM \
+ IOMUX_PAD(0x0594, 0x01C4, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_EB1__WEIM_WEIM_EB_1 \
+ IOMUX_PAD(0x0598, 0x01C8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB1__IPU1_DISP1_DAT_10 \
+ IOMUX_PAD(0x0598, 0x01C8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB1__IPU1_CSI1_D_10 \
+ IOMUX_PAD(0x0598, 0x01C8, 2, 0x0888, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB1__MIPI_CORE_DPHY_TEST_OUT_1 \
+ IOMUX_PAD(0x0598, 0x01C8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB1__GPIO_2_29 \
+ IOMUX_PAD(0x0598, 0x01C8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB1__TPSMP_HDATA_13 \
+ IOMUX_PAD(0x0598, 0x01C8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB1__SRC_BT_CFG_28 \
+ IOMUX_PAD(0x0598, 0x01C8, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB1__EPDC_SDSHR \
+ IOMUX_PAD(0x0598, 0x01C8, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_EB2__WEIM_WEIM_EB_2 \
+ IOMUX_PAD(0x059C, 0x01CC, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB2__ECSPI1_SS0 \
+ IOMUX_PAD(0x059C, 0x01CC, 1, 0x07E4, 2, MX6DL_ECSPI_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB2__CCM_DI1_EXT_CLK \
+ IOMUX_PAD(0x059C, 0x01CC, 2, 0x07D0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB2__IPU1_CSI1_D_19 \
+ IOMUX_PAD(0x059C, 0x01CC, 3, 0x08AC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB2__HDMI_TX_DDC_SCL \
+ IOMUX_PAD(0x059C, 0x01CC, 4, 0x0860, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB2__GPIO_2_30 \
+ IOMUX_PAD(0x059C, 0x01CC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB2__I2C2_SCL \
+ IOMUX_PAD(0x059C, 0x01CC, 6 | IOMUX_CONFIG_SION, 0x0870, 0, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB2__SRC_BT_CFG_30 \
+ IOMUX_PAD(0x059C, 0x01CC, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB2__EPDC_SDDO_5 \
+ IOMUX_PAD(0x059C, 0x01CC, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_EB3__WEIM_WEIM_EB_3 \
+ IOMUX_PAD(0x05A0, 0x01D0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__ECSPI4_RDY \
+ IOMUX_PAD(0x05A0, 0x01D0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__UART3_CTS \
+ IOMUX_PAD(0x05A0, 0x01D0, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__UART3_RTS \
+ IOMUX_PAD(0x05A0, 0x01D0, 2, 0x0908, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__UART1_RI \
+ IOMUX_PAD(0x05A0, 0x01D0, 3, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__IPU1_CSI1_HSYNC \
+ IOMUX_PAD(0x05A0, 0x01D0, 4, 0x08B4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__GPIO_2_31 \
+ IOMUX_PAD(0x05A0, 0x01D0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__IPU1_DI1_PIN3 \
+ IOMUX_PAD(0x05A0, 0x01D0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__SRC_BT_CFG_31 \
+ IOMUX_PAD(0x05A0, 0x01D0, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__EPDC_SDCE_0 \
+ IOMUX_PAD(0x05A0, 0x01D0, 8, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_EB3__WEIM_ACLK_FREERUN \
+ IOMUX_PAD(0x05A0, 0x01D0, 9, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_LBA__WEIM_WEIM_LBA \
+ IOMUX_PAD(0x05A4, 0x01D4, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_LBA__IPU1_DI1_PIN17 \
+ IOMUX_PAD(0x05A4, 0x01D4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_LBA__ECSPI2_SS1 \
+ IOMUX_PAD(0x05A4, 0x01D4, 2, 0x0804, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_LBA__GPIO_2_27 \
+ IOMUX_PAD(0x05A4, 0x01D4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_LBA__TPSMP_HDATA_11 \
+ IOMUX_PAD(0x05A4, 0x01D4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_LBA__SRC_BT_CFG_26 \
+ IOMUX_PAD(0x05A4, 0x01D4, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_LBA__EPDC_SDDO_4 \
+ IOMUX_PAD(0x05A4, 0x01D4, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_OE__WEIM_WEIM_OE \
+ IOMUX_PAD(0x05A8, 0x01D8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_OE__IPU1_DI1_PIN7 \
+ IOMUX_PAD(0x05A8, 0x01D8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_OE__ECSPI2_MISO \
+ IOMUX_PAD(0x05A8, 0x01D8, 2, 0x07F8, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_OE__MIPI_CORE_DPHY_TEST_OUT_26 \
+ IOMUX_PAD(0x05A8, 0x01D8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_OE__GPIO_2_25 \
+ IOMUX_PAD(0x05A8, 0x01D8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_OE__TPSMP_HDATA_9 \
+ IOMUX_PAD(0x05A8, 0x01D8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_OE__EPDC_PWRIRQ \
+ IOMUX_PAD(0x05A8, 0x01D8, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_RW__WEIM_WEIM_RW \
+ IOMUX_PAD(0x05AC, 0x01DC, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_RW__IPU1_DI1_PIN8 \
+ IOMUX_PAD(0x05AC, 0x01DC, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_RW__ECSPI2_SS0 \
+ IOMUX_PAD(0x05AC, 0x01DC, 2, 0x0800, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_RW__MIPI_CORE_DPHY_TEST_OUT_27 \
+ IOMUX_PAD(0x05AC, 0x01DC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_RW__GPIO_2_26 \
+ IOMUX_PAD(0x05AC, 0x01DC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_RW__TPSMP_HDATA_10 \
+ IOMUX_PAD(0x05AC, 0x01DC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_RW__SRC_BT_CFG_29 \
+ IOMUX_PAD(0x05AC, 0x01DC, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_RW__EPDC_SDDO_7 \
+ IOMUX_PAD(0x05AC, 0x01DC, 8, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_EIM_WAIT__WEIM_WEIM_WAIT \
+ IOMUX_PAD(0x05B0, 0x01E0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_WAIT__WEIM_WEIM_DTACK_B \
+ IOMUX_PAD(0x05B0, 0x01E0, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_WAIT__GPIO_5_0 \
+ IOMUX_PAD(0x05B0, 0x01E0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_WAIT__TPSMP_HDATA_30 \
+ IOMUX_PAD(0x05B0, 0x01E0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_EIM_WAIT__SRC_BT_CFG_25 \
+ IOMUX_PAD(0x05B0, 0x01E0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_CRS_DV__ENET_RX_EN \
+ IOMUX_PAD(0x05B4, 0x01E4, 1, 0x0828, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_CRS_DV__ESAI1_SCKT \
+ IOMUX_PAD(0x05B4, 0x01E4, 2, 0x0840, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_ENET_CRS_DV__SPDIF_SPDIF_EXTCLK \
+ IOMUX_PAD(0x05B4, 0x01E4, 3, 0x08F4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_CRS_DV__GPIO_1_25 \
+ IOMUX_PAD(0x05B4, 0x01E4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_CRS_DV__PHY_TDO \
+ IOMUX_PAD(0x05B4, 0x01E4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_CRS_DV__ANATOP_USBPHY1_TSTO_RX_FS_RXD \
+ IOMUX_PAD(0x05B4, 0x01E4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_MDC__MLB_MLBDAT \
+ IOMUX_PAD(0x05B8, 0x01E8, 0, 0x08E0, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDC__ENET_MDC \
+ IOMUX_PAD(0x05B8, 0x01E8, 1, 0x0000, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDC__ESAI1_TX5_RX0 \
+ IOMUX_PAD(0x05B8, 0x01E8, 2, 0x0858, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDC__ENET_1588_EVENT1_IN \
+ IOMUX_PAD(0x05B8, 0x01E8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDC__GPIO_1_31 \
+ IOMUX_PAD(0x05B8, 0x01E8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDC__ANATOP_USBPHY2_TSTO_RX_DISCON_DET \
+ IOMUX_PAD(0x05B8, 0x01E8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_MDIO__ENET_MDIO \
+ IOMUX_PAD(0x05BC, 0x01EC, 1, 0x0810, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDIO__ESAI1_SCKR \
+ IOMUX_PAD(0x05BC, 0x01EC, 2, 0x083C, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDIO__SDMA_DEBUG_BUS_DEVICE_3 \
+ IOMUX_PAD(0x05BC, 0x01EC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDIO__ENET_1588_EVENT1_OUT \
+ IOMUX_PAD(0x05BC, 0x01EC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDIO__GPIO_1_22 \
+ IOMUX_PAD(0x05BC, 0x01EC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_MDIO__SPDIF_PLOCK \
+ IOMUX_PAD(0x05BC, 0x01EC, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_REF_CLK__ENET_TX_CLK \
+ IOMUX_PAD(0x05C0, 0x01F0, 1, 0x0000, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_ENET_REF_CLK__ESAI1_FSR \
+ IOMUX_PAD(0x05C0, 0x01F0, 2, 0x082C, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_REF_CLK__SDMA_DEBUG_BUS_DEVICE_4 \
+ IOMUX_PAD(0x05C0, 0x01F0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_REF_CLK__GPIO_1_23 \
+ IOMUX_PAD(0x05C0, 0x01F0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_REF_CLK__SPDIF_SRCLK \
+ IOMUX_PAD(0x05C0, 0x01F0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_REF_CLK__ANATOP_USBPHY1_TSTO_RX_SQUELCH \
+ IOMUX_PAD(0x05C0, 0x01F0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_RX_ER__ANATOP_USBOTG_ID \
+ IOMUX_PAD(0x05C4, 0x01F4, 0, 0x0790, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RX_ER__ENET_RX_ER \
+ IOMUX_PAD(0x05C4, 0x01F4, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RX_ER__ESAI1_HCKR \
+ IOMUX_PAD(0x05C4, 0x01F4, 2, 0x0834, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_ENET_RX_ER__SPDIF_IN1 \
+ IOMUX_PAD(0x05C4, 0x01F4, 3, 0x08F0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RX_ER__ENET_1588_EVENT2_OUT \
+ IOMUX_PAD(0x05C4, 0x01F4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RX_ER__GPIO_1_24 \
+ IOMUX_PAD(0x05C4, 0x01F4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RX_ER__PHY_TDI \
+ IOMUX_PAD(0x05C4, 0x01F4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RX_ER__ANATOP_USBPHY1_TSTO_RX_HS_RXD \
+ IOMUX_PAD(0x05C4, 0x01F4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_RXD0__OSC32K_32K_OUT \
+ IOMUX_PAD(0x05C8, 0x01F8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD0__ENET_RDATA_0 \
+ IOMUX_PAD(0x05C8, 0x01F8, 1, 0x0818, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD0__ESAI1_HCKT \
+ IOMUX_PAD(0x05C8, 0x01F8, 2, 0x0838, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD0__SPDIF_OUT1 \
+ IOMUX_PAD(0x05C8, 0x01F8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD0__GPIO_1_27 \
+ IOMUX_PAD(0x05C8, 0x01F8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD0__PHY_TMS \
+ IOMUX_PAD(0x05C8, 0x01F8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD0__ANATOP_USBPHY1_TSTO_PLL_CLK20DIV \
+ IOMUX_PAD(0x05C8, 0x01F8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_RXD1__MLB_MLBSIG \
+ IOMUX_PAD(0x05CC, 0x01FC, 0, 0x08E4, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD1__ENET_RDATA_1 \
+ IOMUX_PAD(0x05CC, 0x01FC, 1, 0x081C, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD1__ESAI1_FST \
+ IOMUX_PAD(0x05CC, 0x01FC, 2, 0x0830, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD1__ENET_1588_EVENT3_OUT \
+ IOMUX_PAD(0x05CC, 0x01FC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD1__GPIO_1_26 \
+ IOMUX_PAD(0x05CC, 0x01FC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD1__PHY_TCK \
+ IOMUX_PAD(0x05CC, 0x01FC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_RXD1__ANATOP_USBPHY1_TSTO_RX_DISCON_DET \
+ IOMUX_PAD(0x05CC, 0x01FC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_TX_EN__ENET_TX_EN \
+ IOMUX_PAD(0x05D0, 0x0200, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TX_EN__ESAI1_TX3_RX2 \
+ IOMUX_PAD(0x05D0, 0x0200, 2, 0x0850, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_ENET_TX_EN__GPIO_1_28 \
+ IOMUX_PAD(0x05D0, 0x0200, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TX_EN__ANATOP_USBPHY2_TSTO_RX_SQUELCH \
+ IOMUX_PAD(0x05D0, 0x0200, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TX_EN__I2C4_SCL \
+ IOMUX_PAD(0x05D0, 0x0200, 9 | IOMUX_CONFIG_SION, 0x0880, 0, MX6DL_I2C_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_TXD0__ENET_TDATA_0 \
+ IOMUX_PAD(0x05D4, 0x0204, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD0__ESAI1_TX4_RX1 \
+ IOMUX_PAD(0x05D4, 0x0204, 2, 0x0854, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD0__GPIO_1_30 \
+ IOMUX_PAD(0x05D4, 0x0204, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD0__ANATOP_USBPHY2_TSTO_RX_FS_RXD \
+ IOMUX_PAD(0x05D4, 0x0204, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_ENET_TXD1__MLB_MLBCLK \
+ IOMUX_PAD(0x05D8, 0x0208, 0, 0x08DC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD1__ENET_TDATA_1 \
+ IOMUX_PAD(0x05D8, 0x0208, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD1__ESAI1_TX2_RX3 \
+ IOMUX_PAD(0x05D8, 0x0208, 2, 0x084C, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD1__ENET_1588_EVENT0_IN \
+ IOMUX_PAD(0x05D8, 0x0208, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD1__GPIO_1_29 \
+ IOMUX_PAD(0x05D8, 0x0208, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD1__ANATOP_USBPHY2_TSTO_RX_HS_RXD \
+ IOMUX_PAD(0x05D8, 0x0208, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_ENET_TXD1__I2C4_SDA \
+ IOMUX_PAD(0x05D8, 0x0208, 9 | IOMUX_CONFIG_SION, 0x0884, 0, MX6DL_I2C_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_0__CCM_CLKO \
+ IOMUX_PAD(0x05DC, 0x020C, 0, 0x0000, 0, MX6DL_CCM_CLK0_PAD_CTRL)
+#define MX6DL_PAD_GPIO_0__KPP_COL_5 \
+ IOMUX_PAD(0x05DC, 0x020C, 2, 0x08C0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_0__ASRC_ASRC_EXT_CLK \
+ IOMUX_PAD(0x05DC, 0x020C, 3, 0x0794, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_0__EPIT1_EPITO \
+ IOMUX_PAD(0x05DC, 0x020C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_0__GPIO_1_0 \
+ IOMUX_PAD(0x05DC, 0x020C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_0__USBOH3_USBH1_PWR \
+ IOMUX_PAD(0x05DC, 0x020C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_0__SNVS_HP_WRAPPER_SNVS_VIO_5 \
+ IOMUX_PAD(0x05DC, 0x020C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_1__ESAI1_SCKR \
+ IOMUX_PAD(0x05E0, 0x0210, 0, 0x083C, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_1__WDOG2_WDOG_B \
+ IOMUX_PAD(0x05E0, 0x0210, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_1__KPP_ROW_5 \
+ IOMUX_PAD(0x05E0, 0x0210, 2, 0x08CC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_1__USBOTG_ID \
+ IOMUX_PAD(0x05E0, 0x0210, 3, 0x0790, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_1__PWM2_PWMO \
+ IOMUX_PAD(0x05E0, 0x0210, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_1__GPIO_1_1 \
+ IOMUX_PAD(0x05E0, 0x0210, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_1__USDHC1_CD \
+ IOMUX_PAD(0x05E0, 0x0210, 6, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_GPIO_1__SRC_TESTER_ACK \
+ IOMUX_PAD(0x05E0, 0x0210, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_16__ESAI1_TX3_RX2 \
+ IOMUX_PAD(0x05E4, 0x0214, 0, 0x0850, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_16__ENET_1588_EVENT2_IN \
+ IOMUX_PAD(0x05E4, 0x0214, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT \
+ IOMUX_PAD(0x05E4, 0x0214, 0x12, 0x080C, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_16__USDHC1_LCTL \
+ IOMUX_PAD(0x05E4, 0x0214, 3, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_GPIO_16__SPDIF_IN1 \
+ IOMUX_PAD(0x05E4, 0x0214, 4, 0x08F0, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_16__GPIO_7_11 \
+ IOMUX_PAD(0x05E4, 0x0214, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_16__I2C3_SDA \
+ IOMUX_PAD(0x05E4, 0x0214, 6 | IOMUX_CONFIG_SION, 0x087C, 1, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_GPIO_16__SJC_DE_B \
+ IOMUX_PAD(0x05E4, 0x0214, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_17__ESAI1_TX0 \
+ IOMUX_PAD(0x05E8, 0x0218, 0, 0x0844, 0, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_GPIO_17__ENET_1588_EVENT3_IN \
+ IOMUX_PAD(0x05E8, 0x0218, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_17__CCM_PMIC_RDY \
+ IOMUX_PAD(0x05E8, 0x0218, 2, 0x07D4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_17__SDMA_SDMA_EXT_EVENT_0 \
+ IOMUX_PAD(0x05E8, 0x0218, 3, 0x08E8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_17__SPDIF_OUT1 \
+ IOMUX_PAD(0x05E8, 0x0218, 4, 0x0000, 0, MX6DL_SPDIF_OUT_PAD_CTRL)
+#define MX6DL_PAD_GPIO_17__GPIO_7_12 \
+ IOMUX_PAD(0x05E8, 0x0218, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_17__SJC_JTAG_ACT \
+ IOMUX_PAD(0x05E8, 0x0218, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_18__ESAI1_TX1 \
+ IOMUX_PAD(0x05EC, 0x021C, 0, 0x0848, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_18__ENET_RX_CLK \
+ IOMUX_PAD(0x05EC, 0x021C, 1, 0x0814, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_18__USDHC3_VSELECT \
+ IOMUX_PAD(0x05EC, 0x021C, 2, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_GPIO_18__SDMA_SDMA_EXT_EVENT_1 \
+ IOMUX_PAD(0x05EC, 0x021C, 3, 0x08EC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_18__ASRC_ASRC_EXT_CLK \
+ IOMUX_PAD(0x05EC, 0x021C, 4, 0x0794, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_18__GPIO_7_13 \
+ IOMUX_PAD(0x05EC, 0x021C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_18__SNVS_HP_WRAPPER_SNVS_VIO_5_CTL \
+ IOMUX_PAD(0x05EC, 0x021C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_18__SRC_SYSTEM_RST \
+ IOMUX_PAD(0x05EC, 0x021C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_19__KPP_COL_5 \
+ IOMUX_PAD(0x05F0, 0x0220, 0, 0x08C0, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_19__ENET_1588_EVENT0_OUT \
+ IOMUX_PAD(0x05F0, 0x0220, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_19__SPDIF_OUT1 \
+ IOMUX_PAD(0x05F0, 0x0220, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_19__CCM_CLKO \
+ IOMUX_PAD(0x05F0, 0x0220, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_19__ECSPI1_RDY \
+ IOMUX_PAD(0x05F0, 0x0220, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_19__GPIO_4_5 \
+ IOMUX_PAD(0x05F0, 0x0220, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_19__ENET_TX_ER \
+ IOMUX_PAD(0x05F0, 0x0220, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_19__SRC_INT_BOOT \
+ IOMUX_PAD(0x05F0, 0x0220, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_2__ESAI1_FST \
+ IOMUX_PAD(0x05F4, 0x0224, 0, 0x0830, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_2__OBSERVE_MUX_OBSRV_INT_OUT2 \
+ IOMUX_PAD(0x05F4, 0x0224, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_2__KPP_ROW_6 \
+ IOMUX_PAD(0x05F4, 0x0224, 2, 0x08D0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_2__CCM_CCM_OUT_1 \
+ IOMUX_PAD(0x05F4, 0x0224, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_2__CSU_CSU_ALARM_AUT_0 \
+ IOMUX_PAD(0x05F4, 0x0224, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_2__GPIO_1_2 \
+ IOMUX_PAD(0x05F4, 0x0224, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_2__USDHC2_WP \
+ IOMUX_PAD(0x05F4, 0x0224, 6, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_GPIO_2__MLB_MLBDAT \
+ IOMUX_PAD(0x05F4, 0x0224, 7, 0x08E0, 1, MX6DL_MLB150_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_3__ESAI1_HCKR \
+ IOMUX_PAD(0x05F8, 0x0228, 0, 0x0834, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_3__OBSERVE_MUX_OBSRV_INT_OUT0 \
+ IOMUX_PAD(0x05F8, 0x0228, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_3__I2C3_SCL \
+ IOMUX_PAD(0x05F8, 0x0228, 2 | IOMUX_CONFIG_SION, 0x0878, 1, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_GPIO_3__ANATOP_ANATOP_24M_OUT \
+ IOMUX_PAD(0x05F8, 0x0228, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_3__CCM_CLKO2 \
+ IOMUX_PAD(0x05F8, 0x0228, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_3__GPIO_1_3 \
+ IOMUX_PAD(0x05F8, 0x0228, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_3__USBOH3_USBH1_OC \
+ IOMUX_PAD(0x05F8, 0x0228, 6, 0x0924, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_3__MLB_MLBCLK \
+ IOMUX_PAD(0x05F8, 0x0228, 7, 0x08DC, 1, MX6DL_MLB150_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_4__ESAI1_HCKT \
+ IOMUX_PAD(0x05FC, 0x022C, 0, 0x0838, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_4__OBSERVE_MUX_OBSRV_INT_OUT3 \
+ IOMUX_PAD(0x05FC, 0x022C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_4__KPP_COL_7 \
+ IOMUX_PAD(0x05FC, 0x022C, 2, 0x08C8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_4__CCM_CCM_OUT_2 \
+ IOMUX_PAD(0x05FC, 0x022C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_4__CSU_CSU_ALARM_AUT_1 \
+ IOMUX_PAD(0x05FC, 0x022C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_4__GPIO_1_4 \
+ IOMUX_PAD(0x05FC, 0x022C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_4__USDHC2_CD \
+ IOMUX_PAD(0x05FC, 0x022C, 6, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_GPIO_4__OCOTP_CTRL_WRAPPER_FUSE_LATCHED \
+ IOMUX_PAD(0x05FC, 0x022C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_5__ESAI1_TX2_RX3 \
+ IOMUX_PAD(0x0600, 0x0230, 0, 0x084C, 1, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_GPIO_5__OBSERVE_MUX_OBSRV_INT_OUT4 \
+ IOMUX_PAD(0x0600, 0x0230, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_5__KPP_ROW_7 \
+ IOMUX_PAD(0x0600, 0x0230, 2, 0x08D4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_5__CCM_CLKO \
+ IOMUX_PAD(0x0600, 0x0230, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_5__CSU_CSU_ALARM_AUT_2 \
+ IOMUX_PAD(0x0600, 0x0230, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_5__GPIO_1_5 \
+ IOMUX_PAD(0x0600, 0x0230, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_5__I2C3_SCL \
+ IOMUX_PAD(0x0600, 0x0230, 6 | IOMUX_CONFIG_SION, 0x0878, 2, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_GPIO_5__SIMBA_EVENTI \
+ IOMUX_PAD(0x0600, 0x0230, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_6__ESAI1_SCKT \
+ IOMUX_PAD(0x0604, 0x0234, 0, 0x0840, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_6__OBSERVE_MUX_OBSRV_INT_OUT1 \
+ IOMUX_PAD(0x0604, 0x0234, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_6__I2C3_SDA \
+ IOMUX_PAD(0x0604, 0x0234, 2 | IOMUX_CONFIG_SION, 0x087C, 2, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_GPIO_6__CCM_CCM_OUT_0 \
+ IOMUX_PAD(0x0604, 0x0234, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_6__CSU_CSU_INT_DEB \
+ IOMUX_PAD(0x0604, 0x0234, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_6__GPIO_1_6 \
+ IOMUX_PAD(0x0604, 0x0234, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_6__USDHC2_LCTL \
+ IOMUX_PAD(0x0604, 0x0234, 6, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_GPIO_6__MLB_MLBSIG \
+ IOMUX_PAD(0x0604, 0x0234, 7, 0x08E4, 1, MX6DL_MLB150_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_7__ESAI1_TX4_RX1 \
+ IOMUX_PAD(0x0608, 0x0238, 0, 0x0854, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_7__EPIT1_EPITO \
+ IOMUX_PAD(0x0608, 0x0238, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_7__CAN1_TXCAN \
+ IOMUX_PAD(0x0608, 0x0238, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_7__UART2_TXD \
+ IOMUX_PAD(0x0608, 0x0238, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_GPIO_7__UART2_RXD \
+ IOMUX_PAD(0x0608, 0x0238, 4, 0x0904, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_GPIO_7__GPIO_1_7 \
+ IOMUX_PAD(0x0608, 0x0238, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_7__SPDIF_PLOCK \
+ IOMUX_PAD(0x0608, 0x0238, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_7__USBOH3_OTGUSB_HOST_MODE \
+ IOMUX_PAD(0x0608, 0x0238, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_7__I2C4_SCL \
+ IOMUX_PAD(0x0608, 0x0238, 8 | IOMUX_CONFIG_SION, 0x0880, 1, MX6DL_I2C_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_8__ESAI1_TX5_RX0 \
+ IOMUX_PAD(0x060C, 0x023C, 0, 0x0858, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__ANATOP_ANATOP_32K_OUT \
+ IOMUX_PAD(0x060C, 0x023C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__EPIT2_EPITO \
+ IOMUX_PAD(0x060C, 0x023C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__CAN1_RXCAN \
+ IOMUX_PAD(0x060C, 0x023C, 3, 0x07C8, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__UART2_TXD \
+ IOMUX_PAD(0x060C, 0x023C, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__UART2_RXD \
+ IOMUX_PAD(0x060C, 0x023C, 4, 0x0904, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__GPIO_1_8 \
+ IOMUX_PAD(0x060C, 0x023C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__SPDIF_SRCLK \
+ IOMUX_PAD(0x060C, 0x023C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__USBOH3_OTGUSB_PWRCTL_WAKEUP \
+ IOMUX_PAD(0x060C, 0x023C, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_8__I2C4_SDA \
+ IOMUX_PAD(0x060C, 0x023C, 8 | IOMUX_CONFIG_SION, 0x0884, 1, MX6DL_I2C_PAD_CTRL)
+
+#define MX6DL_PAD_GPIO_9__ESAI1_FSR \
+ IOMUX_PAD(0x0610, 0x0240, 0, 0x082C, 1, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_GPIO_9__WDOG1_WDOG_B \
+ IOMUX_PAD(0x0610, 0x0240, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_9__KPP_COL_6 \
+ IOMUX_PAD(0x0610, 0x0240, 2, 0x08C4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_9__CCM_REF_EN_B \
+ IOMUX_PAD(0x0610, 0x0240, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_9__PWM1_PWMO \
+ IOMUX_PAD(0x0610, 0x0240, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_9__GPIO_1_9 \
+ IOMUX_PAD(0x0610, 0x0240, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_GPIO_9__USDHC1_WP \
+ IOMUX_PAD(0x0610, 0x0240, 6, 0x092C, 1, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_GPIO_9__SRC_EARLY_RST \
+ IOMUX_PAD(0x0610, 0x0240, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_JTAG_MOD__SJC_MOD \
+ IOMUX_PAD(0x0614, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_JTAG_TCK__SJC_TCK \
+ IOMUX_PAD(0x0618, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_JTAG_TDI__SJC_TDI \
+ IOMUX_PAD(0x061C, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_JTAG_TDO__SJC_TDO \
+ IOMUX_PAD(0x0620, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_JTAG_TMS__SJC_TMS \
+ IOMUX_PAD(0x0624, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_JTAG_TRSTB__SJC_TRSTB \
+ IOMUX_PAD(0x0628, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_COL0__ECSPI1_SCLK \
+ IOMUX_PAD(0x062C, 0x0244, 0, 0x07D8, 3, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL0__ENET_RDATA_3 \
+ IOMUX_PAD(0x062C, 0x0244, 1, 0x0824, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL0__AUDMUX_AUD5_TXC \
+ IOMUX_PAD(0x062C, 0x0244, 2, 0x07C0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL0__KPP_COL_0 \
+ IOMUX_PAD(0x062C, 0x0244, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL0__UART4_TXD \
+ IOMUX_PAD(0x062C, 0x0244, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL0__UART4_RXD \
+ IOMUX_PAD(0x062C, 0x0244, 4, 0x0914, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL0__GPIO_4_6 \
+ IOMUX_PAD(0x062C, 0x0244, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL0__DCIC1_DCIC_OUT \
+ IOMUX_PAD(0x062C, 0x0244, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL0__SRC_ANY_PU_RST \
+ IOMUX_PAD(0x062C, 0x0244, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_COL1__ECSPI1_MISO \
+ IOMUX_PAD(0x0630, 0x0248, 0, 0x07DC, 3, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL1__ENET_MDIO \
+ IOMUX_PAD(0x0630, 0x0248, 1, 0x0810, 1, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL1__AUDMUX_AUD5_TXFS \
+ IOMUX_PAD(0x0630, 0x0248, 2, 0x07C4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL1__KPP_COL_1 \
+ IOMUX_PAD(0x0630, 0x0248, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL1__UART5_TXD \
+ IOMUX_PAD(0x0630, 0x0248, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL1__UART5_RXD \
+ IOMUX_PAD(0x0630, 0x0248, 4, 0x091C, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL1__GPIO_4_8 \
+ IOMUX_PAD(0x0630, 0x0248, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL1__USDHC1_VSELECT \
+ IOMUX_PAD(0x0630, 0x0248, 6, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL1__PL301_SIM_MX6DL_PER1_HADDR_1 \
+ IOMUX_PAD(0x0630, 0x0248, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_COL2__ECSPI1_SS1 \
+ IOMUX_PAD(0x0634, 0x024C, 0, 0x07E8, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL2__ENET_RDATA_2 \
+ IOMUX_PAD(0x0634, 0x024C, 1, 0x0820, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL2__CAN1_TXCAN \
+ IOMUX_PAD(0x0634, 0x024C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL2__KPP_COL_2 \
+ IOMUX_PAD(0x0634, 0x024C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL2__ENET_MDC \
+ IOMUX_PAD(0x0634, 0x024C, 4, 0x0000, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL2__GPIO_4_10 \
+ IOMUX_PAD(0x0634, 0x024C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL2__USBOH3_H1USB_PWRCTL_WAKEUP \
+ IOMUX_PAD(0x0634, 0x024C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL2__PL301_SIM_MX6DL_PER1_HADDR_3 \
+ IOMUX_PAD(0x0634, 0x024C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_COL3__ECSPI1_SS3 \
+ IOMUX_PAD(0x0638, 0x0250, 0, 0x07F0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL3__ENET_CRS \
+ IOMUX_PAD(0x0638, 0x0250, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL3__HDMI_TX_DDC_SCL \
+ IOMUX_PAD(0x0638, 0x0250, 2, 0x0860, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL3__KPP_COL_3 \
+ IOMUX_PAD(0x0638, 0x0250, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL3__I2C2_SCL \
+ IOMUX_PAD(0x0638, 0x0250, 4 | IOMUX_CONFIG_SION, 0x0870, 1, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL3__GPIO_4_12 \
+ IOMUX_PAD(0x0638, 0x0250, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL3__SPDIF_IN1 \
+ IOMUX_PAD(0x0638, 0x0250, 6, 0x08F0, 3, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL3__PL301_SIM_MX6DL_PER1_HADDR_5 \
+ IOMUX_PAD(0x0638, 0x0250, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_COL4__CAN2_TXCAN \
+ IOMUX_PAD(0x063C, 0x0254, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL4__IPU1_SISG_4 \
+ IOMUX_PAD(0x063C, 0x0254, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL4__USBOH3_USBOTG_OC \
+ IOMUX_PAD(0x063C, 0x0254, 2, 0x0920, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL4__KPP_COL_4 \
+ IOMUX_PAD(0x063C, 0x0254, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL4__UART5_CTS \
+ IOMUX_PAD(0x063C, 0x0254, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL4__UART5_RTS \
+ IOMUX_PAD(0x063C, 0x0254, 4, 0x0918, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL4__GPIO_4_14 \
+ IOMUX_PAD(0x063C, 0x0254, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL4__MMDC_MMDC_DEBUG_49 \
+ IOMUX_PAD(0x063C, 0x0254, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_COL4__PL301_SIM_MX6DL_PER1_HADDR_7 \
+ IOMUX_PAD(0x063C, 0x0254, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_ROW0__ECSPI1_MOSI \
+ IOMUX_PAD(0x0640, 0x0258, 0, 0x07E0, 3, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW0__ENET_TDATA_3 \
+ IOMUX_PAD(0x0640, 0x0258, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW0__AUDMUX_AUD5_TXD \
+ IOMUX_PAD(0x0640, 0x0258, 2, 0x07B4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW0__KPP_ROW_0 \
+ IOMUX_PAD(0x0640, 0x0258, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW0__UART4_TXD \
+ IOMUX_PAD(0x0640, 0x0258, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW0__UART4_RXD \
+ IOMUX_PAD(0x0640, 0x0258, 4, 0x0914, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW0__GPIO_4_7 \
+ IOMUX_PAD(0x0640, 0x0258, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW0__DCIC2_DCIC_OUT \
+ IOMUX_PAD(0x0640, 0x0258, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW0__PL301_SIM_MX6DL_PER1_HADDR_0 \
+ IOMUX_PAD(0x0640, 0x0258, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_ROW1__ECSPI1_SS0 \
+ IOMUX_PAD(0x0644, 0x025C, 0, 0x07E4, 3, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW1__ENET_COL \
+ IOMUX_PAD(0x0644, 0x025C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW1__AUDMUX_AUD5_RXD \
+ IOMUX_PAD(0x0644, 0x025C, 2, 0x07B0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW1__KPP_ROW_1 \
+ IOMUX_PAD(0x0644, 0x025C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW1__UART5_TXD \
+ IOMUX_PAD(0x0644, 0x025C, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW1__UART5_RXD \
+ IOMUX_PAD(0x0644, 0x025C, 4, 0x091C, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW1__GPIO_4_9 \
+ IOMUX_PAD(0x0644, 0x025C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW1__USDHC2_VSELECT \
+ IOMUX_PAD(0x0644, 0x025C, 6, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW1__PL301_SIM_MX6DL_PER1_HADDR_2 \
+ IOMUX_PAD(0x0644, 0x025C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_ROW2__ECSPI1_SS2 \
+ IOMUX_PAD(0x0648, 0x0260, 0, 0x07EC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW2__ENET_TDATA_2 \
+ IOMUX_PAD(0x0648, 0x0260, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW2__CAN1_RXCAN \
+ IOMUX_PAD(0x0648, 0x0260, 2, 0x07C8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW2__KPP_ROW_2 \
+ IOMUX_PAD(0x0648, 0x0260, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW2__USDHC2_VSELECT \
+ IOMUX_PAD(0x0648, 0x0260, 4, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW2__GPIO_4_11 \
+ IOMUX_PAD(0x0648, 0x0260, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW2__HDMI_TX_CEC_LINE \
+ IOMUX_PAD(0x0648, 0x0260, 6, 0x085C, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW2__PL301_SIM_MX6DL_PER1_HADDR_4 \
+ IOMUX_PAD(0x0648, 0x0260, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_ROW3__OSC32K_32K_OUT \
+ IOMUX_PAD(0x064C, 0x0264, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW3__ASRC_ASRC_EXT_CLK \
+ IOMUX_PAD(0x064C, 0x0264, 1, 0x0794, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW3__HDMI_TX_DDC_SDA \
+ IOMUX_PAD(0x064C, 0x0264, 2, 0x0864, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW3__KPP_ROW_3 \
+ IOMUX_PAD(0x064C, 0x0264, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW3__I2C2_SDA \
+ IOMUX_PAD(0x064C, 0x0264, 4 | IOMUX_CONFIG_SION, 0x0874, 1, MX6DL_I2C_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW3__GPIO_4_13 \
+ IOMUX_PAD(0x064C, 0x0264, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW3__USDHC1_VSELECT \
+ IOMUX_PAD(0x064C, 0x0264, 6, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW3__PL301_SIM_MX6DL_PER1_HADDR_6 \
+ IOMUX_PAD(0x064C, 0x0264, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_KEY_ROW4__CAN2_RXCAN \
+ IOMUX_PAD(0x0650, 0x0268, 0, 0x07CC, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW4__IPU1_SISG_5 \
+ IOMUX_PAD(0x0650, 0x0268, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW4__USBOH3_USBOTG_PWR \
+ IOMUX_PAD(0x0650, 0x0268, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW4__KPP_ROW_4 \
+ IOMUX_PAD(0x0650, 0x0268, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW4__UART5_CTS \
+ IOMUX_PAD(0x0650, 0x0268, 4, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW4__UART5_RTS \
+ IOMUX_PAD(0x0650, 0x0268, 4, 0x0918, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW4__GPIO_4_15 \
+ IOMUX_PAD(0x0650, 0x0268, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW4__MMDC_MMDC_DEBUG_50 \
+ IOMUX_PAD(0x0650, 0x0268, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_KEY_ROW4__PL301_SIM_MX6DL_PER1_HADDR_8 \
+ IOMUX_PAD(0x0650, 0x0268, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS0_CLK_P__LDB_LVDS0_CLK \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS0_TX0_P__LDB_LVDS0_TX0 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS0_TX1_P__LDB_LVDS0_TX1 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS0_TX2_P__LDB_LVDS0_TX2 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS0_TX3_P__LDB_LVDS0_TX3 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS1_CLK_P__LDB_LVDS1_CLK \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS1_TX0_P__LDB_LVDS1_TX0 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS1_TX1_P__LDB_LVDS1_TX1 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS1_TX2_P__LDB_LVDS1_TX2 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_LVDS1_TX3_P__LDB_LVDS1_TX3 \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_ALE__RAWNAND_ALE \
+ IOMUX_PAD(0x0654, 0x026C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_ALE__USDHC4_RST \
+ IOMUX_PAD(0x0654, 0x026C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_ALE__PCIE_CTRL_DIAG_STATUS_BUS_MUX_0 \
+ IOMUX_PAD(0x0654, 0x026C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_ALE__USBOH3_UH3_DFD_OUT_12 \
+ IOMUX_PAD(0x0654, 0x026C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_ALE__USBOH3_UH2_DFD_OUT_12 \
+ IOMUX_PAD(0x0654, 0x026C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_ALE__GPIO_6_8 \
+ IOMUX_PAD(0x0654, 0x026C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_ALE__MIPI_CORE_DPHY_TEST_IN_24 \
+ IOMUX_PAD(0x0654, 0x026C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_ALE__USDHC3_CLKI \
+ IOMUX_PAD(0x0654, 0x026C, 8, 0x0934, 0, MX6DL_USDHC_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_CLE__RAWNAND_CLE \
+ IOMUX_PAD(0x0658, 0x0270, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_CLE__PCIE_CTRL_DIAG_STATUS_BUS_MUX_31 \
+ IOMUX_PAD(0x0658, 0x0270, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CLE__USBOH3_UH3_DFD_OUT_11 \
+ IOMUX_PAD(0x0658, 0x0270, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CLE__USBOH3_UH2_DFD_OUT_11 \
+ IOMUX_PAD(0x0658, 0x0270, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CLE__GPIO_6_7 \
+ IOMUX_PAD(0x0658, 0x0270, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CLE__MIPI_CORE_DPHY_TEST_IN_23 \
+ IOMUX_PAD(0x0658, 0x0270, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CLE__USDHC3_CLKO \
+ IOMUX_PAD(0x0658, 0x0270, 8, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_CS0__RAWNAND_CE0N \
+ IOMUX_PAD(0x065C, 0x0274, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_CS0__USBOH3_UH3_DFD_OUT_15 \
+ IOMUX_PAD(0x065C, 0x0274, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS0__USBOH3_UH2_DFD_OUT_15 \
+ IOMUX_PAD(0x065C, 0x0274, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS0__GPIO_6_11 \
+ IOMUX_PAD(0x065C, 0x0274, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS0__USDHC1_CLKO \
+ IOMUX_PAD(0x065C, 0x0274, 8, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_CS1__RAWNAND_CE1N \
+ IOMUX_PAD(0x0660, 0x0278, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_CS1__USDHC4_VSELECT \
+ IOMUX_PAD(0x0660, 0x0278, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS1__USDHC3_VSELECT \
+ IOMUX_PAD(0x0660, 0x0278, 2, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS1__PCIE_CTRL_DIAG_STATUS_BUS_MUX_3 \
+ IOMUX_PAD(0x0660, 0x0278, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS1__GPIO_6_14 \
+ IOMUX_PAD(0x0660, 0x0278, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS1__PL301_SIM_MX6DL_PER1_HREADYOUT \
+ IOMUX_PAD(0x0660, 0x0278, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS1__USDHC1_CLKI \
+ IOMUX_PAD(0x0660, 0x0278, 8, 0x0928, 0, MX6DL_USDHC_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_CS2__RAWNAND_CE2N \
+ IOMUX_PAD(0x0664, 0x027C, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_CS2__IPU1_SISG_0 \
+ IOMUX_PAD(0x0664, 0x027C, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS2__ESAI1_TX0 \
+ IOMUX_PAD(0x0664, 0x027C, 2, 0x0844, 1, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS2__WEIM_WEIM_CRE \
+ IOMUX_PAD(0x0664, 0x027C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS2__CCM_CLKO2 \
+ IOMUX_PAD(0x0664, 0x027C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS2__GPIO_6_15 \
+ IOMUX_PAD(0x0664, 0x027C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS2__USDHC2_CLKO \
+ IOMUX_PAD(0x0664, 0x027C, 8, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_CS3__RAWNAND_CE3N \
+ IOMUX_PAD(0x0668, 0x0280, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_CS3__IPU1_SISG_1 \
+ IOMUX_PAD(0x0668, 0x0280, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS3__ESAI1_TX1 \
+ IOMUX_PAD(0x0668, 0x0280, 2, 0x0848, 1, MX6DL_ESAI_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS3__WEIM_WEIM_A_26 \
+ IOMUX_PAD(0x0668, 0x0280, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS3__PCIE_CTRL_DIAG_STATUS_BUS_MUX_4 \
+ IOMUX_PAD(0x0668, 0x0280, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS3__GPIO_6_16 \
+ IOMUX_PAD(0x0668, 0x0280, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS3__TPSMP_CLK \
+ IOMUX_PAD(0x0668, 0x0280, 7, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS3__USDHC2_CLKI \
+ IOMUX_PAD(0x0668, 0x0280, 8, 0x0930, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_CS3__I2C4_SDA \
+ IOMUX_PAD(0x0668, 0x0280, 9 | IOMUX_CONFIG_SION, 0x0884, 2, MX6DL_I2C_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_D0__RAWNAND_D0 \
+ IOMUX_PAD(0x066C, 0x0284, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_D0__USDHC1_DAT4 \
+ IOMUX_PAD(0x066C, 0x0284, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D0__GPU3D_GPU_DEBUG_OUT_0 \
+ IOMUX_PAD(0x066C, 0x0284, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D0__USBOH3_UH2_DFD_OUT_16 \
+ IOMUX_PAD(0x066C, 0x0284, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D0__USBOH3_UH3_DFD_OUT_16 \
+ IOMUX_PAD(0x066C, 0x0284, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D0__GPIO_2_0 \
+ IOMUX_PAD(0x066C, 0x0284, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D0__IPU1_IPU_DIAG_BUS_0 \
+ IOMUX_PAD(0x066C, 0x0284, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_D1__RAWNAND_D1 \
+ IOMUX_PAD(0x0670, 0x0288, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_D1__USDHC1_DAT5 \
+ IOMUX_PAD(0x0670, 0x0288, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D1__GPU3D_GPU_DEBUG_OUT_1 \
+ IOMUX_PAD(0x0670, 0x0288, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D1__USBOH3_UH2_DFD_OUT_17 \
+ IOMUX_PAD(0x0670, 0x0288, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D1__USBOH3_UH3_DFD_OUT_17 \
+ IOMUX_PAD(0x0670, 0x0288, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D1__GPIO_2_1 \
+ IOMUX_PAD(0x0670, 0x0288, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D1__IPU1_IPU_DIAG_BUS_1 \
+ IOMUX_PAD(0x0670, 0x0288, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_D2__RAWNAND_D2 \
+ IOMUX_PAD(0x0674, 0x028C, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_D2__USDHC1_DAT6 \
+ IOMUX_PAD(0x0674, 0x028C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D2__GPU3D_GPU_DEBUG_OUT_2 \
+ IOMUX_PAD(0x0674, 0x028C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D2__USBOH3_UH2_DFD_OUT_18 \
+ IOMUX_PAD(0x0674, 0x028C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D2__USBOH3_UH3_DFD_OUT_18 \
+ IOMUX_PAD(0x0674, 0x028C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D2__GPIO_2_2 \
+ IOMUX_PAD(0x0674, 0x028C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D2__IPU1_IPU_DIAG_BUS_2 \
+ IOMUX_PAD(0x0674, 0x028C, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_D3__RAWNAND_D3 \
+ IOMUX_PAD(0x0678, 0x0290, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_D3__USDHC1_DAT7 \
+ IOMUX_PAD(0x0678, 0x0290, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D3__GPU3D_GPU_DEBUG_OUT_3 \
+ IOMUX_PAD(0x0678, 0x0290, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D3__USBOH3_UH2_DFD_OUT_19 \
+ IOMUX_PAD(0x0678, 0x0290, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D3__USBOH3_UH3_DFD_OUT_19 \
+ IOMUX_PAD(0x0678, 0x0290, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D3__GPIO_2_3 \
+ IOMUX_PAD(0x0678, 0x0290, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D3__IPU1_IPU_DIAG_BUS_3 \
+ IOMUX_PAD(0x0678, 0x0290, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_D4__RAWNAND_D4 \
+ IOMUX_PAD(0x067C, 0x0294, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_D4__USDHC2_DAT4 \
+ IOMUX_PAD(0x067C, 0x0294, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D4__GPU3D_GPU_DEBUG_OUT_4 \
+ IOMUX_PAD(0x067C, 0x0294, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D4__USBOH3_UH2_DFD_OUT_20 \
+ IOMUX_PAD(0x067C, 0x0294, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D4__USBOH3_UH3_DFD_OUT_20 \
+ IOMUX_PAD(0x067C, 0x0294, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D4__GPIO_2_4 \
+ IOMUX_PAD(0x067C, 0x0294, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D4__IPU1_IPU_DIAG_BUS_4 \
+ IOMUX_PAD(0x067C, 0x0294, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_D5__RAWNAND_D5 \
+ IOMUX_PAD(0x0680, 0x0298, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_D5__USDHC2_DAT5 \
+ IOMUX_PAD(0x0680, 0x0298, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D5__GPU3D_GPU_DEBUG_OUT_5 \
+ IOMUX_PAD(0x0680, 0x0298, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D5__USBOH3_UH2_DFD_OUT_21 \
+ IOMUX_PAD(0x0680, 0x0298, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D5__USBOH3_UH3_DFD_OUT_21 \
+ IOMUX_PAD(0x0680, 0x0298, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D5__GPIO_2_5 \
+ IOMUX_PAD(0x0680, 0x0298, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D5__IPU1_IPU_DIAG_BUS_5 \
+ IOMUX_PAD(0x0680, 0x0298, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_D6__RAWNAND_D6 \
+ IOMUX_PAD(0x0684, 0x029C, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_D6__USDHC2_DAT6 \
+ IOMUX_PAD(0x0684, 0x029C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D6__GPU3D_GPU_DEBUG_OUT_6 \
+ IOMUX_PAD(0x0684, 0x029C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D6__USBOH3_UH2_DFD_OUT_22 \
+ IOMUX_PAD(0x0684, 0x029C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D6__USBOH3_UH3_DFD_OUT_22 \
+ IOMUX_PAD(0x0684, 0x029C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D6__GPIO_2_6 \
+ IOMUX_PAD(0x0684, 0x029C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D6__IPU1_IPU_DIAG_BUS_6 \
+ IOMUX_PAD(0x0684, 0x029C, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_D7__RAWNAND_D7 \
+ IOMUX_PAD(0x0688, 0x02A0, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_D7__USDHC2_DAT7 \
+ IOMUX_PAD(0x0688, 0x02A0, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D7__GPU3D_GPU_DEBUG_OUT_7 \
+ IOMUX_PAD(0x0688, 0x02A0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D7__USBOH3_UH2_DFD_OUT_23 \
+ IOMUX_PAD(0x0688, 0x02A0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D7__USBOH3_UH3_DFD_OUT_23 \
+ IOMUX_PAD(0x0688, 0x02A0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D7__GPIO_2_7 \
+ IOMUX_PAD(0x0688, 0x02A0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_D7__IPU1_IPU_DIAG_BUS_7 \
+ IOMUX_PAD(0x0688, 0x02A0, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_RB0__RAWNAND_READY0 \
+ IOMUX_PAD(0x068C, 0x02A4, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL0)
+#define MX6DL_PAD_NANDF_RB0__PCIE_CTRL_DIAG_STATUS_BUS_MUX_2 \
+ IOMUX_PAD(0x068C, 0x02A4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_RB0__USBOH3_UH3_DFD_OUT_14 \
+ IOMUX_PAD(0x068C, 0x02A4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_RB0__USBOH3_UH2_DFD_OUT_14 \
+ IOMUX_PAD(0x068C, 0x02A4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_RB0__GPIO_6_10 \
+ IOMUX_PAD(0x068C, 0x02A4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_RB0__MIPI_CORE_DPHY_TEST_OUT_33 \
+ IOMUX_PAD(0x068C, 0x02A4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_RB0__USDHC4_CLKI \
+ IOMUX_PAD(0x068C, 0x02A4, 8, 0x0938, 0, MX6DL_USDHC_PAD_CTRL)
+
+#define MX6DL_PAD_NANDF_WP_B__RAWNAND_RESETN \
+ IOMUX_PAD(0x0690, 0x02A8, 0, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_NANDF_WP_B__PCIE_CTRL_DIAG_STATUS_BUS_MUX_1 \
+ IOMUX_PAD(0x0690, 0x02A8, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_WP_B__USBOH3_UH3_DFD_OUT_13 \
+ IOMUX_PAD(0x0690, 0x02A8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_WP_B__USBOH3_UH2_DFD_OUT_13 \
+ IOMUX_PAD(0x0690, 0x02A8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_WP_B__GPIO_6_9 \
+ IOMUX_PAD(0x0690, 0x02A8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_WP_B__MIPI_CORE_DPHY_TEST_OUT_32 \
+ IOMUX_PAD(0x0690, 0x02A8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_NANDF_WP_B__USDHC4_CLKO \
+ IOMUX_PAD(0x0690, 0x02A8, 8, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_NANDF_WP_B__I2C4_SCL \
+ IOMUX_PAD(0x0690, 0x02A8, 9 | IOMUX_CONFIG_SION, 0x0880, 2, MX6DL_I2C_PAD_CTRL)
+
+#define MX6DL_PAD_PMIC_ON_REQ__SNVS_LP_WRAPPER_SNVS_WAKEUP_ALARM \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_PMIC_STBY_REQ__CCM_PMIC_VSTBY_REQ \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_POR_B__SRC_POR_B \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RESET_IN_B__SRC_RESET_B \
+ IOMUX_PAD(NO_PAD_I, NO_MUX_I, 0, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_RD0__MIPI_HSI_CTRL_RX_READY \
+ IOMUX_PAD(0x0694, 0x02AC, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD0__ENET_RGMII_RD0 \
+ IOMUX_PAD(0x0694, 0x02AC, 1, 0x0818, 1, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD0__GPIO_6_25 \
+ IOMUX_PAD(0x0694, 0x02AC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD0__MIPI_CORE_DPHY_TEST_IN_6 \
+ IOMUX_PAD(0x0694, 0x02AC, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_RD1__MIPI_HSI_CTRL_TX_FLAG \
+ IOMUX_PAD(0x0698, 0x02B0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD1__ENET_RGMII_RD1 \
+ IOMUX_PAD(0x0698, 0x02B0, 1, 0x081C, 1, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD1__GPIO_6_27 \
+ IOMUX_PAD(0x0698, 0x02B0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD1__MIPI_CORE_DPHY_TEST_IN_8 \
+ IOMUX_PAD(0x0698, 0x02B0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD1__SJC_FAIL \
+ IOMUX_PAD(0x0698, 0x02B0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_RD2__MIPI_HSI_CTRL_TX_DATA \
+ IOMUX_PAD(0x069C, 0x02B4, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD2__ENET_RGMII_RD2 \
+ IOMUX_PAD(0x069C, 0x02B4, 1, 0x0820, 1, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD2__GPIO_6_28 \
+ IOMUX_PAD(0x069C, 0x02B4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD2__MIPI_CORE_DPHY_TEST_IN_9 \
+ IOMUX_PAD(0x069C, 0x02B4, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_RD3__MIPI_HSI_CTRL_TX_WAKE \
+ IOMUX_PAD(0x06A0, 0x02B8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD3__ENET_RGMII_RD3 \
+ IOMUX_PAD(0x06A0, 0x02B8, 1, 0x0824, 1, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD3__GPIO_6_29 \
+ IOMUX_PAD(0x06A0, 0x02B8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RD3__MIPI_CORE_DPHY_TEST_IN_10 \
+ IOMUX_PAD(0x06A0, 0x02B8, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_RX_CTL__USBOH3_H3_DATA \
+ IOMUX_PAD(0x06A4, 0x02BC, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USB_HSIC_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RX_CTL__ENET_RGMII_RX_CTL \
+ IOMUX_PAD(0x06A4, 0x02BC, 1, 0x0828, 1, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RX_CTL__GPIO_6_24 \
+ IOMUX_PAD(0x06A4, 0x02BC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RX_CTL__MIPI_CORE_DPHY_TEST_IN_5 \
+ IOMUX_PAD(0x06A4, 0x02BC, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_RXC__USBOH3_H3_STROBE \
+ IOMUX_PAD(0x06A8, 0x02C0, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USB_HSIC_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RXC__USBOH3_H3_STROBE_START \
+ IOMUX_PAD(0x06A8, 0x02C0, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USB_HSIC_PAD_CTRL | PAD_CTL_PUS_47K_UP)
+#define MX6DL_PAD_RGMII_RXC__ENET_RGMII_RXC \
+ IOMUX_PAD(0x06A8, 0x02C0, 1, 0x0814, 1, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RXC__GPIO_6_30 \
+ IOMUX_PAD(0x06A8, 0x02C0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_RXC__MIPI_CORE_DPHY_TEST_IN_11 \
+ IOMUX_PAD(0x06A8, 0x02C0, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_TD0__MIPI_HSI_CTRL_TX_READY \
+ IOMUX_PAD(0x06AC, 0x02C4, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD0__ENET_RGMII_TD0 \
+ IOMUX_PAD(0x06AC, 0x02C4, 1, 0x0000, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD0__GPIO_6_20 \
+ IOMUX_PAD(0x06AC, 0x02C4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD0__MIPI_CORE_DPHY_TEST_IN_1 \
+ IOMUX_PAD(0x06AC, 0x02C4, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_TD1__MIPI_HSI_CTRL_RX_FLAG \
+ IOMUX_PAD(0x06B0, 0x02C8, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD1__ENET_RGMII_TD1 \
+ IOMUX_PAD(0x06B0, 0x02C8, 1, 0x0000, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD1__GPIO_6_21 \
+ IOMUX_PAD(0x06B0, 0x02C8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD1__MIPI_CORE_DPHY_TEST_IN_2 \
+ IOMUX_PAD(0x06B0, 0x02C8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD1__CCM_PLL3_BYP \
+ IOMUX_PAD(0x06B0, 0x02C8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_TD2__MIPI_HSI_CTRL_RX_DATA \
+ IOMUX_PAD(0x06B4, 0x02CC, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD2__ENET_RGMII_TD2 \
+ IOMUX_PAD(0x06B4, 0x02CC, 1, 0x0000, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD2__GPIO_6_22 \
+ IOMUX_PAD(0x06B4, 0x02CC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD2__MIPI_CORE_DPHY_TEST_IN_3 \
+ IOMUX_PAD(0x06B4, 0x02CC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD2__CCM_PLL2_BYP \
+ IOMUX_PAD(0x06B4, 0x02CC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_TD3__MIPI_HSI_CTRL_RX_WAKE \
+ IOMUX_PAD(0x06B8, 0x02D0, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD3__ENET_RGMII_TD3 \
+ IOMUX_PAD(0x06B8, 0x02D0, 1, 0x0000, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD3__GPIO_6_23 \
+ IOMUX_PAD(0x06B8, 0x02D0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TD3__MIPI_CORE_DPHY_TEST_IN_4 \
+ IOMUX_PAD(0x06B8, 0x02D0, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE \
+ IOMUX_PAD(0x06BC, 0x02D4, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USB_HSIC_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TX_CTL__USBOH3_H2_STROBE_START \
+ IOMUX_PAD(0x06BC, 0x02D4, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USB_HSIC_PAD_CTRL | PAD_CTL_PUS_47K_UP)
+#define MX6DL_PAD_RGMII_TX_CTL__ENET_RGMII_TX_CTL \
+ IOMUX_PAD(0x06BC, 0x02D4, 1, 0x0000, 0, MX6DL_ENET_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TX_CTL__GPIO_6_26 \
+ IOMUX_PAD(0x06BC, 0x02D4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TX_CTL__MIPI_CORE_DPHY_TEST_IN_7 \
+ IOMUX_PAD(0x06BC, 0x02D4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TX_CTL__ENET_ANATOP_ETHERNET_REF_OUT \
+ IOMUX_PAD(0x06BC, 0x02D4, 7, 0x080C, 1, NO_PAD_CTRL)
+
+#define MX6DL_PAD_RGMII_TXC__USBOH3_H2_DATA \
+ IOMUX_PAD(0x06C0, 0x02D8, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USB_HSIC_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TXC__ENET_RGMII_TXC \
+ IOMUX_PAD(0x06C0, 0x02D8, 1, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TXC__SPDIF_SPDIF_EXTCLK \
+ IOMUX_PAD(0x06C0, 0x02D8, 2, 0x08F4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TXC__GPIO_6_19 \
+ IOMUX_PAD(0x06C0, 0x02D8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TXC__MIPI_CORE_DPHY_TEST_IN_0 \
+ IOMUX_PAD(0x06C0, 0x02D8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_RGMII_TXC__ANATOP_ANATOP_24M_OUT \
+ IOMUX_PAD(0x06C0, 0x02D8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD1_CLK__USDHC1_CLK \
+ IOMUX_PAD(0x06C4, 0x02DC, 0, 0x0928, 1, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD1_CLK__OSC32K_32K_OUT \
+ IOMUX_PAD(0x06C4, 0x02DC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_CLK__GPT_CLKIN \
+ IOMUX_PAD(0x06C4, 0x02DC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_CLK__GPIO_1_20 \
+ IOMUX_PAD(0x06C4, 0x02DC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_CLK__PHY_DTB_0 \
+ IOMUX_PAD(0x06C4, 0x02DC, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD1_CMD__USDHC1_CMD \
+ IOMUX_PAD(0x06C8, 0x02E0, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD1_CMD__PWM4_PWMO \
+ IOMUX_PAD(0x06C8, 0x02E0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_CMD__GPT_CMPOUT1 \
+ IOMUX_PAD(0x06C8, 0x02E0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_CMD__GPIO_1_18 \
+ IOMUX_PAD(0x06C8, 0x02E0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_CMD__ANATOP_ANATOP_TESTO_5 \
+ IOMUX_PAD(0x06C8, 0x02E0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD1_DAT0__USDHC1_DAT0 \
+ IOMUX_PAD(0x06CC, 0x02E4, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT0__CAAM_WRAPPER_RNG_OSC_OBS \
+ IOMUX_PAD(0x06CC, 0x02E4, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT0__GPT_CAPIN1 \
+ IOMUX_PAD(0x06CC, 0x02E4, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT0__PCIE_CTRL_DIAG_STATUS_BUS_MUX_8 \
+ IOMUX_PAD(0x06CC, 0x02E4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT0__GPIO_1_16 \
+ IOMUX_PAD(0x06CC, 0x02E4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT0__HDMI_TX_OPHYDTB_1 \
+ IOMUX_PAD(0x06CC, 0x02E4, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT0__ANATOP_ANATOP_TESTO_7 \
+ IOMUX_PAD(0x06CC, 0x02E4, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD1_DAT1__USDHC1_DAT1 \
+ IOMUX_PAD(0x06D0, 0x02E8, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT1__PWM3_PWMO \
+ IOMUX_PAD(0x06D0, 0x02E8, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT1__GPT_CAPIN2 \
+ IOMUX_PAD(0x06D0, 0x02E8, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT1__PCIE_CTRL_DIAG_STATUS_BUS_MUX_7 \
+ IOMUX_PAD(0x06D0, 0x02E8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT1__GPIO_1_17 \
+ IOMUX_PAD(0x06D0, 0x02E8, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT1__HDMI_TX_OPHYDTB_0 \
+ IOMUX_PAD(0x06D0, 0x02E8, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT1__ANATOP_ANATOP_TESTO_8 \
+ IOMUX_PAD(0x06D0, 0x02E8, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD1_DAT2__USDHC1_DAT2 \
+ IOMUX_PAD(0x06D4, 0x02EC, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT2__GPT_CMPOUT2 \
+ IOMUX_PAD(0x06D4, 0x02EC, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT2__PWM2_PWMO \
+ IOMUX_PAD(0x06D4, 0x02EC, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT2__WDOG1_WDOG_B \
+ IOMUX_PAD(0x06D4, 0x02EC, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT2__GPIO_1_19 \
+ IOMUX_PAD(0x06D4, 0x02EC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT2__WDOG1_WDOG_RST_B_DEB \
+ IOMUX_PAD(0x06D4, 0x02EC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT2__ANATOP_ANATOP_TESTO_4 \
+ IOMUX_PAD(0x06D4, 0x02EC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD1_DAT3__USDHC1_DAT3 \
+ IOMUX_PAD(0x06D8, 0x02F0, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT3__GPT_CMPOUT3 \
+ IOMUX_PAD(0x06D8, 0x02F0, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT3__PWM1_PWMO \
+ IOMUX_PAD(0x06D8, 0x02F0, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT3__WDOG2_WDOG_B \
+ IOMUX_PAD(0x06D8, 0x02F0, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT3__GPIO_1_21 \
+ IOMUX_PAD(0x06D8, 0x02F0, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT3__WDOG2_WDOG_RST_B_DEB \
+ IOMUX_PAD(0x06D8, 0x02F0, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD1_DAT3__ANATOP_ANATOP_TESTO_6 \
+ IOMUX_PAD(0x06D8, 0x02F0, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD2_CLK__USDHC2_CLK \
+ IOMUX_PAD(0x06DC, 0x02F4, 0, 0x0930, 1, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD2_CLK__KPP_COL_5 \
+ IOMUX_PAD(0x06DC, 0x02F4, 2, 0x08C0, 3, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_CLK__AUDMUX_AUD4_RXFS \
+ IOMUX_PAD(0x06DC, 0x02F4, 3, 0x07A4, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_CLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_9 \
+ IOMUX_PAD(0x06DC, 0x02F4, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_CLK__GPIO_1_10 \
+ IOMUX_PAD(0x06DC, 0x02F4, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_CLK__PHY_DTB_1 \
+ IOMUX_PAD(0x06DC, 0x02F4, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD2_CMD__USDHC2_CMD \
+ IOMUX_PAD(0x06E0, 0x02F8, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD2_CMD__KPP_ROW_5 \
+ IOMUX_PAD(0x06E0, 0x02F8, 2, 0x08CC, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_CMD__AUDMUX_AUD4_RXC \
+ IOMUX_PAD(0x06E0, 0x02F8, 3, 0x07A0, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_CMD__PCIE_CTRL_DIAG_STATUS_BUS_MUX_10 \
+ IOMUX_PAD(0x06E0, 0x02F8, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_CMD__GPIO_1_11 \
+ IOMUX_PAD(0x06E0, 0x02F8, 5, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD2_DAT0__USDHC2_DAT0 \
+ IOMUX_PAD(0x06E4, 0x02FC, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT0__AUDMUX_AUD4_RXD \
+ IOMUX_PAD(0x06E4, 0x02FC, 3, 0x0798, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT0__KPP_ROW_7 \
+ IOMUX_PAD(0x06E4, 0x02FC, 4, 0x08D4, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT0__GPIO_1_15 \
+ IOMUX_PAD(0x06E4, 0x02FC, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT0__DCIC2_DCIC_OUT \
+ IOMUX_PAD(0x06E4, 0x02FC, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT0__ANATOP_ANATOP_TESTO_2 \
+ IOMUX_PAD(0x06E4, 0x02FC, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD2_DAT1__USDHC2_DAT1 \
+ IOMUX_PAD(0x06E8, 0x0300, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT1__WEIM_WEIM_CS_2 \
+ IOMUX_PAD(0x06E8, 0x0300, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT1__AUDMUX_AUD4_TXFS \
+ IOMUX_PAD(0x06E8, 0x0300, 3, 0x07AC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT1__KPP_COL_7 \
+ IOMUX_PAD(0x06E8, 0x0300, 4, 0x08C8, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT1__GPIO_1_14 \
+ IOMUX_PAD(0x06E8, 0x0300, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT1__CCM_WAIT \
+ IOMUX_PAD(0x06E8, 0x0300, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT1__ANATOP_ANATOP_TESTO_0 \
+ IOMUX_PAD(0x06E8, 0x0300, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD2_DAT2__USDHC2_DAT2 \
+ IOMUX_PAD(0x06EC, 0x0304, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT2__WEIM_WEIM_CS_3 \
+ IOMUX_PAD(0x06EC, 0x0304, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT2__AUDMUX_AUD4_TXD \
+ IOMUX_PAD(0x06EC, 0x0304, 3, 0x079C, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT2__KPP_ROW_6 \
+ IOMUX_PAD(0x06EC, 0x0304, 4, 0x08D0, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT2__GPIO_1_13 \
+ IOMUX_PAD(0x06EC, 0x0304, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT2__CCM_STOP \
+ IOMUX_PAD(0x06EC, 0x0304, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT2__ANATOP_ANATOP_TESTO_1 \
+ IOMUX_PAD(0x06EC, 0x0304, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD2_DAT3__USDHC2_DAT3 \
+ IOMUX_PAD(0x06F0, 0x0308, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT3__KPP_COL_6 \
+ IOMUX_PAD(0x06F0, 0x0308, 2, 0x08C4, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT3__AUDMUX_AUD4_TXC \
+ IOMUX_PAD(0x06F0, 0x0308, 3, 0x07A8, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT3__PCIE_CTRL_DIAG_STATUS_BUS_MUX_11 \
+ IOMUX_PAD(0x06F0, 0x0308, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT3__GPIO_1_12 \
+ IOMUX_PAD(0x06F0, 0x0308, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT3__SJC_DONE \
+ IOMUX_PAD(0x06F0, 0x0308, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD2_DAT3__ANATOP_ANATOP_TESTO_3 \
+ IOMUX_PAD(0x06F0, 0x0308, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_CLK__USDHC3_CLK_50MHZ \
+ IOMUX_PAD(0x06F4, 0x030C, 0, 0x0934, 1, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_CLK__USDHC3_CLK_100MHZ \
+ IOMUX_PAD(0x06F4, 0x030C, 0, 0x0934, 1, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_CLK__USDHC3_CLK_200MHZ \
+ IOMUX_PAD(0x06F4, 0x030C, 0, 0x0934, 1, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_CLK__UART2_CTS \
+ IOMUX_PAD(0x06F4, 0x030C, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_CLK__UART2_RTS \
+ IOMUX_PAD(0x06F4, 0x030C, 1, 0x0900, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_CLK__CAN1_RXCAN \
+ IOMUX_PAD(0x06F4, 0x030C, 2, 0x07C8, 2, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CLK__USBOH3_UH3_DFD_OUT_5 \
+ IOMUX_PAD(0x06F4, 0x030C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CLK__USBOH3_UH2_DFD_OUT_5 \
+ IOMUX_PAD(0x06F4, 0x030C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CLK__GPIO_7_3 \
+ IOMUX_PAD(0x06F4, 0x030C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CLK__MIPI_CORE_DPHY_TEST_IN_17 \
+ IOMUX_PAD(0x06F4, 0x030C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CLK__ANATOP_ANATOP_TESTO_14 \
+ IOMUX_PAD(0x06F4, 0x030C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_CMD__USDHC3_CMD_50MHZ \
+ IOMUX_PAD(0x06F8, 0x0310, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_CMD__USDHC3_CMD_100MHZ \
+ IOMUX_PAD(0x06F8, 0x0310, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_CMD__USDHC3_CMD_200MHZ \
+ IOMUX_PAD(0x06F8, 0x0310, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_CMD__UART2_CTS \
+ IOMUX_PAD(0x06F8, 0x0310, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MXSDL_PAD_SD3_CMD__UART2_RTS \
+ IOMUX_PAD(0x06F8, 0x0310, 1, 0x0900, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_CMD__CAN1_TXCAN \
+ IOMUX_PAD(0x06F8, 0x0310, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CMD__USBOH3_UH3_DFD_OUT_4 \
+ IOMUX_PAD(0x06F8, 0x0310, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CMD__USBOH3_UH2_DFD_OUT_4 \
+ IOMUX_PAD(0x06F8, 0x0310, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CMD__GPIO_7_2 \
+ IOMUX_PAD(0x06F8, 0x0310, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CMD__MIPI_CORE_DPHY_TEST_IN_16 \
+ IOMUX_PAD(0x06F8, 0x0310, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_CMD__ANATOP_ANATOP_TESTO_13 \
+ IOMUX_PAD(0x06F8, 0x0310, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_DAT0__USDHC3_DAT0_50MHZ \
+ IOMUX_PAD(0x06FC, 0x0314, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT0__USDHC3_DAT0_100MHZ \
+ IOMUX_PAD(0x06FC, 0x0314, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_DAT0__USDHC3_DAT0_200MHZ \
+ IOMUX_PAD(0x06FC, 0x0314, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_DAT0__UART1_CTS \
+ IOMUX_PAD(0x06FC, 0x0314, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT0__UART1_RTS \
+ IOMUX_PAD(0x06FC, 0x0314, 1, 0x08F8, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT0__CAN2_TXCAN \
+ IOMUX_PAD(0x06FC, 0x0314, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT0__USBOH3_UH3_DFD_OUT_6 \
+ IOMUX_PAD(0x06FC, 0x0314, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT0__USBOH3_UH2_DFD_OUT_6 \
+ IOMUX_PAD(0x06FC, 0x0314, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT0__GPIO_7_4 \
+ IOMUX_PAD(0x06FC, 0x0314, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT0__MIPI_CORE_DPHY_TEST_IN_18 \
+ IOMUX_PAD(0x06FC, 0x0314, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT0__ANATOP_ANATOP_TESTO_15 \
+ IOMUX_PAD(0x06FC, 0x0314, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_DAT1__USDHC3_DAT1_50MHZ \
+ IOMUX_PAD(0x0700, 0x0318, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT1__USDHC3_DAT1_100MHZ \
+ IOMUX_PAD(0x0700, 0x0318, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_DAT1__USDHC3_DAT1_200MHZ \
+ IOMUX_PAD(0x0700, 0x0318, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_DAT1__UART1_CTS \
+ IOMUX_PAD(0x0700, 0x0318, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT1__UART1_RTS \
+ IOMUX_PAD(0x0700, 0x0318, 1, 0x08F8, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT1__CAN2_RXCAN \
+ IOMUX_PAD(0x0700, 0x0318, 2, 0x07CC, 1, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT1__USBOH3_UH3_DFD_OUT_7 \
+ IOMUX_PAD(0x0700, 0x0318, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT1__USBOH3_UH2_DFD_OUT_7 \
+ IOMUX_PAD(0x0700, 0x0318, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT1__GPIO_7_5 \
+ IOMUX_PAD(0x0700, 0x0318, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT1__MIPI_CORE_DPHY_TEST_IN_19 \
+ IOMUX_PAD(0x0700, 0x0318, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT1__ANATOP_ANATOP_TESTI_0 \
+ IOMUX_PAD(0x0700, 0x0318, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_DAT2__USDHC3_DAT2_50MHZ \
+ IOMUX_PAD(0x0704, 0x031C, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT2__USDHC3_DAT2_100MHZ \
+ IOMUX_PAD(0x0704, 0x031C, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_DAT2__USDHC3_DAT2_200MHZ \
+ IOMUX_PAD(0x0704, 0x031C, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_DAT2__PCIE_CTRL_DIAG_STATUS_BUS_MUX_28 \
+ IOMUX_PAD(0x0704, 0x031C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT2__USBOH3_UH3_DFD_OUT_8 \
+ IOMUX_PAD(0x0704, 0x031C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT2__USBOH3_UH2_DFD_OUT_8 \
+ IOMUX_PAD(0x0704, 0x031C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT2__GPIO_7_6 \
+ IOMUX_PAD(0x0704, 0x031C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT2__MIPI_CORE_DPHY_TEST_IN_20 \
+ IOMUX_PAD(0x0704, 0x031C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT2__ANATOP_ANATOP_TESTI_1 \
+ IOMUX_PAD(0x0704, 0x031C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_DAT3__USDHC3_DAT3_50MHZ \
+ IOMUX_PAD(0x0708, 0x0320, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT3__USDHC3_DAT3_100MHZ \
+ IOMUX_PAD(0x0708, 0x0320, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_DAT3__USDHC3_DAT3_200MHZ \
+ IOMUX_PAD(0x0708, 0x0320, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_DAT3__UART3_CTS \
+ IOMUX_PAD(0x0708, 0x0320, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT3__UART3_RTS \
+ IOMUX_PAD(0x0708, 0x0320, 1, 0x0908, 4, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT3__PCIE_CTRL_DIAG_STATUS_BUS_MUX_29 \
+ IOMUX_PAD(0x0708, 0x0320, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT3__USBOH3_UH3_DFD_OUT_9 \
+ IOMUX_PAD(0x0708, 0x0320, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT3__USBOH3_UH2_DFD_OUT_9 \
+ IOMUX_PAD(0x0708, 0x0320, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT3__GPIO_7_7 \
+ IOMUX_PAD(0x0708, 0x0320, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT3__MIPI_CORE_DPHY_TEST_IN_21 \
+ IOMUX_PAD(0x0708, 0x0320, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT3__ANATOP_ANATOP_TESTI_2 \
+ IOMUX_PAD(0x0708, 0x0320, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_DAT4__USDHC3_DAT4_50MHZ \
+ IOMUX_PAD(0x070C, 0x0324, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT4__USDHC3_DAT4_100MHZ \
+ IOMUX_PAD(0x070C, 0x0324, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_DAT4__USDHC3_DAT4_200MHZ \
+ IOMUX_PAD(0x070C, 0x0324, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_DAT4__UART2_TXD \
+ IOMUX_PAD(0x070C, 0x0324, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT4__UART2_RXD \
+ IOMUX_PAD(0x070C, 0x0324, 1, 0x0904, 4, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT4__PCIE_CTRL_DIAG_STATUS_BUS_MUX_27 \
+ IOMUX_PAD(0x070C, 0x0324, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT4__USBOH3_UH3_DFD_OUT_3 \
+ IOMUX_PAD(0x070C, 0x0324, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT4__USBOH3_UH2_DFD_OUT_3 \
+ IOMUX_PAD(0x070C, 0x0324, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT4__GPIO_7_1 \
+ IOMUX_PAD(0x070C, 0x0324, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT4__MIPI_CORE_DPHY_TEST_IN_15 \
+ IOMUX_PAD(0x070C, 0x0324, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT4__ANATOP_ANATOP_TESTO_12 \
+ IOMUX_PAD(0x070C, 0x0324, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_DAT5__USDHC3_DAT5_50MHZ \
+ IOMUX_PAD(0x0710, 0x0328, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT5__USDHC3_DAT5_100MHZ \
+ IOMUX_PAD(0x0710, 0x0328, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_DAT5__USDHC3_DAT5_200MHZ \
+ IOMUX_PAD(0x0710, 0x0328, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_DAT5__UART2_TXD \
+ IOMUX_PAD(0x0710, 0x0328, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT5__UART2_RXD \
+ IOMUX_PAD(0x0710, 0x0328, 1, 0x0904, 5, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT5__PCIE_CTRL_DIAG_STATUS_BUS_MUX_26 \
+ IOMUX_PAD(0x0710, 0x0328, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT5__USBOH3_UH3_DFD_OUT_2 \
+ IOMUX_PAD(0x0710, 0x0328, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT5__USBOH3_UH2_DFD_OUT_2 \
+ IOMUX_PAD(0x0710, 0x0328, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT5__GPIO_7_0 \
+ IOMUX_PAD(0x0710, 0x0328, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT5__MIPI_CORE_DPHY_TEST_IN_14 \
+ IOMUX_PAD(0x0710, 0x0328, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT5__ANATOP_ANATOP_TESTO_11 \
+ IOMUX_PAD(0x0710, 0x0328, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_DAT6__USDHC3_DAT6_50MHZ \
+ IOMUX_PAD(0x0714, 0x032C, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT6__USDHC3_DAT6_100MHZ \
+ IOMUX_PAD(0x0714, 0x032C, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_DAT6__USDHC3_DAT6_200MHZ \
+ IOMUX_PAD(0x0714, 0x032C, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_DAT6__UART1_TXD \
+ IOMUX_PAD(0x0714, 0x032C, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT6__UART1_RXD \
+ IOMUX_PAD(0x0714, 0x032C, 1, 0x08FC, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT6__PCIE_CTRL_DIAG_STATUS_BUS_MUX_25 \
+ IOMUX_PAD(0x0714, 0x032C, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT6__USBOH3_UH3_DFD_OUT_1 \
+ IOMUX_PAD(0x0714, 0x032C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT6__USBOH3_UH2_DFD_OUT_1 \
+ IOMUX_PAD(0x0714, 0x032C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT6__GPIO_6_18 \
+ IOMUX_PAD(0x0714, 0x032C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT6__MIPI_CORE_DPHY_TEST_IN_13 \
+ IOMUX_PAD(0x0714, 0x032C, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT6__ANATOP_ANATOP_TESTO_10 \
+ IOMUX_PAD(0x0714, 0x032C, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_DAT7__USDHC3_DAT7_50MHZ \
+ IOMUX_PAD(0x0718, 0x0330, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT7__USDHC3_DAT7_100MHZ \
+ IOMUX_PAD(0x0718, 0x0330, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD3_DAT7__USDHC3_DAT7_200MHZ \
+ IOMUX_PAD(0x0718, 0x0330, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD3_DAT7__UART1_TXD \
+ IOMUX_PAD(0x0718, 0x0330, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT7__UART1_RXD \
+ IOMUX_PAD(0x0718, 0x0330, 1, 0x08FC, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT7__PCIE_CTRL_DIAG_STATUS_BUS_MUX_24 \
+ IOMUX_PAD(0x0718, 0x0330, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT7__USBOH3_UH3_DFD_OUT_0 \
+ IOMUX_PAD(0x0718, 0x0330, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT7__USBOH3_UH2_DFD_OUT_0 \
+ IOMUX_PAD(0x0718, 0x0330, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT7__GPIO_6_17 \
+ IOMUX_PAD(0x0718, 0x0330, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT7__MIPI_CORE_DPHY_TEST_IN_12 \
+ IOMUX_PAD(0x0718, 0x0330, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_DAT7__ANATOP_USBPHY2_TSTO_PLL_CLK20DIV \
+ IOMUX_PAD(0x0718, 0x0330, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD3_RST__USDHC3_RST \
+ IOMUX_PAD(0x071C, 0x0334, 0, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD3_RST__UART3_CTS \
+ IOMUX_PAD(0x071C, 0x0334, 1, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_RST__UART3_RTS \
+ IOMUX_PAD(0x071C, 0x0334, 1, 0x0908, 5, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD3_RST__PCIE_CTRL_DIAG_STATUS_BUS_MUX_30 \
+ IOMUX_PAD(0x071C, 0x0334, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_RST__USBOH3_UH3_DFD_OUT_10 \
+ IOMUX_PAD(0x071C, 0x0334, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_RST__USBOH3_UH2_DFD_OUT_10 \
+ IOMUX_PAD(0x071C, 0x0334, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_RST__GPIO_7_8 \
+ IOMUX_PAD(0x071C, 0x0334, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_RST__MIPI_CORE_DPHY_TEST_IN_22 \
+ IOMUX_PAD(0x071C, 0x0334, 6, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD3_RST__ANATOP_ANATOP_TESTI_3 \
+ IOMUX_PAD(0x071C, 0x0334, 7, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_CLK__USDHC4_CLK_50MHZ \
+ IOMUX_PAD(0x0720, 0x0338, 0, 0x0938, 1, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_CLK__USDHC4_CLK_100MHZ \
+ IOMUX_PAD(0x0720, 0x0338, 0, 0x0938, 1, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_CLK__USDHC4_CLK_200MHZ \
+ IOMUX_PAD(0x0720, 0x0338, 0, 0x0938, 1, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_CLK__RAWNAND_WRN \
+ IOMUX_PAD(0x0720, 0x0338, 1, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_SD4_CLK__UART3_TXD \
+ IOMUX_PAD(0x0720, 0x0338, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_CLK__UART3_RXD \
+ IOMUX_PAD(0x0720, 0x0338, 2, 0x090C, 2, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_CLK__PCIE_CTRL_DIAG_STATUS_BUS_MUX_6 \
+ IOMUX_PAD(0x0720, 0x0338, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_CLK__GPIO_7_10 \
+ IOMUX_PAD(0x0720, 0x0338, 5, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_CMD__USDHC4_CMD_50MHZ \
+ IOMUX_PAD(0x0724, 0x033C, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_CMD__USDHC4_CMD_100MHZ \
+ IOMUX_PAD(0x0724, 0x033C, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_CMD__USDHC4_CMD_200MHZ \
+ IOMUX_PAD(0x0724, 0x033C, 0 | IOMUX_CONFIG_SION, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_CMD__RAWNAND_RDN \
+ IOMUX_PAD(0x0724, 0x033C, 1, 0x0000, 0, MX6DL_GPMI_PAD_CTRL2)
+#define MX6DL_PAD_SD4_CMD__UART3_TXD \
+ IOMUX_PAD(0x0724, 0x033C, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_CMD__UART3_RXD \
+ IOMUX_PAD(0x0724, 0x033C, 2, 0x090C, 3, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_CMD__PCIE_CTRL_DIAG_STATUS_BUS_MUX_5 \
+ IOMUX_PAD(0x0724, 0x033C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_CMD__GPIO_7_9 \
+ IOMUX_PAD(0x0724, 0x033C, 5, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_DAT0__RAWNAND_D8 \
+ IOMUX_PAD(0x0728, 0x0340, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT0__USDHC4_DAT0_50MHZ \
+ IOMUX_PAD(0x0728, 0x0340, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT0__USDHC4_DAT0_100MHZ \
+ IOMUX_PAD(0x0728, 0x0340, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_DAT0__USDHC4_DAT0_200MHZ \
+ IOMUX_PAD(0x0728, 0x0340, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_DAT0__RAWNAND_DQS \
+ IOMUX_PAD(0x0728, 0x0340, 2, 0x0000, 0, MX6DL_GPMI_PAD_CTRL1)
+#define MX6DL_PAD_SD4_DAT0__USBOH3_UH2_DFD_OUT_24 \
+ IOMUX_PAD(0x0728, 0x0340, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT0__USBOH3_UH3_DFD_OUT_24 \
+ IOMUX_PAD(0x0728, 0x0340, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT0__GPIO_2_8 \
+ IOMUX_PAD(0x0728, 0x0340, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT0__IPU1_IPU_DIAG_BUS_8 \
+ IOMUX_PAD(0x0728, 0x0340, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_DAT1__RAWNAND_D9 \
+ IOMUX_PAD(0x072C, 0x0344, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT1__USDHC4_DAT1_50MHZ \
+ IOMUX_PAD(0x072C, 0x0344, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT1__USDHC4_DAT1_100MHZ \
+ IOMUX_PAD(0x072C, 0x0344, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_DAT1__USDHC4_DAT1_200MHZ \
+ IOMUX_PAD(0x072C, 0x0344, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_DAT1__PWM3_PWMO \
+ IOMUX_PAD(0x072C, 0x0344, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT1__USBOH3_UH2_DFD_OUT_25 \
+ IOMUX_PAD(0x072C, 0x0344, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT1__USBOH3_UH3_DFD_OUT_25 \
+ IOMUX_PAD(0x072C, 0x0344, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT1__GPIO_2_9 \
+ IOMUX_PAD(0x072C, 0x0344, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT1__IPU1_IPU_DIAG_BUS_9 \
+ IOMUX_PAD(0x072C, 0x0344, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_DAT2__RAWNAND_D10 \
+ IOMUX_PAD(0x0730, 0x0348, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT2__USDHC4_DAT2_50MHZ \
+ IOMUX_PAD(0x0730, 0x0348, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT2__USDHC4_DAT2_100MHZ \
+ IOMUX_PAD(0x0730, 0x0348, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_DAT2__USDHC4_DAT2_200MHZ \
+ IOMUX_PAD(0x0730, 0x0348, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_DAT2__PWM4_PWMO \
+ IOMUX_PAD(0x0730, 0x0348, 2, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT2__USBOH3_UH2_DFD_OUT_26 \
+ IOMUX_PAD(0x0730, 0x0348, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT2__USBOH3_UH3_DFD_OUT_26 \
+ IOMUX_PAD(0x0730, 0x0348, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT2__GPIO_2_10 \
+ IOMUX_PAD(0x0730, 0x0348, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT2__IPU1_IPU_DIAG_BUS_10 \
+ IOMUX_PAD(0x0730, 0x0348, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_DAT3__RAWNAND_D11 \
+ IOMUX_PAD(0x0734, 0x034C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT3__USDHC4_DAT3_50MHZ \
+ IOMUX_PAD(0x0734, 0x034C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT3__USDHC4_DAT3_100MHZ \
+ IOMUX_PAD(0x0734, 0x034C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_DAT3__USDHC4_DAT3_200MHZ \
+ IOMUX_PAD(0x0734, 0x034C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_DAT3__USBOH3_UH2_DFD_OUT_27 \
+ IOMUX_PAD(0x0734, 0x034C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT3__USBOH3_UH3_DFD_OUT_27 \
+ IOMUX_PAD(0x0734, 0x034C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT3__GPIO_2_11 \
+ IOMUX_PAD(0x0734, 0x034C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT3__IPU1_IPU_DIAG_BUS_11 \
+ IOMUX_PAD(0x0734, 0x034C, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_DAT4__RAWNAND_D12 \
+ IOMUX_PAD(0x0738, 0x0350, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT4__USDHC4_DAT4_50MHZ \
+ IOMUX_PAD(0x0738, 0x0350, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT4__USDHC4_DAT4_100MHZ \
+ IOMUX_PAD(0x0738, 0x0350, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_DAT4__USDHC4_DAT4_200MHZ \
+ IOMUX_PAD(0x0738, 0x0350, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_DAT4__UART2_TXD \
+ IOMUX_PAD(0x0738, 0x0350, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT4__UART2_RXD \
+ IOMUX_PAD(0x0738, 0x0350, 2, 0x0904, 6, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT4__USBOH3_UH2_DFD_OUT_28 \
+ IOMUX_PAD(0x0738, 0x0350, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT4__USBOH3_UH3_DFD_OUT_28 \
+ IOMUX_PAD(0x0738, 0x0350, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT4__GPIO_2_12 \
+ IOMUX_PAD(0x0738, 0x0350, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT4__IPU1_IPU_DIAG_BUS_12 \
+ IOMUX_PAD(0x0738, 0x0350, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_DAT5__RAWNAND_D13 \
+ IOMUX_PAD(0x073C, 0x0354, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT5__USDHC4_DAT5_50MHZ \
+ IOMUX_PAD(0x073C, 0x0354, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT5__USDHC4_DAT5_100MHZ \
+ IOMUX_PAD(0x073C, 0x0354, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_DAT5__USDHC4_DAT5_200MHZ \
+ IOMUX_PAD(0x073C, 0x0354, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_DAT5__UART2_CTS \
+ IOMUX_PAD(0x073C, 0x0354, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT5__UART2_RTS \
+ IOMUX_PAD(0x073C, 0x0354, 2, 0x0900, 4, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT5__USBOH3_UH2_DFD_OUT_29 \
+ IOMUX_PAD(0x073C, 0x0354, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT5__USBOH3_UH3_DFD_OUT_29 \
+ IOMUX_PAD(0x073C, 0x0354, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT5__GPIO_2_13 \
+ IOMUX_PAD(0x073C, 0x0354, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT5__IPU1_IPU_DIAG_BUS_13 \
+ IOMUX_PAD(0x073C, 0x0354, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_DAT6__RAWNAND_D14 \
+ IOMUX_PAD(0x0740, 0x0358, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT6__USDHC4_DAT6_50MHZ \
+ IOMUX_PAD(0x0740, 0x0358, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT6__USDHC4_DAT6_100MHZ \
+ IOMUX_PAD(0x0740, 0x0358, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_DAT6__USDHC4_DAT6_200MHZ \
+ IOMUX_PAD(0x0740, 0x0358, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_DAT6__UART2_CTS \
+ IOMUX_PAD(0x0740, 0x0358, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT6__UART2_RTS \
+ IOMUX_PAD(0x0740, 0x0358, 2, 0x0900, 5, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT6__USBOH3_UH2_DFD_OUT_30 \
+ IOMUX_PAD(0x0740, 0x0358, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT6__USBOH3_UH3_DFD_OUT_30 \
+ IOMUX_PAD(0x0740, 0x0358, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT6__GPIO_2_14 \
+ IOMUX_PAD(0x0740, 0x0358, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT6__IPU1_IPU_DIAG_BUS_14 \
+ IOMUX_PAD(0x0740, 0x0358, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#define MX6DL_PAD_SD4_DAT7__RAWNAND_D15 \
+ IOMUX_PAD(0x0744, 0x035C, 0, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT7__USDHC4_DAT7_50MHZ \
+ IOMUX_PAD(0x0744, 0x035C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT7__USDHC4_DAT7_100MHZ \
+ IOMUX_PAD(0x0744, 0x035C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_100MHZ)
+#define MX6DL_PAD_SD4_DAT7__USDHC4_DAT7_200MHZ \
+ IOMUX_PAD(0x0744, 0x035C, 1, 0x0000, 0, MX6DL_USDHC_PAD_CTRL_200MHZ)
+#define MX6DL_PAD_SD4_DAT7__UART2_TXD \
+ IOMUX_PAD(0x0744, 0x035C, 2, 0x0000, 0, MX6DL_UART_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT7__UART2_RXD \
+ IOMUX_PAD(0x0744, 0x035C, 2, 0x0904, 7, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT7__USBOH3_UH2_DFD_OUT_31 \
+ IOMUX_PAD(0x0744, 0x035C, 3, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT7__USBOH3_UH3_DFD_OUT_31 \
+ IOMUX_PAD(0x0744, 0x035C, 4, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT7__GPIO_2_15 \
+ IOMUX_PAD(0x0744, 0x035C, 5, 0x0000, 0, NO_PAD_CTRL)
+#define MX6DL_PAD_SD4_DAT7__IPU1_IPU_DIAG_BUS_15 \
+ IOMUX_PAD(0x0744, 0x035C, 6, 0x0000, 0, NO_PAD_CTRL)
+
+#endif /*__MACH_IOMUX_MX6DL_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/iomux-mx6q.h b/arch/arm/plat-mxc/include/mach/iomux-mx6q.h
index ca94008e8e76..3345cca68ecb 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-mx6q.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-mx6q.h
@@ -2429,7 +2429,7 @@ typedef enum iomux_config {
#define _MX6Q_PAD_GPIO_16__ENET_1588_EVENT2_IN \
IOMUX_PAD(0x0618, 0x0248, 1, 0x0000, 0, 0)
#define _MX6Q_PAD_GPIO_16__ENET_ANATOP_ETHERNET_REF_OUT \
- IOMUX_PAD(0x0618, 0x0248, 2, 0x083C, 1, 0)
+ IOMUX_PAD(0x0618, 0x0248, 0x12, 0x083C, 1, 0)
#define _MX6Q_PAD_GPIO_16__USDHC1_LCTL \
IOMUX_PAD(0x0618, 0x0248, 3, 0x0000, 0, 0)
#define _MX6Q_PAD_GPIO_16__SPDIF_IN1 \
diff --git a/arch/arm/plat-mxc/include/mach/mx6.h b/arch/arm/plat-mxc/include/mach/mx6.h
index e09be19b8d82..d4b31eaeb60c 100644
--- a/arch/arm/plat-mxc/include/mach/mx6.h
+++ b/arch/arm/plat-mxc/include/mach/mx6.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -41,231 +41,236 @@
* This option is used to set or clear the RXDMUXSEL bit in control reg 3.
* Certain platforms need this bit to be set in order to receive Irda data.
*/
-#define MXC_UART_IR_RXDMUX 0x0004
+#define MXC_UART_IR_RXDMUX 0x0004
/*!
* This option is used to set or clear the RXDMUXSEL bit in control reg 3.
* Certain platforms need this bit to be set in order to receive UART data.
*/
-#define MXC_UART_RXDMUX 0x0004
+#define MXC_UART_RXDMUX 0x0004
/*!
* The maximum frequency that the pixel clock can be at so as to
* activate DVFS-PER.
*/
-#define DVFS_MAX_PIX_CLK 54000000
+#define DVFS_MAX_PIX_CLK 54000000
/* IROM
*/
-#define IROM_BASE_ADDR 0x0
+#define IROM_BASE_ADDR 0x0
#define IROM_SIZE SZ_64K
/* CPU Memory Map */
-#define MMDC0_ARB_BASE_ADDR 0x10000000
-#define MMDC0_ARB_END_ADDR 0x7FFFFFFF
-#define MMDC1_ARB_BASE_ADDR 0x80000000
-#define MMDC1_ARB_END_ADDR 0xFFFFFFFF
-#define OCRAM_ARB_BASE_ADDR 0x00900000
-#define OCRAM_ARB_END_ADDR 0x009FFFFF
-#define IRAM_BASE_ADDR OCRAM_ARB_BASE_ADDR
-#define PCIE_ARB_BASE_ADDR 0x01000000
-#define PCIE_ARB_END_ADDR 0x01FFFFFF
+#define MMDC0_ARB_BASE_ADDR 0x10000000
+#define MMDC0_ARB_END_ADDR 0x7FFFFFFF
+#define MMDC1_ARB_BASE_ADDR 0x80000000
+#define MMDC1_ARB_END_ADDR 0xFFFFFFFF
+#define OCRAM_ARB_BASE_ADDR 0x00900000
+#define OCRAM_ARB_END_ADDR 0x009FFFFF
+#define IRAM_BASE_ADDR OCRAM_ARB_BASE_ADDR
+#define PCIE_ARB_BASE_ADDR 0x01000000
+#define PCIE_ARB_END_ADDR 0x01FFFFFF
/* IRAM
*/
#define MX6Q_IRAM_BASE_ADDR IRAM_BASE_ADDR
/* The last 4K is for cpu hotplug to workaround wdog issue*/
#define MX6Q_IRAM_SIZE (SZ_256K - SZ_4K)
+#define MX6DL_IRAM_SIZE (SZ_128K - SZ_4K)
/* Blocks connected via pl301periph */
-#define ROMCP_ARB_BASE_ADDR 0x00000000
-#define ROMCP_ARB_END_ADDR 0x000FFFFF
-#define BOOT_ROM_BASE_ADDR ROMCP_ARB_BASE_ADDR
-#define CAAM_ARB_BASE_ADDR 0x00100000
-#define CAAM_ARB_END_ADDR 0x00103FFF
-#define APBH_DMA_ARB_BASE_ADDR 0x00110000
-#define APBH_DMA_ARB_END_ADDR 0x00117FFF
-#define MX6Q_HDMI_ARB_BASE_ADDR 0x00120000
-#define MX6Q_HDMI_ARB_END_ADDR 0x00128FFF
-#define GPU_3D_ARB_BASE_ADDR 0x00130000
-#define GPU_3D_ARB_END_ADDR 0x00133FFF
-#define GPU_2D_ARB_BASE_ADDR 0x00134000
-#define GPU_2D_ARB_END_ADDR 0x00137FFF
-#define DTCP_ARB_BASE_ADDR 0x00138000
-#define DTCP_ARB_END_ADDR 0x0013BFFF
+#define ROMCP_ARB_BASE_ADDR 0x00000000
+#define ROMCP_ARB_END_ADDR 0x000FFFFF
+#define BOOT_ROM_BASE_ADDR ROMCP_ARB_BASE_ADDR
+#define CAAM_ARB_BASE_ADDR 0x00100000
+#define CAAM_ARB_END_ADDR 0x00103FFF
+#define APBH_DMA_ARB_BASE_ADDR 0x00110000
+#define APBH_DMA_ARB_END_ADDR 0x00117FFF
+#define MX6Q_HDMI_ARB_BASE_ADDR 0x00120000
+#define MX6Q_HDMI_ARB_END_ADDR 0x00128FFF
+#define GPU_3D_ARB_BASE_ADDR 0x00130000
+#define GPU_3D_ARB_END_ADDR 0x00133FFF
+#define GPU_2D_ARB_BASE_ADDR 0x00134000
+#define GPU_2D_ARB_END_ADDR 0x00137FFF
+#define DTCP_ARB_BASE_ADDR 0x00138000
+#define DTCP_ARB_END_ADDR 0x0013BFFF
/* GPV - PL301 configuration ports */
-#define GPV0_BASE_ADDR 0x00B00000
-#define GPV1_BASE_ADDR 0x00C00000
-#define GPV2_BASE_ADDR 0x00200000
-#define GPV3_BASE_ADDR 0x00300000
-#define GPV4_BASE_ADDR 0x00800000
-
-#define AIPS1_ARB_BASE_ADDR 0x02000000
-#define AIPS1_ARB_END_ADDR 0x020FFFFF
-#define AIPS2_ARB_BASE_ADDR 0x02100000
-#define AIPS2_ARB_END_ADDR 0x021FFFFF
-#define MX6Q_SATA_BASE_ADDR 0x02200000
-#define SATA_ARB_END_ADDR 0x02203FFF
-#define OPENVG_ARB_BASE_ADDR 0x02204000
-#define OPENVG_ARB_END_ADDR 0x02207FFF
-#define HSI_ARB_BASE_ADDR 0x02208000
-#define HSI_ARB_END_ADDR 0x0220BFFF
-#define MX6Q_IPU1_ARB_BASE_ADDR 0x02400000
-#define MX6Q_IPU1_ARB_END_ADDR 0x027FFFFF
-#define MX6Q_IPU2_ARB_BASE_ADDR 0x02800000
-#define MX6Q_IPU2_ARB_END_ADDR 0x02BFFFFF
-#define WEIM_ARB_BASE_ADDR 0x08000000
-#define WEIM_ARB_END_ADDR 0x0FFFFFFF
+#define GPV0_BASE_ADDR 0x00B00000
+#define GPV1_BASE_ADDR 0x00C00000
+#define GPV2_BASE_ADDR 0x00200000
+#define GPV3_BASE_ADDR 0x00300000
+#define GPV4_BASE_ADDR 0x00800000
+
+#define AIPS1_ARB_BASE_ADDR 0x02000000
+#define AIPS1_ARB_END_ADDR 0x020FFFFF
+#define AIPS2_ARB_BASE_ADDR 0x02100000
+#define AIPS2_ARB_END_ADDR 0x021FFFFF
+#define MX6Q_SATA_BASE_ADDR 0x02200000
+#define MX6Q_SATA_ARB_END_ADDR 0x02203FFF
+#define OPENVG_ARB_BASE_ADDR 0x02204000
+#define OPENVG_ARB_END_ADDR 0x02207FFF
+#define HSI_ARB_BASE_ADDR 0x02208000
+#define HSI_ARB_END_ADDR 0x0220BFFF
+#define MX6Q_IPU1_ARB_BASE_ADDR 0x02400000
+#define MX6Q_IPU1_ARB_END_ADDR 0x027FFFFF
+#define MX6Q_IPU2_ARB_BASE_ADDR 0x02800000
+#define MX6Q_IPU2_ARB_END_ADDR 0x02BFFFFF
+#define WEIM_ARB_BASE_ADDR 0x08000000
+#define WEIM_ARB_END_ADDR 0x0FFFFFFF
/* Legacy Defines */
-#define CSD0_DDR_BASE_ADDR MMDC0_ARB_BASE_ADDR
-#define CSD1_DDR_BASE_ADDR MMDC1_ARB_BASE_ADDR
-#define CS0_BASE_ADDR WEIM_ARB_BASE_ADDR
-#define NAND_FLASH_BASE_ADDR APBH_DMA_ARB_BASE_ADDR
+#define CSD0_DDR_BASE_ADDR MMDC0_ARB_BASE_ADDR
+#define CSD1_DDR_BASE_ADDR MMDC1_ARB_BASE_ADDR
+#define CS0_BASE_ADDR WEIM_ARB_BASE_ADDR
+#define NAND_FLASH_BASE_ADDR APBH_DMA_ARB_BASE_ADDR
#define MX6Q_GPMI_BASE_ADDR (APBH_DMA_ARB_BASE_ADDR + 0x02000)
#define MX6Q_BCH_BASE_ADDR (APBH_DMA_ARB_BASE_ADDR + 0x04000)
/* Defines for Blocks connected via AIPS (SkyBlue) */
-#define ATZ1_BASE_ADDR AIPS1_ARB_BASE_ADDR
-#define ATZ2_BASE_ADDR AIPS2_ARB_BASE_ADDR
+#define ATZ1_BASE_ADDR AIPS1_ARB_BASE_ADDR
+#define ATZ2_BASE_ADDR AIPS2_ARB_BASE_ADDR
/* slots 0,7 of SDMA reserved, therefore left unused in IPMUX3 */
-#define MX6Q_SPDIF_BASE_ADDR (ATZ1_BASE_ADDR + 0x04000) /* slot 1 */
-#define MX6Q_ECSPI1_BASE_ADDR (ATZ1_BASE_ADDR + 0x08000) /* slot 2 */
-#define MX6Q_ECSPI2_BASE_ADDR (ATZ1_BASE_ADDR + 0x0C000) /* slot 3 */
-#define MX6Q_ECSPI3_BASE_ADDR (ATZ1_BASE_ADDR + 0x10000) /* slot 4 */
-#define MX6Q_ECSPI4_BASE_ADDR (ATZ1_BASE_ADDR + 0x14000) /* slot 5 */
-#define MX6Q_ECSPI5_BASE_ADDR (ATZ1_BASE_ADDR + 0x18000) /* slot 6 */
-#define UART1_BASE_ADDR (ATZ1_BASE_ADDR + 0x20000) /* slot 8 */
-#define ESAI1_BASE_ADDR (ATZ1_BASE_ADDR + 0x24000) /* slot 9 */
-#define MX6Q_SSI1_BASE_ADDR (ATZ1_BASE_ADDR + 0x28000) /* slot 10 */
-#define MX6Q_SSI2_BASE_ADDR (ATZ1_BASE_ADDR + 0x2C000) /* slot 11 */
-#define MX6Q_SSI3_BASE_ADDR (ATZ1_BASE_ADDR + 0x30000) /* slot 12 */
-#define MX6Q_ASRC_BASE_ADDR (ATZ1_BASE_ADDR + 0x34000) /* slot 13 */
-#define SPBA_BASE_ADDR (ATZ1_BASE_ADDR + 0x3C000) /* slot 15 */
-#define MX6Q_VPU_BASE_ADDR (ATZ1_BASE_ADDR + 0x40000) /* slot 33,
+#define MX6Q_SPDIF_BASE_ADDR (ATZ1_BASE_ADDR + 0x04000) /* slot 1 */
+#define MX6Q_ECSPI1_BASE_ADDR (ATZ1_BASE_ADDR + 0x08000) /* slot 2 */
+#define MX6Q_ECSPI2_BASE_ADDR (ATZ1_BASE_ADDR + 0x0C000) /* slot 3 */
+#define MX6Q_ECSPI3_BASE_ADDR (ATZ1_BASE_ADDR + 0x10000) /* slot 4 */
+#define MX6Q_ECSPI4_BASE_ADDR (ATZ1_BASE_ADDR + 0x14000) /* slot 5 */
+#define MX6Q_ECSPI5_BASE_ADDR (ATZ1_BASE_ADDR + 0x18000) /* slot 6 */
+#define UART1_BASE_ADDR (ATZ1_BASE_ADDR + 0x20000) /* slot 8 */
+#define ESAI1_BASE_ADDR (ATZ1_BASE_ADDR + 0x24000) /* slot 9 */
+#define MX6Q_SSI1_BASE_ADDR (ATZ1_BASE_ADDR + 0x28000) /* slot 10 */
+#define MX6Q_SSI2_BASE_ADDR (ATZ1_BASE_ADDR + 0x2C000) /* slot 11 */
+#define MX6Q_SSI3_BASE_ADDR (ATZ1_BASE_ADDR + 0x30000) /* slot 12 */
+#define MX6Q_ASRC_BASE_ADDR (ATZ1_BASE_ADDR + 0x34000) /* slot 13 */
+#define SPBA_BASE_ADDR (ATZ1_BASE_ADDR + 0x3C000) /* slot 15 */
+#define MX6Q_VPU_BASE_ADDR (ATZ1_BASE_ADDR + 0x40000) /* slot 33,
global en[1], til 0x7BFFF */
/* ATZ#1- On Platform */
-#define AIPS1_ON_BASE_ADDR (ATZ1_BASE_ADDR + 0x7C000)
+#define AIPS1_ON_BASE_ADDR (ATZ1_BASE_ADDR + 0x7C000)
/* ATZ#1- Off Platform */
-#define AIPS1_OFF_BASE_ADDR (ATZ1_BASE_ADDR + 0x80000)
-
-#define MX6Q_PWM1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x0000)
-#define MX6Q_PWM2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x4000)
-#define MX6Q_PWM3_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x8000)
-#define MX6Q_PWM4_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0xC000)
-#define MX6Q_CAN1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x10000)
-#define MX6Q_CAN2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x14000)
-#define GPT_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x18000)
-#define GPIO1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x1C000)
-#define GPIO2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x20000)
-#define GPIO3_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x24000)
-#define GPIO4_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x28000)
-#define GPIO5_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x2C000)
-#define GPIO6_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x30000)
-#define GPIO7_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x34000)
-#define KPP_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x38000)
-#define MX6Q_WDOG1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x3C000)
-#define MX6Q_WDOG2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x40000)
-#define CCM_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x44000)
-#define ANATOP_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x48000)
-#define USB_PHY0_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x49000)
-#define USB_PHY1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x4a000)
-#define MX6Q_SNVS_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x4C000)
-#define EPIT1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x50000)
-#define EPIT2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x54000)
-#define SRC_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x58000)
-#define GPC_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x5C000)
-#define MX6Q_IOMUXC_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x60000)
-#define DCIC1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x64000)
-#define DCIC2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x68000)
-#define MX6Q_SDMA_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x6C000)
-#define MX6Q_DVFSCORE_BASE_ADDR (GPC_BASE_ADDR + 0x180)
+#define AIPS1_OFF_BASE_ADDR (ATZ1_BASE_ADDR + 0x80000)
+
+#define MX6Q_PWM1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x0000)
+#define MX6Q_PWM2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x4000)
+#define MX6Q_PWM3_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x8000)
+#define MX6Q_PWM4_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0xC000)
+#define MX6Q_CAN1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x10000)
+#define MX6Q_CAN2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x14000)
+#define GPT_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x18000)
+#define GPIO1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x1C000)
+#define GPIO2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x20000)
+#define GPIO3_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x24000)
+#define GPIO4_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x28000)
+#define GPIO5_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x2C000)
+#define GPIO6_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x30000)
+#define GPIO7_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x34000)
+#define KPP_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x38000)
+#define MX6Q_WDOG1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x3C000)
+#define MX6Q_WDOG2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x40000)
+#define CCM_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x44000)
+#define ANATOP_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x48000)
+#define USB_PHY0_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x49000)
+#define USB_PHY1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x4a000)
+#define MX6Q_SNVS_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x4C000)
+#define EPIT1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x50000)
+#define EPIT2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x54000)
+#define SRC_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x58000)
+#define GPC_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x5C000)
+#define MX6Q_IOMUXC_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x60000)
+#define DCIC1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x64000)
+#define DCIC2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x68000)
+#define MX6Q_SDMA_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x6C000)
+#define MX6DL_EPXP_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x70000)
+#define MX6DL_EPDC_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x74000)
+#define MX6DL_LCDIF_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x78000)
+#define MX6Q_DVFSCORE_BASE_ADDR (GPC_BASE_ADDR + 0x180)
/* ATZ#2- On Platform */
-#define AIPS2_ON_BASE_ADDR (ATZ2_BASE_ADDR + 0x7C000)
+#define AIPS2_ON_BASE_ADDR (ATZ2_BASE_ADDR + 0x7C000)
/* ATZ#2- Off Platform */
-#define AIPS2_OFF_BASE_ADDR (ATZ2_BASE_ADDR + 0x80000)
+#define AIPS2_OFF_BASE_ADDR (ATZ2_BASE_ADDR + 0x80000)
/* ATZ#2 - Global enable (0) */
-#define CAAM_BASE_ADDR ATZ2_BASE_ADDR
-#define ARM_BASE_ADDR (ATZ2_BASE_ADDR + 0x40000)
+#define CAAM_BASE_ADDR ATZ2_BASE_ADDR
+#define ARM_BASE_ADDR (ATZ2_BASE_ADDR + 0x40000)
/* ARM Cortex A9 MPCore Platform */
#define MX6Q_A9_PLATFRM_BASE (ARM_BASE_ADDR + 0x20000)
-#define MX6Q_PL301_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x0000)
-#define MX6Q_USB_OTG_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4000)
-#define MX6Q_USB_HS1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4200)
-#define MX6Q_USB_HS2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4400)
-#define MX6Q_USB_HS3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4600)
-#define ENET_BASE_ADDR (AIPS2_OFF_BASE_ADDR+0x8000)
-#define MLB_BASE_ADDR (AIPS2_OFF_BASE_ADDR+0xC000)
-
-#define MX6Q_USDHC1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x10000)
-#define MX6Q_USDHC2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x14000)
-#define MX6Q_USDHC3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x18000)
-#define MX6Q_USDHC4_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x1C000)
-#define MX6Q_I2C1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x20000)
-#define MX6Q_I2C2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x24000)
-#define MX6Q_I2C3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x28000)
-#define ROMCP_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x2C000)
-#define MMDC_P0_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x30000)
-#define MMDC_P1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x34000)
-#define WEIM_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x38000)
-#define OCOTP_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x3C000)
-#define CSU_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x40000)
-#define IP2APB_PERFMON1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x44000)
-#define IP2APB_PERFMON2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x48000)
-#define IP2APB_PERFMON3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4C000)
-#define IP2APB_TZASC1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x50000)
-#define IP2APB_TZASC2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x54000)
-#define MX6Q_AUDMUX_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x58000)
-#define MIPI_CSI2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x5C000)
-#define MIPI_DSI_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x60000)
-#define VDOA_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x64000)
-#define UART2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x68000)
-#define UART3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x6C000)
-#define UART4_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x70000)
-#define UART5_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x74000)
+#define MX6Q_PL301_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x0000)
+#define MX6Q_USB_OTG_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4000)
+#define MX6Q_USB_HS1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4200)
+#define MX6Q_USB_HS2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4400)
+#define MX6Q_USB_HS3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4600)
+#define ENET_BASE_ADDR (AIPS2_OFF_BASE_ADDR+0x8000)
+#define MLB_BASE_ADDR (AIPS2_OFF_BASE_ADDR+0xC000)
+
+#define MX6Q_USDHC1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x10000)
+#define MX6Q_USDHC2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x14000)
+#define MX6Q_USDHC3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x18000)
+#define MX6Q_USDHC4_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x1C000)
+#define MX6Q_I2C1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x20000)
+#define MX6Q_I2C2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x24000)
+#define MX6Q_I2C3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x28000)
+#define ROMCP_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x2C000)
+#define MMDC_P0_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x30000)
+#define MMDC_P1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x34000)
+#define WEIM_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x38000)
+#define OCOTP_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x3C000)
+#define CSU_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x40000)
+#define IP2APB_PERFMON1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x44000)
+#define IP2APB_PERFMON2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x48000)
+#define IP2APB_PERFMON3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4C000)
+#define IP2APB_TZASC1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x50000)
+#define IP2APB_TZASC2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x54000)
+#define MX6Q_AUDMUX_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x58000)
+#define MIPI_CSI2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x5C000)
+#define MIPI_DSI_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x60000)
+#define VDOA_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x64000)
+#define UART2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x68000)
+#define UART3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x6C000)
+#define UART4_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x70000)
+#define UART5_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x74000)
+#define MX6DL_I2C4_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x78000)
/* Cortex-A9 MPCore private memory region */
-#define ARM_PERIPHBASE 0x00A00000
-#define SCU_BASE_ADDR ARM_PERIPHBASE
+#define ARM_PERIPHBASE 0x00A00000
+#define SCU_BASE_ADDR ARM_PERIPHBASE
#define LOCAL_TWD_ADDR (SCU_BASE_ADDR + 0x600)
-#define IC_INTERFACES_BASE_ADDR (ARM_PERIPHBASE + 0x0100)
-#define GLOBAL_TIMER_BASE_ADDR (ARM_PERIPHBASE + 0x0200)
-#define PRIVATE_TIMERS_WD_BASE_ADDR (ARM_PERIPHBASE + 0x0600)
-#define IC_DISTRIBUTOR_BASE_ADDR (ARM_PERIPHBASE + 0x1000)
+#define IC_INTERFACES_BASE_ADDR (ARM_PERIPHBASE + 0x0100)
+#define GLOBAL_TIMER_BASE_ADDR (ARM_PERIPHBASE + 0x0200)
+#define PRIVATE_TIMERS_WD_BASE_ADDR (ARM_PERIPHBASE + 0x0600)
+#define IC_DISTRIBUTOR_BASE_ADDR (ARM_PERIPHBASE + 0x1000)
#define L2_BASE_ADDR (ARM_PERIPHBASE + 0x2000)
-#define MX6Q_UART1_BASE_ADDR UART1_BASE_ADDR
-#define MX6Q_UART2_BASE_ADDR UART2_BASE_ADDR
-#define MX6Q_UART3_BASE_ADDR UART3_BASE_ADDR
-#define MX6Q_UART4_BASE_ADDR UART4_BASE_ADDR
-#define MX6Q_FEC_BASE_ADDR ENET_BASE_ADDR
-#define MX6Q_MIPI_DSI_BASE_ADDR MIPI_DSI_BASE_ADDR
+#define MX6Q_UART1_BASE_ADDR UART1_BASE_ADDR
+#define MX6Q_UART2_BASE_ADDR UART2_BASE_ADDR
+#define MX6Q_UART3_BASE_ADDR UART3_BASE_ADDR
+#define MX6Q_UART4_BASE_ADDR UART4_BASE_ADDR
+#define MX6Q_FEC_BASE_ADDR ENET_BASE_ADDR
+#define MX6Q_MIPI_DSI_BASE_ADDR MIPI_DSI_BASE_ADDR
#define MX6Q_MIPI_CSI2_BASE_ADDR MIPI_CSI2_BASE_ADDR
/* define virtual address */
-#define PERIPBASE_VIRT 0xF2000000
-#define BOOT_ROM_BASE_ADDR_VIRT (PERIPBASE_VIRT + BOOT_ROM_BASE_ADDR)
-#define AIPS1_BASE_ADDR_VIRT (PERIPBASE_VIRT + AIPS1_ARB_BASE_ADDR)
-#define AIPS2_BASE_ADDR_VIRT (PERIPBASE_VIRT + AIPS2_ARB_BASE_ADDR)
-#define ARM_PERIPHBASE_VIRT (PERIPBASE_VIRT + ARM_PERIPHBASE)
-#define ROMCP_SIZE SZ_1M
-#define AIPS1_SIZE SZ_1M
-#define AIPS2_SIZE SZ_1M
-#define ARM_PERIPHBASE_SIZE (SZ_8K + SZ_4K)
+#define PERIPBASE_VIRT 0xF2000000
+#define BOOT_ROM_BASE_ADDR_VIRT (PERIPBASE_VIRT + BOOT_ROM_BASE_ADDR)
+#define AIPS1_BASE_ADDR_VIRT (PERIPBASE_VIRT + AIPS1_ARB_BASE_ADDR)
+#define AIPS2_BASE_ADDR_VIRT (PERIPBASE_VIRT + AIPS2_ARB_BASE_ADDR)
+#define ARM_PERIPHBASE_VIRT (PERIPBASE_VIRT + ARM_PERIPHBASE)
+#define ROMCP_SIZE SZ_1M
+#define AIPS1_SIZE SZ_1M
+#define AIPS2_SIZE SZ_1M
+#define ARM_PERIPHBASE_SIZE (SZ_8K + SZ_4K)
/* GPC offsets */
#define MXC_GPC_CNTR_OFFSET 0x0
-#define MX6_IO_ADDRESS(x) (void __force __iomem *)((x) + PERIPBASE_VIRT)
+#define MX6_IO_ADDRESS(x) (void __force __iomem *)((x) + PERIPBASE_VIRT)
/*!
* This macro defines the physical to virtual address mapping for all the
@@ -283,151 +288,153 @@
/*
* Interrupt numbers
*/
-#define MXC_INT_START 32
-#define MXC_INT_GPR 32
-#define MXC_INT_CHEETAH_CSYSPWRUPREQ 33
-#define MX6Q_INT_SDMA 34
-#define MX6Q_INT_VPU_JPG 35
-#define MXC_INT_INTERRUPT_36_NUM 36
-#define MX6Q_INT_IPU1_ERR 37
-#define MX6Q_INT_IPU1_SYN 38
-#define MX6Q_INT_IPU2_ERR 39
-#define MX6Q_INT_IPU2_SYN 40
-#define MXC_INT_GPU3D_IRQ 41
-#define MXC_INT_GPU2D_IRQ 42
-#define MXC_INT_OPENVG_XAQ2 43
-#define MX6Q_INT_VPU_IPI 44
-#define MXC_INT_APBHDMA_DMA 45
-#define MXC_INT_WEIM 46
-#define MXC_INT_RAWNAND_BCH 47
-#define MXC_INT_RAWNAND_GPMI 48
-#define MXC_INT_DTCP 49
-#define MXC_INT_VDOA 50
-#define MX6Q_INT_SNVS 51
-#define MXC_INT_SNVS_SEC 52
-#define MXC_INT_CSU 53
-#define MX6Q_INT_USDHC1 54
-#define MX6Q_INT_USDHC2 55
-#define MX6Q_INT_USDHC3 56
-#define MX6Q_INT_USDHC4 57
-#define MXC_INT_UART1_ANDED 58
-#define MXC_INT_UART2_ANDED 59
-#define MXC_INT_UART3_ANDED 60
-#define MXC_INT_UART4_ANDED 61
-#define MXC_INT_UART5_ANDED 62
-#define MX6Q_INT_ECSPI1 63
-#define MX6Q_INT_ECSPI2 64
-#define MX6Q_INT_ECSPI3 65
-#define MX6Q_INT_ECSPI4 66
-#define MX6Q_INT_ECSPI5 67
-#define MX6Q_INT_I2C1 68
-#define MX6Q_INT_I2C2 69
-#define MX6Q_INT_I2C3 70
-#define MX6Q_INT_SATA 71
-#define MX6Q_INT_USB_HS1 72
-#define MX6Q_INT_USB_HS2 73
-#define MX6Q_INT_USB_HS3 74
-#define MX6Q_INT_USB_OTG 75
-#define MX6Q_INT_USB_PHY0 76
-#define MX6Q_INT_USB_PHY1 77
+#define MXC_INT_START 32
+#define MXC_INT_GPR 32
+#define MXC_INT_CHEETAH_CSYSPWRUPREQ 33
+#define MX6Q_INT_SDMA 34
+#define MX6Q_INT_VPU_JPG 35
+#define MXC_INT_INTERRUPT_36_NUM 36
+#define MX6Q_INT_IPU1_ERR 37
+#define MX6Q_INT_IPU1_SYN 38
+#define MX6Q_INT_IPU2_ERR 39
+#define MX6Q_INT_IPU2_SYN 40
+#define MXC_INT_GPU3D_IRQ 41
+#define MXC_INT_GPU2D_IRQ 42
+#define MXC_INT_OPENVG_XAQ2 43
+#define MX6Q_INT_VPU_IPI 44
+#define MXC_INT_APBHDMA_DMA 45
+#define MXC_INT_WEIM 46
+#define MXC_INT_RAWNAND_BCH 47
+#define MXC_INT_RAWNAND_GPMI 48
+#define MXC_INT_DTCP 49
+#define MXC_INT_VDOA 50
+#define MX6Q_INT_SNVS 51
+#define MXC_INT_SNVS_SEC 52
+#define MXC_INT_CSU 53
+#define MX6Q_INT_USDHC1 54
+#define MX6Q_INT_USDHC2 55
+#define MX6Q_INT_USDHC3 56
+#define MX6Q_INT_USDHC4 57
+#define MXC_INT_UART1_ANDED 58
+#define MXC_INT_UART2_ANDED 59
+#define MXC_INT_UART3_ANDED 60
+#define MXC_INT_UART4_ANDED 61
+#define MXC_INT_UART5_ANDED 62
+#define MX6Q_INT_ECSPI1 63
+#define MX6Q_INT_ECSPI2 64
+#define MX6Q_INT_ECSPI3 65
+#define MX6Q_INT_ECSPI4 66
+#define MX6Q_INT_ECSPI5 67
+#define MX6DL_INT_I2C4 67
+#define MX6Q_INT_I2C1 68
+#define MX6Q_INT_I2C2 69
+#define MX6Q_INT_I2C3 70
+#define MX6Q_INT_SATA 71
+#define MX6DL_INT_LCDIF 71
+#define MX6Q_INT_USB_HS1 72
+#define MX6Q_INT_USB_HS2 73
+#define MX6Q_INT_USB_HS3 74
+#define MX6Q_INT_USB_OTG 75
+#define MX6Q_INT_USB_PHY0 76
+#define MX6Q_INT_USB_PHY1 77
/*
* MX6Q_INT_USB_PHY2, MX6Q_INT_USB_PHY3 are dummy interrupts
* In order to compile pass for platform device's definition
*/
-#define MX6Q_INT_USB_PHY2 73
-#define MX6Q_INT_USB_PHY3 74
-#define MX6Q_INT_SSI1 78
-#define MX6Q_INT_SSI2 79
-#define MX6Q_INT_SSI3 80
-#define MXC_INT_ANATOP_TEMPSNSR 81
-#define MX6Q_INT_ASRC 82
-#define MXC_INT_ESAI 83
-#define MX6Q_INT_SPDIF 84
-#define MXC_INT_MLB 85
-#define MXC_INT_ANATOP_ANA1 86
-#define MXC_INT_GPT 87
-#define MXC_INT_EPIT1 88
-#define MXC_INT_EPIT2 89
-#define MXC_INT_GPIO1_INT7_NUM 90
-#define MXC_INT_GPIO1_INT6_NUM 91
-#define MXC_INT_GPIO1_INT5_NUM 92
-#define MXC_INT_GPIO1_INT4_NUM 93
-#define MXC_INT_GPIO1_INT3_NUM 94
-#define MXC_INT_GPIO1_INT2_NUM 95
-#define MXC_INT_GPIO1_INT1_NUM 96
-#define MXC_INT_GPIO1_INT0_NUM 97
-#define MXC_INT_GPIO1_INT15_0_NUM 98
-#define MXC_INT_GPIO1_INT31_16_NUM 99
-#define MXC_INT_GPIO2_INT15_0_NUM 100
-#define MXC_INT_GPIO2_INT31_16_NUM 101
-#define MXC_INT_GPIO3_INT15_0_NUM 102
-#define MXC_INT_GPIO3_INT31_16_NUM 103
-#define MXC_INT_GPIO4_INT15_0_NUM 104
-#define MXC_INT_GPIO4_INT31_16_NUM 105
-#define MXC_INT_GPIO5_INT15_0_NUM 106
-#define MXC_INT_GPIO5_INT31_16_NUM 107
-#define MXC_INT_GPIO6_INT15_0_NUM 108
-#define MXC_INT_GPIO6_INT31_16_NUM 109
-#define MXC_INT_GPIO7_INT15_0_NUM 110
-#define MXC_INT_GPIO7_INT31_16_NUM 111
-#define MXC_INT_WDOG1 112
-#define MXC_INT_WDOG2 113
-#define MXC_INT_KPP 114
-#define MX6Q_INT_PWM1 115
-#define MX6Q_INT_PWM2 116
-#define MX6Q_INT_PWM3 117
-#define MX6Q_INT_PWM4 118
-#define MXC_INT_CCM_INT1_NUM 119
-#define MXC_INT_CCM_INT2_NUM 120
-#define MX6Q_INT_GPC1 121
-#define MXC_INT_GPC_INT2_NUM 122
-#define MXC_INT_SRC 123
-#define MXC_INT_CHEETAH_L2 124
-#define MXC_INT_CHEETAH_PARITY 125
-#define MXC_INT_CHEETAH_PERFORM 126
-#define MXC_INT_CHEETAH_TRIGGER 127
-#define MXC_INT_SRC_CPU_WDOG 128
-#define MXC_INT_INTERRUPT_129_NUM 129
-#define MXC_INT_INTERRUPT_130_NUM 130
-#define MXC_INT_INTERRUPT_131_NUM 131
-#define MXC_INT_CSI_INTR1 132
-#define MXC_INT_CSI_INTR2 133
-#define MXC_INT_DSI 134
-#define MXC_INT_HSI 135
-#define MXC_INT_SJC 136
-#define MXC_INT_CAAM_INT0_NUM 137
-#define MXC_INT_CAAM_INT1_NUM 138
-#define MXC_INT_INTERRUPT_139_NUM 139
-#define MXC_INT_TZASC1 140
-#define MXC_INT_TZASC2 141
-#define MX6Q_INT_CAN1 142
-#define MX6Q_INT_CAN2 143
-#define MXC_INT_PERFMON1 144
-#define MXC_INT_PERFMON2 145
-#define MXC_INT_PERFMON3 146
-#define MX6Q_INT_HDMI_TX 147
-#define MX6Q_INT_HDMI_TX_WAKEUP 148
-#define MXC_INT_MLB_AHB0 149
-#define MXC_INT_ENET1 150
-#define MXC_INT_ENET2 151
-#define MXC_INT_PCIE_0 152
-#define MXC_INT_PCIE_1 153
-#define MXC_INT_PCIE_2 154
-#define MXC_INT_PCIE_3 155
-#define MXC_INT_DCIC1 156
-#define MXC_INT_DCIC2 157
-#define MXC_INT_MLB_AHB1 158
-#define MXC_INT_ANATOP_ANA2 159
-#define MXC_INT_END 159
-
-#define MX6Q_INT_UART1 MXC_INT_UART1_ANDED
-#define MX6Q_INT_UART2 MXC_INT_UART2_ANDED
-#define MX6Q_INT_UART3 MXC_INT_UART3_ANDED
-#define MX6Q_INT_UART4 MXC_INT_UART4_ANDED
-#define MX6Q_INT_FEC MXC_INT_ENET1
-#define MX6Q_INT_DSI MXC_INT_DSI
-
-#define IRQ_LOCALTIMER 29
+#define MX6Q_INT_USB_PHY2 73
+#define MX6Q_INT_USB_PHY3 74
+#define MX6Q_INT_SSI1 78
+#define MX6Q_INT_SSI2 79
+#define MX6Q_INT_SSI3 80
+#define MXC_INT_ANATOP_TEMPSNSR 81
+#define MX6Q_INT_ASRC 82
+#define MXC_INT_ESAI 83
+#define MX6Q_INT_SPDIF 84
+#define MXC_INT_MLB 85
+#define MXC_INT_ANATOP_ANA1 86
+#define MXC_INT_GPT 87
+#define MXC_INT_EPIT1 88
+#define MXC_INT_EPIT2 89
+#define MXC_INT_GPIO1_INT7_NUM 90
+#define MXC_INT_GPIO1_INT6_NUM 91
+#define MXC_INT_GPIO1_INT5_NUM 92
+#define MXC_INT_GPIO1_INT4_NUM 93
+#define MXC_INT_GPIO1_INT3_NUM 94
+#define MXC_INT_GPIO1_INT2_NUM 95
+#define MXC_INT_GPIO1_INT1_NUM 96
+#define MXC_INT_GPIO1_INT0_NUM 97
+#define MXC_INT_GPIO1_INT15_0_NUM 98
+#define MXC_INT_GPIO1_INT31_16_NUM 99
+#define MXC_INT_GPIO2_INT15_0_NUM 100
+#define MXC_INT_GPIO2_INT31_16_NUM 101
+#define MXC_INT_GPIO3_INT15_0_NUM 102
+#define MXC_INT_GPIO3_INT31_16_NUM 103
+#define MXC_INT_GPIO4_INT15_0_NUM 104
+#define MXC_INT_GPIO4_INT31_16_NUM 105
+#define MXC_INT_GPIO5_INT15_0_NUM 106
+#define MXC_INT_GPIO5_INT31_16_NUM 107
+#define MXC_INT_GPIO6_INT15_0_NUM 108
+#define MXC_INT_GPIO6_INT31_16_NUM 109
+#define MXC_INT_GPIO7_INT15_0_NUM 110
+#define MXC_INT_GPIO7_INT31_16_NUM 111
+#define MXC_INT_WDOG1 112
+#define MXC_INT_WDOG2 113
+#define MXC_INT_KPP 114
+#define MX6Q_INT_PWM1 115
+#define MX6Q_INT_PWM2 116
+#define MX6Q_INT_PWM3 117
+#define MX6Q_INT_PWM4 118
+#define MXC_INT_CCM_INT1_NUM 119
+#define MXC_INT_CCM_INT2_NUM 120
+#define MX6Q_INT_GPC1 121
+#define MXC_INT_GPC_INT2_NUM 122
+#define MXC_INT_SRC 123
+#define MXC_INT_CHEETAH_L2 124
+#define MXC_INT_CHEETAH_PARITY 125
+#define MXC_INT_CHEETAH_PERFORM 126
+#define MXC_INT_CHEETAH_TRIGGER 127
+#define MXC_INT_SRC_CPU_WDOG 128
+#define MX6DL_INT_EPDC 129
+#define MX6DL_INT_EPXP 130
+#define MXC_INT_INTERRUPT_131_NUM 131
+#define MXC_INT_CSI_INTR1 132
+#define MXC_INT_CSI_INTR2 133
+#define MXC_INT_DSI 134
+#define MXC_INT_HSI 135
+#define MXC_INT_SJC 136
+#define MXC_INT_CAAM_INT0_NUM 137
+#define MXC_INT_CAAM_INT1_NUM 138
+#define MXC_INT_INTERRUPT_139_NUM 139
+#define MXC_INT_TZASC1 140
+#define MXC_INT_TZASC2 141
+#define MX6Q_INT_CAN1 142
+#define MX6Q_INT_CAN2 143
+#define MX6Q_INT_PERFMON1 144
+#define MX6Q_INT_PERFMON2 145
+#define MX6Q_INT_PERFMON3 146
+#define MX6Q_INT_HDMI_TX 147
+#define MX6Q_INT_HDMI_TX_WAKEUP 148
+#define MXC_INT_MLB_AHB0 149
+#define MXC_INT_ENET1 150
+#define MXC_INT_ENET2 151
+#define MXC_INT_PCIE_0 152
+#define MXC_INT_PCIE_1 153
+#define MXC_INT_PCIE_2 154
+#define MXC_INT_PCIE_3 155
+#define MXC_INT_DCIC1 156
+#define MXC_INT_DCIC2 157
+#define MXC_INT_MLB_AHB1 158
+#define MXC_INT_ANATOP_ANA2 159
+#define MXC_INT_END 159
+
+#define MX6Q_INT_UART1 MXC_INT_UART1_ANDED
+#define MX6Q_INT_UART2 MXC_INT_UART2_ANDED
+#define MX6Q_INT_UART3 MXC_INT_UART3_ANDED
+#define MX6Q_INT_UART4 MXC_INT_UART4_ANDED
+#define MX6Q_INT_FEC MXC_INT_ENET1
+#define MX6Q_INT_DSI MXC_INT_DSI
+
+#define IRQ_LOCALTIMER 29
/* APBH-DMA */
#define MX6Q_DMA_CHANNEL_AHB_APBH_GPMI0 0
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index 628ef1467a6b..c8f18052c6af 100755
--- a/arch/arm/plat-mxc/include/mach/mxc.h
+++ b/arch/arm/plat-mxc/include/mach/mxc.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2007, 2011 Freescale Semiconductor, Inc.
+ * Copyright 2004-2007, 2011-2012 Freescale Semiconductor, Inc.
* Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
*
* This program is free software; you can redistribute it and/or
@@ -36,6 +36,8 @@
#define MXC_CPU_MX50 50
#define MXC_CPU_MX51 51
#define MXC_CPU_MX53 53
+#define MXC_CPU_MX6Q 63
+#define MXC_CPU_MX6DL 61
#define IMX_CHIP_REVISION_1_0 0x10
#define IMX_CHIP_REVISION_1_1 0x11
@@ -218,12 +220,20 @@ extern unsigned int __mxc_cpu_type;
# define cpu_is_mx53() (0)
#endif
-#ifndef __ASSEMBLY__
+#ifdef CONFIG_SOC_IMX6Q
+# define mxc_cpu_type __mxc_cpu_type
+# define cpu_is_mx6q() (mxc_cpu_type == MXC_CPU_MX6Q)
+# define cpu_is_mx6dl() (mxc_cpu_type == MXC_CPU_MX6DL)
+#else
+# define cpu_is_mx6q() (0)
+# define cpu_is_mx6dl() (0)
+#endif
+#ifndef __ASSEMBLY__
#ifdef CONFIG_SOC_IMX6Q
-#define cpu_is_mx6q() (1)
+extern int mx6q_revision(void);
#else
-#define cpu_is_mx6q() (0)
+#define mx6q_revision(void) (0)
#endif
struct cpu_op {
@@ -264,6 +274,7 @@ extern int tzic_enable_wake(int is_idle);
#define cpu_is_mx5() (cpu_is_mx51() || cpu_is_mx53() || cpu_is_mx50())
#define cpu_is_mx3() (cpu_is_mx31() || cpu_is_mx35())
#define cpu_is_mx2() (cpu_is_mx21() || cpu_is_mx27())
+#define cpu_is_mx6() (cpu_is_mx6q() || cpu_is_mx6dl())
#define MXC_PGCR_PCR 1
#define MXC_SRPGCR_PCR 1
diff --git a/arch/arm/plat-mxc/include/mach/mxc_edid.h b/arch/arm/plat-mxc/include/mach/mxc_edid.h
index 4cbbb78ad703..10baa01bf9b1 100755
--- a/arch/arm/plat-mxc/include/mach/mxc_edid.h
+++ b/arch/arm/plat-mxc/include/mach/mxc_edid.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2009-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -26,10 +26,31 @@
#ifndef MXC_EDID_H
#define MXC_EDID_H
+#include <linux/fb.h>
+
#define FB_VMODE_ASPECT_4_3 0x10
#define FB_VMODE_ASPECT_16_9 0x20
#define FB_VMODE_ASPECT_MASK (FB_VMODE_ASPECT_4_3 | FB_VMODE_ASPECT_16_9)
+enum cea_audio_coding_types {
+ AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0,
+ AUDIO_CODING_TYPE_LPCM = 1,
+ AUDIO_CODING_TYPE_AC3 = 2,
+ AUDIO_CODING_TYPE_MPEG1 = 3,
+ AUDIO_CODING_TYPE_MP3 = 4,
+ AUDIO_CODING_TYPE_MPEG2 = 5,
+ AUDIO_CODING_TYPE_AACLC = 6,
+ AUDIO_CODING_TYPE_DTS = 7,
+ AUDIO_CODING_TYPE_ATRAC = 8,
+ AUDIO_CODING_TYPE_SACD = 9,
+ AUDIO_CODING_TYPE_EAC3 = 10,
+ AUDIO_CODING_TYPE_DTS_HD = 11,
+ AUDIO_CODING_TYPE_MLP = 12,
+ AUDIO_CODING_TYPE_DST = 13,
+ AUDIO_CODING_TYPE_WMAPRO = 14,
+ AUDIO_CODING_TYPE_RESERVED = 15,
+};
+
struct mxc_edid_cfg {
bool cea_underscan;
bool cea_basicaudio;
@@ -43,6 +64,10 @@ struct mxc_edid_cfg {
bool vsd_dc_30bit;
bool vsd_dc_y444;
bool vsd_dvi_dual;
+
+ u8 max_channels;
+ u8 sample_sizes;
+ u8 sample_rates;
};
int mxc_edid_var_to_vic(struct fb_var_screeninfo *var);
diff --git a/arch/arm/plat-mxc/include/mach/regs-usbphy-mx6.h b/arch/arm/plat-mxc/include/mach/regs-usbphy-mx6.h
index 060b176b43af..473d16c4fb48 100644
--- a/arch/arm/plat-mxc/include/mach/regs-usbphy-mx6.h
+++ b/arch/arm/plat-mxc/include/mach/regs-usbphy-mx6.h
@@ -1,7 +1,7 @@
/*
* Freescale USBPHY Register Definitions
*
- * Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -468,6 +468,7 @@
/* Host2/3 HSIC Ctrl */
#define CLK_VLD (1 << 31) /* Indicating whether HSIC clock is valid */
+#define HSIC_DEV_CONN (1 << 21) /* set after device connected */
#define HSIC_EN (1 << 12) /* HSIC enable */
#define HSIC_CLK_ON (1 << 11) /* Force HSIC module 480M clock on,
* even when in Host is in suspend mode
diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h
index 1a51cca1bfa4..7021c85d1b59 100755
--- a/arch/arm/plat-mxc/include/mach/system.h
+++ b/arch/arm/plat-mxc/include/mach/system.h
@@ -1,7 +1,7 @@
/*
* Copyright (C) 1999 ARM Limited
* Copyright (C) 2000 Deep Blue Solutions Ltd
- * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -25,5 +25,4 @@ extern void mx5_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
void arch_idle(void);
void arch_reset(char mode, const char *cmd);
-int mxs_reset_block(void __iomem *hwreg, int just_enable);
#endif /* __ASM_ARCH_MXC_SYSTEM_H__ */
diff --git a/arch/arm/plat-mxc/usb_common.c b/arch/arm/plat-mxc/usb_common.c
index b50963b9b403..bb9c45a0127e 100755
--- a/arch/arm/plat-mxc/usb_common.c
+++ b/arch/arm/plat-mxc/usb_common.c
@@ -88,7 +88,7 @@ static int fsl_check_usbclk(void)
usb_ahb_clk = clk_get(NULL, "usb_ahb_clk");
if (clk_enable(usb_ahb_clk)) {
- if (cpu_is_mx6q())
+ if (cpu_is_mx6q() || cpu_is_mx6dl())
return 0; /* there is no ahb clock at mx6 */
printk(KERN_ERR "clk_enable(usb_ahb_clk) failed\n");
return -EINVAL;
@@ -97,7 +97,7 @@ static int fsl_check_usbclk(void)
usb_clk = clk_get(NULL, "usb_clk");
if (clk_enable(usb_clk)) {
- if (cpu_is_mx6q())
+ if (cpu_is_mx6q() || cpu_is_mx6dl())
return 0; /* there is usb_clk at mx6 */
printk(KERN_ERR "clk_enable(usb_clk) failed\n");
return -EINVAL;
@@ -502,7 +502,7 @@ int fsl_usb_host_init(struct platform_device *pdev)
if (usb_register_remote_wakeup(pdev))
pr_debug("%s port is not a wakeup source.\n", pdata->name);
- if (!cpu_is_mx6q()) {
+ if (!(cpu_is_mx6q() || cpu_is_mx6dl())) {
if (xops->xcvr_type == PORTSC_PTS_SERIAL) {
if (cpu_is_mx35()) {
usbh2_set_serial_xcvr();
@@ -814,7 +814,7 @@ int usbotg_init(struct platform_device *pdev)
return -EINVAL;
if (xops->init)
xops->init(xops);
- if (!(cpu_is_mx6q())) {
+ if (!((cpu_is_mx6q() || cpu_is_mx6dl()))) {
UOG_PORTSC1 = UOG_PORTSC1 & ~PORTSC_PHCD;
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 4c053288032f..89d1b01d9af9 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -145,10 +145,14 @@ config MXC_PXP
bool "MXC PxP support"
select DMA_ENGINE
+config MXC_PXP_V2
+ bool "MXC PxP V2 support"
+ select DMA_ENGINE
+
config MXC_PXP_CLIENT_DEVICE
bool "MXC PxP Client Device"
default y
- depends on MXC_PXP
+ depends on MXC_PXP || MXC_PXP_V2
config TXX9_DMAC
tristate "Toshiba TXx9 SoC DMA support"
@@ -240,7 +244,7 @@ config IMX_DMA
config MXS_DMA
bool "MXS DMA support"
- depends on SOC_IMX23 || SOC_IMX28
+ depends on SOC_IMX23 || SOC_IMX28 || SOC_IMX6Q
select DMA_ENGINE
help
Support the MXS DMA engine. This engine including APBH-DMA
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index e34807156e7a..0b7457b456a9 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -13,7 +13,7 @@ obj-$(CONFIG_MV_XOR) += mv_xor.o
obj-$(CONFIG_DW_DMAC) += dw_dmac.o
obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
obj-$(CONFIG_MX3_IPU) += ipu/
-obj-$(CONFIG_MXC_PXP) += pxp/
+obj-y += pxp/
obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
obj-$(CONFIG_SH_DMAE) += shdma.o
obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o
diff --git a/drivers/dma/mxs-dma.c b/drivers/dma/mxs-dma.c
index b06cd4ca626f..4456b331e1d5 100644
--- a/drivers/dma/mxs-dma.c
+++ b/drivers/dma/mxs-dma.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* Refer to drivers/dma/imx-sdma.c
*
@@ -22,10 +22,10 @@
#include <linux/platform_device.h>
#include <linux/dmaengine.h>
#include <linux/delay.h>
+#include <linux/mxs-dma.h>
#include <asm/irq.h>
#include <mach/mxs.h>
-#include <mach/dma.h>
#include <mach/common.h>
/*
@@ -349,10 +349,32 @@ static void mxs_dma_free_chan_resources(struct dma_chan *chan)
clk_disable_unprepare(mxs_dma->clk);
}
+/*
+ * How to use the flags for ->device_prep_slave_sg() :
+ * [1] If there is only one DMA command in the DMA chain, the code should be:
+ * ......
+ * ->device_prep_slave_sg(DMA_CTRL_ACK);
+ * ......
+ * [2] If there are two DMA commands in the DMA chain, the code should be
+ * ......
+ * ->device_prep_slave_sg(0);
+ * ......
+ * ->device_prep_slave_sg(DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+ * ......
+ * [3] If there are more than two DMA commands in the DMA chain, the code
+ * should be:
+ * ......
+ * ->device_prep_slave_sg(0); // First
+ * ......
+ * ->device_prep_slave_sg(DMA_PREP_INTERRUPT [| DMA_CTRL_ACK]);
+ * ......
+ * ->device_prep_slave_sg(DMA_PREP_INTERRUPT | DMA_CTRL_ACK); // Last
+ * ......
+ */
static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
struct dma_chan *chan, struct scatterlist *sgl,
unsigned int sg_len, enum dma_transfer_direction direction,
- unsigned long append)
+ unsigned long flags)
{
struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
@@ -360,6 +382,7 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
struct scatterlist *sg;
int i, j;
u32 *pio;
+ bool append = flags & DMA_PREP_INTERRUPT;
int idx = append ? mxs_chan->desc_count : 0;
if (mxs_chan->status == DMA_IN_PROGRESS && !append)
@@ -386,7 +409,6 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
ccw->bits |= CCW_CHAIN;
ccw->bits &= ~CCW_IRQ;
ccw->bits &= ~CCW_DEC_SEM;
- ccw->bits &= ~CCW_WAIT4END;
} else {
idx = 0;
}
@@ -401,7 +423,8 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
ccw->bits = 0;
ccw->bits |= CCW_IRQ;
ccw->bits |= CCW_DEC_SEM;
- ccw->bits |= CCW_WAIT4END;
+ if (flags & DMA_CTRL_ACK)
+ ccw->bits |= CCW_WAIT4END;
ccw->bits |= CCW_HALT_ON_TERM;
ccw->bits |= CCW_TERM_FLUSH;
ccw->bits |= BF_CCW(sg_len, PIO_NUM);
@@ -432,7 +455,8 @@ static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
ccw->bits &= ~CCW_CHAIN;
ccw->bits |= CCW_IRQ;
ccw->bits |= CCW_DEC_SEM;
- ccw->bits |= CCW_WAIT4END;
+ if (flags & DMA_CTRL_ACK)
+ ccw->bits |= CCW_WAIT4END;
}
}
}
diff --git a/drivers/dma/pxp/Makefile b/drivers/dma/pxp/Makefile
index 88e51a7fb1e2..7372a8c032d3 100644
--- a/drivers/dma/pxp/Makefile
+++ b/drivers/dma/pxp/Makefile
@@ -1,2 +1,3 @@
obj-$(CONFIG_MXC_PXP) += pxp_dma.o
+obj-$(CONFIG_MXC_PXP_V2) += pxp_dma_v2.o
obj-$(CONFIG_MXC_PXP_CLIENT_DEVICE) += pxp_device.o
diff --git a/drivers/dma/pxp/pxp_device.c b/drivers/dma/pxp/pxp_device.c
index 5f3016be80f5..6b3d7aa37dce 100644
--- a/drivers/dma/pxp/pxp_device.c
+++ b/drivers/dma/pxp/pxp_device.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -24,10 +24,14 @@
#include <linux/uaccess.h>
#include <linux/delay.h>
#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/sched.h>
#include <linux/pxp_dma.h>
#include <linux/atomic.h>
+#include <mach/dma.h>
+
static atomic_t open_count = ATOMIC_INIT(0);
static DEFINE_SPINLOCK(pxp_mem_lock);
@@ -237,6 +241,14 @@ static int pxp_device_mmap(struct file *file, struct vm_area_struct *vma)
request_size, vma->vm_page_prot) ? -EAGAIN : 0;
}
+static bool chan_filter(struct dma_chan *chan, void *arg)
+{
+ if (imx_dma_is_pxp(chan))
+ return true;
+ else
+ return false;
+}
+
static long pxp_device_ioctl(struct file *filp,
unsigned int cmd, unsigned long arg)
{
@@ -258,7 +270,7 @@ static long pxp_device_ioctl(struct file *filp,
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
dma_cap_set(DMA_PRIVATE, mask);
- info->dma_chan = dma_request_channel(mask, NULL, NULL);
+ info->dma_chan = dma_request_channel(mask, chan_filter, NULL);
if (!info->dma_chan) {
pr_err("Unsccessfully received channel!\n");
kfree(info);
diff --git a/drivers/dma/pxp/pxp_dma_v2.c b/drivers/dma/pxp/pxp_dma_v2.c
new file mode 100644
index 000000000000..3fadd9a5f762
--- /dev/null
+++ b/drivers/dma/pxp/pxp_dma_v2.c
@@ -0,0 +1,1633 @@
+/*
+ * Copyright (C) 2010-2012 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+/*
+ * Based on STMP378X PxP driver
+ * Copyright 2008-2009 Embedded Alley Solutions, Inc All Rights Reserved.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/vmalloc.h>
+#include <linux/dmaengine.h>
+#include <linux/pxp_dma.h>
+#include <linux/timer.h>
+#include <linux/clk.h>
+#include <linux/workqueue.h>
+#include <linux/sched.h>
+
+#include "regs-pxp_v2.h"
+
+#define PXP_DOWNSCALE_THRESHOLD 0x4000
+
+static LIST_HEAD(head);
+static int timeout_in_ms = 600;
+
+struct pxp_dma {
+ struct dma_device dma;
+};
+
+struct pxps {
+ struct platform_device *pdev;
+ struct clk *clk;
+ void __iomem *base;
+ int irq; /* PXP IRQ to the CPU */
+
+ spinlock_t lock;
+ struct mutex clk_mutex;
+ int clk_stat;
+#define CLK_STAT_OFF 0
+#define CLK_STAT_ON 1
+ int pxp_ongoing;
+ int lut_state;
+
+ struct device *dev;
+ struct pxp_dma pxp_dma;
+ struct pxp_channel channel[NR_PXP_VIRT_CHANNEL];
+ wait_queue_head_t done;
+ struct work_struct work;
+
+ /* describes most recent processing configuration */
+ struct pxp_config_data pxp_conf_state;
+
+ /* to turn clock off when pxp is inactive */
+ struct timer_list clk_timer;
+};
+
+#define to_pxp_dma(d) container_of(d, struct pxp_dma, dma)
+#define to_tx_desc(tx) container_of(tx, struct pxp_tx_desc, txd)
+#define to_pxp_channel(d) container_of(d, struct pxp_channel, dma_chan)
+#define to_pxp(id) container_of(id, struct pxps, pxp_dma)
+
+#define PXP_DEF_BUFS 2
+#define PXP_MIN_PIX 8
+
+#define PXP_WAITCON ((__raw_readl(pxp->base + HW_PXP_STAT) & \
+ BM_PXP_STAT_IRQ) != BM_PXP_STAT_IRQ)
+
+static uint32_t pxp_s0_formats[] = {
+ PXP_PIX_FMT_RGB24,
+ PXP_PIX_FMT_RGB565,
+ PXP_PIX_FMT_RGB555,
+ PXP_PIX_FMT_YUV420P,
+ PXP_PIX_FMT_YUV422P,
+};
+
+/*
+ * PXP common functions
+ */
+static void dump_pxp_reg(struct pxps *pxp)
+{
+ dev_dbg(pxp->dev, "PXP_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CTRL));
+ dev_dbg(pxp->dev, "PXP_STAT 0x%x",
+ __raw_readl(pxp->base + HW_PXP_STAT));
+ dev_dbg(pxp->dev, "PXP_OUT_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_CTRL));
+ dev_dbg(pxp->dev, "PXP_OUT_BUF 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_BUF));
+ dev_dbg(pxp->dev, "PXP_OUT_BUF2 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_BUF2));
+ dev_dbg(pxp->dev, "PXP_OUT_PITCH 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_PITCH));
+ dev_dbg(pxp->dev, "PXP_OUT_LRC 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_LRC));
+ dev_dbg(pxp->dev, "PXP_OUT_PS_ULC 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_PS_ULC));
+ dev_dbg(pxp->dev, "PXP_OUT_PS_LRC 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_PS_LRC));
+ dev_dbg(pxp->dev, "PXP_OUT_AS_ULC 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_AS_ULC));
+ dev_dbg(pxp->dev, "PXP_OUT_AS_LRC 0x%x",
+ __raw_readl(pxp->base + HW_PXP_OUT_AS_LRC));
+ dev_dbg(pxp->dev, "PXP_PS_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_CTRL));
+ dev_dbg(pxp->dev, "PXP_PS_BUF 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_BUF));
+ dev_dbg(pxp->dev, "PXP_PS_UBUF 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_UBUF));
+ dev_dbg(pxp->dev, "PXP_PS_VBUF 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_VBUF));
+ dev_dbg(pxp->dev, "PXP_PS_PITCH 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_PITCH));
+ dev_dbg(pxp->dev, "PXP_PS_BACKGROUND 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_BACKGROUND));
+ dev_dbg(pxp->dev, "PXP_PS_SCALE 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_SCALE));
+ dev_dbg(pxp->dev, "PXP_PS_OFFSET 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_OFFSET));
+ dev_dbg(pxp->dev, "PXP_PS_CLRKEYLOW 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_CLRKEYLOW));
+ dev_dbg(pxp->dev, "PXP_PS_CLRKEYHIGH 0x%x",
+ __raw_readl(pxp->base + HW_PXP_PS_CLRKEYHIGH));
+ dev_dbg(pxp->dev, "PXP_AS_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_AS_CTRL));
+ dev_dbg(pxp->dev, "PXP_AS_BUF 0x%x",
+ __raw_readl(pxp->base + HW_PXP_AS_BUF));
+ dev_dbg(pxp->dev, "PXP_AS_PITCH 0x%x",
+ __raw_readl(pxp->base + HW_PXP_AS_PITCH));
+ dev_dbg(pxp->dev, "PXP_AS_CLRKEYLOW 0x%x",
+ __raw_readl(pxp->base + HW_PXP_AS_CLRKEYLOW));
+ dev_dbg(pxp->dev, "PXP_AS_CLRKEYHIGH 0x%x",
+ __raw_readl(pxp->base + HW_PXP_AS_CLRKEYHIGH));
+ dev_dbg(pxp->dev, "PXP_CSC1_COEF0 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC1_COEF0));
+ dev_dbg(pxp->dev, "PXP_CSC1_COEF1 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC1_COEF1));
+ dev_dbg(pxp->dev, "PXP_CSC1_COEF2 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC1_COEF2));
+ dev_dbg(pxp->dev, "PXP_CSC2_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_CTRL));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF0 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF0));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF1 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF1));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF2 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF2));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF3 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF3));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF4 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF4));
+ dev_dbg(pxp->dev, "PXP_CSC2_COEF5 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CSC2_COEF5));
+ dev_dbg(pxp->dev, "PXP_LUT_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_LUT_CTRL));
+ dev_dbg(pxp->dev, "PXP_LUT_ADDR 0x%x",
+ __raw_readl(pxp->base + HW_PXP_LUT_ADDR));
+ dev_dbg(pxp->dev, "PXP_LUT_DATA 0x%x",
+ __raw_readl(pxp->base + HW_PXP_LUT_DATA));
+ dev_dbg(pxp->dev, "PXP_LUT_EXTMEM 0x%x",
+ __raw_readl(pxp->base + HW_PXP_LUT_EXTMEM));
+ dev_dbg(pxp->dev, "PXP_CFA 0x%x",
+ __raw_readl(pxp->base + HW_PXP_CFA));
+ dev_dbg(pxp->dev, "PXP_HIST_CTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST_CTRL));
+ dev_dbg(pxp->dev, "PXP_HIST2_PARAM 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST2_PARAM));
+ dev_dbg(pxp->dev, "PXP_HIST4_PARAM 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST4_PARAM));
+ dev_dbg(pxp->dev, "PXP_HIST8_PARAM0 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST8_PARAM0));
+ dev_dbg(pxp->dev, "PXP_HIST8_PARAM1 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST8_PARAM1));
+ dev_dbg(pxp->dev, "PXP_HIST16_PARAM0 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST16_PARAM0));
+ dev_dbg(pxp->dev, "PXP_HIST16_PARAM1 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST16_PARAM1));
+ dev_dbg(pxp->dev, "PXP_HIST16_PARAM2 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST16_PARAM2));
+ dev_dbg(pxp->dev, "PXP_HIST16_PARAM3 0x%x",
+ __raw_readl(pxp->base + HW_PXP_HIST16_PARAM3));
+ dev_dbg(pxp->dev, "PXP_POWER 0x%x",
+ __raw_readl(pxp->base + HW_PXP_POWER));
+ dev_dbg(pxp->dev, "PXP_NEXT 0x%x",
+ __raw_readl(pxp->base + HW_PXP_NEXT));
+ dev_dbg(pxp->dev, "PXP_DEBUGCTRL 0x%x",
+ __raw_readl(pxp->base + HW_PXP_DEBUGCTRL));
+ dev_dbg(pxp->dev, "PXP_DEBUG 0x%x",
+ __raw_readl(pxp->base + HW_PXP_DEBUG));
+ dev_dbg(pxp->dev, "PXP_VERSION 0x%x",
+ __raw_readl(pxp->base + HW_PXP_VERSION));
+}
+
+static bool is_yuv(u32 pix_fmt)
+{
+ if ((pix_fmt == PXP_PIX_FMT_YUYV) |
+ (pix_fmt == PXP_PIX_FMT_UYVY) |
+ (pix_fmt == PXP_PIX_FMT_Y41P) |
+ (pix_fmt == PXP_PIX_FMT_YUV444) |
+ (pix_fmt == PXP_PIX_FMT_NV12) |
+ (pix_fmt == PXP_PIX_FMT_GREY) |
+ (pix_fmt == PXP_PIX_FMT_YVU410P) |
+ (pix_fmt == PXP_PIX_FMT_YUV410P) |
+ (pix_fmt == PXP_PIX_FMT_YVU420P) |
+ (pix_fmt == PXP_PIX_FMT_YUV420P) |
+ (pix_fmt == PXP_PIX_FMT_YUV420P2) |
+ (pix_fmt == PXP_PIX_FMT_YVU422P) |
+ (pix_fmt == PXP_PIX_FMT_YUV422P)) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+static void pxp_set_ctrl(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+ u32 ctrl;
+ u32 fmt_ctrl;
+
+ /* Configure S0 input format */
+ switch (pxp_conf->s0_param.pixel_fmt) {
+ case PXP_PIX_FMT_RGB24:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB888;
+ break;
+ case PXP_PIX_FMT_RGB565:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB565;
+ break;
+ case PXP_PIX_FMT_RGB555:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__RGB555;
+ break;
+ case PXP_PIX_FMT_YUV420P:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV420;
+ break;
+ case PXP_PIX_FMT_GREY:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__Y8;
+ break;
+ case PXP_PIX_FMT_YUV422P:
+ fmt_ctrl = BV_PXP_PS_CTRL_FORMAT__YUV422;
+ break;
+ default:
+ fmt_ctrl = 0;
+ }
+
+ ctrl = BF_PXP_PS_CTRL_FORMAT(fmt_ctrl);
+ __raw_writel(ctrl, pxp->base + HW_PXP_PS_CTRL);
+
+ /* Configure output format based on out_channel format */
+ switch (pxp_conf->out_param.pixel_fmt) {
+ case PXP_PIX_FMT_RGB24:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB888;
+ break;
+ case PXP_PIX_FMT_RGB565:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB565;
+ break;
+ case PXP_PIX_FMT_RGB555:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__RGB555;
+ break;
+ case PXP_PIX_FMT_YUV420P:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YUV2P420;
+ break;
+ case PXP_PIX_FMT_YUV422P:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__YUV2P422;
+ break;
+ case PXP_PIX_FMT_GREY:
+ fmt_ctrl = BV_PXP_OUT_CTRL_FORMAT__Y8;
+ break;
+ default:
+ fmt_ctrl = 0;
+ }
+
+ ctrl = BF_PXP_OUT_CTRL_FORMAT(fmt_ctrl);
+ __raw_writel(ctrl, pxp->base + HW_PXP_OUT_CTRL);
+
+ ctrl = 0;
+ if (proc_data->scaling)
+ ;
+ if (proc_data->vflip)
+ ctrl |= BM_PXP_CTRL_VFLIP;
+ if (proc_data->hflip)
+ ctrl |= BM_PXP_CTRL_HFLIP;
+ if (proc_data->rotate)
+ ctrl |= BF_PXP_CTRL_ROTATE(proc_data->rotate / 90);
+
+ /* H/W support: controls where rotation will occur in the PXP datapath,
+ * will export an interfance if needed
+ */
+ /* ctrl |= BM_PXP_CTRL_ROT_POS; post rotation */
+
+ __raw_writel(ctrl, pxp->base + HW_PXP_CTRL);
+}
+
+static int pxp_start(struct pxps *pxp)
+{
+ __raw_writel(BM_PXP_CTRL_IRQ_ENABLE, pxp->base + HW_PXP_CTRL_SET);
+ __raw_writel(BM_PXP_CTRL_ENABLE, pxp->base + HW_PXP_CTRL_SET);
+ dump_pxp_reg(pxp);
+
+ return 0;
+}
+
+static void pxp_set_outbuf(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *out_params = &pxp_conf->out_param;
+
+ __raw_writel(out_params->paddr, pxp->base + HW_PXP_OUT_BUF);
+
+ __raw_writel(BF_PXP_OUT_LRC_X(out_params->width - 1) |
+ BF_PXP_OUT_LRC_Y(out_params->height - 1),
+ pxp->base + HW_PXP_OUT_LRC);
+
+ __raw_writel(out_params->stride, pxp->base + HW_PXP_OUT_PITCH);
+}
+
+static void pxp_set_s0colorkey(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
+
+ /* Low and high are set equal. V4L does not allow a chromakey range */
+ if (s0_params->color_key == -1) {
+ /* disable color key */
+ __raw_writel(0xFFFFFF, pxp->base + HW_PXP_PS_CLRKEYLOW);
+ __raw_writel(0, pxp->base + HW_PXP_PS_CLRKEYHIGH);
+ } else {
+ __raw_writel(s0_params->color_key,
+ pxp->base + HW_PXP_PS_CLRKEYLOW);
+ __raw_writel(s0_params->color_key,
+ pxp->base + HW_PXP_PS_CLRKEYHIGH);
+ }
+}
+
+static void pxp_set_olcolorkey(int layer_no, struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *ol_params = &pxp_conf->ol_param[layer_no];
+
+ /* Low and high are set equal. V4L does not allow a chromakey range */
+ if (ol_params->color_key_enable != 0 && ol_params->color_key != -1) {
+ __raw_writel(ol_params->color_key,
+ pxp->base + HW_PXP_AS_CLRKEYLOW);
+ __raw_writel(ol_params->color_key,
+ pxp->base + HW_PXP_AS_CLRKEYHIGH);
+ } else {
+ /* disable color key */
+ __raw_writel(0xFFFFFF, pxp->base + HW_PXP_AS_CLRKEYLOW);
+ __raw_writel(0, pxp->base + HW_PXP_AS_CLRKEYHIGH);
+ }
+}
+
+static void pxp_set_oln(int layer_no, struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *olparams_data = &pxp_conf->ol_param[layer_no];
+ dma_addr_t phys_addr = olparams_data->paddr;
+ __raw_writel(phys_addr, pxp->base + HW_PXP_AS_BUF);
+
+ /* Fixme */
+ __raw_writel(0x0, pxp->base + HW_PXP_OUT_AS_ULC);
+ __raw_writel(BF_PXP_OUT_AS_LRC_X(olparams_data->width) |
+ BF_PXP_OUT_AS_LRC_Y(olparams_data->height),
+ pxp->base + HW_PXP_OUT_AS_LRC);
+}
+
+static void pxp_set_olparam(int layer_no, struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *olparams_data = &pxp_conf->ol_param[layer_no];
+ u32 olparam;
+
+ olparam = BF_PXP_AS_CTRL_ALPHA(olparams_data->global_alpha);
+ if (olparams_data->pixel_fmt == PXP_PIX_FMT_RGB24)
+ olparam |=
+ BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__RGB888);
+ else
+ olparam |=
+ BF_PXP_AS_CTRL_FORMAT(BV_PXP_AS_CTRL_FORMAT__RGB565);
+ if (olparams_data->global_alpha_enable)
+ olparam |=
+ BF_PXP_AS_CTRL_ALPHA_CTRL
+ (BV_PXP_AS_CTRL_ALPHA_CTRL__Override);
+ if (olparams_data->color_key_enable)
+ olparam |= BM_PXP_AS_CTRL_ENABLE_COLORKEY;
+ if (olparams_data->combine_enable)
+ ;
+ __raw_writel(olparam, pxp->base + HW_PXP_AS_CTRL);
+}
+
+static void pxp_set_s0param(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *s0params_data = &pxp_conf->s0_param;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+ u32 s0param;
+
+ s0param = BF_PXP_OUT_PS_ULC_X(proc_data->srect.left);
+ s0param |= BF_PXP_OUT_PS_ULC_Y(proc_data->srect.top);
+ __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_ULC);
+ s0param = BF_PXP_OUT_PS_LRC_X(s0params_data->width);
+ s0param |= BF_PXP_OUT_PS_LRC_Y(s0params_data->height);
+ __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_LRC);
+
+}
+
+/* TODO: crop behavior is re-designed in h/w. */
+static void pxp_set_s0crop(struct pxps *pxp)
+{
+}
+
+static int pxp_set_scaling(struct pxps *pxp)
+{
+ int ret = 0;
+ u32 xscale, yscale, s0scale;
+ struct pxp_proc_data *proc_data = &pxp->pxp_conf_state.proc_data;
+
+ if ((proc_data->srect.width == proc_data->drect.width) &&
+ (proc_data->srect.height == proc_data->drect.height)) {
+ proc_data->scaling = 0;
+ __raw_writel(0x10001000, pxp->base + HW_PXP_PS_SCALE);
+ goto out;
+ }
+
+ proc_data->scaling = 1;
+ xscale = proc_data->srect.width * 0x1000 / proc_data->drect.width;
+ yscale = proc_data->srect.height * 0x1000 / proc_data->drect.height;
+ if (xscale > PXP_DOWNSCALE_THRESHOLD)
+ xscale = PXP_DOWNSCALE_THRESHOLD;
+ if (yscale > PXP_DOWNSCALE_THRESHOLD)
+ yscale = PXP_DOWNSCALE_THRESHOLD;
+ s0scale = BF_PXP_PS_SCALE_YSCALE(yscale) |
+ BF_PXP_PS_SCALE_XSCALE(xscale);
+ __raw_writel(s0scale, pxp->base + HW_PXP_PS_SCALE);
+
+out:
+ pxp_set_ctrl(pxp);
+
+ return ret;
+}
+
+static void pxp_set_bg(struct pxps *pxp)
+{
+ __raw_writel(pxp->pxp_conf_state.proc_data.bgcolor,
+ pxp->base + HW_PXP_PS_BACKGROUND);
+}
+
+static void pxp_set_lut(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ int lut_op = pxp_conf->proc_data.lut_transform;
+ u32 reg_val;
+ int i;
+ bool use_cmap = (lut_op & PXP_LUT_USE_CMAP) ? true : false;
+ u8 *cmap = pxp_conf->proc_data.lut_map;
+ u32 entry_src;
+ u32 pix_val;
+ u8 entry[4];
+
+ /*
+ * If LUT already configured as needed, return...
+ * Unless CMAP is needed and it has been updated.
+ */
+ if ((pxp->lut_state == lut_op) &&
+ !(use_cmap && pxp_conf->proc_data.lut_map_updated))
+ return;
+
+ if (lut_op == PXP_LUT_NONE) {
+ __raw_writel(BM_PXP_LUT_CTRL_BYPASS,
+ pxp->base + HW_PXP_LUT_CTRL);
+ } else if (((lut_op & PXP_LUT_INVERT) != 0)
+ && ((lut_op & PXP_LUT_BLACK_WHITE) != 0)) {
+ /* Fill out LUT table with inverted monochromized values */
+
+ /* clear bypass bit, set lookup mode & out mode */
+ __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
+ (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
+ BF_PXP_LUT_CTRL_OUT_MODE
+ (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
+ pxp->base + HW_PXP_LUT_CTRL);
+
+ /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
+ __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
+
+ /* LUT address pointer auto-increments after each data write */
+ for (pix_val = 0; pix_val < 256; pix_val += 4) {
+ for (i = 0; i < 4; i++) {
+ entry_src = use_cmap ? cmap[pix_val + i] : pix_val + i;
+ entry[i] = (entry_src < 0x80) ? 0xFF : 0x00;
+ }
+ reg_val = (entry[3] << 24) | (entry[2] << 16) |
+ (entry[1] << 8) | entry[0];
+ __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
+ }
+ } else if ((lut_op & PXP_LUT_INVERT) != 0) {
+ /* Fill out LUT table with 8-bit inverted values */
+
+ /* clear bypass bit, set lookup mode & out mode */
+ __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
+ (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
+ BF_PXP_LUT_CTRL_OUT_MODE
+ (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
+ pxp->base + HW_PXP_LUT_CTRL);
+
+ /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
+ __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
+
+ /* LUT address pointer auto-increments after each data write */
+ for (pix_val = 0; pix_val < 256; pix_val += 4) {
+ for (i = 0; i < 4; i++) {
+ entry_src = use_cmap ? cmap[pix_val + i] : pix_val + i;
+ entry[i] = ~entry_src & 0xFF;
+ }
+ reg_val = (entry[3] << 24) | (entry[2] << 16) |
+ (entry[1] << 8) | entry[0];
+ __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
+ }
+ } else if ((lut_op & PXP_LUT_BLACK_WHITE) != 0) {
+ /* Fill out LUT table with 8-bit monochromized values */
+
+ /* clear bypass bit, set lookup mode & out mode */
+ __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
+ (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
+ BF_PXP_LUT_CTRL_OUT_MODE
+ (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
+ pxp->base + HW_PXP_LUT_CTRL);
+
+ /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
+ __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
+
+ /* LUT address pointer auto-increments after each data write */
+ for (pix_val = 0; pix_val < 256; pix_val += 4) {
+ for (i = 0; i < 4; i++) {
+ entry_src = use_cmap ? cmap[pix_val + i] : pix_val + i;
+ entry[i] = (entry_src < 0x80) ? 0x00 : 0xFF;
+ }
+ reg_val = (entry[3] << 24) | (entry[2] << 16) |
+ (entry[1] << 8) | entry[0];
+ __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
+ }
+ } else if (use_cmap) {
+ /* Fill out LUT table using colormap values */
+
+ /* clear bypass bit, set lookup mode & out mode */
+ __raw_writel(BF_PXP_LUT_CTRL_LOOKUP_MODE
+ (BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8) |
+ BF_PXP_LUT_CTRL_OUT_MODE
+ (BV_PXP_LUT_CTRL_OUT_MODE__Y8),
+ pxp->base + HW_PXP_LUT_CTRL);
+
+ /* Initialize LUT address to 0 and set NUM_BYTES to 0 */
+ __raw_writel(0, pxp->base + HW_PXP_LUT_ADDR);
+
+ /* LUT address pointer auto-increments after each data write */
+ for (pix_val = 0; pix_val < 256; pix_val += 4) {
+ for (i = 0; i < 4; i++)
+ entry[i] = cmap[pix_val + i];
+ reg_val = (entry[3] << 24) | (entry[2] << 16) |
+ (entry[1] << 8) | entry[0];
+ __raw_writel(reg_val, pxp->base + HW_PXP_LUT_DATA);
+ }
+ }
+
+ pxp->lut_state = lut_op;
+}
+
+static void pxp_set_csc(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
+ struct pxp_layer_param *ol_params = &pxp_conf->ol_param[0];
+ struct pxp_layer_param *out_params = &pxp_conf->out_param;
+
+ bool input_is_YUV = is_yuv(s0_params->pixel_fmt);
+ bool output_is_YUV = is_yuv(out_params->pixel_fmt);
+
+ if (input_is_YUV && output_is_YUV) {
+ /*
+ * Input = YUV, Output = YUV
+ * No CSC unless we need to do combining
+ */
+ if (ol_params->combine_enable) {
+ /* Must convert to RGB for combining with RGB overlay */
+
+ /* CSC1 - YUV->RGB */
+ __raw_writel(0x04030000, pxp->base + HW_PXP_CSC1_COEF0);
+ __raw_writel(0x01230208, pxp->base + HW_PXP_CSC1_COEF1);
+ __raw_writel(0x076b079c, pxp->base + HW_PXP_CSC1_COEF2);
+
+ /* CSC2 - RGB->YUV */
+ __raw_writel(0x4, pxp->base + HW_PXP_CSC2_CTRL);
+ __raw_writel(0x0096004D, pxp->base + HW_PXP_CSC2_COEF0);
+ __raw_writel(0x05DA001D, pxp->base + HW_PXP_CSC2_COEF1);
+ __raw_writel(0x007005B6, pxp->base + HW_PXP_CSC2_COEF2);
+ __raw_writel(0x057C009E, pxp->base + HW_PXP_CSC2_COEF3);
+ __raw_writel(0x000005E6, pxp->base + HW_PXP_CSC2_COEF4);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_CSC2_COEF5);
+ } else {
+ /* Input & Output both YUV, so bypass both CSCs */
+
+ /* CSC1 - Bypass */
+ __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
+
+ /* CSC2 - Bypass */
+ __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
+ }
+ } else if (input_is_YUV && !output_is_YUV) {
+ /*
+ * Input = YUV, Output = RGB
+ * Use CSC1 to convert to RGB
+ */
+
+ /* CSC1 - YUV->RGB */
+ __raw_writel(0x84ab01f0, pxp->base + HW_PXP_CSC1_COEF0);
+ __raw_writel(0x01230204, pxp->base + HW_PXP_CSC1_COEF1);
+ __raw_writel(0x0730079c, pxp->base + HW_PXP_CSC1_COEF2);
+
+ /* CSC2 - Bypass */
+ __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
+ } else if (!input_is_YUV && output_is_YUV) {
+ /*
+ * Input = RGB, Output = YUV
+ * Use CSC2 to convert to YUV
+ */
+
+ /* CSC1 - Bypass */
+ __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
+
+ /* CSC2 - RGB->YUV */
+ __raw_writel(0x4, pxp->base + HW_PXP_CSC2_CTRL);
+ __raw_writel(0x0096004D, pxp->base + HW_PXP_CSC2_COEF0);
+ __raw_writel(0x05DA001D, pxp->base + HW_PXP_CSC2_COEF1);
+ __raw_writel(0x007005B6, pxp->base + HW_PXP_CSC2_COEF2);
+ __raw_writel(0x057C009E, pxp->base + HW_PXP_CSC2_COEF3);
+ __raw_writel(0x000005E6, pxp->base + HW_PXP_CSC2_COEF4);
+ __raw_writel(0x00000000, pxp->base + HW_PXP_CSC2_COEF5);
+ } else {
+ /*
+ * Input = RGB, Output = RGB
+ * Input & Output both RGB, so bypass both CSCs
+ */
+
+ /* CSC1 - Bypass */
+ __raw_writel(0x40000000, pxp->base + HW_PXP_CSC1_COEF0);
+
+ /* CSC2 - Bypass */
+ __raw_writel(0x1, pxp->base + HW_PXP_CSC2_CTRL);
+ }
+
+ /* YCrCb colorspace */
+ /* Not sure when we use this...no YCrCb formats are defined for PxP */
+ /*
+ __raw_writel(0x84ab01f0, HW_PXP_CSCCOEFF0_ADDR);
+ __raw_writel(0x01230204, HW_PXP_CSCCOEFF1_ADDR);
+ __raw_writel(0x0730079c, HW_PXP_CSCCOEFF2_ADDR);
+ */
+
+}
+
+static void pxp_set_s0buf(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_layer_param *s0_params = &pxp_conf->s0_param;
+ dma_addr_t Y, U, V;
+
+ Y = s0_params->paddr;
+ __raw_writel(Y, pxp->base + HW_PXP_PS_BUF);
+ if ((s0_params->pixel_fmt == PXP_PIX_FMT_YUV420P) ||
+ (s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P) ||
+ (s0_params->pixel_fmt == PXP_PIX_FMT_GREY)) {
+ /* Set to 1 if YUV format is 4:2:2 rather than 4:2:0 */
+ int s = 2;
+ U = Y + (s0_params->width * s0_params->height);
+ V = U + ((s0_params->width * s0_params->height) >> s);
+ __raw_writel(U, pxp->base + HW_PXP_PS_UBUF);
+ __raw_writel(V, pxp->base + HW_PXP_PS_VBUF);
+ }
+
+ /* TODO: only support RGB565, Y8 */
+ if (s0_params->pixel_fmt == PXP_PIX_FMT_GREY)
+ __raw_writel(s0_params->width, pxp->base + HW_PXP_PS_PITCH);
+ else
+ __raw_writel(s0_params->width * 2, pxp->base + HW_PXP_PS_PITCH);
+}
+
+/**
+ * pxp_config() - configure PxP for a processing task
+ * @pxps: PXP context.
+ * @pxp_chan: PXP channel.
+ * @return: 0 on success or negative error code on failure.
+ */
+static int pxp_config(struct pxps *pxp, struct pxp_channel *pxp_chan)
+{
+ struct pxp_config_data *pxp_conf_data = &pxp->pxp_conf_state;
+ int ol_nr;
+ int i;
+
+ /* Configure PxP regs */
+ pxp_set_ctrl(pxp);
+ pxp_set_s0param(pxp);
+ pxp_set_s0crop(pxp);
+ pxp_set_scaling(pxp);
+ ol_nr = pxp_conf_data->layer_nr - 2;
+ while (ol_nr > 0) {
+ i = pxp_conf_data->layer_nr - 2 - ol_nr;
+ pxp_set_oln(i, pxp);
+ pxp_set_olparam(i, pxp);
+ /* only the color key in higher overlay will take effect. */
+ pxp_set_olcolorkey(i, pxp);
+ ol_nr--;
+ }
+ pxp_set_s0colorkey(pxp);
+ pxp_set_csc(pxp);
+ pxp_set_bg(pxp);
+ pxp_set_lut(pxp);
+
+ pxp_set_s0buf(pxp);
+ pxp_set_outbuf(pxp);
+
+ return 0;
+}
+
+static void pxp_clk_enable(struct pxps *pxp)
+{
+ mutex_lock(&pxp->clk_mutex);
+
+ if (pxp->clk_stat == CLK_STAT_ON) {
+ mutex_unlock(&pxp->clk_mutex);
+ return;
+ }
+
+ clk_enable(pxp->clk);
+ pxp->clk_stat = CLK_STAT_ON;
+
+ mutex_unlock(&pxp->clk_mutex);
+}
+
+static void pxp_clk_disable(struct pxps *pxp)
+{
+ unsigned long flags;
+
+ mutex_lock(&pxp->clk_mutex);
+
+ if (pxp->clk_stat == CLK_STAT_OFF) {
+ mutex_unlock(&pxp->clk_mutex);
+ return;
+ }
+
+ spin_lock_irqsave(&pxp->lock, flags);
+ if ((pxp->pxp_ongoing == 0) && list_empty(&head)) {
+ spin_unlock_irqrestore(&pxp->lock, flags);
+ clk_disable(pxp->clk);
+ pxp->clk_stat = CLK_STAT_OFF;
+ } else
+ spin_unlock_irqrestore(&pxp->lock, flags);
+
+ mutex_unlock(&pxp->clk_mutex);
+}
+
+static inline void clkoff_callback(struct work_struct *w)
+{
+ struct pxps *pxp = container_of(w, struct pxps, work);
+
+ pxp_clk_disable(pxp);
+}
+
+static void pxp_clkoff_timer(unsigned long arg)
+{
+ struct pxps *pxp = (struct pxps *)arg;
+
+ if ((pxp->pxp_ongoing == 0) && list_empty(&head))
+ schedule_work(&pxp->work);
+ else
+ mod_timer(&pxp->clk_timer,
+ jiffies + msecs_to_jiffies(timeout_in_ms));
+}
+
+static struct pxp_tx_desc *pxpdma_first_active(struct pxp_channel *pxp_chan)
+{
+ return list_entry(pxp_chan->active_list.next, struct pxp_tx_desc, list);
+}
+
+static struct pxp_tx_desc *pxpdma_first_queued(struct pxp_channel *pxp_chan)
+{
+ return list_entry(pxp_chan->queue.next, struct pxp_tx_desc, list);
+}
+
+/* called with pxp_chan->lock held */
+static void __pxpdma_dostart(struct pxp_channel *pxp_chan)
+{
+ struct pxp_dma *pxp_dma = to_pxp_dma(pxp_chan->dma_chan.device);
+ struct pxps *pxp = to_pxp(pxp_dma);
+ struct pxp_tx_desc *desc;
+ struct pxp_tx_desc *child;
+ int i = 0;
+
+ /* so far we presume only one transaction on active_list */
+ /* S0 */
+ desc = pxpdma_first_active(pxp_chan);
+ memcpy(&pxp->pxp_conf_state.s0_param,
+ &desc->layer_param.s0_param, sizeof(struct pxp_layer_param));
+ memcpy(&pxp->pxp_conf_state.proc_data,
+ &desc->proc_data, sizeof(struct pxp_proc_data));
+
+ /* Save PxP configuration */
+ list_for_each_entry(child, &desc->tx_list, list) {
+ if (i == 0) { /* Output */
+ memcpy(&pxp->pxp_conf_state.out_param,
+ &child->layer_param.out_param,
+ sizeof(struct pxp_layer_param));
+ } else { /* Overlay */
+ memcpy(&pxp->pxp_conf_state.ol_param[i - 1],
+ &child->layer_param.ol_param,
+ sizeof(struct pxp_layer_param));
+ }
+
+ i++;
+ }
+ pr_debug("%s:%d S0 w/h %d/%d paddr %08x\n", __func__, __LINE__,
+ pxp->pxp_conf_state.s0_param.width,
+ pxp->pxp_conf_state.s0_param.height,
+ pxp->pxp_conf_state.s0_param.paddr);
+ pr_debug("%s:%d OUT w/h %d/%d paddr %08x\n", __func__, __LINE__,
+ pxp->pxp_conf_state.out_param.width,
+ pxp->pxp_conf_state.out_param.height,
+ pxp->pxp_conf_state.out_param.paddr);
+}
+
+static void pxpdma_dostart_work(struct pxps *pxp)
+{
+ struct pxp_channel *pxp_chan = NULL;
+ unsigned long flags, flags1;
+
+ while (__raw_readl(pxp->base + HW_PXP_CTRL) & BM_PXP_CTRL_ENABLE)
+ ;
+
+ spin_lock_irqsave(&pxp->lock, flags);
+ if (list_empty(&head)) {
+ pxp->pxp_ongoing = 0;
+ spin_unlock_irqrestore(&pxp->lock, flags);
+ return;
+ }
+
+ pxp_chan = list_entry(head.next, struct pxp_channel, list);
+
+ spin_lock_irqsave(&pxp_chan->lock, flags1);
+ if (!list_empty(&pxp_chan->active_list)) {
+ struct pxp_tx_desc *desc;
+ /* REVISIT */
+ desc = pxpdma_first_active(pxp_chan);
+ __pxpdma_dostart(pxp_chan);
+ }
+ spin_unlock_irqrestore(&pxp_chan->lock, flags1);
+
+ /* Configure PxP */
+ pxp_config(pxp, pxp_chan);
+
+ pxp_start(pxp);
+
+ spin_unlock_irqrestore(&pxp->lock, flags);
+}
+
+static void pxpdma_dequeue(struct pxp_channel *pxp_chan, struct list_head *list)
+{
+ struct pxp_tx_desc *desc = NULL;
+ do {
+ desc = pxpdma_first_queued(pxp_chan);
+ list_move_tail(&desc->list, list);
+ } while (!list_empty(&pxp_chan->queue));
+}
+
+static dma_cookie_t pxp_tx_submit(struct dma_async_tx_descriptor *tx)
+{
+ struct pxp_tx_desc *desc = to_tx_desc(tx);
+ struct pxp_channel *pxp_chan = to_pxp_channel(tx->chan);
+ dma_cookie_t cookie;
+ unsigned long flags;
+
+ dev_dbg(&pxp_chan->dma_chan.dev->device, "received TX\n");
+
+ mutex_lock(&pxp_chan->chan_mutex);
+
+ cookie = pxp_chan->dma_chan.cookie;
+
+ if (++cookie < 0)
+ cookie = 1;
+
+ /* from dmaengine.h: "last cookie value returned to client" */
+ pxp_chan->dma_chan.cookie = cookie;
+ tx->cookie = cookie;
+
+ /* pxp_chan->lock can be taken under ichan->lock, but not v.v. */
+ spin_lock_irqsave(&pxp_chan->lock, flags);
+
+ /* Here we add the tx descriptor to our PxP task queue. */
+ list_add_tail(&desc->list, &pxp_chan->queue);
+
+ spin_unlock_irqrestore(&pxp_chan->lock, flags);
+
+ dev_dbg(&pxp_chan->dma_chan.dev->device, "done TX\n");
+
+ mutex_unlock(&pxp_chan->chan_mutex);
+ return cookie;
+}
+
+/* Called with pxp_chan->chan_mutex held */
+static int pxp_desc_alloc(struct pxp_channel *pxp_chan, int n)
+{
+ struct pxp_tx_desc *desc = vmalloc(n * sizeof(struct pxp_tx_desc));
+
+ if (!desc)
+ return -ENOMEM;
+
+ pxp_chan->n_tx_desc = n;
+ pxp_chan->desc = desc;
+ INIT_LIST_HEAD(&pxp_chan->active_list);
+ INIT_LIST_HEAD(&pxp_chan->queue);
+ INIT_LIST_HEAD(&pxp_chan->free_list);
+
+ while (n--) {
+ struct dma_async_tx_descriptor *txd = &desc->txd;
+
+ memset(txd, 0, sizeof(*txd));
+ INIT_LIST_HEAD(&desc->tx_list);
+ dma_async_tx_descriptor_init(txd, &pxp_chan->dma_chan);
+ txd->tx_submit = pxp_tx_submit;
+
+ list_add(&desc->list, &pxp_chan->free_list);
+
+ desc++;
+ }
+
+ return 0;
+}
+
+/**
+ * pxp_init_channel() - initialize a PXP channel.
+ * @pxp_dma: PXP DMA context.
+ * @pchan: pointer to the channel object.
+ * @return 0 on success or negative error code on failure.
+ */
+static int pxp_init_channel(struct pxp_dma *pxp_dma,
+ struct pxp_channel *pxp_chan)
+{
+ unsigned long flags;
+ struct pxps *pxp = to_pxp(pxp_dma);
+ int ret = 0, n_desc = 0;
+
+ /*
+ * We are using _virtual_ channel here.
+ * Each channel contains all parameters of corresponding layers
+ * for one transaction; each layer is represented as one descriptor
+ * (i.e., pxp_tx_desc) here.
+ */
+
+ spin_lock_irqsave(&pxp->lock, flags);
+
+ /* max desc nr: S0+OL+OUT = 1+8+1 */
+ n_desc = 16;
+
+ spin_unlock_irqrestore(&pxp->lock, flags);
+
+ if (n_desc && !pxp_chan->desc)
+ ret = pxp_desc_alloc(pxp_chan, n_desc);
+
+ return ret;
+}
+
+/**
+ * pxp_uninit_channel() - uninitialize a PXP channel.
+ * @pxp_dma: PXP DMA context.
+ * @pchan: pointer to the channel object.
+ * @return 0 on success or negative error code on failure.
+ */
+static int pxp_uninit_channel(struct pxp_dma *pxp_dma,
+ struct pxp_channel *pxp_chan)
+{
+ int ret = 0;
+
+ if (pxp_chan->desc)
+ vfree(pxp_chan->desc);
+
+ pxp_chan->desc = NULL;
+
+ return ret;
+}
+
+static irqreturn_t pxp_irq(int irq, void *dev_id)
+{
+ struct pxps *pxp = dev_id;
+ struct pxp_channel *pxp_chan;
+ struct pxp_tx_desc *desc;
+ dma_async_tx_callback callback;
+ void *callback_param;
+ unsigned long flags;
+ u32 hist_status;
+
+ dump_pxp_reg(pxp);
+
+ hist_status =
+ __raw_readl(pxp->base + HW_PXP_HIST_CTRL) & BM_PXP_HIST_CTRL_STATUS;
+
+ __raw_writel(BM_PXP_STAT_IRQ, pxp->base + HW_PXP_STAT_CLR);
+
+ spin_lock_irqsave(&pxp->lock, flags);
+
+ if (list_empty(&head)) {
+ pxp->pxp_ongoing = 0;
+ spin_unlock_irqrestore(&pxp->lock, flags);
+ return IRQ_NONE;
+ }
+
+ pxp_chan = list_entry(head.next, struct pxp_channel, list);
+ list_del_init(&pxp_chan->list);
+
+ if (list_empty(&pxp_chan->active_list)) {
+ pr_debug("PXP_IRQ pxp_chan->active_list empty. chan_id %d\n",
+ pxp_chan->dma_chan.chan_id);
+ pxp->pxp_ongoing = 0;
+ spin_unlock_irqrestore(&pxp->lock, flags);
+ return IRQ_NONE;
+ }
+
+ /* Get descriptor and call callback */
+ desc = pxpdma_first_active(pxp_chan);
+
+ pxp_chan->completed = desc->txd.cookie;
+
+ callback = desc->txd.callback;
+ callback_param = desc->txd.callback_param;
+
+ /* Send histogram status back to caller */
+ desc->hist_status = hist_status;
+
+ if ((desc->txd.flags & DMA_PREP_INTERRUPT) && callback)
+ callback(callback_param);
+
+ pxp_chan->status = PXP_CHANNEL_INITIALIZED;
+
+ list_splice_init(&desc->tx_list, &pxp_chan->free_list);
+ list_move(&desc->list, &pxp_chan->free_list);
+
+ wake_up(&pxp->done);
+ pxp->pxp_ongoing = 0;
+ mod_timer(&pxp->clk_timer, jiffies + msecs_to_jiffies(timeout_in_ms));
+
+ spin_unlock_irqrestore(&pxp->lock, flags);
+
+ return IRQ_HANDLED;
+}
+
+/* called with pxp_chan->lock held */
+static struct pxp_tx_desc *pxpdma_desc_get(struct pxp_channel *pxp_chan)
+{
+ struct pxp_tx_desc *desc, *_desc;
+ struct pxp_tx_desc *ret = NULL;
+
+ list_for_each_entry_safe(desc, _desc, &pxp_chan->free_list, list) {
+ list_del_init(&desc->list);
+ ret = desc;
+ break;
+ }
+
+ return ret;
+}
+
+/* called with pxp_chan->lock held */
+static void pxpdma_desc_put(struct pxp_channel *pxp_chan,
+ struct pxp_tx_desc *desc)
+{
+ if (desc) {
+ struct device *dev = &pxp_chan->dma_chan.dev->device;
+ struct pxp_tx_desc *child;
+
+ list_for_each_entry(child, &desc->tx_list, list)
+ dev_info(dev, "moving child desc %p to freelist\n", child);
+ list_splice_init(&desc->tx_list, &pxp_chan->free_list);
+ dev_info(dev, "moving desc %p to freelist\n", desc);
+ list_add(&desc->list, &pxp_chan->free_list);
+ }
+}
+
+/* Allocate and initialise a transfer descriptor. */
+static struct dma_async_tx_descriptor *pxp_prep_slave_sg(struct dma_chan *chan,
+ struct scatterlist
+ *sgl,
+ unsigned int sg_len,
+ enum dma_transfer_direction
+ direction,
+ unsigned long tx_flags)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
+ struct pxps *pxp = to_pxp(pxp_dma);
+ struct pxp_tx_desc *desc = NULL;
+ struct pxp_tx_desc *first = NULL, *prev = NULL;
+ struct scatterlist *sg;
+ unsigned long flags;
+ dma_addr_t phys_addr;
+ int i;
+
+ if (direction != DMA_DEV_TO_MEM && direction != DMA_MEM_TO_DEV) {
+ dev_err(chan->device->dev, "Invalid DMA direction %d!\n",
+ direction);
+ return NULL;
+ }
+
+ if (unlikely(sg_len < 2))
+ return NULL;
+
+ spin_lock_irqsave(&pxp_chan->lock, flags);
+ for_each_sg(sgl, sg, sg_len, i) {
+ desc = pxpdma_desc_get(pxp_chan);
+ if (!desc) {
+ pxpdma_desc_put(pxp_chan, first);
+ dev_err(chan->device->dev, "Can't get DMA desc.\n");
+ spin_unlock_irqrestore(&pxp_chan->lock, flags);
+ return NULL;
+ }
+
+ phys_addr = sg_dma_address(sg);
+
+ if (!first) {
+ first = desc;
+
+ desc->layer_param.s0_param.paddr = phys_addr;
+ } else {
+ list_add_tail(&desc->list, &first->tx_list);
+ prev->next = desc;
+ desc->next = NULL;
+
+ if (i == 1)
+ desc->layer_param.out_param.paddr = phys_addr;
+ else
+ desc->layer_param.ol_param.paddr = phys_addr;
+ }
+
+ prev = desc;
+ }
+ spin_unlock_irqrestore(&pxp_chan->lock, flags);
+
+ pxp->pxp_conf_state.layer_nr = sg_len;
+ first->txd.flags = tx_flags;
+ first->len = sg_len;
+ pr_debug("%s:%d first %p, first->len %d, flags %08x\n",
+ __func__, __LINE__, first, first->len, first->txd.flags);
+
+ return &first->txd;
+}
+
+static void pxp_issue_pending(struct dma_chan *chan)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
+ struct pxps *pxp = to_pxp(pxp_dma);
+ unsigned long flags0, flags;
+
+ spin_lock_irqsave(&pxp->lock, flags0);
+ spin_lock_irqsave(&pxp_chan->lock, flags);
+
+ if (!list_empty(&pxp_chan->queue)) {
+ pxpdma_dequeue(pxp_chan, &pxp_chan->active_list);
+ pxp_chan->status = PXP_CHANNEL_READY;
+ list_add_tail(&pxp_chan->list, &head);
+ } else {
+ spin_unlock_irqrestore(&pxp_chan->lock, flags);
+ spin_unlock_irqrestore(&pxp->lock, flags0);
+ return;
+ }
+ spin_unlock_irqrestore(&pxp_chan->lock, flags);
+ spin_unlock_irqrestore(&pxp->lock, flags0);
+
+ pxp_clk_enable(pxp);
+ if (!wait_event_interruptible_timeout(pxp->done, PXP_WAITCON, 2 * HZ) ||
+ signal_pending(current)) {
+ pxp_clk_disable(pxp);
+ return;
+ }
+
+ spin_lock_irqsave(&pxp->lock, flags);
+ pxp->pxp_ongoing = 1;
+ spin_unlock_irqrestore(&pxp->lock, flags);
+ pxpdma_dostart_work(pxp);
+}
+
+static void __pxp_terminate_all(struct dma_chan *chan)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ unsigned long flags;
+
+ /* pchan->queue is modified in ISR, have to spinlock */
+ spin_lock_irqsave(&pxp_chan->lock, flags);
+ list_splice_init(&pxp_chan->queue, &pxp_chan->free_list);
+ list_splice_init(&pxp_chan->active_list, &pxp_chan->free_list);
+
+ spin_unlock_irqrestore(&pxp_chan->lock, flags);
+
+ pxp_chan->status = PXP_CHANNEL_INITIALIZED;
+}
+
+static int pxp_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
+ unsigned long arg)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+
+ /* Only supports DMA_TERMINATE_ALL */
+ if (cmd != DMA_TERMINATE_ALL)
+ return -ENXIO;
+
+ mutex_lock(&pxp_chan->chan_mutex);
+ __pxp_terminate_all(chan);
+ mutex_unlock(&pxp_chan->chan_mutex);
+
+ return 0;
+}
+
+static int pxp_alloc_chan_resources(struct dma_chan *chan)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
+ int ret;
+
+ /* dmaengine.c now guarantees to only offer free channels */
+ BUG_ON(chan->client_count > 1);
+ WARN_ON(pxp_chan->status != PXP_CHANNEL_FREE);
+
+ chan->cookie = 1;
+ pxp_chan->completed = -ENXIO;
+
+ pr_debug("%s dma_chan.chan_id %d\n", __func__, chan->chan_id);
+ ret = pxp_init_channel(pxp_dma, pxp_chan);
+ if (ret < 0)
+ goto err_chan;
+
+ pxp_chan->status = PXP_CHANNEL_INITIALIZED;
+
+ dev_dbg(&chan->dev->device, "Found channel 0x%x, irq %d\n",
+ chan->chan_id, pxp_chan->eof_irq);
+
+ return ret;
+
+err_chan:
+ return ret;
+}
+
+static void pxp_free_chan_resources(struct dma_chan *chan)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+ struct pxp_dma *pxp_dma = to_pxp_dma(chan->device);
+
+ mutex_lock(&pxp_chan->chan_mutex);
+
+ __pxp_terminate_all(chan);
+
+ pxp_chan->status = PXP_CHANNEL_FREE;
+
+ pxp_uninit_channel(pxp_dma, pxp_chan);
+
+ mutex_unlock(&pxp_chan->chan_mutex);
+}
+
+static enum dma_status pxp_tx_status(struct dma_chan *chan,
+ dma_cookie_t cookie,
+ struct dma_tx_state *txstate)
+{
+ struct pxp_channel *pxp_chan = to_pxp_channel(chan);
+
+ if (cookie != chan->cookie)
+ return DMA_ERROR;
+
+ if (txstate) {
+ txstate->last = pxp_chan->completed;
+ txstate->used = chan->cookie;
+ txstate->residue = 0;
+ }
+ return DMA_SUCCESS;
+}
+
+static int pxp_hw_init(struct pxps *pxp)
+{
+ struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
+ struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
+ u32 reg_val;
+
+ /* Pull PxP out of reset */
+ __raw_writel(0, pxp->base + HW_PXP_CTRL);
+
+ /* Config defaults */
+
+ /* Initialize non-channel-specific PxP parameters */
+ proc_data->drect.left = proc_data->srect.left = 0;
+ proc_data->drect.top = proc_data->srect.top = 0;
+ proc_data->drect.width = proc_data->srect.width = 0;
+ proc_data->drect.height = proc_data->srect.height = 0;
+ proc_data->scaling = 0;
+ proc_data->hflip = 0;
+ proc_data->vflip = 0;
+ proc_data->rotate = 0;
+ proc_data->bgcolor = 0;
+
+ /* Initialize S0 channel parameters */
+ pxp_conf->s0_param.pixel_fmt = pxp_s0_formats[0];
+ pxp_conf->s0_param.width = 0;
+ pxp_conf->s0_param.height = 0;
+ pxp_conf->s0_param.color_key = -1;
+ pxp_conf->s0_param.color_key_enable = false;
+
+ /* Initialize OL channel parameters */
+ pxp_conf->ol_param[0].combine_enable = false;
+ pxp_conf->ol_param[0].width = 0;
+ pxp_conf->ol_param[0].height = 0;
+ pxp_conf->ol_param[0].pixel_fmt = PXP_PIX_FMT_RGB565;
+ pxp_conf->ol_param[0].color_key_enable = false;
+ pxp_conf->ol_param[0].color_key = -1;
+ pxp_conf->ol_param[0].global_alpha_enable = false;
+ pxp_conf->ol_param[0].global_alpha = 0;
+ pxp_conf->ol_param[0].local_alpha_enable = false;
+
+ /* Initialize Output channel parameters */
+ pxp_conf->out_param.width = 0;
+ pxp_conf->out_param.height = 0;
+ pxp_conf->out_param.pixel_fmt = PXP_PIX_FMT_RGB565;
+
+ proc_data->overlay_state = 0;
+
+ /* Write default h/w config */
+ pxp_set_ctrl(pxp);
+ pxp_set_s0param(pxp);
+ pxp_set_s0crop(pxp);
+ /*
+ * simply program the ULC to a higher value than the LRC
+ * to avoid any AS pixels to show up in the output buffer.
+ */
+ __raw_writel(0xFFFFFFFF, pxp->base + HW_PXP_OUT_AS_ULC);
+ pxp_set_olparam(0, pxp);
+ pxp_set_olcolorkey(0, pxp);
+
+ pxp_set_s0colorkey(pxp);
+ pxp_set_csc(pxp);
+ pxp_set_bg(pxp);
+ pxp_set_lut(pxp);
+
+ /* One-time histogram configuration */
+ reg_val =
+ BF_PXP_HIST_CTRL_PANEL_MODE(BV_PXP_HIST_CTRL_PANEL_MODE__GRAY16);
+ __raw_writel(reg_val, pxp->base + HW_PXP_HIST_CTRL);
+
+ reg_val = BF_PXP_HIST2_PARAM_VALUE0(0x00) |
+ BF_PXP_HIST2_PARAM_VALUE1(0x00F);
+ __raw_writel(reg_val, pxp->base + HW_PXP_HIST2_PARAM);
+
+ reg_val = BF_PXP_HIST4_PARAM_VALUE0(0x00) |
+ BF_PXP_HIST4_PARAM_VALUE1(0x05) |
+ BF_PXP_HIST4_PARAM_VALUE2(0x0A) | BF_PXP_HIST4_PARAM_VALUE3(0x0F);
+ __raw_writel(reg_val, pxp->base + HW_PXP_HIST4_PARAM);
+
+ reg_val = BF_PXP_HIST8_PARAM0_VALUE0(0x00) |
+ BF_PXP_HIST8_PARAM0_VALUE1(0x02) |
+ BF_PXP_HIST8_PARAM0_VALUE2(0x04) | BF_PXP_HIST8_PARAM0_VALUE3(0x06);
+ __raw_writel(reg_val, pxp->base + HW_PXP_HIST8_PARAM0);
+ reg_val = BF_PXP_HIST8_PARAM1_VALUE4(0x09) |
+ BF_PXP_HIST8_PARAM1_VALUE5(0x0B) |
+ BF_PXP_HIST8_PARAM1_VALUE6(0x0D) | BF_PXP_HIST8_PARAM1_VALUE7(0x0F);
+ __raw_writel(reg_val, pxp->base + HW_PXP_HIST8_PARAM1);
+
+ reg_val = BF_PXP_HIST16_PARAM0_VALUE0(0x00) |
+ BF_PXP_HIST16_PARAM0_VALUE1(0x01) |
+ BF_PXP_HIST16_PARAM0_VALUE2(0x02) |
+ BF_PXP_HIST16_PARAM0_VALUE3(0x03);
+ __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM0);
+ reg_val = BF_PXP_HIST16_PARAM1_VALUE4(0x04) |
+ BF_PXP_HIST16_PARAM1_VALUE5(0x05) |
+ BF_PXP_HIST16_PARAM1_VALUE6(0x06) |
+ BF_PXP_HIST16_PARAM1_VALUE7(0x07);
+ __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM1);
+ reg_val = BF_PXP_HIST16_PARAM2_VALUE8(0x08) |
+ BF_PXP_HIST16_PARAM2_VALUE9(0x09) |
+ BF_PXP_HIST16_PARAM2_VALUE10(0x0A) |
+ BF_PXP_HIST16_PARAM2_VALUE11(0x0B);
+ __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM2);
+ reg_val = BF_PXP_HIST16_PARAM3_VALUE12(0x0C) |
+ BF_PXP_HIST16_PARAM3_VALUE13(0x0D) |
+ BF_PXP_HIST16_PARAM3_VALUE14(0x0E) |
+ BF_PXP_HIST16_PARAM3_VALUE15(0x0F);
+ __raw_writel(reg_val, pxp->base + HW_PXP_HIST16_PARAM3);
+
+ return 0;
+}
+
+static int pxp_dma_init(struct pxps *pxp)
+{
+ struct pxp_dma *pxp_dma = &pxp->pxp_dma;
+ struct dma_device *dma = &pxp_dma->dma;
+ int i;
+
+ dma_cap_set(DMA_SLAVE, dma->cap_mask);
+ dma_cap_set(DMA_PRIVATE, dma->cap_mask);
+
+ /* Compulsory common fields */
+ dma->dev = pxp->dev;
+ dma->device_alloc_chan_resources = pxp_alloc_chan_resources;
+ dma->device_free_chan_resources = pxp_free_chan_resources;
+ dma->device_tx_status = pxp_tx_status;
+ dma->device_issue_pending = pxp_issue_pending;
+
+ /* Compulsory for DMA_SLAVE fields */
+ dma->device_prep_slave_sg = pxp_prep_slave_sg;
+ dma->device_control = pxp_control;
+
+ /* Initialize PxP Channels */
+ INIT_LIST_HEAD(&dma->channels);
+ for (i = 0; i < NR_PXP_VIRT_CHANNEL; i++) {
+ struct pxp_channel *pxp_chan = pxp->channel + i;
+ struct dma_chan *dma_chan = &pxp_chan->dma_chan;
+
+ spin_lock_init(&pxp_chan->lock);
+ mutex_init(&pxp_chan->chan_mutex);
+
+ /* Only one EOF IRQ for PxP, shared by all channels */
+ pxp_chan->eof_irq = pxp->irq;
+ pxp_chan->status = PXP_CHANNEL_FREE;
+ pxp_chan->completed = -ENXIO;
+ snprintf(pxp_chan->eof_name, sizeof(pxp_chan->eof_name),
+ "PXP EOF %d", i);
+
+ dma_chan->device = &pxp_dma->dma;
+ dma_chan->cookie = 1;
+ dma_chan->chan_id = i;
+ list_add_tail(&dma_chan->device_node, &dma->channels);
+ }
+
+ return dma_async_device_register(&pxp_dma->dma);
+}
+
+static ssize_t clk_off_timeout_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ return sprintf(buf, "%d\n", timeout_in_ms);
+}
+
+static ssize_t clk_off_timeout_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int val;
+ if (sscanf(buf, "%d", &val) > 0) {
+ timeout_in_ms = val;
+ return count;
+ }
+ return -EINVAL;
+}
+
+static DEVICE_ATTR(clk_off_timeout, 0644, clk_off_timeout_show,
+ clk_off_timeout_store);
+
+static int pxp_probe(struct platform_device *pdev)
+{
+ struct pxps *pxp;
+ struct resource *res;
+ int irq;
+ int err = 0;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ irq = platform_get_irq(pdev, 0);
+ if (!res || irq < 0) {
+ err = -ENODEV;
+ goto exit;
+ }
+
+ pxp = kzalloc(sizeof(*pxp), GFP_KERNEL);
+ if (!pxp) {
+ dev_err(&pdev->dev, "failed to allocate control object\n");
+ err = -ENOMEM;
+ goto exit;
+ }
+
+ pxp->dev = &pdev->dev;
+
+ platform_set_drvdata(pdev, pxp);
+ pxp->irq = irq;
+
+ pxp->pxp_ongoing = 0;
+ pxp->lut_state = 0;
+
+ spin_lock_init(&pxp->lock);
+ mutex_init(&pxp->clk_mutex);
+
+ if (!request_mem_region(res->start, resource_size(res), "pxp-mem")) {
+ err = -EBUSY;
+ goto freepxp;
+ }
+
+ pxp->base = ioremap(res->start, SZ_4K);
+ pxp->pdev = pdev;
+
+ pxp->clk = clk_get(NULL, "pxp_axi");
+ clk_enable(pxp->clk);
+
+ err = pxp_hw_init(pxp);
+ if (err) {
+ dev_err(&pdev->dev, "failed to initialize hardware\n");
+ goto release;
+ }
+ clk_disable(pxp->clk);
+
+ err = request_irq(pxp->irq, pxp_irq, 0, "pxp-irq", pxp);
+ if (err)
+ goto release;
+ /* Initialize DMA engine */
+ err = pxp_dma_init(pxp);
+ if (err < 0)
+ goto err_dma_init;
+
+ if (device_create_file(&pdev->dev, &dev_attr_clk_off_timeout)) {
+ dev_err(&pdev->dev,
+ "Unable to create file from clk_off_timeout\n");
+ goto err_dma_init;
+ }
+ dump_pxp_reg(pxp);
+
+ INIT_WORK(&pxp->work, clkoff_callback);
+ init_waitqueue_head(&pxp->done);
+ init_timer(&pxp->clk_timer);
+ pxp->clk_timer.function = pxp_clkoff_timer;
+ pxp->clk_timer.data = (unsigned long)pxp;
+exit:
+ return err;
+err_dma_init:
+ free_irq(pxp->irq, pxp);
+release:
+ release_mem_region(res->start, resource_size(res));
+freepxp:
+ kfree(pxp);
+ dev_err(&pdev->dev, "Exiting (unsuccessfully) pxp_probe function\n");
+ return err;
+}
+
+static int __devexit pxp_remove(struct platform_device *pdev)
+{
+ struct pxps *pxp = platform_get_drvdata(pdev);
+
+ cancel_work_sync(&pxp->work);
+ del_timer_sync(&pxp->clk_timer);
+ free_irq(pxp->irq, pxp);
+ clk_disable(pxp->clk);
+ clk_put(pxp->clk);
+ iounmap(pxp->base);
+ device_remove_file(&pdev->dev, &dev_attr_clk_off_timeout);
+
+ kfree(pxp);
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int pxp_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct pxps *pxp = platform_get_drvdata(pdev);
+
+ pxp_clk_enable(pxp);
+ while (__raw_readl(pxp->base + HW_PXP_CTRL) & BM_PXP_CTRL_ENABLE)
+ ;
+
+ __raw_writel(BM_PXP_CTRL_SFTRST, pxp->base + HW_PXP_CTRL);
+ pxp_clk_disable(pxp);
+
+ return 0;
+}
+
+static int pxp_resume(struct platform_device *pdev)
+{
+ struct pxps *pxp = platform_get_drvdata(pdev);
+
+ pxp_clk_enable(pxp);
+ /* Pull PxP out of reset */
+ __raw_writel(0, pxp->base + HW_PXP_CTRL);
+ pxp_clk_disable(pxp);
+
+ return 0;
+}
+#else
+#define pxp_suspend NULL
+#define pxp_resume NULL
+#endif
+
+static struct platform_driver pxp_driver = {
+ .driver = {
+ .name = "imx-pxp",
+ },
+ .probe = pxp_probe,
+ .remove = __exit_p(pxp_remove),
+ .suspend = pxp_suspend,
+ .resume = pxp_resume,
+};
+
+static int __init pxp_init(void)
+{
+ return platform_driver_register(&pxp_driver);
+}
+
+subsys_initcall(pxp_init);
+
+static void __exit pxp_exit(void)
+{
+ platform_driver_unregister(&pxp_driver);
+}
+
+module_exit(pxp_exit);
+
+MODULE_DESCRIPTION("i.MX PxP driver");
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_LICENSE("GPL");
diff --git a/drivers/dma/pxp/regs-pxp_v2.h b/drivers/dma/pxp/regs-pxp_v2.h
new file mode 100644
index 000000000000..5ac56ce00e45
--- /dev/null
+++ b/drivers/dma/pxp/regs-pxp_v2.h
@@ -0,0 +1,1152 @@
+/*
+ * Freescale PXP Register Definitions
+ *
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * This file is created by xml file. Don't Edit it.
+ *
+ * Xml Revision: 1.29
+ * Template revision: 1.3
+ */
+
+#ifndef __ARCH_ARM___PXP_H
+#define __ARCH_ARM___PXP_H
+
+#define HW_PXP_CTRL (0x00000000)
+#define HW_PXP_CTRL_SET (0x00000004)
+#define HW_PXP_CTRL_CLR (0x00000008)
+#define HW_PXP_CTRL_TOG (0x0000000c)
+
+#define BM_PXP_CTRL_SFTRST 0x80000000
+#define BM_PXP_CTRL_CLKGATE 0x40000000
+#define BM_PXP_CTRL_RSVD4 0x20000000
+#define BM_PXP_CTRL_EN_REPEAT 0x10000000
+#define BP_PXP_CTRL_RSVD3 26
+#define BM_PXP_CTRL_RSVD3 0x0C000000
+#define BF_PXP_CTRL_RSVD3(v) \
+ (((v) << 26) & BM_PXP_CTRL_RSVD3)
+#define BP_PXP_CTRL_INTERLACED_INPUT 24
+#define BM_PXP_CTRL_INTERLACED_INPUT 0x03000000
+#define BF_PXP_CTRL_INTERLACED_INPUT(v) \
+ (((v) << 24) & BM_PXP_CTRL_INTERLACED_INPUT)
+#define BV_PXP_CTRL_INTERLACED_INPUT__PROGRESSIVE 0x0
+#define BV_PXP_CTRL_INTERLACED_INPUT__FIELD0 0x2
+#define BV_PXP_CTRL_INTERLACED_INPUT__FIELD1 0x3
+#define BM_PXP_CTRL_BLOCK_SIZE 0x00800000
+#define BV_PXP_CTRL_BLOCK_SIZE__8X8 0x0
+#define BV_PXP_CTRL_BLOCK_SIZE__16X16 0x1
+#define BM_PXP_CTRL_ROT_POS 0x00400000
+#define BM_PXP_CTRL_IN_PLACE 0x00200000
+#define BP_PXP_CTRL_RSVD1 12
+#define BM_PXP_CTRL_RSVD1 0x001FF000
+#define BF_PXP_CTRL_RSVD1(v) \
+ (((v) << 12) & BM_PXP_CTRL_RSVD1)
+#define BM_PXP_CTRL_VFLIP 0x00000800
+#define BM_PXP_CTRL_HFLIP 0x00000400
+#define BP_PXP_CTRL_ROTATE 8
+#define BM_PXP_CTRL_ROTATE 0x00000300
+#define BF_PXP_CTRL_ROTATE(v) \
+ (((v) << 8) & BM_PXP_CTRL_ROTATE)
+#define BV_PXP_CTRL_ROTATE__ROT_0 0x0
+#define BV_PXP_CTRL_ROTATE__ROT_90 0x1
+#define BV_PXP_CTRL_ROTATE__ROT_180 0x2
+#define BV_PXP_CTRL_ROTATE__ROT_270 0x3
+#define BP_PXP_CTRL_RSVD0 5
+#define BM_PXP_CTRL_RSVD0 0x000000E0
+#define BF_PXP_CTRL_RSVD0(v) \
+ (((v) << 5) & BM_PXP_CTRL_RSVD0)
+#define BM_PXP_CTRL_ENABLE_LCD_HANDSHAKE 0x00000010
+#define BM_PXP_CTRL_LUT_DMA_IRQ_ENABLE 0x00000008
+#define BM_PXP_CTRL_NEXT_IRQ_ENABLE 0x00000004
+#define BM_PXP_CTRL_IRQ_ENABLE 0x00000002
+#define BM_PXP_CTRL_ENABLE 0x00000001
+
+#define HW_PXP_STAT (0x00000010)
+#define HW_PXP_STAT_SET (0x00000014)
+#define HW_PXP_STAT_CLR (0x00000018)
+#define HW_PXP_STAT_TOG (0x0000001c)
+
+#define BP_PXP_STAT_BLOCKX 24
+#define BM_PXP_STAT_BLOCKX 0xFF000000
+#define BF_PXP_STAT_BLOCKX(v) \
+ (((v) << 24) & BM_PXP_STAT_BLOCKX)
+#define BP_PXP_STAT_BLOCKY 16
+#define BM_PXP_STAT_BLOCKY 0x00FF0000
+#define BF_PXP_STAT_BLOCKY(v) \
+ (((v) << 16) & BM_PXP_STAT_BLOCKY)
+#define BP_PXP_STAT_RSVD2 9
+#define BM_PXP_STAT_RSVD2 0x0000FE00
+#define BF_PXP_STAT_RSVD2(v) \
+ (((v) << 9) & BM_PXP_STAT_RSVD2)
+#define BM_PXP_STAT_LUT_DMA_LOAD_DONE_IRQ 0x00000100
+#define BP_PXP_STAT_AXI_ERROR_ID 4
+#define BM_PXP_STAT_AXI_ERROR_ID 0x000000F0
+#define BF_PXP_STAT_AXI_ERROR_ID(v) \
+ (((v) << 4) & BM_PXP_STAT_AXI_ERROR_ID)
+#define BM_PXP_STAT_NEXT_IRQ 0x00000008
+#define BM_PXP_STAT_AXI_READ_ERROR 0x00000004
+#define BM_PXP_STAT_AXI_WRITE_ERROR 0x00000002
+#define BM_PXP_STAT_IRQ 0x00000001
+
+#define HW_PXP_OUT_CTRL (0x00000020)
+#define HW_PXP_OUT_CTRL_SET (0x00000024)
+#define HW_PXP_OUT_CTRL_CLR (0x00000028)
+#define HW_PXP_OUT_CTRL_TOG (0x0000002c)
+
+#define BP_PXP_OUT_CTRL_ALPHA 24
+#define BM_PXP_OUT_CTRL_ALPHA 0xFF000000
+#define BF_PXP_OUT_CTRL_ALPHA(v) \
+ (((v) << 24) & BM_PXP_OUT_CTRL_ALPHA)
+#define BM_PXP_OUT_CTRL_ALPHA_OUTPUT 0x00800000
+#define BP_PXP_OUT_CTRL_RSVD1 10
+#define BM_PXP_OUT_CTRL_RSVD1 0x007FFC00
+#define BF_PXP_OUT_CTRL_RSVD1(v) \
+ (((v) << 10) & BM_PXP_OUT_CTRL_RSVD1)
+#define BP_PXP_OUT_CTRL_INTERLACED_OUTPUT 8
+#define BM_PXP_OUT_CTRL_INTERLACED_OUTPUT 0x00000300
+#define BF_PXP_OUT_CTRL_INTERLACED_OUTPUT(v) \
+ (((v) << 8) & BM_PXP_OUT_CTRL_INTERLACED_OUTPUT)
+#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__PROGRESSIVE 0x0
+#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__FIELD0 0x1
+#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__FIELD1 0x2
+#define BV_PXP_OUT_CTRL_INTERLACED_OUTPUT__INTERLACED 0x3
+#define BP_PXP_OUT_CTRL_RSVD0 5
+#define BM_PXP_OUT_CTRL_RSVD0 0x000000E0
+#define BF_PXP_OUT_CTRL_RSVD0(v) \
+ (((v) << 5) & BM_PXP_OUT_CTRL_RSVD0)
+#define BP_PXP_OUT_CTRL_FORMAT 0
+#define BM_PXP_OUT_CTRL_FORMAT 0x0000001F
+#define BF_PXP_OUT_CTRL_FORMAT(v) \
+ (((v) << 0) & BM_PXP_OUT_CTRL_FORMAT)
+#define BV_PXP_OUT_CTRL_FORMAT__ARGB8888 0x0
+#define BV_PXP_OUT_CTRL_FORMAT__RGB888 0x4
+#define BV_PXP_OUT_CTRL_FORMAT__RGB888P 0x5
+#define BV_PXP_OUT_CTRL_FORMAT__ARGB1555 0x8
+#define BV_PXP_OUT_CTRL_FORMAT__ARGB4444 0x9
+#define BV_PXP_OUT_CTRL_FORMAT__RGB555 0xC
+#define BV_PXP_OUT_CTRL_FORMAT__RGB444 0xD
+#define BV_PXP_OUT_CTRL_FORMAT__RGB565 0xE
+#define BV_PXP_OUT_CTRL_FORMAT__YUV1P444 0x10
+#define BV_PXP_OUT_CTRL_FORMAT__UYVY1P422 0x12
+#define BV_PXP_OUT_CTRL_FORMAT__VYUY1P422 0x13
+#define BV_PXP_OUT_CTRL_FORMAT__Y8 0x14
+#define BV_PXP_OUT_CTRL_FORMAT__Y4 0x15
+#define BV_PXP_OUT_CTRL_FORMAT__YUV2P422 0x18
+#define BV_PXP_OUT_CTRL_FORMAT__YUV2P420 0x19
+#define BV_PXP_OUT_CTRL_FORMAT__YVU2P422 0x1A
+#define BV_PXP_OUT_CTRL_FORMAT__YVU2P420 0x1B
+
+#define HW_PXP_OUT_BUF (0x00000030)
+
+#define BP_PXP_OUT_BUF_ADDR 0
+#define BM_PXP_OUT_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_OUT_BUF_ADDR(v) (v)
+
+#define HW_PXP_OUT_BUF2 (0x00000040)
+
+#define BP_PXP_OUT_BUF2_ADDR 0
+#define BM_PXP_OUT_BUF2_ADDR 0xFFFFFFFF
+#define BF_PXP_OUT_BUF2_ADDR(v) (v)
+
+#define HW_PXP_OUT_PITCH (0x00000050)
+
+#define BP_PXP_OUT_PITCH_RSVD 16
+#define BM_PXP_OUT_PITCH_RSVD 0xFFFF0000
+#define BF_PXP_OUT_PITCH_RSVD(v) \
+ (((v) << 16) & BM_PXP_OUT_PITCH_RSVD)
+#define BP_PXP_OUT_PITCH_PITCH 0
+#define BM_PXP_OUT_PITCH_PITCH 0x0000FFFF
+#define BF_PXP_OUT_PITCH_PITCH(v) \
+ (((v) << 0) & BM_PXP_OUT_PITCH_PITCH)
+
+#define HW_PXP_OUT_LRC (0x00000060)
+
+#define BP_PXP_OUT_LRC_RSVD1 30
+#define BM_PXP_OUT_LRC_RSVD1 0xC0000000
+#define BF_PXP_OUT_LRC_RSVD1(v) \
+ (((v) << 30) & BM_PXP_OUT_LRC_RSVD1)
+#define BP_PXP_OUT_LRC_X 16
+#define BM_PXP_OUT_LRC_X 0x3FFF0000
+#define BF_PXP_OUT_LRC_X(v) \
+ (((v) << 16) & BM_PXP_OUT_LRC_X)
+#define BP_PXP_OUT_LRC_RSVD0 14
+#define BM_PXP_OUT_LRC_RSVD0 0x0000C000
+#define BF_PXP_OUT_LRC_RSVD0(v) \
+ (((v) << 14) & BM_PXP_OUT_LRC_RSVD0)
+#define BP_PXP_OUT_LRC_Y 0
+#define BM_PXP_OUT_LRC_Y 0x00003FFF
+#define BF_PXP_OUT_LRC_Y(v) \
+ (((v) << 0) & BM_PXP_OUT_LRC_Y)
+
+#define HW_PXP_OUT_PS_ULC (0x00000070)
+
+#define BP_PXP_OUT_PS_ULC_RSVD1 30
+#define BM_PXP_OUT_PS_ULC_RSVD1 0xC0000000
+#define BF_PXP_OUT_PS_ULC_RSVD1(v) \
+ (((v) << 30) & BM_PXP_OUT_PS_ULC_RSVD1)
+#define BP_PXP_OUT_PS_ULC_X 16
+#define BM_PXP_OUT_PS_ULC_X 0x3FFF0000
+#define BF_PXP_OUT_PS_ULC_X(v) \
+ (((v) << 16) & BM_PXP_OUT_PS_ULC_X)
+#define BP_PXP_OUT_PS_ULC_RSVD0 14
+#define BM_PXP_OUT_PS_ULC_RSVD0 0x0000C000
+#define BF_PXP_OUT_PS_ULC_RSVD0(v) \
+ (((v) << 14) & BM_PXP_OUT_PS_ULC_RSVD0)
+#define BP_PXP_OUT_PS_ULC_Y 0
+#define BM_PXP_OUT_PS_ULC_Y 0x00003FFF
+#define BF_PXP_OUT_PS_ULC_Y(v) \
+ (((v) << 0) & BM_PXP_OUT_PS_ULC_Y)
+
+#define HW_PXP_OUT_PS_LRC (0x00000080)
+
+#define BP_PXP_OUT_PS_LRC_RSVD1 30
+#define BM_PXP_OUT_PS_LRC_RSVD1 0xC0000000
+#define BF_PXP_OUT_PS_LRC_RSVD1(v) \
+ (((v) << 30) & BM_PXP_OUT_PS_LRC_RSVD1)
+#define BP_PXP_OUT_PS_LRC_X 16
+#define BM_PXP_OUT_PS_LRC_X 0x3FFF0000
+#define BF_PXP_OUT_PS_LRC_X(v) \
+ (((v) << 16) & BM_PXP_OUT_PS_LRC_X)
+#define BP_PXP_OUT_PS_LRC_RSVD0 14
+#define BM_PXP_OUT_PS_LRC_RSVD0 0x0000C000
+#define BF_PXP_OUT_PS_LRC_RSVD0(v) \
+ (((v) << 14) & BM_PXP_OUT_PS_LRC_RSVD0)
+#define BP_PXP_OUT_PS_LRC_Y 0
+#define BM_PXP_OUT_PS_LRC_Y 0x00003FFF
+#define BF_PXP_OUT_PS_LRC_Y(v) \
+ (((v) << 0) & BM_PXP_OUT_PS_LRC_Y)
+
+#define HW_PXP_OUT_AS_ULC (0x00000090)
+
+#define BP_PXP_OUT_AS_ULC_RSVD1 30
+#define BM_PXP_OUT_AS_ULC_RSVD1 0xC0000000
+#define BF_PXP_OUT_AS_ULC_RSVD1(v) \
+ (((v) << 30) & BM_PXP_OUT_AS_ULC_RSVD1)
+#define BP_PXP_OUT_AS_ULC_X 16
+#define BM_PXP_OUT_AS_ULC_X 0x3FFF0000
+#define BF_PXP_OUT_AS_ULC_X(v) \
+ (((v) << 16) & BM_PXP_OUT_AS_ULC_X)
+#define BP_PXP_OUT_AS_ULC_RSVD0 14
+#define BM_PXP_OUT_AS_ULC_RSVD0 0x0000C000
+#define BF_PXP_OUT_AS_ULC_RSVD0(v) \
+ (((v) << 14) & BM_PXP_OUT_AS_ULC_RSVD0)
+#define BP_PXP_OUT_AS_ULC_Y 0
+#define BM_PXP_OUT_AS_ULC_Y 0x00003FFF
+#define BF_PXP_OUT_AS_ULC_Y(v) \
+ (((v) << 0) & BM_PXP_OUT_AS_ULC_Y)
+
+#define HW_PXP_OUT_AS_LRC (0x000000a0)
+
+#define BP_PXP_OUT_AS_LRC_RSVD1 30
+#define BM_PXP_OUT_AS_LRC_RSVD1 0xC0000000
+#define BF_PXP_OUT_AS_LRC_RSVD1(v) \
+ (((v) << 30) & BM_PXP_OUT_AS_LRC_RSVD1)
+#define BP_PXP_OUT_AS_LRC_X 16
+#define BM_PXP_OUT_AS_LRC_X 0x3FFF0000
+#define BF_PXP_OUT_AS_LRC_X(v) \
+ (((v) << 16) & BM_PXP_OUT_AS_LRC_X)
+#define BP_PXP_OUT_AS_LRC_RSVD0 14
+#define BM_PXP_OUT_AS_LRC_RSVD0 0x0000C000
+#define BF_PXP_OUT_AS_LRC_RSVD0(v) \
+ (((v) << 14) & BM_PXP_OUT_AS_LRC_RSVD0)
+#define BP_PXP_OUT_AS_LRC_Y 0
+#define BM_PXP_OUT_AS_LRC_Y 0x00003FFF
+#define BF_PXP_OUT_AS_LRC_Y(v) \
+ (((v) << 0) & BM_PXP_OUT_AS_LRC_Y)
+
+#define HW_PXP_PS_CTRL (0x000000b0)
+#define HW_PXP_PS_CTRL_SET (0x000000b4)
+#define HW_PXP_PS_CTRL_CLR (0x000000b8)
+#define HW_PXP_PS_CTRL_TOG (0x000000bc)
+
+#define BP_PXP_PS_CTRL_RSVD1 12
+#define BM_PXP_PS_CTRL_RSVD1 0xFFFFF000
+#define BF_PXP_PS_CTRL_RSVD1(v) \
+ (((v) << 12) & BM_PXP_PS_CTRL_RSVD1)
+#define BP_PXP_PS_CTRL_DECX 10
+#define BM_PXP_PS_CTRL_DECX 0x00000C00
+#define BF_PXP_PS_CTRL_DECX(v) \
+ (((v) << 10) & BM_PXP_PS_CTRL_DECX)
+#define BV_PXP_PS_CTRL_DECX__DISABLE 0x0
+#define BV_PXP_PS_CTRL_DECX__DECX2 0x1
+#define BV_PXP_PS_CTRL_DECX__DECX4 0x2
+#define BV_PXP_PS_CTRL_DECX__DECX8 0x3
+#define BP_PXP_PS_CTRL_DECY 8
+#define BM_PXP_PS_CTRL_DECY 0x00000300
+#define BF_PXP_PS_CTRL_DECY(v) \
+ (((v) << 8) & BM_PXP_PS_CTRL_DECY)
+#define BV_PXP_PS_CTRL_DECY__DISABLE 0x0
+#define BV_PXP_PS_CTRL_DECY__DECY2 0x1
+#define BV_PXP_PS_CTRL_DECY__DECY4 0x2
+#define BV_PXP_PS_CTRL_DECY__DECY8 0x3
+#define BP_PXP_PS_CTRL_RSVD0 5
+#define BM_PXP_PS_CTRL_RSVD0 0x000000E0
+#define BF_PXP_PS_CTRL_RSVD0(v) \
+ (((v) << 5) & BM_PXP_PS_CTRL_RSVD0)
+#define BP_PXP_PS_CTRL_FORMAT 0
+#define BM_PXP_PS_CTRL_FORMAT 0x0000001F
+#define BF_PXP_PS_CTRL_FORMAT(v) \
+ (((v) << 0) & BM_PXP_PS_CTRL_FORMAT)
+#define BV_PXP_PS_CTRL_FORMAT__RGB888 0x4
+#define BV_PXP_PS_CTRL_FORMAT__RGB555 0xC
+#define BV_PXP_PS_CTRL_FORMAT__RGB444 0xD
+#define BV_PXP_PS_CTRL_FORMAT__RGB565 0xE
+#define BV_PXP_PS_CTRL_FORMAT__YUV1P444 0x10
+#define BV_PXP_PS_CTRL_FORMAT__UYVY1P422 0x12
+#define BV_PXP_PS_CTRL_FORMAT__VYUY1P422 0x13
+#define BV_PXP_PS_CTRL_FORMAT__Y8 0x14
+#define BV_PXP_PS_CTRL_FORMAT__Y4 0x15
+#define BV_PXP_PS_CTRL_FORMAT__YUV2P422 0x18
+#define BV_PXP_PS_CTRL_FORMAT__YUV2P420 0x19
+#define BV_PXP_PS_CTRL_FORMAT__YVU2P422 0x1A
+#define BV_PXP_PS_CTRL_FORMAT__YVU2P420 0x1B
+#define BV_PXP_PS_CTRL_FORMAT__YUV422 0x1E
+#define BV_PXP_PS_CTRL_FORMAT__YUV420 0x1F
+
+#define HW_PXP_PS_BUF (0x000000c0)
+
+#define BP_PXP_PS_BUF_ADDR 0
+#define BM_PXP_PS_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_PS_BUF_ADDR(v) (v)
+
+#define HW_PXP_PS_UBUF (0x000000d0)
+
+#define BP_PXP_PS_UBUF_ADDR 0
+#define BM_PXP_PS_UBUF_ADDR 0xFFFFFFFF
+#define BF_PXP_PS_UBUF_ADDR(v) (v)
+
+#define HW_PXP_PS_VBUF (0x000000e0)
+
+#define BP_PXP_PS_VBUF_ADDR 0
+#define BM_PXP_PS_VBUF_ADDR 0xFFFFFFFF
+#define BF_PXP_PS_VBUF_ADDR(v) (v)
+
+#define HW_PXP_PS_PITCH (0x000000f0)
+
+#define BP_PXP_PS_PITCH_RSVD 16
+#define BM_PXP_PS_PITCH_RSVD 0xFFFF0000
+#define BF_PXP_PS_PITCH_RSVD(v) \
+ (((v) << 16) & BM_PXP_PS_PITCH_RSVD)
+#define BP_PXP_PS_PITCH_PITCH 0
+#define BM_PXP_PS_PITCH_PITCH 0x0000FFFF
+#define BF_PXP_PS_PITCH_PITCH(v) \
+ (((v) << 0) & BM_PXP_PS_PITCH_PITCH)
+
+#define HW_PXP_PS_BACKGROUND (0x00000100)
+
+#define BP_PXP_PS_BACKGROUND_RSVD 24
+#define BM_PXP_PS_BACKGROUND_RSVD 0xFF000000
+#define BF_PXP_PS_BACKGROUND_RSVD(v) \
+ (((v) << 24) & BM_PXP_PS_BACKGROUND_RSVD)
+#define BP_PXP_PS_BACKGROUND_COLOR 0
+#define BM_PXP_PS_BACKGROUND_COLOR 0x00FFFFFF
+#define BF_PXP_PS_BACKGROUND_COLOR(v) \
+ (((v) << 0) & BM_PXP_PS_BACKGROUND_COLOR)
+
+#define HW_PXP_PS_SCALE (0x00000110)
+
+#define BM_PXP_PS_SCALE_RSVD2 0x80000000
+#define BP_PXP_PS_SCALE_YSCALE 16
+#define BM_PXP_PS_SCALE_YSCALE 0x7FFF0000
+#define BF_PXP_PS_SCALE_YSCALE(v) \
+ (((v) << 16) & BM_PXP_PS_SCALE_YSCALE)
+#define BM_PXP_PS_SCALE_RSVD1 0x00008000
+#define BP_PXP_PS_SCALE_XSCALE 0
+#define BM_PXP_PS_SCALE_XSCALE 0x00007FFF
+#define BF_PXP_PS_SCALE_XSCALE(v) \
+ (((v) << 0) & BM_PXP_PS_SCALE_XSCALE)
+
+#define HW_PXP_PS_OFFSET (0x00000120)
+
+#define BP_PXP_PS_OFFSET_RSVD2 28
+#define BM_PXP_PS_OFFSET_RSVD2 0xF0000000
+#define BF_PXP_PS_OFFSET_RSVD2(v) \
+ (((v) << 28) & BM_PXP_PS_OFFSET_RSVD2)
+#define BP_PXP_PS_OFFSET_YOFFSET 16
+#define BM_PXP_PS_OFFSET_YOFFSET 0x0FFF0000
+#define BF_PXP_PS_OFFSET_YOFFSET(v) \
+ (((v) << 16) & BM_PXP_PS_OFFSET_YOFFSET)
+#define BP_PXP_PS_OFFSET_RSVD1 12
+#define BM_PXP_PS_OFFSET_RSVD1 0x0000F000
+#define BF_PXP_PS_OFFSET_RSVD1(v) \
+ (((v) << 12) & BM_PXP_PS_OFFSET_RSVD1)
+#define BP_PXP_PS_OFFSET_XOFFSET 0
+#define BM_PXP_PS_OFFSET_XOFFSET 0x00000FFF
+#define BF_PXP_PS_OFFSET_XOFFSET(v) \
+ (((v) << 0) & BM_PXP_PS_OFFSET_XOFFSET)
+
+#define HW_PXP_PS_CLRKEYLOW (0x00000130)
+
+#define BP_PXP_PS_CLRKEYLOW_RSVD1 24
+#define BM_PXP_PS_CLRKEYLOW_RSVD1 0xFF000000
+#define BF_PXP_PS_CLRKEYLOW_RSVD1(v) \
+ (((v) << 24) & BM_PXP_PS_CLRKEYLOW_RSVD1)
+#define BP_PXP_PS_CLRKEYLOW_PIXEL 0
+#define BM_PXP_PS_CLRKEYLOW_PIXEL 0x00FFFFFF
+#define BF_PXP_PS_CLRKEYLOW_PIXEL(v) \
+ (((v) << 0) & BM_PXP_PS_CLRKEYLOW_PIXEL)
+
+#define HW_PXP_PS_CLRKEYHIGH (0x00000140)
+
+#define BP_PXP_PS_CLRKEYHIGH_RSVD1 24
+#define BM_PXP_PS_CLRKEYHIGH_RSVD1 0xFF000000
+#define BF_PXP_PS_CLRKEYHIGH_RSVD1(v) \
+ (((v) << 24) & BM_PXP_PS_CLRKEYHIGH_RSVD1)
+#define BP_PXP_PS_CLRKEYHIGH_PIXEL 0
+#define BM_PXP_PS_CLRKEYHIGH_PIXEL 0x00FFFFFF
+#define BF_PXP_PS_CLRKEYHIGH_PIXEL(v) \
+ (((v) << 0) & BM_PXP_PS_CLRKEYHIGH_PIXEL)
+
+#define HW_PXP_AS_CTRL (0x00000150)
+
+#define BP_PXP_AS_CTRL_RSVD1 21
+#define BM_PXP_AS_CTRL_RSVD1 0xFFE00000
+#define BF_PXP_AS_CTRL_RSVD1(v) \
+ (((v) << 21) & BM_PXP_AS_CTRL_RSVD1)
+#define BM_PXP_AS_CTRL_ALPHA_INVERT 0x00100000
+#define BP_PXP_AS_CTRL_ROP 16
+#define BM_PXP_AS_CTRL_ROP 0x000F0000
+#define BF_PXP_AS_CTRL_ROP(v) \
+ (((v) << 16) & BM_PXP_AS_CTRL_ROP)
+#define BV_PXP_AS_CTRL_ROP__MASKAS 0x0
+#define BV_PXP_AS_CTRL_ROP__MASKNOTAS 0x1
+#define BV_PXP_AS_CTRL_ROP__MASKASNOT 0x2
+#define BV_PXP_AS_CTRL_ROP__MERGEAS 0x3
+#define BV_PXP_AS_CTRL_ROP__MERGENOTAS 0x4
+#define BV_PXP_AS_CTRL_ROP__MERGEASNOT 0x5
+#define BV_PXP_AS_CTRL_ROP__NOTCOPYAS 0x6
+#define BV_PXP_AS_CTRL_ROP__NOT 0x7
+#define BV_PXP_AS_CTRL_ROP__NOTMASKAS 0x8
+#define BV_PXP_AS_CTRL_ROP__NOTMERGEAS 0x9
+#define BV_PXP_AS_CTRL_ROP__XORAS 0xA
+#define BV_PXP_AS_CTRL_ROP__NOTXORAS 0xB
+#define BP_PXP_AS_CTRL_ALPHA 8
+#define BM_PXP_AS_CTRL_ALPHA 0x0000FF00
+#define BF_PXP_AS_CTRL_ALPHA(v) \
+ (((v) << 8) & BM_PXP_AS_CTRL_ALPHA)
+#define BP_PXP_AS_CTRL_FORMAT 4
+#define BM_PXP_AS_CTRL_FORMAT 0x000000F0
+#define BF_PXP_AS_CTRL_FORMAT(v) \
+ (((v) << 4) & BM_PXP_AS_CTRL_FORMAT)
+#define BV_PXP_AS_CTRL_FORMAT__ARGB8888 0x0
+#define BV_PXP_AS_CTRL_FORMAT__RGB888 0x4
+#define BV_PXP_AS_CTRL_FORMAT__ARGB1555 0x8
+#define BV_PXP_AS_CTRL_FORMAT__ARGB4444 0x9
+#define BV_PXP_AS_CTRL_FORMAT__RGB555 0xC
+#define BV_PXP_AS_CTRL_FORMAT__RGB444 0xD
+#define BV_PXP_AS_CTRL_FORMAT__RGB565 0xE
+#define BM_PXP_AS_CTRL_ENABLE_COLORKEY 0x00000008
+#define BP_PXP_AS_CTRL_ALPHA_CTRL 1
+#define BM_PXP_AS_CTRL_ALPHA_CTRL 0x00000006
+#define BF_PXP_AS_CTRL_ALPHA_CTRL(v) \
+ (((v) << 1) & BM_PXP_AS_CTRL_ALPHA_CTRL)
+#define BV_PXP_AS_CTRL_ALPHA_CTRL__Embedded 0x0
+#define BV_PXP_AS_CTRL_ALPHA_CTRL__Override 0x1
+#define BV_PXP_AS_CTRL_ALPHA_CTRL__Multiply 0x2
+#define BV_PXP_AS_CTRL_ALPHA_CTRL__ROPs 0x3
+#define BM_PXP_AS_CTRL_RSVD0 0x00000001
+
+#define HW_PXP_AS_BUF (0x00000160)
+
+#define BP_PXP_AS_BUF_ADDR 0
+#define BM_PXP_AS_BUF_ADDR 0xFFFFFFFF
+#define BF_PXP_AS_BUF_ADDR(v) (v)
+
+#define HW_PXP_AS_PITCH (0x00000170)
+
+#define BP_PXP_AS_PITCH_RSVD 16
+#define BM_PXP_AS_PITCH_RSVD 0xFFFF0000
+#define BF_PXP_AS_PITCH_RSVD(v) \
+ (((v) << 16) & BM_PXP_AS_PITCH_RSVD)
+#define BP_PXP_AS_PITCH_PITCH 0
+#define BM_PXP_AS_PITCH_PITCH 0x0000FFFF
+#define BF_PXP_AS_PITCH_PITCH(v) \
+ (((v) << 0) & BM_PXP_AS_PITCH_PITCH)
+
+#define HW_PXP_AS_CLRKEYLOW (0x00000180)
+
+#define BP_PXP_AS_CLRKEYLOW_RSVD1 24
+#define BM_PXP_AS_CLRKEYLOW_RSVD1 0xFF000000
+#define BF_PXP_AS_CLRKEYLOW_RSVD1(v) \
+ (((v) << 24) & BM_PXP_AS_CLRKEYLOW_RSVD1)
+#define BP_PXP_AS_CLRKEYLOW_PIXEL 0
+#define BM_PXP_AS_CLRKEYLOW_PIXEL 0x00FFFFFF
+#define BF_PXP_AS_CLRKEYLOW_PIXEL(v) \
+ (((v) << 0) & BM_PXP_AS_CLRKEYLOW_PIXEL)
+
+#define HW_PXP_AS_CLRKEYHIGH (0x00000190)
+
+#define BP_PXP_AS_CLRKEYHIGH_RSVD1 24
+#define BM_PXP_AS_CLRKEYHIGH_RSVD1 0xFF000000
+#define BF_PXP_AS_CLRKEYHIGH_RSVD1(v) \
+ (((v) << 24) & BM_PXP_AS_CLRKEYHIGH_RSVD1)
+#define BP_PXP_AS_CLRKEYHIGH_PIXEL 0
+#define BM_PXP_AS_CLRKEYHIGH_PIXEL 0x00FFFFFF
+#define BF_PXP_AS_CLRKEYHIGH_PIXEL(v) \
+ (((v) << 0) & BM_PXP_AS_CLRKEYHIGH_PIXEL)
+
+#define HW_PXP_CSC1_COEF0 (0x000001a0)
+
+#define BM_PXP_CSC1_COEF0_YCBCR_MODE 0x80000000
+#define BM_PXP_CSC1_COEF0_BYPASS 0x40000000
+#define BM_PXP_CSC1_COEF0_RSVD1 0x20000000
+#define BP_PXP_CSC1_COEF0_C0 18
+#define BM_PXP_CSC1_COEF0_C0 0x1FFC0000
+#define BF_PXP_CSC1_COEF0_C0(v) \
+ (((v) << 18) & BM_PXP_CSC1_COEF0_C0)
+#define BP_PXP_CSC1_COEF0_UV_OFFSET 9
+#define BM_PXP_CSC1_COEF0_UV_OFFSET 0x0003FE00
+#define BF_PXP_CSC1_COEF0_UV_OFFSET(v) \
+ (((v) << 9) & BM_PXP_CSC1_COEF0_UV_OFFSET)
+#define BP_PXP_CSC1_COEF0_Y_OFFSET 0
+#define BM_PXP_CSC1_COEF0_Y_OFFSET 0x000001FF
+#define BF_PXP_CSC1_COEF0_Y_OFFSET(v) \
+ (((v) << 0) & BM_PXP_CSC1_COEF0_Y_OFFSET)
+
+#define HW_PXP_CSC1_COEF1 (0x000001b0)
+
+#define BP_PXP_CSC1_COEF1_RSVD1 27
+#define BM_PXP_CSC1_COEF1_RSVD1 0xF8000000
+#define BF_PXP_CSC1_COEF1_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC1_COEF1_RSVD1)
+#define BP_PXP_CSC1_COEF1_C1 16
+#define BM_PXP_CSC1_COEF1_C1 0x07FF0000
+#define BF_PXP_CSC1_COEF1_C1(v) \
+ (((v) << 16) & BM_PXP_CSC1_COEF1_C1)
+#define BP_PXP_CSC1_COEF1_RSVD0 11
+#define BM_PXP_CSC1_COEF1_RSVD0 0x0000F800
+#define BF_PXP_CSC1_COEF1_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC1_COEF1_RSVD0)
+#define BP_PXP_CSC1_COEF1_C4 0
+#define BM_PXP_CSC1_COEF1_C4 0x000007FF
+#define BF_PXP_CSC1_COEF1_C4(v) \
+ (((v) << 0) & BM_PXP_CSC1_COEF1_C4)
+
+#define HW_PXP_CSC1_COEF2 (0x000001c0)
+
+#define BP_PXP_CSC1_COEF2_RSVD1 27
+#define BM_PXP_CSC1_COEF2_RSVD1 0xF8000000
+#define BF_PXP_CSC1_COEF2_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC1_COEF2_RSVD1)
+#define BP_PXP_CSC1_COEF2_C2 16
+#define BM_PXP_CSC1_COEF2_C2 0x07FF0000
+#define BF_PXP_CSC1_COEF2_C2(v) \
+ (((v) << 16) & BM_PXP_CSC1_COEF2_C2)
+#define BP_PXP_CSC1_COEF2_RSVD0 11
+#define BM_PXP_CSC1_COEF2_RSVD0 0x0000F800
+#define BF_PXP_CSC1_COEF2_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC1_COEF2_RSVD0)
+#define BP_PXP_CSC1_COEF2_C3 0
+#define BM_PXP_CSC1_COEF2_C3 0x000007FF
+#define BF_PXP_CSC1_COEF2_C3(v) \
+ (((v) << 0) & BM_PXP_CSC1_COEF2_C3)
+
+#define HW_PXP_CSC2_CTRL (0x000001d0)
+
+#define BP_PXP_CSC2_CTRL_RSVD 3
+#define BM_PXP_CSC2_CTRL_RSVD 0xFFFFFFF8
+#define BF_PXP_CSC2_CTRL_RSVD(v) \
+ (((v) << 3) & BM_PXP_CSC2_CTRL_RSVD)
+#define BP_PXP_CSC2_CTRL_CSC_MODE 1
+#define BM_PXP_CSC2_CTRL_CSC_MODE 0x00000006
+#define BF_PXP_CSC2_CTRL_CSC_MODE(v) \
+ (((v) << 1) & BM_PXP_CSC2_CTRL_CSC_MODE)
+#define BV_PXP_CSC2_CTRL_CSC_MODE__YUV2RGB 0x0
+#define BV_PXP_CSC2_CTRL_CSC_MODE__YCbCr2RGB 0x1
+#define BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YUV 0x2
+#define BV_PXP_CSC2_CTRL_CSC_MODE__RGB2YCbCr 0x3
+#define BM_PXP_CSC2_CTRL_BYPASS 0x00000001
+
+#define HW_PXP_CSC2_COEF0 (0x000001e0)
+
+#define BP_PXP_CSC2_COEF0_RSVD1 27
+#define BM_PXP_CSC2_COEF0_RSVD1 0xF8000000
+#define BF_PXP_CSC2_COEF0_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC2_COEF0_RSVD1)
+#define BP_PXP_CSC2_COEF0_A2 16
+#define BM_PXP_CSC2_COEF0_A2 0x07FF0000
+#define BF_PXP_CSC2_COEF0_A2(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF0_A2)
+#define BP_PXP_CSC2_COEF0_RSVD0 11
+#define BM_PXP_CSC2_COEF0_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF0_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC2_COEF0_RSVD0)
+#define BP_PXP_CSC2_COEF0_A1 0
+#define BM_PXP_CSC2_COEF0_A1 0x000007FF
+#define BF_PXP_CSC2_COEF0_A1(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF0_A1)
+
+#define HW_PXP_CSC2_COEF1 (0x000001f0)
+
+#define BP_PXP_CSC2_COEF1_RSVD1 27
+#define BM_PXP_CSC2_COEF1_RSVD1 0xF8000000
+#define BF_PXP_CSC2_COEF1_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC2_COEF1_RSVD1)
+#define BP_PXP_CSC2_COEF1_B1 16
+#define BM_PXP_CSC2_COEF1_B1 0x07FF0000
+#define BF_PXP_CSC2_COEF1_B1(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF1_B1)
+#define BP_PXP_CSC2_COEF1_RSVD0 11
+#define BM_PXP_CSC2_COEF1_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF1_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC2_COEF1_RSVD0)
+#define BP_PXP_CSC2_COEF1_A3 0
+#define BM_PXP_CSC2_COEF1_A3 0x000007FF
+#define BF_PXP_CSC2_COEF1_A3(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF1_A3)
+
+#define HW_PXP_CSC2_COEF2 (0x00000200)
+
+#define BP_PXP_CSC2_COEF2_RSVD1 27
+#define BM_PXP_CSC2_COEF2_RSVD1 0xF8000000
+#define BF_PXP_CSC2_COEF2_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC2_COEF2_RSVD1)
+#define BP_PXP_CSC2_COEF2_B3 16
+#define BM_PXP_CSC2_COEF2_B3 0x07FF0000
+#define BF_PXP_CSC2_COEF2_B3(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF2_B3)
+#define BP_PXP_CSC2_COEF2_RSVD0 11
+#define BM_PXP_CSC2_COEF2_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF2_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC2_COEF2_RSVD0)
+#define BP_PXP_CSC2_COEF2_B2 0
+#define BM_PXP_CSC2_COEF2_B2 0x000007FF
+#define BF_PXP_CSC2_COEF2_B2(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF2_B2)
+
+#define HW_PXP_CSC2_COEF3 (0x00000210)
+
+#define BP_PXP_CSC2_COEF3_RSVD1 27
+#define BM_PXP_CSC2_COEF3_RSVD1 0xF8000000
+#define BF_PXP_CSC2_COEF3_RSVD1(v) \
+ (((v) << 27) & BM_PXP_CSC2_COEF3_RSVD1)
+#define BP_PXP_CSC2_COEF3_C2 16
+#define BM_PXP_CSC2_COEF3_C2 0x07FF0000
+#define BF_PXP_CSC2_COEF3_C2(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF3_C2)
+#define BP_PXP_CSC2_COEF3_RSVD0 11
+#define BM_PXP_CSC2_COEF3_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF3_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC2_COEF3_RSVD0)
+#define BP_PXP_CSC2_COEF3_C1 0
+#define BM_PXP_CSC2_COEF3_C1 0x000007FF
+#define BF_PXP_CSC2_COEF3_C1(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF3_C1)
+
+#define HW_PXP_CSC2_COEF4 (0x00000220)
+
+#define BP_PXP_CSC2_COEF4_RSVD1 25
+#define BM_PXP_CSC2_COEF4_RSVD1 0xFE000000
+#define BF_PXP_CSC2_COEF4_RSVD1(v) \
+ (((v) << 25) & BM_PXP_CSC2_COEF4_RSVD1)
+#define BP_PXP_CSC2_COEF4_D1 16
+#define BM_PXP_CSC2_COEF4_D1 0x01FF0000
+#define BF_PXP_CSC2_COEF4_D1(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF4_D1)
+#define BP_PXP_CSC2_COEF4_RSVD0 11
+#define BM_PXP_CSC2_COEF4_RSVD0 0x0000F800
+#define BF_PXP_CSC2_COEF4_RSVD0(v) \
+ (((v) << 11) & BM_PXP_CSC2_COEF4_RSVD0)
+#define BP_PXP_CSC2_COEF4_C3 0
+#define BM_PXP_CSC2_COEF4_C3 0x000007FF
+#define BF_PXP_CSC2_COEF4_C3(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF4_C3)
+
+#define HW_PXP_CSC2_COEF5 (0x00000230)
+
+#define BP_PXP_CSC2_COEF5_RSVD1 25
+#define BM_PXP_CSC2_COEF5_RSVD1 0xFE000000
+#define BF_PXP_CSC2_COEF5_RSVD1(v) \
+ (((v) << 25) & BM_PXP_CSC2_COEF5_RSVD1)
+#define BP_PXP_CSC2_COEF5_D3 16
+#define BM_PXP_CSC2_COEF5_D3 0x01FF0000
+#define BF_PXP_CSC2_COEF5_D3(v) \
+ (((v) << 16) & BM_PXP_CSC2_COEF5_D3)
+#define BP_PXP_CSC2_COEF5_RSVD0 9
+#define BM_PXP_CSC2_COEF5_RSVD0 0x0000FE00
+#define BF_PXP_CSC2_COEF5_RSVD0(v) \
+ (((v) << 9) & BM_PXP_CSC2_COEF5_RSVD0)
+#define BP_PXP_CSC2_COEF5_D2 0
+#define BM_PXP_CSC2_COEF5_D2 0x000001FF
+#define BF_PXP_CSC2_COEF5_D2(v) \
+ (((v) << 0) & BM_PXP_CSC2_COEF5_D2)
+
+#define HW_PXP_LUT_CTRL (0x00000240)
+
+#define BM_PXP_LUT_CTRL_BYPASS 0x80000000
+#define BP_PXP_LUT_CTRL_RSVD3 26
+#define BM_PXP_LUT_CTRL_RSVD3 0x7C000000
+#define BF_PXP_LUT_CTRL_RSVD3(v) \
+ (((v) << 26) & BM_PXP_LUT_CTRL_RSVD3)
+#define BP_PXP_LUT_CTRL_LOOKUP_MODE 24
+#define BM_PXP_LUT_CTRL_LOOKUP_MODE 0x03000000
+#define BF_PXP_LUT_CTRL_LOOKUP_MODE(v) \
+ (((v) << 24) & BM_PXP_LUT_CTRL_LOOKUP_MODE)
+#define BV_PXP_LUT_CTRL_LOOKUP_MODE__CACHE_RGB565 0x0
+#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_Y8 0x1
+#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_RGB444 0x2
+#define BV_PXP_LUT_CTRL_LOOKUP_MODE__DIRECT_RGB454 0x3
+#define BP_PXP_LUT_CTRL_RSVD2 18
+#define BM_PXP_LUT_CTRL_RSVD2 0x00FC0000
+#define BF_PXP_LUT_CTRL_RSVD2(v) \
+ (((v) << 18) & BM_PXP_LUT_CTRL_RSVD2)
+#define BP_PXP_LUT_CTRL_OUT_MODE 16
+#define BM_PXP_LUT_CTRL_OUT_MODE 0x00030000
+#define BF_PXP_LUT_CTRL_OUT_MODE(v) \
+ (((v) << 16) & BM_PXP_LUT_CTRL_OUT_MODE)
+#define BV_PXP_LUT_CTRL_OUT_MODE__RESERVED 0x0
+#define BV_PXP_LUT_CTRL_OUT_MODE__Y8 0x1
+#define BV_PXP_LUT_CTRL_OUT_MODE__RGBW4444CFA 0x2
+#define BV_PXP_LUT_CTRL_OUT_MODE__RGB888 0x3
+#define BP_PXP_LUT_CTRL_RSVD1 11
+#define BM_PXP_LUT_CTRL_RSVD1 0x0000F800
+#define BF_PXP_LUT_CTRL_RSVD1(v) \
+ (((v) << 11) & BM_PXP_LUT_CTRL_RSVD1)
+#define BM_PXP_LUT_CTRL_SEL_8KB 0x00000400
+#define BM_PXP_LUT_CTRL_LRU_UPD 0x00000200
+#define BM_PXP_LUT_CTRL_INVALID 0x00000100
+#define BP_PXP_LUT_CTRL_RSVD0 1
+#define BM_PXP_LUT_CTRL_RSVD0 0x000000FE
+#define BF_PXP_LUT_CTRL_RSVD0(v) \
+ (((v) << 1) & BM_PXP_LUT_CTRL_RSVD0)
+#define BM_PXP_LUT_CTRL_DMA_START 0x00000001
+
+#define HW_PXP_LUT_ADDR (0x00000250)
+
+#define BM_PXP_LUT_ADDR_RSVD2 0x80000000
+#define BP_PXP_LUT_ADDR_NUM_BYTES 16
+#define BM_PXP_LUT_ADDR_NUM_BYTES 0x7FFF0000
+#define BF_PXP_LUT_ADDR_NUM_BYTES(v) \
+ (((v) << 16) & BM_PXP_LUT_ADDR_NUM_BYTES)
+#define BP_PXP_LUT_ADDR_RSVD1 14
+#define BM_PXP_LUT_ADDR_RSVD1 0x0000C000
+#define BF_PXP_LUT_ADDR_RSVD1(v) \
+ (((v) << 14) & BM_PXP_LUT_ADDR_RSVD1)
+#define BP_PXP_LUT_ADDR_ADDR 0
+#define BM_PXP_LUT_ADDR_ADDR 0x00003FFF
+#define BF_PXP_LUT_ADDR_ADDR(v) \
+ (((v) << 0) & BM_PXP_LUT_ADDR_ADDR)
+
+#define HW_PXP_LUT_DATA (0x00000260)
+
+#define BP_PXP_LUT_DATA_DATA 0
+#define BM_PXP_LUT_DATA_DATA 0xFFFFFFFF
+#define BF_PXP_LUT_DATA_DATA(v) (v)
+
+#define HW_PXP_LUT_EXTMEM (0x00000270)
+
+#define BP_PXP_LUT_EXTMEM_ADDR 0
+#define BM_PXP_LUT_EXTMEM_ADDR 0xFFFFFFFF
+#define BF_PXP_LUT_EXTMEM_ADDR(v) (v)
+
+#define HW_PXP_CFA (0x00000280)
+
+#define BP_PXP_CFA_DATA 0
+#define BM_PXP_CFA_DATA 0xFFFFFFFF
+#define BF_PXP_CFA_DATA(v) (v)
+
+#define HW_PXP_HIST_CTRL (0x00000290)
+
+#define BP_PXP_HIST_CTRL_RSVD 6
+#define BM_PXP_HIST_CTRL_RSVD 0xFFFFFFC0
+#define BF_PXP_HIST_CTRL_RSVD(v) \
+ (((v) << 6) & BM_PXP_HIST_CTRL_RSVD)
+#define BP_PXP_HIST_CTRL_PANEL_MODE 4
+#define BM_PXP_HIST_CTRL_PANEL_MODE 0x00000030
+#define BF_PXP_HIST_CTRL_PANEL_MODE(v) \
+ (((v) << 4) & BM_PXP_HIST_CTRL_PANEL_MODE)
+#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY4 0x0
+#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY8 0x1
+#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY16 0x2
+#define BV_PXP_HIST_CTRL_PANEL_MODE__GRAY32 0x3
+#define BP_PXP_HIST_CTRL_STATUS 0
+#define BM_PXP_HIST_CTRL_STATUS 0x0000000F
+#define BF_PXP_HIST_CTRL_STATUS(v) \
+ (((v) << 0) & BM_PXP_HIST_CTRL_STATUS)
+
+#define HW_PXP_HIST2_PARAM (0x000002a0)
+
+#define BP_PXP_HIST2_PARAM_RSVD 16
+#define BM_PXP_HIST2_PARAM_RSVD 0xFFFF0000
+#define BF_PXP_HIST2_PARAM_RSVD(v) \
+ (((v) << 16) & BM_PXP_HIST2_PARAM_RSVD)
+#define BP_PXP_HIST2_PARAM_RSVD1 13
+#define BM_PXP_HIST2_PARAM_RSVD1 0x0000E000
+#define BF_PXP_HIST2_PARAM_RSVD1(v) \
+ (((v) << 13) & BM_PXP_HIST2_PARAM_RSVD1)
+#define BP_PXP_HIST2_PARAM_VALUE1 8
+#define BM_PXP_HIST2_PARAM_VALUE1 0x00001F00
+#define BF_PXP_HIST2_PARAM_VALUE1(v) \
+ (((v) << 8) & BM_PXP_HIST2_PARAM_VALUE1)
+#define BP_PXP_HIST2_PARAM_RSVD0 5
+#define BM_PXP_HIST2_PARAM_RSVD0 0x000000E0
+#define BF_PXP_HIST2_PARAM_RSVD0(v) \
+ (((v) << 5) & BM_PXP_HIST2_PARAM_RSVD0)
+#define BP_PXP_HIST2_PARAM_VALUE0 0
+#define BM_PXP_HIST2_PARAM_VALUE0 0x0000001F
+#define BF_PXP_HIST2_PARAM_VALUE0(v) \
+ (((v) << 0) & BM_PXP_HIST2_PARAM_VALUE0)
+
+#define HW_PXP_HIST4_PARAM (0x000002b0)
+
+#define BP_PXP_HIST4_PARAM_RSVD3 29
+#define BM_PXP_HIST4_PARAM_RSVD3 0xE0000000
+#define BF_PXP_HIST4_PARAM_RSVD3(v) \
+ (((v) << 29) & BM_PXP_HIST4_PARAM_RSVD3)
+#define BP_PXP_HIST4_PARAM_VALUE3 24
+#define BM_PXP_HIST4_PARAM_VALUE3 0x1F000000
+#define BF_PXP_HIST4_PARAM_VALUE3(v) \
+ (((v) << 24) & BM_PXP_HIST4_PARAM_VALUE3)
+#define BP_PXP_HIST4_PARAM_RSVD2 21
+#define BM_PXP_HIST4_PARAM_RSVD2 0x00E00000
+#define BF_PXP_HIST4_PARAM_RSVD2(v) \
+ (((v) << 21) & BM_PXP_HIST4_PARAM_RSVD2)
+#define BP_PXP_HIST4_PARAM_VALUE2 16
+#define BM_PXP_HIST4_PARAM_VALUE2 0x001F0000
+#define BF_PXP_HIST4_PARAM_VALUE2(v) \
+ (((v) << 16) & BM_PXP_HIST4_PARAM_VALUE2)
+#define BP_PXP_HIST4_PARAM_RSVD1 13
+#define BM_PXP_HIST4_PARAM_RSVD1 0x0000E000
+#define BF_PXP_HIST4_PARAM_RSVD1(v) \
+ (((v) << 13) & BM_PXP_HIST4_PARAM_RSVD1)
+#define BP_PXP_HIST4_PARAM_VALUE1 8
+#define BM_PXP_HIST4_PARAM_VALUE1 0x00001F00
+#define BF_PXP_HIST4_PARAM_VALUE1(v) \
+ (((v) << 8) & BM_PXP_HIST4_PARAM_VALUE1)
+#define BP_PXP_HIST4_PARAM_RSVD0 5
+#define BM_PXP_HIST4_PARAM_RSVD0 0x000000E0
+#define BF_PXP_HIST4_PARAM_RSVD0(v) \
+ (((v) << 5) & BM_PXP_HIST4_PARAM_RSVD0)
+#define BP_PXP_HIST4_PARAM_VALUE0 0
+#define BM_PXP_HIST4_PARAM_VALUE0 0x0000001F
+#define BF_PXP_HIST4_PARAM_VALUE0(v) \
+ (((v) << 0) & BM_PXP_HIST4_PARAM_VALUE0)
+
+#define HW_PXP_HIST8_PARAM0 (0x000002c0)
+
+#define BP_PXP_HIST8_PARAM0_RSVD3 29
+#define BM_PXP_HIST8_PARAM0_RSVD3 0xE0000000
+#define BF_PXP_HIST8_PARAM0_RSVD3(v) \
+ (((v) << 29) & BM_PXP_HIST8_PARAM0_RSVD3)
+#define BP_PXP_HIST8_PARAM0_VALUE3 24
+#define BM_PXP_HIST8_PARAM0_VALUE3 0x1F000000
+#define BF_PXP_HIST8_PARAM0_VALUE3(v) \
+ (((v) << 24) & BM_PXP_HIST8_PARAM0_VALUE3)
+#define BP_PXP_HIST8_PARAM0_RSVD2 21
+#define BM_PXP_HIST8_PARAM0_RSVD2 0x00E00000
+#define BF_PXP_HIST8_PARAM0_RSVD2(v) \
+ (((v) << 21) & BM_PXP_HIST8_PARAM0_RSVD2)
+#define BP_PXP_HIST8_PARAM0_VALUE2 16
+#define BM_PXP_HIST8_PARAM0_VALUE2 0x001F0000
+#define BF_PXP_HIST8_PARAM0_VALUE2(v) \
+ (((v) << 16) & BM_PXP_HIST8_PARAM0_VALUE2)
+#define BP_PXP_HIST8_PARAM0_RSVD1 13
+#define BM_PXP_HIST8_PARAM0_RSVD1 0x0000E000
+#define BF_PXP_HIST8_PARAM0_RSVD1(v) \
+ (((v) << 13) & BM_PXP_HIST8_PARAM0_RSVD1)
+#define BP_PXP_HIST8_PARAM0_VALUE1 8
+#define BM_PXP_HIST8_PARAM0_VALUE1 0x00001F00
+#define BF_PXP_HIST8_PARAM0_VALUE1(v) \
+ (((v) << 8) & BM_PXP_HIST8_PARAM0_VALUE1)
+#define BP_PXP_HIST8_PARAM0_RSVD0 5
+#define BM_PXP_HIST8_PARAM0_RSVD0 0x000000E0
+#define BF_PXP_HIST8_PARAM0_RSVD0(v) \
+ (((v) << 5) & BM_PXP_HIST8_PARAM0_RSVD0)
+#define BP_PXP_HIST8_PARAM0_VALUE0 0
+#define BM_PXP_HIST8_PARAM0_VALUE0 0x0000001F
+#define BF_PXP_HIST8_PARAM0_VALUE0(v) \
+ (((v) << 0) & BM_PXP_HIST8_PARAM0_VALUE0)
+
+#define HW_PXP_HIST8_PARAM1 (0x000002d0)
+
+#define BP_PXP_HIST8_PARAM1_RSVD7 29
+#define BM_PXP_HIST8_PARAM1_RSVD7 0xE0000000
+#define BF_PXP_HIST8_PARAM1_RSVD7(v) \
+ (((v) << 29) & BM_PXP_HIST8_PARAM1_RSVD7)
+#define BP_PXP_HIST8_PARAM1_VALUE7 24
+#define BM_PXP_HIST8_PARAM1_VALUE7 0x1F000000
+#define BF_PXP_HIST8_PARAM1_VALUE7(v) \
+ (((v) << 24) & BM_PXP_HIST8_PARAM1_VALUE7)
+#define BP_PXP_HIST8_PARAM1_RSVD6 21
+#define BM_PXP_HIST8_PARAM1_RSVD6 0x00E00000
+#define BF_PXP_HIST8_PARAM1_RSVD6(v) \
+ (((v) << 21) & BM_PXP_HIST8_PARAM1_RSVD6)
+#define BP_PXP_HIST8_PARAM1_VALUE6 16
+#define BM_PXP_HIST8_PARAM1_VALUE6 0x001F0000
+#define BF_PXP_HIST8_PARAM1_VALUE6(v) \
+ (((v) << 16) & BM_PXP_HIST8_PARAM1_VALUE6)
+#define BP_PXP_HIST8_PARAM1_RSVD5 13
+#define BM_PXP_HIST8_PARAM1_RSVD5 0x0000E000
+#define BF_PXP_HIST8_PARAM1_RSVD5(v) \
+ (((v) << 13) & BM_PXP_HIST8_PARAM1_RSVD5)
+#define BP_PXP_HIST8_PARAM1_VALUE5 8
+#define BM_PXP_HIST8_PARAM1_VALUE5 0x00001F00
+#define BF_PXP_HIST8_PARAM1_VALUE5(v) \
+ (((v) << 8) & BM_PXP_HIST8_PARAM1_VALUE5)
+#define BP_PXP_HIST8_PARAM1_RSVD4 5
+#define BM_PXP_HIST8_PARAM1_RSVD4 0x000000E0
+#define BF_PXP_HIST8_PARAM1_RSVD4(v) \
+ (((v) << 5) & BM_PXP_HIST8_PARAM1_RSVD4)
+#define BP_PXP_HIST8_PARAM1_VALUE4 0
+#define BM_PXP_HIST8_PARAM1_VALUE4 0x0000001F
+#define BF_PXP_HIST8_PARAM1_VALUE4(v) \
+ (((v) << 0) & BM_PXP_HIST8_PARAM1_VALUE4)
+
+#define HW_PXP_HIST16_PARAM0 (0x000002e0)
+
+#define BP_PXP_HIST16_PARAM0_RSVD3 29
+#define BM_PXP_HIST16_PARAM0_RSVD3 0xE0000000
+#define BF_PXP_HIST16_PARAM0_RSVD3(v) \
+ (((v) << 29) & BM_PXP_HIST16_PARAM0_RSVD3)
+#define BP_PXP_HIST16_PARAM0_VALUE3 24
+#define BM_PXP_HIST16_PARAM0_VALUE3 0x1F000000
+#define BF_PXP_HIST16_PARAM0_VALUE3(v) \
+ (((v) << 24) & BM_PXP_HIST16_PARAM0_VALUE3)
+#define BP_PXP_HIST16_PARAM0_RSVD2 21
+#define BM_PXP_HIST16_PARAM0_RSVD2 0x00E00000
+#define BF_PXP_HIST16_PARAM0_RSVD2(v) \
+ (((v) << 21) & BM_PXP_HIST16_PARAM0_RSVD2)
+#define BP_PXP_HIST16_PARAM0_VALUE2 16
+#define BM_PXP_HIST16_PARAM0_VALUE2 0x001F0000
+#define BF_PXP_HIST16_PARAM0_VALUE2(v) \
+ (((v) << 16) & BM_PXP_HIST16_PARAM0_VALUE2)
+#define BP_PXP_HIST16_PARAM0_RSVD1 13
+#define BM_PXP_HIST16_PARAM0_RSVD1 0x0000E000
+#define BF_PXP_HIST16_PARAM0_RSVD1(v) \
+ (((v) << 13) & BM_PXP_HIST16_PARAM0_RSVD1)
+#define BP_PXP_HIST16_PARAM0_VALUE1 8
+#define BM_PXP_HIST16_PARAM0_VALUE1 0x00001F00
+#define BF_PXP_HIST16_PARAM0_VALUE1(v) \
+ (((v) << 8) & BM_PXP_HIST16_PARAM0_VALUE1)
+#define BP_PXP_HIST16_PARAM0_RSVD0 5
+#define BM_PXP_HIST16_PARAM0_RSVD0 0x000000E0
+#define BF_PXP_HIST16_PARAM0_RSVD0(v) \
+ (((v) << 5) & BM_PXP_HIST16_PARAM0_RSVD0)
+#define BP_PXP_HIST16_PARAM0_VALUE0 0
+#define BM_PXP_HIST16_PARAM0_VALUE0 0x0000001F
+#define BF_PXP_HIST16_PARAM0_VALUE0(v) \
+ (((v) << 0) & BM_PXP_HIST16_PARAM0_VALUE0)
+
+#define HW_PXP_HIST16_PARAM1 (0x000002f0)
+
+#define BP_PXP_HIST16_PARAM1_RSVD7 29
+#define BM_PXP_HIST16_PARAM1_RSVD7 0xE0000000
+#define BF_PXP_HIST16_PARAM1_RSVD7(v) \
+ (((v) << 29) & BM_PXP_HIST16_PARAM1_RSVD7)
+#define BP_PXP_HIST16_PARAM1_VALUE7 24
+#define BM_PXP_HIST16_PARAM1_VALUE7 0x1F000000
+#define BF_PXP_HIST16_PARAM1_VALUE7(v) \
+ (((v) << 24) & BM_PXP_HIST16_PARAM1_VALUE7)
+#define BP_PXP_HIST16_PARAM1_RSVD6 21
+#define BM_PXP_HIST16_PARAM1_RSVD6 0x00E00000
+#define BF_PXP_HIST16_PARAM1_RSVD6(v) \
+ (((v) << 21) & BM_PXP_HIST16_PARAM1_RSVD6)
+#define BP_PXP_HIST16_PARAM1_VALUE6 16
+#define BM_PXP_HIST16_PARAM1_VALUE6 0x001F0000
+#define BF_PXP_HIST16_PARAM1_VALUE6(v) \
+ (((v) << 16) & BM_PXP_HIST16_PARAM1_VALUE6)
+#define BP_PXP_HIST16_PARAM1_RSVD5 13
+#define BM_PXP_HIST16_PARAM1_RSVD5 0x0000E000
+#define BF_PXP_HIST16_PARAM1_RSVD5(v) \
+ (((v) << 13) & BM_PXP_HIST16_PARAM1_RSVD5)
+#define BP_PXP_HIST16_PARAM1_VALUE5 8
+#define BM_PXP_HIST16_PARAM1_VALUE5 0x00001F00
+#define BF_PXP_HIST16_PARAM1_VALUE5(v) \
+ (((v) << 8) & BM_PXP_HIST16_PARAM1_VALUE5)
+#define BP_PXP_HIST16_PARAM1_RSVD4 5
+#define BM_PXP_HIST16_PARAM1_RSVD4 0x000000E0
+#define BF_PXP_HIST16_PARAM1_RSVD4(v) \
+ (((v) << 5) & BM_PXP_HIST16_PARAM1_RSVD4)
+#define BP_PXP_HIST16_PARAM1_VALUE4 0
+#define BM_PXP_HIST16_PARAM1_VALUE4 0x0000001F
+#define BF_PXP_HIST16_PARAM1_VALUE4(v) \
+ (((v) << 0) & BM_PXP_HIST16_PARAM1_VALUE4)
+
+#define HW_PXP_HIST16_PARAM2 (0x00000300)
+
+#define BP_PXP_HIST16_PARAM2_RSVD11 29
+#define BM_PXP_HIST16_PARAM2_RSVD11 0xE0000000
+#define BF_PXP_HIST16_PARAM2_RSVD11(v) \
+ (((v) << 29) & BM_PXP_HIST16_PARAM2_RSVD11)
+#define BP_PXP_HIST16_PARAM2_VALUE11 24
+#define BM_PXP_HIST16_PARAM2_VALUE11 0x1F000000
+#define BF_PXP_HIST16_PARAM2_VALUE11(v) \
+ (((v) << 24) & BM_PXP_HIST16_PARAM2_VALUE11)
+#define BP_PXP_HIST16_PARAM2_RSVD10 21
+#define BM_PXP_HIST16_PARAM2_RSVD10 0x00E00000
+#define BF_PXP_HIST16_PARAM2_RSVD10(v) \
+ (((v) << 21) & BM_PXP_HIST16_PARAM2_RSVD10)
+#define BP_PXP_HIST16_PARAM2_VALUE10 16
+#define BM_PXP_HIST16_PARAM2_VALUE10 0x001F0000
+#define BF_PXP_HIST16_PARAM2_VALUE10(v) \
+ (((v) << 16) & BM_PXP_HIST16_PARAM2_VALUE10)
+#define BP_PXP_HIST16_PARAM2_RSVD9 13
+#define BM_PXP_HIST16_PARAM2_RSVD9 0x0000E000
+#define BF_PXP_HIST16_PARAM2_RSVD9(v) \
+ (((v) << 13) & BM_PXP_HIST16_PARAM2_RSVD9)
+#define BP_PXP_HIST16_PARAM2_VALUE9 8
+#define BM_PXP_HIST16_PARAM2_VALUE9 0x00001F00
+#define BF_PXP_HIST16_PARAM2_VALUE9(v) \
+ (((v) << 8) & BM_PXP_HIST16_PARAM2_VALUE9)
+#define BP_PXP_HIST16_PARAM2_RSVD8 5
+#define BM_PXP_HIST16_PARAM2_RSVD8 0x000000E0
+#define BF_PXP_HIST16_PARAM2_RSVD8(v) \
+ (((v) << 5) & BM_PXP_HIST16_PARAM2_RSVD8)
+#define BP_PXP_HIST16_PARAM2_VALUE8 0
+#define BM_PXP_HIST16_PARAM2_VALUE8 0x0000001F
+#define BF_PXP_HIST16_PARAM2_VALUE8(v) \
+ (((v) << 0) & BM_PXP_HIST16_PARAM2_VALUE8)
+
+#define HW_PXP_HIST16_PARAM3 (0x00000310)
+
+#define BP_PXP_HIST16_PARAM3_RSVD15 29
+#define BM_PXP_HIST16_PARAM3_RSVD15 0xE0000000
+#define BF_PXP_HIST16_PARAM3_RSVD15(v) \
+ (((v) << 29) & BM_PXP_HIST16_PARAM3_RSVD15)
+#define BP_PXP_HIST16_PARAM3_VALUE15 24
+#define BM_PXP_HIST16_PARAM3_VALUE15 0x1F000000
+#define BF_PXP_HIST16_PARAM3_VALUE15(v) \
+ (((v) << 24) & BM_PXP_HIST16_PARAM3_VALUE15)
+#define BP_PXP_HIST16_PARAM3_RSVD14 21
+#define BM_PXP_HIST16_PARAM3_RSVD14 0x00E00000
+#define BF_PXP_HIST16_PARAM3_RSVD14(v) \
+ (((v) << 21) & BM_PXP_HIST16_PARAM3_RSVD14)
+#define BP_PXP_HIST16_PARAM3_VALUE14 16
+#define BM_PXP_HIST16_PARAM3_VALUE14 0x001F0000
+#define BF_PXP_HIST16_PARAM3_VALUE14(v) \
+ (((v) << 16) & BM_PXP_HIST16_PARAM3_VALUE14)
+#define BP_PXP_HIST16_PARAM3_RSVD13 13
+#define BM_PXP_HIST16_PARAM3_RSVD13 0x0000E000
+#define BF_PXP_HIST16_PARAM3_RSVD13(v) \
+ (((v) << 13) & BM_PXP_HIST16_PARAM3_RSVD13)
+#define BP_PXP_HIST16_PARAM3_VALUE13 8
+#define BM_PXP_HIST16_PARAM3_VALUE13 0x00001F00
+#define BF_PXP_HIST16_PARAM3_VALUE13(v) \
+ (((v) << 8) & BM_PXP_HIST16_PARAM3_VALUE13)
+#define BP_PXP_HIST16_PARAM3_RSVD12 5
+#define BM_PXP_HIST16_PARAM3_RSVD12 0x000000E0
+#define BF_PXP_HIST16_PARAM3_RSVD12(v) \
+ (((v) << 5) & BM_PXP_HIST16_PARAM3_RSVD12)
+#define BP_PXP_HIST16_PARAM3_VALUE12 0
+#define BM_PXP_HIST16_PARAM3_VALUE12 0x0000001F
+#define BF_PXP_HIST16_PARAM3_VALUE12(v) \
+ (((v) << 0) & BM_PXP_HIST16_PARAM3_VALUE12)
+
+#define HW_PXP_POWER (0x00000320)
+
+#define BP_PXP_POWER_CTRL 12
+#define BM_PXP_POWER_CTRL 0xFFFFF000
+#define BF_PXP_POWER_CTRL(v) \
+ (((v) << 12) & BM_PXP_POWER_CTRL)
+#define BP_PXP_POWER_ROT_MEM_LP_STATE 9
+#define BM_PXP_POWER_ROT_MEM_LP_STATE 0x00000E00
+#define BF_PXP_POWER_ROT_MEM_LP_STATE(v) \
+ (((v) << 9) & BM_PXP_POWER_ROT_MEM_LP_STATE)
+#define BV_PXP_POWER_ROT_MEM_LP_STATE__NONE 0x0
+#define BV_PXP_POWER_ROT_MEM_LP_STATE__LS 0x1
+#define BV_PXP_POWER_ROT_MEM_LP_STATE__DS 0x2
+#define BV_PXP_POWER_ROT_MEM_LP_STATE__SD 0x4
+#define BP_PXP_POWER_LUT_LP_STATE_WAY1_BANKN 6
+#define BM_PXP_POWER_LUT_LP_STATE_WAY1_BANKN 0x000001C0
+#define BF_PXP_POWER_LUT_LP_STATE_WAY1_BANKN(v) \
+ (((v) << 6) & BM_PXP_POWER_LUT_LP_STATE_WAY1_BANKN)
+#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__NONE 0x0
+#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__LS 0x1
+#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__DS 0x2
+#define BV_PXP_POWER_LUT_LP_STATE_WAY1_BANKN__SD 0x4
+#define BP_PXP_POWER_LUT_LP_STATE_WAY0_BANKN 3
+#define BM_PXP_POWER_LUT_LP_STATE_WAY0_BANKN 0x00000038
+#define BF_PXP_POWER_LUT_LP_STATE_WAY0_BANKN(v) \
+ (((v) << 3) & BM_PXP_POWER_LUT_LP_STATE_WAY0_BANKN)
+#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__NONE 0x0
+#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__LS 0x1
+#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__DS 0x2
+#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANKN__SD 0x4
+#define BP_PXP_POWER_LUT_LP_STATE_WAY0_BANK0 0
+#define BM_PXP_POWER_LUT_LP_STATE_WAY0_BANK0 0x00000007
+#define BF_PXP_POWER_LUT_LP_STATE_WAY0_BANK0(v) \
+ (((v) << 0) & BM_PXP_POWER_LUT_LP_STATE_WAY0_BANK0)
+#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__NONE 0x0
+#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__LS 0x1
+#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__DS 0x2
+#define BV_PXP_POWER_LUT_LP_STATE_WAY0_BANK0__SD 0x4
+
+#define HW_PXP_NEXT (0x00000400)
+
+#define BP_PXP_NEXT_POINTER 2
+#define BM_PXP_NEXT_POINTER 0xFFFFFFFC
+#define BF_PXP_NEXT_POINTER(v) \
+ (((v) << 2) & BM_PXP_NEXT_POINTER)
+#define BM_PXP_NEXT_RSVD 0x00000002
+#define BM_PXP_NEXT_ENABLED 0x00000001
+
+#define HW_PXP_DEBUGCTRL (0x00000410)
+
+#define BP_PXP_DEBUGCTRL_RSVD 12
+#define BM_PXP_DEBUGCTRL_RSVD 0xFFFFF000
+#define BF_PXP_DEBUGCTRL_RSVD(v) \
+ (((v) << 12) & BM_PXP_DEBUGCTRL_RSVD)
+#define BP_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT 8
+#define BM_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT 0x00000F00
+#define BF_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT(v) \
+ (((v) << 8) & BM_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT)
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__NONE 0x0
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__MISS_CNT 0x1
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__HIT_CNT 0x2
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__LAT_CNT 0x4
+#define BV_PXP_DEBUGCTRL_LUT_CLR_STAT_CNT__MAX_LAT 0x8
+#define BP_PXP_DEBUGCTRL_SELECT 0
+#define BM_PXP_DEBUGCTRL_SELECT 0x000000FF
+#define BF_PXP_DEBUGCTRL_SELECT(v) \
+ (((v) << 0) & BM_PXP_DEBUGCTRL_SELECT)
+#define BV_PXP_DEBUGCTRL_SELECT__NONE 0x0
+#define BV_PXP_DEBUGCTRL_SELECT__CTRL 0x1
+#define BV_PXP_DEBUGCTRL_SELECT__PSBUF 0x2
+#define BV_PXP_DEBUGCTRL_SELECT__PSBAX 0x3
+#define BV_PXP_DEBUGCTRL_SELECT__PSBAY 0x4
+#define BV_PXP_DEBUGCTRL_SELECT__ASBUF 0x5
+#define BV_PXP_DEBUGCTRL_SELECT__ROTATION 0x6
+#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF0 0x7
+#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF1 0x8
+#define BV_PXP_DEBUGCTRL_SELECT__OUTBUF2 0x9
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_STAT 0x10
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_MISS 0x11
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_HIT 0x12
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_LAT 0x13
+#define BV_PXP_DEBUGCTRL_SELECT__LUT_MAX_LAT 0x14
+
+#define HW_PXP_DEBUG (0x00000420)
+
+#define BP_PXP_DEBUG_DATA 0
+#define BM_PXP_DEBUG_DATA 0xFFFFFFFF
+#define BF_PXP_DEBUG_DATA(v) (v)
+
+#define HW_PXP_VERSION (0x00000430)
+
+#define BP_PXP_VERSION_MAJOR 24
+#define BM_PXP_VERSION_MAJOR 0xFF000000
+#define BF_PXP_VERSION_MAJOR(v) \
+ (((v) << 24) & BM_PXP_VERSION_MAJOR)
+#define BP_PXP_VERSION_MINOR 16
+#define BM_PXP_VERSION_MINOR 0x00FF0000
+#define BF_PXP_VERSION_MINOR(v) \
+ (((v) << 16) & BM_PXP_VERSION_MINOR)
+#define BP_PXP_VERSION_STEP 0
+#define BM_PXP_VERSION_STEP 0x0000FFFF
+#define BF_PXP_VERSION_STEP(v) \
+ (((v) << 0) & BM_PXP_VERSION_STEP)
+#endif /* __ARCH_ARM___PXP_H */
diff --git a/drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c b/drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c
index 121b328ad18b..0e0792b65a01 100644
--- a/drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c
+++ b/drivers/media/video/mxc/capture/ipu_prp_vf_sdc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -506,8 +506,6 @@ int prp_vf_sdc_select(void *private)
int prp_vf_sdc_deselect(void *private)
{
cam_data *cam;
- int err = 0;
- err = prpvf_stop(private);
if (private) {
cam = (cam_data *) private;
@@ -516,7 +514,7 @@ int prp_vf_sdc_deselect(void *private)
cam->vf_enable_csi = NULL;
cam->vf_disable_csi = NULL;
}
- return err;
+ return 0;
}
/*!
diff --git a/drivers/media/video/mxc/capture/ipu_prp_vf_sdc_bg.c b/drivers/media/video/mxc/capture/ipu_prp_vf_sdc_bg.c
index 99fa4eaecfac..e6bf7910faef 100644
--- a/drivers/media/video/mxc/capture/ipu_prp_vf_sdc_bg.c
+++ b/drivers/media/video/mxc/capture/ipu_prp_vf_sdc_bg.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -472,8 +472,6 @@ int prp_vf_sdc_select_bg(void *private)
int prp_vf_sdc_deselect_bg(void *private)
{
cam_data *cam = (cam_data *) private;
- int err = 0;
- err = prpvf_stop(private);
if (cam) {
cam->vf_start_sdc = NULL;
@@ -481,7 +479,7 @@ int prp_vf_sdc_deselect_bg(void *private)
cam->vf_enable_csi = NULL;
cam->vf_disable_csi = NULL;
}
- return err;
+ return 0;
}
/*!
diff --git a/drivers/media/video/mxc/capture/mxc_v4l2_capture.c b/drivers/media/video/mxc/capture/mxc_v4l2_capture.c
index 12c4a9f53927..75d35b116fe2 100644
--- a/drivers/media/video/mxc/capture/mxc_v4l2_capture.c
+++ b/drivers/media/video/mxc/capture/mxc_v4l2_capture.c
@@ -40,6 +40,8 @@
#include "ipu_prp_sw.h"
#define init_MUTEX(sem) sema_init(sem, 1)
+#define MXC_SENSOR_NUM 2
+static int sensor_index;
static int video_nr = -1, local_buf_num;
static cam_data *g_cam;
@@ -453,12 +455,30 @@ static int mxc_streamoff(cam_data *cam)
if (cam->capture_on == false)
return 0;
- if (cam->enc_disable)
- err = cam->enc_disable(cam);
- if (cam->enc_disable_csi) {
- err = cam->enc_disable_csi(cam);
- if (err != 0)
- return err;
+ if (strcmp(mxc_capture_inputs[cam->current_input].name,
+ "CSI MEM") == 0) {
+ if (cam->enc_disable_csi) {
+ err = cam->enc_disable_csi(cam);
+ if (err != 0)
+ return err;
+ }
+ if (cam->enc_disable) {
+ err = cam->enc_disable(cam);
+ if (err != 0)
+ return err;
+ }
+ } else if (strcmp(mxc_capture_inputs[cam->current_input].name,
+ "CSI IC MEM") == 0) {
+ if (cam->enc_disable) {
+ err = cam->enc_disable(cam);
+ if (err != 0)
+ return err;
+ }
+ if (cam->enc_disable_csi) {
+ err = cam->enc_disable_csi(cam);
+ if (err != 0)
+ return err;
+ }
}
mxc_free_frames(cam);
@@ -618,9 +638,11 @@ static int start_preview(cam_data *cam)
if (err != 0)
return err;
- err = cam->vf_start_sdc(cam);
- if (err != 0)
- return err;
+ if (cam->vf_start_sdc) {
+ err = cam->vf_start_sdc(cam);
+ if (err != 0)
+ return err;
+ }
if (cam->vf_enable_csi)
err = cam->vf_enable_csi(cam);
@@ -652,12 +674,11 @@ static int stop_preview(cam_data *cam)
{
int err = 0;
- pr_debug("MVC: stop preview\n");
-
- if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY)
- err = prp_vf_sdc_deselect(cam);
- else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY)
- err = prp_vf_sdc_deselect_bg(cam);
+ if (cam->vf_stop_sdc) {
+ err = cam->vf_stop_sdc(cam);
+ if (err != 0)
+ return err;
+ }
if (cam->vf_disable_csi) {
err = cam->vf_disable_csi(cam);
@@ -665,6 +686,11 @@ static int stop_preview(cam_data *cam)
return err;
}
+ if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_OVERLAY)
+ err = prp_vf_sdc_deselect(cam);
+ else if (cam->v4l2_fb.flags == V4L2_FBUF_FLAG_PRIMARY)
+ err = prp_vf_sdc_deselect_bg(cam);
+
return err;
}
@@ -1009,8 +1035,9 @@ static int mxc_v4l2_g_ctrl(cam_data *cam, struct v4l2_control *c)
*/
static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
{
- int ret = 0;
+ int i, ret = 0;
int tmp_rotation = IPU_ROTATE_NONE;
+ struct sensor_data *sensor_data;
pr_debug("In MVC:mxc_v4l2_s_ctrl\n");
@@ -1179,6 +1206,25 @@ static int mxc_v4l2_s_ctrl(cam_data *cam, struct v4l2_control *c)
ipu_csi_flash_strobe(true);
#endif
break;
+ case V4L2_CID_MXC_SWITCH_CAM:
+ if (cam->sensor != cam->all_sensors[c->value]) {
+ /* power down other cameraes before enable new one */
+ for (i = 0; i < sensor_index; i++) {
+ if (i != c->value) {
+ vidioc_int_dev_exit(cam->all_sensors[i]);
+ vidioc_int_s_power(cam->all_sensors[i], 0);
+ }
+ }
+ sensor_data = cam->all_sensors[c->value]->priv;
+ if (sensor_data->io_init)
+ sensor_data->io_init();
+ cam->sensor = cam->all_sensors[c->value];
+ ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C, cam->csi, true, true);
+ vidioc_int_s_power(cam->sensor, 1);
+ vidioc_int_dev_init(cam->sensor);
+ ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C, cam->csi, false, false);
+ }
+ break;
default:
pr_debug(" default case\n");
ret = -EINVAL;
@@ -1655,7 +1701,7 @@ static int mxc_v4l_close(struct file *file)
}
/* for the case somebody hit the ctrl C */
- if (cam->overlay_pid == current->pid) {
+ if (cam->overlay_pid == current->pid && cam->overlay_on) {
err = stop_preview(cam);
cam->overlay_on = false;
}
@@ -2794,17 +2840,32 @@ static int mxc_v4l2_master_attach(struct v4l2_int_device *slave)
{
cam_data *cam = slave->u.slave->master->priv;
struct v4l2_format cam_fmt;
+ int i;
pr_debug("In MVC: mxc_v4l2_master_attach\n");
pr_debug(" slave.name = %s\n", slave->name);
pr_debug(" master.name = %s\n", slave->u.slave->master->name);
- cam->sensor = slave;
if (slave == NULL) {
pr_err("ERROR: v4l2 capture: slave parameter not valid.\n");
return -1;
}
+ cam->sensor = slave;
+
+ if (sensor_index < MXC_SENSOR_NUM) {
+ cam->all_sensors[sensor_index] = slave;
+ sensor_index++;
+ } else {
+ pr_err("ERROR: v4l2 capture: slave number exceeds the maximum.\n");
+ return -1;
+ }
+
+ for (i = 0; i < sensor_index - 1; i++) {
+ vidioc_int_dev_exit(cam->all_sensors[i]);
+ vidioc_int_s_power(cam->all_sensors[i], 0);
+ }
+
ipu_csi_enable_mclk_if(cam->ipu, CSI_MCLK_I2C, cam->csi, true, true);
vidioc_int_s_power(cam->sensor, 1);
vidioc_int_dev_init(slave);
diff --git a/drivers/media/video/mxc/capture/mxc_v4l2_capture.h b/drivers/media/video/mxc/capture/mxc_v4l2_capture.h
index 350d4bd7f59c..5b7b0bfe7706 100644
--- a/drivers/media/video/mxc/capture/mxc_v4l2_capture.h
+++ b/drivers/media/video/mxc/capture/mxc_v4l2_capture.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -194,10 +194,35 @@ typedef struct _cam_data {
/* camera sensor interface */
struct camera_sensor *cam_sensor; /* old version */
+ struct v4l2_int_device *all_sensors[2];
struct v4l2_int_device *sensor;
void *ipu;
} cam_data;
+struct sensor_data {
+ const struct ov5642_platform_data *platform_data;
+ struct v4l2_int_device *v4l2_int_device;
+ struct i2c_client *i2c_client;
+ struct v4l2_pix_format pix;
+ struct v4l2_captureparm streamcap;
+ bool on;
+
+ /* control settings */
+ int brightness;
+ int hue;
+ int contrast;
+ int saturation;
+ int red;
+ int green;
+ int blue;
+ int ae_mode;
+
+ u32 mclk;
+ int csi;
+
+ void (*io_init)(void);
+};
+
#if defined(CONFIG_MXC_IPU_V1) || defined(CONFIG_VIDEO_MXC_EMMA_CAMERA) \
|| defined(CONFIG_VIDEO_MXC_CSI_CAMERA_MODULE) \
|| defined(CONFIG_VIDEO_MXC_CSI_CAMERA)
diff --git a/drivers/media/video/mxc/capture/ov3640.c b/drivers/media/video/mxc/capture/ov3640.c
index 570f50bae161..b1d1abb884d9 100644
--- a/drivers/media/video/mxc/capture/ov3640.c
+++ b/drivers/media/video/mxc/capture/ov3640.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -72,27 +72,7 @@ struct ov3640_mode_info {
/*!
* Maintains the information on the current state of the sesor.
*/
-struct sensor {
- const struct ov3640_platform_data *platform_data;
- struct v4l2_int_device *v4l2_int_device;
- struct i2c_client *i2c_client;
- struct v4l2_pix_format pix;
- struct v4l2_captureparm streamcap;
- bool on;
-
- /* control settings */
- int brightness;
- int hue;
- int contrast;
- int saturation;
- int red;
- int green;
- int blue;
- int ae_mode;
-
- u32 mclk;
- int csi;
-} ov3640_data;
+struct sensor_data ov3640_data;
static struct reg_value ov3640_setting_15fps_QXGA_2048_1536[] = {
#if 0
@@ -1005,7 +985,7 @@ static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
*/
static int ioctl_s_power(struct v4l2_int_device *s, int on)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
if (on && !sensor->on) {
if (io_regulator)
@@ -1033,6 +1013,9 @@ static int ioctl_s_power(struct v4l2_int_device *s, int on)
regulator_disable(io_regulator);
if (gpo_regulator)
regulator_disable(gpo_regulator);
+
+ if (camera_plat->pwdn)
+ camera_plat->pwdn(1);
}
sensor->on = on;
@@ -1049,7 +1032,7 @@ static int ioctl_s_power(struct v4l2_int_device *s, int on)
*/
static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
struct v4l2_captureparm *cparm = &a->parm.capture;
int ret = 0;
@@ -1094,7 +1077,7 @@ static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
*/
static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
u32 tgt_fps; /* target frames per secound */
enum ov3640_frame_rate frame_rate;
@@ -1178,7 +1161,7 @@ static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
*/
static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
f->fmt.pix = sensor->pix;
@@ -1357,7 +1340,7 @@ static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
*/
static int ioctl_dev_init(struct v4l2_int_device *s)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
u32 tgt_xclk; /* target xclk */
u32 tgt_fps; /* target frames per secound */
enum ov3640_frame_rate frame_rate;
@@ -1460,6 +1443,7 @@ static int ov3640_probe(struct i2c_client *client,
ov3640_data.mclk = 24000000; /* 6 - 54 MHz, typical 24MHz */
ov3640_data.mclk = plat_data->mclk;
ov3640_data.csi = plat_data->csi;
+ ov3640_data.io_init = plat_data->io_init;
ov3640_data.i2c_client = client;
ov3640_data.pix.pixelformat = V4L2_PIX_FMT_UYVY;
@@ -1547,9 +1531,6 @@ static int ov3640_probe(struct i2c_client *client,
if (plat_data->io_init)
plat_data->io_init();
- if (plat_data->pwdn)
- plat_data->pwdn(0);
-
camera_plat = plat_data;
ov3640_int_device.priv = &ov3640_data;
diff --git a/drivers/media/video/mxc/capture/ov5640.c b/drivers/media/video/mxc/capture/ov5640.c
index 64ee178f2e58..f9087499b5f1 100644
--- a/drivers/media/video/mxc/capture/ov5640.c
+++ b/drivers/media/video/mxc/capture/ov5640.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -78,27 +78,7 @@ struct ov5640_mode_info {
/*!
* Maintains the information on the current state of the sesor.
*/
-struct sensor {
- const struct ov5640_platform_data *platform_data;
- struct v4l2_int_device *v4l2_int_device;
- struct i2c_client *i2c_client;
- struct v4l2_pix_format pix;
- struct v4l2_captureparm streamcap;
- bool on;
-
- /* control settings */
- int brightness;
- int hue;
- int contrast;
- int saturation;
- int red;
- int green;
- int blue;
- int ae_mode;
-
- u32 mclk;
- int csi;
-} ov5640_data;
+struct sensor_data ov5640_data;
static struct reg_value ov5640_setting_15fps_QSXGA_2592_1944[] = {
{0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 0}, {0x3008, 0x42, 0, 0},
@@ -960,7 +940,7 @@ static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
*/
static int ioctl_s_power(struct v4l2_int_device *s, int on)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
if (on && !sensor->on) {
if (io_regulator)
@@ -988,7 +968,10 @@ static int ioctl_s_power(struct v4l2_int_device *s, int on)
regulator_disable(io_regulator);
if (gpo_regulator)
regulator_disable(gpo_regulator);
- }
+
+ if (camera_plat->pwdn)
+ camera_plat->pwdn(1);
+}
sensor->on = on;
@@ -1004,7 +987,7 @@ static int ioctl_s_power(struct v4l2_int_device *s, int on)
*/
static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
struct v4l2_captureparm *cparm = &a->parm.capture;
int ret = 0;
@@ -1049,7 +1032,7 @@ static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
*/
static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
u32 tgt_fps; /* target frames per secound */
enum ov5640_frame_rate frame_rate;
@@ -1133,7 +1116,7 @@ static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
*/
static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
f->fmt.pix = sensor->pix;
@@ -1312,7 +1295,7 @@ static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
*/
static int ioctl_dev_init(struct v4l2_int_device *s)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
u32 tgt_xclk; /* target xclk */
u32 tgt_fps; /* target frames per secound */
enum ov5640_frame_rate frame_rate;
@@ -1415,6 +1398,7 @@ static int ov5640_probe(struct i2c_client *client,
ov5640_data.mclk = 24000000; /* 6 - 54 MHz, typical 24MHz */
ov5640_data.mclk = plat_data->mclk;
ov5640_data.csi = plat_data->csi;
+ ov5640_data.io_init = plat_data->io_init;
ov5640_data.i2c_client = client;
ov5640_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
@@ -1484,9 +1468,6 @@ static int ov5640_probe(struct i2c_client *client,
if (plat_data->io_init)
plat_data->io_init();
- if (plat_data->pwdn)
- plat_data->pwdn(0);
-
camera_plat = plat_data;
ov5640_int_device.priv = &ov5640_data;
diff --git a/drivers/media/video/mxc/capture/ov5640_mipi.c b/drivers/media/video/mxc/capture/ov5640_mipi.c
index 7b678f7fa0e4..bd47d9d45413 100644
--- a/drivers/media/video/mxc/capture/ov5640_mipi.c
+++ b/drivers/media/video/mxc/capture/ov5640_mipi.c
@@ -80,27 +80,7 @@ struct ov5640_mode_info {
/*!
* Maintains the information on the current state of the sesor.
*/
-struct sensor {
- const struct ov5640_platform_data *platform_data;
- struct v4l2_int_device *v4l2_int_device;
- struct i2c_client *i2c_client;
- struct v4l2_pix_format pix;
- struct v4l2_captureparm streamcap;
- bool on;
-
- /* control settings */
- int brightness;
- int hue;
- int contrast;
- int saturation;
- int red;
- int green;
- int blue;
- int ae_mode;
-
- u32 mclk;
- int csi;
-} ov5640_data;
+struct sensor_data ov5640_data;
static struct reg_value ov5640_init_setting_30fps_VGA[] = {
{0x3103, 0x11, 0, 0}, {0x3008, 0x82, 0, 5}, {0x3008, 0x42, 0, 0},
@@ -773,7 +753,7 @@ static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
*/
static int ioctl_s_power(struct v4l2_int_device *s, int on)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
if (on && !sensor->on) {
if (io_regulator)
@@ -801,6 +781,9 @@ static int ioctl_s_power(struct v4l2_int_device *s, int on)
regulator_disable(io_regulator);
if (gpo_regulator)
regulator_disable(gpo_regulator);
+
+ if (camera_plat->pwdn)
+ camera_plat->pwdn(1);
}
sensor->on = on;
@@ -817,7 +800,7 @@ static int ioctl_s_power(struct v4l2_int_device *s, int on)
*/
static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
struct v4l2_captureparm *cparm = &a->parm.capture;
int ret = 0;
@@ -862,7 +845,7 @@ static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
*/
static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
u32 tgt_fps; /* target frames per secound */
enum ov5640_frame_rate frame_rate;
@@ -946,7 +929,7 @@ static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
*/
static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
f->fmt.pix = sensor->pix;
@@ -1125,7 +1108,7 @@ static int ioctl_enum_fmt_cap(struct v4l2_int_device *s,
*/
static int ioctl_dev_init(struct v4l2_int_device *s)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
u32 tgt_xclk; /* target xclk */
u32 tgt_fps; /* target frames per secound */
int ret;
@@ -1250,6 +1233,7 @@ static int ov5640_probe(struct i2c_client *client,
ov5640_data.mclk = 24000000; /* 6 - 54 MHz, typical 24MHz */
ov5640_data.mclk = plat_data->mclk;
ov5640_data.csi = plat_data->csi;
+ ov5640_data.io_init = plat_data->io_init;
ov5640_data.i2c_client = client;
ov5640_data.pix.pixelformat = V4L2_PIX_FMT_UYVY;
@@ -1319,9 +1303,6 @@ static int ov5640_probe(struct i2c_client *client,
if (plat_data->io_init)
plat_data->io_init();
- if (plat_data->pwdn)
- plat_data->pwdn(0);
-
camera_plat = plat_data;
ov5640_int_device.priv = &ov5640_data;
diff --git a/drivers/media/video/mxc/capture/ov5642.c b/drivers/media/video/mxc/capture/ov5642.c
index 206c96b5ebc7..38f22e7a942a 100644
--- a/drivers/media/video/mxc/capture/ov5642.c
+++ b/drivers/media/video/mxc/capture/ov5642.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -79,27 +79,7 @@ struct ov5642_mode_info {
/*!
* Maintains the information on the current state of the sesor.
*/
-struct sensor {
- const struct ov5642_platform_data *platform_data;
- struct v4l2_int_device *v4l2_int_device;
- struct i2c_client *i2c_client;
- struct v4l2_pix_format pix;
- struct v4l2_captureparm streamcap;
- bool on;
-
- /* control settings */
- int brightness;
- int hue;
- int contrast;
- int saturation;
- int red;
- int green;
- int blue;
- int ae_mode;
-
- u32 mclk;
- int csi;
-} ov5642_data;
+struct sensor_data ov5642_data;
static struct reg_value ov5642_rotate_none_VGA[] = {
{0x3818, 0xc1, 0x00, 0x00}, {0x3621, 0x87, 0x00, 0x00},
@@ -2155,7 +2135,7 @@ static int ioctl_g_ifparm(struct v4l2_int_device *s, struct v4l2_ifparm *p)
*/
static int ioctl_s_power(struct v4l2_int_device *s, int on)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
if (on && !sensor->on) {
if (io_regulator)
@@ -2183,6 +2163,9 @@ static int ioctl_s_power(struct v4l2_int_device *s, int on)
regulator_disable(io_regulator);
if (gpo_regulator)
regulator_disable(gpo_regulator);
+
+ if (camera_plat->pwdn)
+ camera_plat->pwdn(1);
}
sensor->on = on;
@@ -2199,7 +2182,7 @@ static int ioctl_s_power(struct v4l2_int_device *s, int on)
*/
static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
struct v4l2_captureparm *cparm = &a->parm.capture;
int ret = 0;
@@ -2244,7 +2227,7 @@ static int ioctl_g_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
*/
static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
struct v4l2_fract *timeperframe = &a->parm.capture.timeperframe;
u32 tgt_fps; /* target frames per secound */
enum ov5642_frame_rate frame_rate;
@@ -2326,7 +2309,7 @@ static int ioctl_s_parm(struct v4l2_int_device *s, struct v4l2_streamparm *a)
*/
static int ioctl_g_fmt_cap(struct v4l2_int_device *s, struct v4l2_format *f)
{
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
f->fmt.pix = sensor->pix;
@@ -2387,7 +2370,7 @@ static int ioctl_g_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
static int ioctl_s_ctrl(struct v4l2_int_device *s, struct v4l2_control *vc)
{
int retval = 0;
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
__u32 captureMode = sensor->streamcap.capturemode;
pr_debug("In ov5642:ioctl_s_ctrl %d\n",
@@ -2561,7 +2544,7 @@ static int ioctl_dev_init(struct v4l2_int_device *s)
u8 RegVal = 0;
int retval = 0;
- struct sensor *sensor = s->priv;
+ struct sensor_data *sensor = s->priv;
u32 tgt_xclk; /* target xclk */
u32 tgt_fps; /* target frames per secound */
enum ov5642_frame_rate frame_rate;
@@ -2689,6 +2672,7 @@ static int ov5642_probe(struct i2c_client *client,
ov5642_data.mclk = 24000000; /* 6 - 54 MHz, typical 24MHz */
ov5642_data.mclk = plat_data->mclk;
ov5642_data.csi = plat_data->csi;
+ ov5642_data.io_init = plat_data->io_init;
ov5642_data.i2c_client = client;
ov5642_data.pix.pixelformat = V4L2_PIX_FMT_YUYV;
@@ -2758,9 +2742,6 @@ static int ov5642_probe(struct i2c_client *client,
if (plat_data->io_init)
plat_data->io_init();
- if (plat_data->pwdn)
- plat_data->pwdn(0);
-
camera_plat = plat_data;
ov5642_int_device.priv = &ov5642_data;
diff --git a/drivers/media/video/mxc/capture/sensor_clock.c b/drivers/media/video/mxc/capture/sensor_clock.c
index 2159836699f3..2e758d177ffc 100644
--- a/drivers/media/video/mxc/capture/sensor_clock.c
+++ b/drivers/media/video/mxc/capture/sensor_clock.c
@@ -71,7 +71,7 @@ void set_mclk_rate(uint32_t *p_mclk_freq, uint32_t csi)
pr_err("invalid csi num %d\n", csi);
return;
}
- } else if (cpu_is_mx6q()) {
+ } else if (cpu_is_mx6q() || cpu_is_mx6dl()) {
if (csi == 0) {
if (machine_is_mx6q_sabrelite())
mclk = "clko2_clk";
diff --git a/drivers/mfd/mxc-hdmi-core.c b/drivers/mfd/mxc-hdmi-core.c
index 5f86788750a1..1aa92a01c40c 100644
--- a/drivers/mfd/mxc-hdmi-core.c
+++ b/drivers/mfd/mxc-hdmi-core.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
*
* 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
@@ -36,6 +36,7 @@
#include <mach/clock.h>
#include <mach/mxc_hdmi.h>
#include <mach/ipu-v3.h>
+#include <mach/mxc_edid.h>
#include "../mxc/ipu3/ipu_prv.h"
#include <linux/mfd/mxc-hdmi-core.h>
#include <linux/fsl_devices.h>
@@ -48,18 +49,20 @@ struct mxc_hdmi_data {
};
static unsigned long hdmi_base;
-struct clk *isfr_clk;
-struct clk *iahb_clk;
+static struct clk *isfr_clk;
+static struct clk *iahb_clk;
static unsigned int irq_enable_cnt;
-spinlock_t irq_spinlock;
-bool irq_initialized;
-bool irq_enabled;
-unsigned int sample_rate;
-unsigned long pixel_clk_rate;
-struct clk *pixel_clk;
-int hdmi_ratio;
+static spinlock_t irq_spinlock;
+static spinlock_t edid_spinlock;
+static bool irq_initialized;
+static bool irq_enabled;
+static unsigned int sample_rate;
+static unsigned long pixel_clk_rate;
+static struct clk *pixel_clk;
+static int hdmi_ratio;
int mxc_hdmi_ipu_id;
int mxc_hdmi_disp_id;
+static struct mxc_edid_cfg hdmi_core_edid_cfg;
u8 hdmi_readb(unsigned int reg)
{
@@ -466,6 +469,24 @@ void hdmi_set_sample_rate(unsigned int rate)
hdmi_set_clk_regenerator();
}
+void hdmi_set_edid_cfg(struct mxc_edid_cfg *cfg)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&edid_spinlock, flags);
+ memcpy(&hdmi_core_edid_cfg, cfg, sizeof(struct mxc_edid_cfg));
+ spin_unlock_irqrestore(&edid_spinlock, flags);
+}
+
+void hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&edid_spinlock, flags);
+ memcpy(cfg, &hdmi_core_edid_cfg, sizeof(struct mxc_edid_cfg));
+ spin_unlock_irqrestore(&edid_spinlock, flags);
+}
+
static int mxc_hdmi_core_probe(struct platform_device *pdev)
{
struct fsl_mxc_hdmi_core_platform_data *pdata = pdev->dev.platform_data;
@@ -497,6 +518,7 @@ static int mxc_hdmi_core_probe(struct platform_device *pdev)
irq_initialized = false;
irq_enabled = true;
spin_lock_init(&irq_spinlock);
+ spin_lock_init(&edid_spinlock);
isfr_clk = clk_get(&hdmi_data->pdev->dev, "hdmi_isfr_clk");
if (IS_ERR(isfr_clk)) {
diff --git a/drivers/misc/mxs-perfmon.c b/drivers/misc/mxs-perfmon.c
index 5986e1ca9508..c2ac287a3cb7 100644
--- a/drivers/misc/mxs-perfmon.c
+++ b/drivers/misc/mxs-perfmon.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -171,7 +171,7 @@ perfmon_show(struct device *dev, struct device_attribute *attr, char *buf)
if (pdata->plt_init)
pdata->plt_init();
- mxs_reset_block((void *)pd->base, true);
+ mxs_reset_block((void *)pd->base);
pd->initial = true;
}
@@ -234,7 +234,7 @@ perfmon_store(struct device *dev, struct device_attribute *attr,
if (pdata->plt_init)
pdata->plt_init();
- mxs_reset_block((void *)pd->base, true);
+ mxs_reset_block((void *)pd->base);
pd->initial = true;
}
diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c
index 625bd9e46d70..efb3e7c36b88 100644
--- a/drivers/mmc/card/block.c
+++ b/drivers/mmc/card/block.c
@@ -1464,8 +1464,8 @@ static void mmc_blk_remove(struct mmc_card *card)
#endif
}
-#ifdef CONFIG_PM
-static int mmc_blk_suspend(struct mmc_card *card, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int mmc_blk_suspend(struct mmc_card *card)
{
struct mmc_blk_data *part_md;
struct mmc_blk_data *md = mmc_get_drvdata(card);
diff --git a/drivers/mmc/core/bus.c b/drivers/mmc/core/bus.c
index e07d6c90caec..d4a50128fe03 100644
--- a/drivers/mmc/core/bus.c
+++ b/drivers/mmc/core/bus.c
@@ -120,7 +120,8 @@ static int mmc_bus_remove(struct device *dev)
return 0;
}
-static int mmc_bus_pm_suspend(struct device *dev)
+#ifdef CONFIG_PM_SLEEP
+static int mmc_bus_suspend(struct device *dev)
{
struct mmc_driver *drv = to_mmc_driver(dev->driver);
struct mmc_card *card = mmc_dev_to_card(dev);
@@ -128,11 +129,11 @@ static int mmc_bus_pm_suspend(struct device *dev)
pm_message_t state = { PM_EVENT_SUSPEND };
if (dev->driver && drv->suspend)
- ret = drv->suspend(card, state);
+ ret = drv->suspend(card);
return ret;
}
-static int mmc_bus_pm_resume(struct device *dev)
+static int mmc_bus_resume(struct device *dev)
{
struct mmc_driver *drv = to_mmc_driver(dev->driver);
struct mmc_card *card = mmc_dev_to_card(dev);
@@ -142,6 +143,7 @@ static int mmc_bus_pm_resume(struct device *dev)
ret = drv->resume(card);
return ret;
}
+#endif
#ifdef CONFIG_PM_RUNTIME
static int mmc_runtime_suspend(struct device *dev)
@@ -165,8 +167,9 @@ static int mmc_runtime_idle(struct device *dev)
#endif /* CONFIG_PM_RUNTIME */
static const struct dev_pm_ops mmc_bus_pm_ops = {
- SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_pm_suspend, mmc_bus_pm_resume)
- SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume, mmc_runtime_idle)
+ SET_SYSTEM_SLEEP_PM_OPS(mmc_bus_suspend, mmc_bus_resume)
+ SET_RUNTIME_PM_OPS(mmc_runtime_suspend, mmc_runtime_resume,
+mmc_runtime_idle)
};
static struct bus_type mmc_bus_type = {
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c
index 845ce7c533b9..b11876c2c2df 100644
--- a/drivers/mmc/core/mmc_ops.c
+++ b/drivers/mmc/core/mmc_ops.c
@@ -397,6 +397,7 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value,
err = mmc_wait_for_cmd(card->host, &cmd, MMC_CMD_RETRIES);
if (err)
return err;
+ mdelay(1);
/* Must check status to be sure of no errors */
do {
diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c
index 5a7d8f5d41e0..28eb9d664fd8 100644
--- a/drivers/mmc/core/sd.c
+++ b/drivers/mmc/core/sd.c
@@ -477,17 +477,17 @@ static int sd_set_bus_speed_mode(struct mmc_card *card, u8 *status)
bus_speed = UHS_SDR104_BUS_SPEED;
timing = MMC_TIMING_UHS_SDR104;
card->sw_caps.uhs_max_dtr = UHS_SDR104_MAX_DTR;
- } else if ((card->host->caps & MMC_CAP_UHS_DDR50) &&
- (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) {
- bus_speed = UHS_DDR50_BUS_SPEED;
- timing = MMC_TIMING_UHS_DDR50;
- card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
MMC_CAP_UHS_SDR50)) && (card->sw_caps.sd3_bus_mode &
SD_MODE_UHS_SDR50)) {
bus_speed = UHS_SDR50_BUS_SPEED;
timing = MMC_TIMING_UHS_SDR50;
card->sw_caps.uhs_max_dtr = UHS_SDR50_MAX_DTR;
+ } else if ((card->host->caps & MMC_CAP_UHS_DDR50) &&
+ (card->sw_caps.sd3_bus_mode & SD_MODE_UHS_DDR50)) {
+ bus_speed = UHS_DDR50_BUS_SPEED;
+ timing = MMC_TIMING_UHS_DDR50;
+ card->sw_caps.uhs_max_dtr = UHS_DDR50_MAX_DTR;
} else if ((card->host->caps & (MMC_CAP_UHS_SDR104 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR25)) &&
(card->sw_caps.sd3_bus_mode & SD_MODE_UHS_SDR25)) {
@@ -733,8 +733,9 @@ int mmc_sd_get_cid(struct mmc_host *host, u32 ocr, u32 *cid, u32 *rocr)
* If the host supports one of UHS-I modes, request the card
* to switch to 1.8V signaling level.
*/
- if (host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
+ if ((host->caps & (MMC_CAP_UHS_SDR12 | MMC_CAP_UHS_SDR25 |
MMC_CAP_UHS_SDR50 | MMC_CAP_UHS_SDR104 | MMC_CAP_UHS_DDR50))
+ && (host->ocr_avail_sd & MMC_VDD_165_195))
ocr |= SD_OCR_S18R;
/* If the host can supply more than 150mA, XPC should be set to 1. */
diff --git a/drivers/mmc/host/sdhci-esdhc-imx.c b/drivers/mmc/host/sdhci-esdhc-imx.c
index 5aec0bfe6fd6..fc9b25b5e48d 100644
--- a/drivers/mmc/host/sdhci-esdhc-imx.c
+++ b/drivers/mmc/host/sdhci-esdhc-imx.c
@@ -31,17 +31,21 @@
/* VENDOR SPEC register */
#define SDHCI_VENDOR_SPEC 0xC0
#define SDHCI_VENDOR_SPEC_SDIO_QUIRK 0x00000002
-#define SDHCI_MIX_CTRL 0x48
-#define SDHCI_TUNE_CTRL_STATUS 0x68
-#define SDHCI_TUNE_CTRL_STEP 0x1
-#define SDHCI_TUNE_CTRL_MIN 0x0
-#define SDHCI_TUNE_CTRL_MAX ((1 << 7) - 1)
#define SDHCI_MIX_CTRL_EXE_TUNE (1 << 22)
#define SDHCI_MIX_CTRL_SMPCLK_SEL (1 << 23)
-#define SDHCI_MIX_CTRL_AUTOTUNE_EN (1 << 24)
+#define SDHCI_MIX_CTRL_AUTO_TUNE (1 << 24)
#define SDHCI_MIX_CTRL_FBCLK_SEL (1 << 25)
+#define SDHCI_DLL_CTRL 0x60
+#define SDHCI_DLL_OVERRIDE_OFFSET 0x9
+#define SDHCI_DLL_OVERRIDE_EN_OFFSET 0x8
+
+#define SDHCI_TUNE_CTRL_STATUS 0x68
+#define SDHCI_TUNE_CTRL_STEP 0x1
+#define SDHCI_TUNE_CTRL_MIN 0x0
+#define SDHCI_TUNE_CTRL_MAX ((1 << 7) - 1)
+
#define SDHCI_VENDOR_SPEC_VSELECT (1 << 1)
#define SDHCI_VENDOR_SPEC_FRC_SDCLK_ON (1 << 8)
@@ -52,6 +56,14 @@
#define ESDHC_FLAG_GPIO_FOR_CD_WP (1 << 0)
#define SDHCI_CTRL_D3CD 0x08
+
+#define SDHCI_PROT_CTRL_DMASEL_MASK (3 << 8)
+#define SDHCI_PROT_CTRL_DTW (3 << 1)
+#define SDHCI_PROT_CTRL_8BIT (2 << 1)
+#define SDHCI_PROT_CTRL_4BIT (1 << 1)
+#define SDHCI_PROT_CTRL_1BIT (0 << 1)
+#define SDHCI_PROT_CTRL_LCTL (1 << 0)
+
/*
* The CMDTYPE of the CMD register (offset 0xE) should be set to
* "11" when the STOP CMD12 is issued on imx53 to abort one
@@ -88,6 +100,21 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
/* fake CARD_PRESENT flag on mx25/35 */
u32 val = readl(host->ioaddr + reg);
+ /*
+ * mx6q: SDHCI_PRESENT_STATE bit 16, CINST is not functional on SD3.
+ * So move the section up, and check GPIO for card presence again in
+ * the following block.
+ */
+ if (reg == SDHCI_PRESENT_STATE && cpu_is_mx6()) {
+ u32 fsl_prss = readl(host->ioaddr + SDHCI_PRESENT_STATE);
+ /* save the least 20 bits */
+ val |= fsl_prss & 0x000FFFFF;
+ /* move dat[0-3] line signal bits */
+ val |= (fsl_prss & 0x0F000000) >> 4;
+ /* move cmd line signal bits */
+ val |= (fsl_prss & 0x00800000) << 1;
+ }
+
if (unlikely((reg == SDHCI_PRESENT_STATE)
&& (imx_data->flags & ESDHC_FLAG_GPIO_FOR_CD_WP))) {
struct esdhc_platform_data *boarddata =
@@ -102,9 +129,10 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
val |= SDHCI_CARD_PRESENT;
}
- if (reg == SDHCI_INT_STATUS && cpu_is_mx6q()) {
+ if (reg == SDHCI_INT_STATUS && cpu_is_mx6()
+ && mx6q_revision() == IMX_CHIP_REVISION_1_0) {
/*
- * on mx6q, there is low possibility that
+ * on mx6q TO1.0, there is low possibility that
* DATA END interrupt comes ealier than DMA
* END interrupt which is conflict with standard
* host controller spec. In this case, read the
@@ -113,13 +141,13 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
if ((val & SDHCI_INT_DATA_END) && \
!(val & SDHCI_INT_DMA_END))
val = readl(host->ioaddr + reg);
- } else if (reg == SDHCI_CAPABILITIES_1 && cpu_is_mx6q()) {
+ } else if (reg == SDHCI_CAPABILITIES_1 && cpu_is_mx6()) {
/*
* on mx6q, no cap_1 available, fake one.
*/
val = SDHCI_SUPPORT_DDR50 | SDHCI_SUPPORT_SDR104 | \
SDHCI_SUPPORT_SDR50;
- } else if (reg == SDHCI_MAX_CURRENT && cpu_is_mx6q()) {
+ } else if (reg == SDHCI_MAX_CURRENT && cpu_is_mx6()) {
/*
* on mx6q, no max current available, fake one.
*/
@@ -129,16 +157,6 @@ static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
val |= 0xFF << SDHCI_MAX_CURRENT_180_SHIFT;
}
- if (reg == SDHCI_PRESENT_STATE && cpu_is_mx6q()) {
- u32 fsl_prss = readl(host->ioaddr + SDHCI_PRESENT_STATE);
- /* save the least 20 bits */
- val = fsl_prss & 0x000FFFFF;
- /* move dat[0-3] line signal bits */
- val |= (fsl_prss & 0x0F000000) >> 4;
- /* move cmd line signal bits */
- val |= (fsl_prss & 0x00800000) << 1;
- }
-
return val;
}
@@ -157,10 +175,11 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
val &= ~(SDHCI_INT_CARD_REMOVE | \
SDHCI_INT_CARD_INSERT);
- if (!(val & SDHCI_INT_CARD_INT) && cpu_is_mx6q())
+ if (!(val & SDHCI_INT_CARD_INT) && cpu_is_mx6()
+ && mx6q_revision() == IMX_CHIP_REVISION_1_0)
/*
* write 1 to clear card interrupt status bit
- * (only applied to mx6q)
+ * (only applied to mx6q TO1.0)
* uSDHC used for mx6q has such problem which is
* not consistant with standard host controller
* definition.
@@ -170,7 +189,7 @@ static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
writel(SDHCI_INT_CARD_INT, \
host->ioaddr + SDHCI_INT_STATUS);
- if (val & SDHCI_INT_CARD_INT && (!cpu_is_mx6q())) {
+ if (val & SDHCI_INT_CARD_INT && !cpu_is_mx6()) {
/*
* clear D3CD bit and set D3CD bit to avoid
* losing card interrupt
@@ -238,19 +257,21 @@ void esdhc_prepare_tuning(struct sdhci_host *host, u32 val)
{
u32 reg;
- reg = sdhci_readl(host, SDHCI_MIX_CTRL);
+ reg = readl(host->ioaddr + SDHCI_MIX_CTRL);
reg |= SDHCI_MIX_CTRL_EXE_TUNE | \
SDHCI_MIX_CTRL_SMPCLK_SEL | \
- SDHCI_MIX_CTRL_AUTOTUNE_EN | \
+ SDHCI_MIX_CTRL_AUTO_TUNE | \
SDHCI_MIX_CTRL_FBCLK_SEL;
- sdhci_writel(host, reg, SDHCI_MIX_CTRL);
- sdhci_writel(host, (val << 8), SDHCI_TUNE_CTRL_STATUS);
+ writel(reg, host->ioaddr + SDHCI_MIX_CTRL);
+ writel((val << 8), host->ioaddr + SDHCI_TUNE_CTRL_STATUS);
}
static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
{
struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+ struct esdhc_platform_data *boarddata =
+ host->mmc->parent->platform_data;
struct pltfm_imx_data *imx_data = pltfm_host->priv;
u32 orig_reg;
@@ -291,10 +312,26 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
orig_reg |= (val & SDHCI_CTRL_TUNED_CLK)
? 0 : SDHCI_MIX_CTRL_SMPCLK_SEL;
+ orig_reg |= (val & SDHCI_CTRL_UHS_DDR50)
+ ? SDHCI_MIX_CTRL_DDREN : 0;
writel(orig_reg, host->ioaddr + SDHCI_MIX_CTRL);
+ /* set clock frequency again */
+ esdhc_set_clock(host, host->clock);
imx_data->uhs_mode = val & SDHCI_CTRL_UHS_MASK;
+ /* delay line setting */
+ if (!boarddata->delay_line)
+ return;
+
+ if (val & SDHCI_CTRL_UHS_DDR50)
+ writel((boarddata->delay_line \
+ << SDHCI_DLL_OVERRIDE_OFFSET) \
+ | (1 << SDHCI_DLL_OVERRIDE_EN_OFFSET),
+ host->ioaddr + SDHCI_DLL_CTRL);
+ else
+ writel(0, host->ioaddr + SDHCI_DLL_CTRL);
+
return;
case SDHCI_TRANSFER_MODE:
/*
@@ -318,9 +355,14 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
val |= SDHCI_CMD_ABORTCMD;
writel(0x08800880, host->ioaddr + SDHCI_CAPABILITIES_1);
- if (cpu_is_mx6q()) {
+ if (cpu_is_mx6()) {
imx_data->scratchpad |= \
- (readl(host->ioaddr + SDHCI_MIX_CTRL) & (0xf << 22));
+ (readl(host->ioaddr + SDHCI_MIX_CTRL) & \
+ (SDHCI_MIX_CTRL_EXE_TUNE | \
+ SDHCI_MIX_CTRL_SMPCLK_SEL | \
+ SDHCI_MIX_CTRL_AUTO_TUNE | \
+ SDHCI_MIX_CTRL_FBCLK_SEL | \
+ SDHCI_MIX_CTRL_DDREN));
writel(imx_data->scratchpad,
host->ioaddr + SDHCI_MIX_CTRL);
@@ -338,6 +380,59 @@ static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
esdhc_clrset_le(host, 0xffff, val, reg);
}
+static u8 esdhc_readb_le(struct sdhci_host *host, int reg)
+{
+ u8 ret;
+ u32 reg_val;
+
+ ret = 0;
+ switch (reg) {
+ case SDHCI_POWER_CONTROL:
+ reg_val = readl(host->ioaddr + SDHCI_VENDOR_SPEC);
+ ret |= reg_val & SDHCI_VENDOR_SPEC_VSELECT
+ ? SDHCI_POWER_180 : SDHCI_POWER_330;
+ /* could not power off */
+ ret |= SDHCI_POWER_ON;
+ return ret;
+ case SDHCI_HOST_CONTROL:
+ reg_val = readl(host->ioaddr + SDHCI_HOST_CONTROL);
+ ret |= reg_val & SDHCI_PROT_CTRL_LCTL
+ ? SDHCI_CTRL_LED : ~SDHCI_CTRL_LED;
+ ret |= (reg_val & SDHCI_PROT_CTRL_DMASEL_MASK) >> 5;
+ if (SDHCI_PROT_CTRL_8BIT == (reg_val & SDHCI_PROT_CTRL_DTW)) {
+ ret &= ~SDHCI_CTRL_4BITBUS;
+ ret |= SDHCI_CTRL_8BITBUS;
+ } else if (SDHCI_PROT_CTRL_4BIT
+ == (reg_val & SDHCI_PROT_CTRL_DTW)) {
+ ret &= ~SDHCI_CTRL_8BITBUS;
+ ret |= SDHCI_CTRL_4BITBUS;
+ } else if (SDHCI_PROT_CTRL_1BIT
+ == (reg_val & SDHCI_PROT_CTRL_DTW))
+ ret &= ~(SDHCI_CTRL_8BITBUS | SDHCI_CTRL_4BITBUS);
+ return ret;
+ case SDHCI_SOFTWARE_RESET:
+ reg_val = readl(host->ioaddr + SDHCI_CLOCK_CONTROL);
+ ret = reg_val >> 24;
+ return ret;
+ case SDHCI_RESPONSE + 3:
+ reg_val = readl(host->ioaddr + SDHCI_RESPONSE);
+ ret = reg_val >> 24;
+ return ret;
+ case SDHCI_RESPONSE + 7:
+ reg_val = readl(host->ioaddr + SDHCI_RESPONSE + 4);
+ ret = reg_val >> 24;
+ return ret;
+ case SDHCI_RESPONSE + 11:
+ reg_val = readl(host->ioaddr + SDHCI_RESPONSE + 8);
+ ret = reg_val >> 24;
+ return ret;
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg)
{
u32 new_val;
@@ -375,9 +470,14 @@ static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg)
return;
case SDHCI_HOST_CONTROL:
/* FSL messed up here, so we can just keep those three */
- new_val = val & (SDHCI_CTRL_LED | \
- SDHCI_CTRL_4BITBUS | \
- SDHCI_CTRL_D3CD);
+ new_val = val & (SDHCI_CTRL_LED);
+ if (val & SDHCI_CTRL_8BITBUS) {
+ new_val |= SDHCI_PROT_CTRL_8BIT;
+ new_val &= ~SDHCI_PROT_CTRL_4BIT;
+ } else if (val & SDHCI_CTRL_4BITBUS) {
+ new_val &= ~SDHCI_PROT_CTRL_8BIT;
+ new_val |= SDHCI_PROT_CTRL_4BIT;
+ }
/* ensure the endianess */
new_val |= ESDHC_HOST_CONTROL_LE;
/* DMA mode bits are shifted */
@@ -413,9 +513,40 @@ static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
return -ENOSYS;
}
+static int plt_8bit_width(struct sdhci_host *host, int width)
+{
+ u32 reg = readl(host->ioaddr + SDHCI_HOST_CONTROL);
+
+ reg &= ~SDHCI_PROT_CTRL_DTW;
+
+ if (width == MMC_BUS_WIDTH_8)
+ reg |= SDHCI_PROT_CTRL_8BIT;
+ else if (width == MMC_BUS_WIDTH_4)
+ reg |= SDHCI_PROT_CTRL_4BIT;
+ else if (width == MMC_BUS_WIDTH_1)
+ host->mmc->ios.ddr = 0;
+
+ writel(reg, host->ioaddr + SDHCI_HOST_CONTROL);
+ return 0;
+}
+
+static void plt_clk_ctrl(struct sdhci_host *host, bool enable)
+{
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
+
+ if (enable) {
+ clk_enable(pltfm_host->clk);
+ host->clk_status = true;
+ } else {
+ clk_disable(pltfm_host->clk);
+ host->clk_status = false;
+ }
+}
+
static struct sdhci_ops sdhci_esdhc_ops = {
.read_l = esdhc_readl_le,
.read_w = esdhc_readw_le,
+ .read_b = esdhc_readb_le,
.write_l = esdhc_writel_le,
.write_w = esdhc_writew_le,
.write_b = esdhc_writeb_le,
@@ -423,14 +554,21 @@ static struct sdhci_ops sdhci_esdhc_ops = {
.get_max_clock = esdhc_pltfm_get_max_clock,
.get_min_clock = esdhc_pltfm_get_min_clock,
.pre_tuning = esdhc_prepare_tuning,
+ .platform_8bit_width = plt_8bit_width,
+ .platform_clk_ctrl = plt_clk_ctrl,
};
static irqreturn_t cd_irq(int irq, void *data)
{
struct sdhci_host *sdhost = (struct sdhci_host *)data;
+ struct sdhci_pltfm_host *pltfm_host = sdhci_priv(sdhost);
+ struct pltfm_imx_data *imx_data = pltfm_host->priv;
+
+ writel(0, sdhost->ioaddr + SDHCI_MIX_CTRL);
+ writel(0, sdhost->ioaddr + SDHCI_TUNE_CTRL_STATUS);
- sdhci_writel(sdhost, 0, SDHCI_MIX_CTRL);
- sdhci_writel(sdhost, 0, SDHCI_TUNE_CTRL_STATUS);
+ if (cpu_is_mx6())
+ imx_data->scratchpad &= ~SDHCI_MIX_CTRL_DDREN;
tasklet_schedule(&sdhost->card_tasklet);
return IRQ_HANDLED;
};
@@ -442,6 +580,7 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
struct clk *clk;
int err;
struct pltfm_imx_data *imx_data;
+ u32 reg;
clk = clk_get(mmc_dev(host->mmc), NULL);
if (IS_ERR(clk)) {
@@ -469,9 +608,43 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
/* write_protect can't be routed to controller, use gpio */
sdhci_esdhc_ops.get_ro = esdhc_pltfm_get_ro;
- if (!(cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51() || cpu_is_mx6q()))
+ if (!(cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51() || cpu_is_mx6()))
imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;
+ host->ocr_avail_sd = MMC_VDD_29_30 | MMC_VDD_30_31 | \
+ MMC_VDD_32_33 | MMC_VDD_33_34;
+ host->ocr_avail_mmc = MMC_VDD_29_30 | MMC_VDD_30_31 | \
+ MMC_VDD_32_33 | MMC_VDD_33_34;
+
+ if (boarddata->support_18v)
+ host->ocr_avail_sd |= MMC_VDD_165_195;
+ if (boarddata->support_8bit)
+ host->mmc->caps |= MMC_CAP_8_BIT_DATA;
+ if (boarddata->keep_power_at_suspend)
+ host->mmc->pm_caps |= MMC_PM_KEEP_POWER;
+ if (cpu_is_mx6()) {
+ host->mmc->caps |= MMC_CAP_1_8V_DDR;
+ host->tuning_min = SDHCI_TUNE_CTRL_MIN;
+ host->tuning_max = SDHCI_TUNE_CTRL_MAX;
+ host->tuning_step = SDHCI_TUNE_CTRL_STEP;
+ host->clk_mgr_en = true;
+ }
+
+ reg = readl(host->ioaddr + SDHCI_MIX_CTRL);
+ /* disable card interrupt enable bit, and clear status bit
+ * the default value of this enable bit is 1, but it should
+ * be 0 regarding to standard host controller spec 2.1.3.
+ * if this bit is 1, it may cause some problems.
+ * there's dat1 glitch when some cards inserting into the slot,
+ * thus wrongly generate a card interrupt that will cause
+ * system panic because it lacks of sdio handler
+ * following code will solve the problem.
+ */
+ reg = sdhci_readl(host, SDHCI_INT_ENABLE);
+ reg &= ~SDHCI_INT_CARD_INT;
+ sdhci_writel(host, reg, SDHCI_INT_ENABLE);
+ sdhci_writel(host, SDHCI_INT_CARD_INT, SDHCI_INT_STATUS);
+
if (boarddata) {
/* Device is always present, e.x, populated emmc device */
if (boarddata->always_present) {
@@ -508,16 +681,9 @@ static int esdhc_pltfm_init(struct sdhci_host *host, struct sdhci_pltfm_data *pd
/* Now we have a working card_detect again */
host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
}
- host->ocr_avail_sd = MMC_VDD_29_30 | MMC_VDD_30_31 | \
- MMC_VDD_32_33 | MMC_VDD_33_34;
-
- if (boarddata->support_18v)
- host->ocr_avail_sd |= MMC_VDD_165_195;
-
- host->tuning_min = SDHCI_TUNE_CTRL_MIN;
- host->tuning_max = SDHCI_TUNE_CTRL_MAX;
- host->tuning_step = SDHCI_TUNE_CTRL_STEP;
+ if (host->clk_mgr_en)
+ clk_disable(pltfm_host->clk);
return 0;
no_card_detect_irq:
diff --git a/drivers/mmc/host/sdhci-esdhc.h b/drivers/mmc/host/sdhci-esdhc.h
index 8ee1d622c56d..c64cdcdca4ba 100644
--- a/drivers/mmc/host/sdhci-esdhc.h
+++ b/drivers/mmc/host/sdhci-esdhc.h
@@ -1,7 +1,7 @@
/*
* Freescale eSDHC controller driver generics for OF and pltfm.
*
- * Copyright (C) 2007, 2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2007, 2011, 2012 Freescale Semiconductor, Inc.
* Copyright (c) 2009 MontaVista Software, Inc.
* Copyright (c) 2010 Pengutronix e.K.
* Author: Wolfram Sang <w.sang@pengutronix.de>
@@ -54,7 +54,7 @@ static inline void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
int ddr_mode = 0;
boarddata = host->mmc->parent->platform_data;
- if (cpu_is_mx6q()) {
+ if (cpu_is_mx6q() || cpu_is_mx6dl()) {
pre_div = 1;
if (readl(host->ioaddr + SDHCI_MIX_CTRL) &
SDHCI_MIX_CTRL_DDREN) {
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig
index bd5a79f3cb82..d6f72f8c69a3 100644
--- a/drivers/mtd/nand/Kconfig
+++ b/drivers/mtd/nand/Kconfig
@@ -449,7 +449,7 @@ config MTD_NAND_NANDSIM
config MTD_NAND_GPMI_NAND
bool "GPMI NAND Flash Controller driver"
- depends on MTD_NAND && (SOC_IMX23 || SOC_IMX28)
+ depends on MTD_NAND && (SOC_IMX23 || SOC_IMX28 || SOC_IMX6Q)
select MTD_PARTITIONS
select MTD_CMDLINE_PARTS
help
diff --git a/drivers/mtd/nand/gpmi-nand/bch-regs.h b/drivers/mtd/nand/gpmi-nand/bch-regs.h
index 4effb8c579db..04acf6413b16 100644
--- a/drivers/mtd/nand/gpmi-nand/bch-regs.h
+++ b/drivers/mtd/nand/gpmi-nand/bch-regs.h
@@ -1,7 +1,7 @@
/*
* Freescale GPMI NAND Flash Driver
*
- * Copyright 2008-2011 Freescale Semiconductor, Inc.
+ * Copyright 2008-2012 Freescale Semiconductor, Inc.
* Copyright 2008 Embedded Alley Solutions, Inc.
*
* This program is free software; you can redistribute it and/or modify
@@ -51,15 +51,26 @@
#define BP_BCH_FLASH0LAYOUT0_ECC0 12
#define BM_BCH_FLASH0LAYOUT0_ECC0 (0xf << BP_BCH_FLASH0LAYOUT0_ECC0)
-#define BF_BCH_FLASH0LAYOUT0_ECC0(v) \
- (((v) << BP_BCH_FLASH0LAYOUT0_ECC0) & BM_BCH_FLASH0LAYOUT0_ECC0)
+#define MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0 11
+#define MX6Q_BM_BCH_FLASH0LAYOUT0_ECC0 (0x1f << MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0)
+#define BF_BCH_FLASH0LAYOUT0_ECC0(v, x) \
+ (GPMI_IS_MX6Q(x) \
+ ? (((v) << MX6Q_BP_BCH_FLASH0LAYOUT0_ECC0) \
+ & MX6Q_BM_BCH_FLASH0LAYOUT0_ECC0) \
+ : (((v) << BP_BCH_FLASH0LAYOUT0_ECC0) \
+ & BM_BCH_FLASH0LAYOUT0_ECC0) \
+ )
#define BP_BCH_FLASH0LAYOUT0_DATA0_SIZE 0
#define BM_BCH_FLASH0LAYOUT0_DATA0_SIZE \
(0xfff << BP_BCH_FLASH0LAYOUT0_DATA0_SIZE)
-#define BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(v) \
- (((v) << BP_BCH_FLASH0LAYOUT0_DATA0_SIZE)\
- & BM_BCH_FLASH0LAYOUT0_DATA0_SIZE)
+#define MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE \
+ (0x3ff << BP_BCH_FLASH0LAYOUT0_DATA0_SIZE)
+#define BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(v, x) \
+ (GPMI_IS_MX6Q(x) \
+ ? (((v) >> 2) & MX6Q_BM_BCH_FLASH0LAYOUT0_DATA0_SIZE) \
+ : ((v) & BM_BCH_FLASH0LAYOUT0_DATA0_SIZE) \
+ )
#define HW_BCH_FLASH0LAYOUT1 0x00000090
@@ -72,13 +83,24 @@
#define BP_BCH_FLASH0LAYOUT1_ECCN 12
#define BM_BCH_FLASH0LAYOUT1_ECCN (0xf << BP_BCH_FLASH0LAYOUT1_ECCN)
-#define BF_BCH_FLASH0LAYOUT1_ECCN(v) \
- (((v) << BP_BCH_FLASH0LAYOUT1_ECCN) & BM_BCH_FLASH0LAYOUT1_ECCN)
+#define MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN 11
+#define MX6Q_BM_BCH_FLASH0LAYOUT1_ECCN (0x1f << MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN)
+#define BF_BCH_FLASH0LAYOUT1_ECCN(v, x) \
+ (GPMI_IS_MX6Q(x) \
+ ? (((v) << MX6Q_BP_BCH_FLASH0LAYOUT1_ECCN) \
+ & MX6Q_BM_BCH_FLASH0LAYOUT1_ECCN) \
+ : (((v) << BP_BCH_FLASH0LAYOUT1_ECCN) \
+ & BM_BCH_FLASH0LAYOUT1_ECCN) \
+ )
#define BP_BCH_FLASH0LAYOUT1_DATAN_SIZE 0
#define BM_BCH_FLASH0LAYOUT1_DATAN_SIZE \
(0xfff << BP_BCH_FLASH0LAYOUT1_DATAN_SIZE)
-#define BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(v) \
- (((v) << BP_BCH_FLASH0LAYOUT1_DATAN_SIZE) \
- & BM_BCH_FLASH0LAYOUT1_DATAN_SIZE)
+#define MX6Q_BM_BCH_FLASH0LAYOUT1_DATAN_SIZE \
+ (0x3ff << BP_BCH_FLASH0LAYOUT1_DATAN_SIZE)
+#define BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(v, x) \
+ (GPMI_IS_MX6Q(x) \
+ ? (((v) >> 2) & MX6Q_BM_BCH_FLASH0LAYOUT1_DATAN_SIZE) \
+ : ((v) & BM_BCH_FLASH0LAYOUT1_DATAN_SIZE) \
+ )
#endif
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
index b2c987bd6dc5..698535773ff4 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-lib.c
@@ -1,7 +1,7 @@
/*
* Freescale GPMI NAND Flash Driver
*
- * Copyright (C) 2008-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2008-2012 Freescale Semiconductor, Inc.
* Copyright (C) 2008 Embedded Alley Solutions, Inc.
*
* This program is free software; you can redistribute it and/or modify
@@ -223,13 +223,13 @@ int bch_set_geometry(struct gpmi_nand_data *this)
/* Configure layout 0. */
writel(BF_BCH_FLASH0LAYOUT0_NBLOCKS(block_count)
| BF_BCH_FLASH0LAYOUT0_META_SIZE(metadata_size)
- | BF_BCH_FLASH0LAYOUT0_ECC0(ecc_strength)
- | BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(block_size),
+ | BF_BCH_FLASH0LAYOUT0_ECC0(ecc_strength, this)
+ | BF_BCH_FLASH0LAYOUT0_DATA0_SIZE(block_size, this),
r->bch_regs + HW_BCH_FLASH0LAYOUT0);
writel(BF_BCH_FLASH0LAYOUT1_PAGE_SIZE(page_size)
- | BF_BCH_FLASH0LAYOUT1_ECCN(ecc_strength)
- | BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(block_size),
+ | BF_BCH_FLASH0LAYOUT1_ECCN(ecc_strength, this)
+ | BF_BCH_FLASH0LAYOUT1_DATAN_SIZE(block_size, this),
r->bch_regs + HW_BCH_FLASH0LAYOUT1);
/* Set *all* chip selects to use layout 0. */
@@ -803,7 +803,8 @@ int gpmi_is_ready(struct gpmi_nand_data *this, unsigned chip)
if (GPMI_IS_MX23(this)) {
mask = MX23_BM_GPMI_DEBUG_READY0 << chip;
reg = readl(r->gpmi_regs + HW_GPMI_DEBUG);
- } else if (GPMI_IS_MX28(this)) {
+ } else if (GPMI_IS_MX28(this) || GPMI_IS_MX6Q(this)) {
+ /* MX28 shares the same R/B register as MX6Q. */
mask = MX28_BF_GPMI_STAT_READY_BUSY(1 << chip);
reg = readl(r->gpmi_regs + HW_GPMI_STAT);
} else
@@ -849,7 +850,9 @@ int gpmi_send_command(struct gpmi_nand_data *this)
sg_init_one(sgl, this->cmd_buffer, this->command_length);
dma_map_sg(this->dev, sgl, 1, DMA_TO_DEVICE);
desc = channel->device->device_prep_slave_sg(channel,
- sgl, 1, DMA_MEM_TO_DEV, 1);
+ sgl, 1, DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+
if (!desc) {
pr_err("step 2 error\n");
return -1;
@@ -891,7 +894,8 @@ int gpmi_send_data(struct gpmi_nand_data *this)
/* [2] send DMA request */
prepare_data_dma(this, DMA_TO_DEVICE);
desc = channel->device->device_prep_slave_sg(channel, &this->data_sgl,
- 1, DMA_MEM_TO_DEV, 1);
+ 1, DMA_MEM_TO_DEV,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
pr_err("step 2 error\n");
return -1;
@@ -927,7 +931,8 @@ int gpmi_read_data(struct gpmi_nand_data *this)
/* [2] : send DMA request */
prepare_data_dma(this, DMA_FROM_DEVICE);
desc = channel->device->device_prep_slave_sg(channel, &this->data_sgl,
- 1, DMA_DEV_TO_MEM, 1);
+ 1, DMA_DEV_TO_MEM,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
pr_err("step 2 error\n");
return -1;
@@ -974,7 +979,8 @@ int gpmi_send_page(struct gpmi_nand_data *this,
desc = channel->device->device_prep_slave_sg(channel,
(struct scatterlist *)pio,
- ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
+ ARRAY_SIZE(pio), DMA_TRANS_NONE,
+ DMA_CTRL_ACK);
if (!desc) {
pr_err("step 2 error\n");
return -1;
@@ -994,6 +1000,7 @@ int gpmi_read_page(struct gpmi_nand_data *this,
struct dma_async_tx_descriptor *desc;
struct dma_chan *channel = get_dma_chan(this);
int chip = this->current_chip;
+ unsigned long flags;
u32 pio[6];
/* [1] Wait for the chip to report ready. */
@@ -1036,9 +1043,14 @@ int gpmi_read_page(struct gpmi_nand_data *this,
pio[3] = geo->page_size;
pio[4] = payload;
pio[5] = auxiliary;
+
+ /* Set DMA_CTRL_ACK for MX6Q which uses the new GPMI. */
+ flags = DMA_PREP_INTERRUPT;
+ if (GPMI_IS_MX6Q(this))
+ flags |= DMA_CTRL_ACK;
desc = channel->device->device_prep_slave_sg(channel,
(struct scatterlist *)pio,
- ARRAY_SIZE(pio), DMA_TRANS_NONE, 1);
+ ARRAY_SIZE(pio), DMA_TRANS_NONE, flags);
if (!desc) {
pr_err("step 2 error\n");
return -1;
@@ -1055,9 +1067,11 @@ int gpmi_read_page(struct gpmi_nand_data *this,
| BF_GPMI_CTRL0_ADDRESS(address)
| BF_GPMI_CTRL0_XFER_COUNT(geo->page_size);
pio[1] = 0;
+ pio[2] = 0; /* set GPMI_HW_GPMI_ECCCTRL, disable the BCH */
desc = channel->device->device_prep_slave_sg(channel,
- (struct scatterlist *)pio, 2,
- DMA_TRANS_NONE, 1);
+ (struct scatterlist *)pio, 3,
+ DMA_TRANS_NONE,
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
if (!desc) {
pr_err("step 3 error\n");
return -1;
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
index ff61e35581e7..ea3ce22ff9d5 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.c
@@ -1,7 +1,7 @@
/*
* Freescale GPMI NAND Flash Driver
*
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010-2012 Freescale Semiconductor, Inc.
* Copyright (C) 2008 Embedded Alley Solutions, Inc.
*
* This program is free software; you can redistribute it and/or modify
@@ -1493,6 +1493,8 @@ static int __devinit gpmi_nfc_init(struct gpmi_nand_data *this)
chip->ecc.mode = NAND_ECC_HW;
chip->ecc.size = 1;
chip->ecc.layout = &gpmi_hw_ecclayout;
+ if (pdata->enable_bbt)
+ chip->options |= NAND_BBT_USE_FLASH | NAND_USE_FLASH_BBT_NO_OOB;
/* Allocate a temporary DMA buffer for reading ID in the nand_scan() */
this->bch_geometry.payload_size = 1024;
@@ -1582,6 +1584,9 @@ static const struct platform_device_id gpmi_ids[] = {
}, {
.name = "imx28-gpmi-nand",
.driver_data = IS_MX28,
+ }, {
+ .name = "imx6q-gpmi-nand",
+ .driver_data = IS_MX6Q,
}, {},
};
diff --git a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
index e023bccb7781..06a072bf85a1 100644
--- a/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
+++ b/drivers/mtd/nand/gpmi-nand/gpmi-nand.h
@@ -1,7 +1,7 @@
/*
* Freescale GPMI NAND Flash Driver
*
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010-2012 Freescale Semiconductor, Inc.
* Copyright (C) 2008 Embedded Alley Solutions, Inc.
*
* This program is free software; you can redistribute it and/or modify
@@ -20,7 +20,7 @@
#include <linux/mtd/nand.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
-#include <mach/dma.h>
+#include <linux/mxs-dma.h>
struct resources {
void *gpmi_regs;
@@ -268,6 +268,8 @@ extern int gpmi_read_page(struct gpmi_nand_data *,
/* Use the platform_id to distinguish different Archs. */
#define IS_MX23 0x1
#define IS_MX28 0x2
+#define IS_MX6Q 0x8
#define GPMI_IS_MX23(x) ((x)->pdev->id_entry->driver_data == IS_MX23)
#define GPMI_IS_MX28(x) ((x)->pdev->id_entry->driver_data == IS_MX28)
+#define GPMI_IS_MX6Q(x) ((x)->pdev->id_entry->driver_data == IS_MX6Q)
#endif
diff --git a/drivers/mxc/asrc/mxc_asrc.c b/drivers/mxc/asrc/mxc_asrc.c
index bf36aec4bd34..dbf3fffcb100 100644
--- a/drivers/mxc/asrc/mxc_asrc.c
+++ b/drivers/mxc/asrc/mxc_asrc.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -890,14 +890,19 @@ static void asrc_output_dma_callback(void *data)
static void mxc_free_dma_buf(struct asrc_pair_params *params)
{
int i;
- for (i = 0; i < ASRC_DMA_BUFFER_NUM; i++) {
- if (params->input_dma[i].dma_vaddr != NULL) {
- kfree(params->input_dma[i].dma_vaddr);
+
+ if (params->input_dma[0].dma_vaddr != NULL) {
+ kfree(params->input_dma[0].dma_vaddr);
+ for (i = 0; i < ASRC_DMA_BUFFER_NUM; i++) {
params->input_dma[i].dma_vaddr = NULL;
+ params->input_dma[i].dma_paddr = 0;
}
- if (params->output_dma[i].dma_vaddr != NULL) {
- kfree(params->output_dma[i].dma_vaddr);
+ }
+ if (params->output_dma[0].dma_vaddr != NULL) {
+ kfree(params->output_dma[0].dma_vaddr);
+ for (i = 0; i < ASRC_DMA_BUFFER_NUM; i++) {
params->output_dma[i].dma_vaddr = NULL;
+ params->output_dma[i].dma_paddr = 0;
}
}
@@ -907,9 +912,23 @@ static void mxc_free_dma_buf(struct asrc_pair_params *params)
static int mxc_allocate_dma_buf(struct asrc_pair_params *params)
{
int i;
+
+ params->input_dma[0].dma_vaddr = NULL;
+ params->input_dma[0].dma_vaddr =
+ kzalloc(params->input_buffer_size * ASRC_DMA_BUFFER_NUM,
+ GFP_KERNEL);
+
+ if (!params->input_dma[0].dma_vaddr) {
+ mxc_free_dma_buf(params);
+ pr_info("can't allocate buff\n");
+ return -ENOBUFS;
+ }
+
for (i = 0; i < ASRC_DMA_BUFFER_NUM; i++) {
params->input_dma[i].dma_vaddr =
- kzalloc(params->input_buffer_size, GFP_KERNEL);
+ (unsigned char *)
+ ((unsigned long)params->input_dma[0].dma_vaddr +
+ i * params->input_buffer_size);
params->input_dma[i].dma_paddr =
virt_to_dma(NULL, params->input_dma[i].dma_vaddr);
if (params->input_dma[i].dma_vaddr == NULL) {
@@ -918,17 +937,30 @@ static int mxc_allocate_dma_buf(struct asrc_pair_params *params)
return -ENOBUFS;
}
}
+
+ params->output_dma[0].dma_vaddr = NULL;
+ params->output_dma[0].dma_vaddr =
+ kzalloc(params->output_buffer_size * ASRC_DMA_BUFFER_NUM,
+ GFP_KERNEL);
+ if (!params->output_dma[0].dma_vaddr) {
+ mxc_free_dma_buf(params);
+ pr_info("can't allocate buff\n");
+ return -ENOBUFS;
+ }
+
for (i = 0; i < ASRC_DMA_BUFFER_NUM; i++) {
params->output_dma[i].dma_vaddr =
- kzalloc(params->output_buffer_size, GFP_KERNEL);
+ (unsigned char *)
+ ((unsigned long)params->output_dma[0].dma_vaddr +
+ i * params->output_buffer_size);
params->output_dma[i].dma_paddr =
virt_to_dma(NULL, params->output_dma[i].dma_vaddr);
if (params->output_dma[i].dma_vaddr == NULL) {
mxc_free_dma_buf(params);
+ pr_info("can't allocate buff\n");
return -ENOBUFS;
}
}
-
return 0;
}
diff --git a/drivers/mxc/ipu3/ipu_common.c b/drivers/mxc/ipu3/ipu_common.c
index 40297a8718af..8a0efa444440 100644
--- a/drivers/mxc/ipu3/ipu_common.c
+++ b/drivers/mxc/ipu3/ipu_common.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2005-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -1259,7 +1259,7 @@ int32_t ipu_init_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
if (idma_is_set(ipu, IDMAC_CHA_PRI, dma_chan)) {
unsigned reg = IDMAC_CH_LOCK_EN_1;
uint32_t value = 0;
- if (cpu_is_mx53() || cpu_is_mx6q()) {
+ if (cpu_is_mx53() || cpu_is_mx6q() || cpu_is_mx6dl()) {
_ipu_ch_param_set_axi_id(ipu, dma_chan, 0);
switch (dma_chan) {
case 5:
@@ -1327,7 +1327,7 @@ int32_t ipu_init_channel_buffer(struct ipu_soc *ipu, ipu_channel_t channel,
} else
_ipu_ch_param_set_axi_id(ipu, dma_chan, 1);
} else {
- if (cpu_is_mx6q())
+ if (cpu_is_mx6q() || cpu_is_mx6dl())
_ipu_ch_param_set_axi_id(ipu, dma_chan, 1);
}
diff --git a/drivers/mxc/vpu/mxc_vpu.c b/drivers/mxc/vpu/mxc_vpu.c
index 0e0e03835e87..20d523aac9e1 100644
--- a/drivers/mxc/vpu/mxc_vpu.c
+++ b/drivers/mxc/vpu/mxc_vpu.c
@@ -45,6 +45,10 @@
#include <mach/mxc_vpu.h>
+/* Define one new pgprot which combined uncached and XN(never executable) */
+#define pgprot_noncachedxn(prot) \
+ __pgprot_modify(prot, L_PTE_MT_MASK, L_PTE_MT_UNCACHED | L_PTE_XN)
+
struct vpu_priv {
struct fasync_struct *async_queue;
struct work_struct work;
@@ -511,7 +515,13 @@ static int vpu_map_hwregs(struct file *fp, struct vm_area_struct *vm)
unsigned long pfn;
vm->vm_flags |= VM_IO | VM_RESERVED;
- vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot);
+ /*
+ * Since vpu registers have been mapped with ioremap() at probe
+ * which L_PTE_XN is 1, and the same physical address must be
+ * mapped multiple times with same type, so set L_PTE_XN to 1 here.
+ * Otherwise, there may be unexpected result in video codec.
+ */
+ vm->vm_page_prot = pgprot_noncachedxn(vm->vm_page_prot);
pfn = phy_vpu_base_addr >> PAGE_SHIFT;
pr_debug("size=0x%x, page no.=0x%x\n",
(int)(vm->vm_end - vm->vm_start), (int)pfn);
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 18d356e0a8eb..872b7c4c5cc6 100755
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -19,7 +19,7 @@
* Copyright (c) 2004-2006 Macq Electronique SA.
*
* Support for FEC IEEE 1588.
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2010-2012 Freescale Semiconductor, Inc.
*/
#include <linux/module.h>
@@ -145,6 +145,8 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
#define FEC_ENET_EBERR ((uint)0x00400000) /* SDMA bus error */
#define FEC_ENET_TS_AVAIL ((uint)0x00010000)
#define FEC_ENET_TS_TIMER ((uint)0x00008000)
+#define FEC_ENET_MII_CLK ((uint)2500000)
+#define FEC_ENET_HOLD_TIME ((uint)0x100) /* 2 internal clock cycle*/
#if defined(CONFIG_FEC_1588) && (defined(CONFIG_ARCH_MX28) || \
defined(CONFIG_ARCH_MX6))
@@ -608,6 +610,7 @@ fec_enet_interrupt(int irq, void *dev_id)
{
struct net_device *ndev = dev_id;
struct fec_enet_private *fep = netdev_priv(ndev);
+ struct fec_ptp_private *fpp = fep->ptp_priv;
uint int_events;
irqreturn_t ret = IRQ_NONE;
@@ -629,6 +632,12 @@ fec_enet_interrupt(int irq, void *dev_id)
fec_enet_tx(ndev);
}
+ if (int_events & FEC_ENET_TS_TIMER) {
+ ret = IRQ_HANDLED;
+ if (fep->ptimer_present && fpp)
+ fpp->prtc++;
+ }
+
if (int_events & FEC_ENET_MII) {
ret = IRQ_HANDLED;
complete(&fep->mdio_done);
@@ -838,7 +847,7 @@ static int fec_enet_mii_probe(struct net_device *ndev)
}
/* mask with MAC supported features */
- if (cpu_is_mx6q())
+ if (cpu_is_mx6())
phy_dev->supported &= PHY_GBIT_FEATURES;
else
phy_dev->supported &= PHY_BASIC_FEATURES;
@@ -893,15 +902,12 @@ static int fec_enet_mii_init(struct platform_device *pdev)
/*
* Set MII speed to 2.5 MHz (= clk_get_rate() / 2 * phy_speed)
*/
- fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk), 5000000) << 1;
+ fep->phy_speed = DIV_ROUND_UP(clk_get_rate(fep->clk),
+ (FEC_ENET_MII_CLK << 2)) << 1;
- if (cpu_is_mx6q()) {
- /* FIXME: non-1588 MII clk: 66MHz, 1588 mode : 40MHz */
- if (fep->ptimer_present)
- fep->phy_speed = 0xe;
- else
- fep->phy_speed = 0x11a;
- }
+ /* set hold time to 2 internal clock cycle */
+ if (cpu_is_mx6())
+ fep->phy_speed |= FEC_ENET_HOLD_TIME;
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
@@ -1458,7 +1464,7 @@ fec_restart(struct net_device *dev, int duplex)
fep->phy_dev->speed == SPEED_1000)
val |= (0x1 << 5);
- if (cpu_is_mx6q()) {
+ if (cpu_is_mx6()) {
/* enable endian swap */
val |= (0x1 << 8);
/* enable ENET store and forward mode */
@@ -1489,7 +1495,7 @@ fec_stop(struct net_device *dev)
writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
- if (cpu_is_mx6q())
+ if (cpu_is_mx6())
/* FIXME: we have to enable enet to keep mii interrupt works. */
writel(2, fep->hwp + FEC_ECNTRL);
diff --git a/drivers/net/fec_1588.c b/drivers/net/fec_1588.c
index c7d3a63b96e1..43b60941cc99 100644
--- a/drivers/net/fec_1588.c
+++ b/drivers/net/fec_1588.c
@@ -1,7 +1,7 @@
/*
* drivers/net/fec_1588.c
*
- * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
* Copyright (C) 2009 IXXAT Automation, GmbH
*
* FEC Ethernet Driver -- IEEE 1588 interface functionality
@@ -164,7 +164,7 @@ int fec_ptp_start(struct fec_ptp_private *priv)
* enable FEC1 timer's slave mode. */
if ((fpp == ptp_private[0]) || !(ptp_private[0]->ptp_active)) {
writel(FEC_T_CTRL_RESTART, fpp->hwp + FEC_ATIME_CTRL);
- writel(FEC_T_INC_40MHZ << FEC_T_INC_OFFSET,
+ writel(FEC_T_INC_CLK << FEC_T_INC_OFFSET,
fpp->hwp + FEC_ATIME_INC);
writel(FEC_T_PERIOD_ONE_SEC, fpp->hwp + FEC_ATIME_EVT_PERIOD);
/* start counter */
@@ -180,7 +180,7 @@ int fec_ptp_start(struct fec_ptp_private *priv)
fpp->prtc = ptp_private[1]->prtc;
writel(FEC_T_CTRL_RESTART,
ptp_private[1]->hwp + FEC_ATIME_CTRL);
- writel(FEC_T_INC_40MHZ << FEC_T_INC_OFFSET,
+ writel(FEC_T_INC_CLK << FEC_T_INC_OFFSET,
ptp_private[1]->hwp + FEC_ATIME_INC);
/* Set the timer as slave mode */
writel(FEC_T_CTRL_SLAVE,
@@ -190,7 +190,7 @@ int fec_ptp_start(struct fec_ptp_private *priv)
}
#endif
} else {
- writel(FEC_T_INC_40MHZ << FEC_T_INC_OFFSET,
+ writel(FEC_T_INC_CLK << FEC_T_INC_OFFSET,
fpp->hwp + FEC_ATIME_INC);
/* Set the timer as slave mode */
writel(FEC_T_CTRL_SLAVE, fpp->hwp + FEC_ATIME_CTRL);
@@ -584,18 +584,18 @@ static void fec_handle_ptpdrift(struct ptp_set_comp *comp,
ptc->corr_inc = 0;
ptc->corr_period = 0;
return;
- } else if (ndrift >= FEC_ATIME_40MHZ) {
- ptc->corr_inc = (u32)(ndrift / FEC_ATIME_40MHZ);
+ } else if (ndrift >= FEC_ATIME_CLK) {
+ ptc->corr_inc = (u32)(ndrift / FEC_ATIME_CLK);
ptc->corr_period = 1;
return;
} else {
tmp_winner = 0xFFFFFFFF;
adj_inc = 1;
- if (ndrift > (FEC_ATIME_40MHZ / FEC_T_INC_40MHZ)) {
- adj_inc = FEC_T_INC_40MHZ / 2;
- } else if (ndrift > (FEC_ATIME_40MHZ / (FEC_T_INC_40MHZ * 4))) {
- adj_inc = FEC_T_INC_40MHZ / 4;
+ if (ndrift > (FEC_ATIME_CLK / FEC_T_INC_CLK)) {
+ adj_inc = FEC_T_INC_CLK / 2;
+ } else if (ndrift > (FEC_ATIME_CLK / (FEC_T_INC_CLK * 4))) {
+ adj_inc = FEC_T_INC_CLK / 4;
adj_period = 2;
} else {
adj_inc = 4;
@@ -603,15 +603,15 @@ static void fec_handle_ptpdrift(struct ptp_set_comp *comp,
}
for (i = 1; i < adj_inc; i++) {
- tmp_current = (FEC_ATIME_40MHZ * i) % ndrift;
+ tmp_current = (FEC_ATIME_CLK * i) % ndrift;
if (tmp_current == 0) {
ptc->corr_inc = i;
- ptc->corr_period = (u32)((FEC_ATIME_40MHZ *
+ ptc->corr_period = (u32)((FEC_ATIME_CLK *
adj_period * i) / ndrift);
break;
} else if (tmp_current < tmp_winner) {
ptc->corr_inc = i;
- ptc->corr_period = (u32)((FEC_ATIME_40MHZ *
+ ptc->corr_period = (u32)((FEC_ATIME_CLK *
adj_period * i) / ndrift);
tmp_winner = tmp_current;
}
@@ -632,9 +632,9 @@ static void fec_set_drift(struct fec_ptp_private *priv,
return;
if (comp->o_ops == TRUE)
- corr_ns = FEC_T_INC_40MHZ + tc.corr_inc;
+ corr_ns = FEC_T_INC_CLK + tc.corr_inc;
else
- corr_ns = FEC_T_INC_40MHZ - tc.corr_inc;
+ corr_ns = FEC_T_INC_CLK - tc.corr_inc;
if (!priv->ptp_slave)
fpp = priv;
diff --git a/drivers/net/fec_1588.h b/drivers/net/fec_1588.h
index e947abdf4a82..8e21519ec45d 100644
--- a/drivers/net/fec_1588.h
+++ b/drivers/net/fec_1588.h
@@ -1,7 +1,7 @@
/*
* drivers/net/fec_1588.h
*
- * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
*
* 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
@@ -42,12 +42,10 @@
#define FEC_T_INC_CORR_OFFSET 8
-#define FEC_T_INC_40MHZ 25
-#define FEC_ATIME_40MHZ 40000000
-/*
-#define FEC_T_INC_40MHZ 15
-#define FEC_ATIME_40MHZ 66000000
-*/
+#define FEC_T_INC_50MHZ 20
+#define FEC_ATIME_50MHZ 50000000
+#define FEC_T_INC_CLK FEC_T_INC_50MHZ
+#define FEC_ATIME_CLK FEC_ATIME_50MHZ
#define FEC_T_PERIOD_ONE_SEC 0x3B9ACA00
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index d1b23067619f..073548836413 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -25,5 +25,6 @@ config ATH_DEBUG
source "drivers/net/wireless/ath/ath5k/Kconfig"
source "drivers/net/wireless/ath/ath9k/Kconfig"
source "drivers/net/wireless/ath/carl9170/Kconfig"
+source "drivers/net/wireless/ath/ath6kl/Kconfig"
endif
diff --git a/drivers/net/wireless/ath/Makefile b/drivers/net/wireless/ath/Makefile
index 0e8f528c81c0..d1214696a35b 100644
--- a/drivers/net/wireless/ath/Makefile
+++ b/drivers/net/wireless/ath/Makefile
@@ -1,6 +1,7 @@
obj-$(CONFIG_ATH5K) += ath5k/
obj-$(CONFIG_ATH9K_HW) += ath9k/
obj-$(CONFIG_CARL9170) += carl9170/
+obj-$(CONFIG_ATH6KL) += ath6kl/
obj-$(CONFIG_ATH_COMMON) += ath.o
diff --git a/drivers/net/wireless/ath/ath6kl/Kconfig b/drivers/net/wireless/ath/ath6kl/Kconfig
new file mode 100644
index 000000000000..fc9f69c1f945
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/Kconfig
@@ -0,0 +1,17 @@
+config ATH6KL
+ tristate "Atheros ath6kl support"
+ depends on MMC
+ depends on CFG80211
+ select WIRELESS_EXT
+ select WEXT_PRIV
+ ---help---
+ This module adds support for wireless adapters based on
+ Atheros AR6003 chipset running over SDIO. If you choose to
+ build it as a module, it will be called ath6kl. Pls note
+ that AR6002 and AR6001 are not supported by this driver.
+
+config ATH6KL_DEBUG
+ bool "Atheros ath6kl debugging"
+ depends on ATH6KL
+ ---help---
+ Enables debug support
diff --git a/drivers/net/wireless/ath/ath6kl/Makefile b/drivers/net/wireless/ath/ath6kl/Makefile
new file mode 100644
index 000000000000..e1bb07ea8e80
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/Makefile
@@ -0,0 +1,35 @@
+#------------------------------------------------------------------------------
+# Copyright (c) 2004-2010 Atheros Communications Inc.
+# 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.
+#
+#
+#
+# Author(s): ="Atheros"
+#------------------------------------------------------------------------------
+
+obj-$(CONFIG_ATH6KL) := ath6kl.o
+ath6kl-y += debug.o
+ath6kl-y += htc_hif.o
+ath6kl-y += htc.o
+ath6kl-y += bmi.o
+ath6kl-y += cfg80211.o
+ath6kl-y += init.o
+ath6kl-y += main.o
+ath6kl-y += txrx.o
+ath6kl-y += wmi.o
+ath6kl-y += node.o
+ath6kl-y += sdio.o
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.c b/drivers/net/wireless/ath/ath6kl/bmi.c
new file mode 100644
index 000000000000..84676697d7eb
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/bmi.c
@@ -0,0 +1,692 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications Inc.
+ *
+ * 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 "core.h"
+#include "hif-ops.h"
+#include "target.h"
+#include "debug.h"
+
+static int ath6kl_get_bmi_cmd_credits(struct ath6kl *ar)
+{
+ u32 addr;
+ unsigned long timeout;
+ int ret;
+
+ ar->bmi.cmd_credits = 0;
+
+ /* Read the counter register to get the command credits */
+ addr = COUNT_DEC_ADDRESS + (HTC_MAILBOX_NUM_MAX + ENDPOINT1) * 4;
+
+ timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
+ while (time_before(jiffies, timeout) && !ar->bmi.cmd_credits) {
+
+ /*
+ * Hit the credit counter with a 4-byte access, the first byte
+ * read will hit the counter and cause a decrement, while the
+ * remaining 3 bytes has no effect. The rationale behind this
+ * is to make all HIF accesses 4-byte aligned.
+ */
+ ret = hif_read_write_sync(ar, addr,
+ (u8 *)&ar->bmi.cmd_credits, 4,
+ HIF_RD_SYNC_BYTE_INC);
+ if (ret) {
+ ath6kl_err("Unable to decrement the command credit count register: %d\n",
+ ret);
+ return ret;
+ }
+
+ /* The counter is only 8 bits.
+ * Ignore anything in the upper 3 bytes
+ */
+ ar->bmi.cmd_credits &= 0xFF;
+ }
+
+ if (!ar->bmi.cmd_credits) {
+ ath6kl_err("bmi communication timeout\n");
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+static int ath6kl_bmi_get_rx_lkahd(struct ath6kl *ar, bool need_timeout)
+{
+ unsigned long timeout;
+ u32 rx_word = 0;
+ int ret = 0;
+
+ timeout = jiffies + msecs_to_jiffies(BMI_COMMUNICATION_TIMEOUT);
+ while ((!need_timeout || time_before(jiffies, timeout)) && !rx_word) {
+ ret = hif_read_write_sync(ar, RX_LOOKAHEAD_VALID_ADDRESS,
+ (u8 *)&rx_word, sizeof(rx_word),
+ HIF_RD_SYNC_BYTE_INC);
+ if (ret) {
+ ath6kl_err("unable to read RX_LOOKAHEAD_VALID\n");
+ return ret;
+ }
+
+ /* all we really want is one bit */
+ rx_word &= (1 << ENDPOINT1);
+ }
+
+ if (!rx_word) {
+ ath6kl_err("bmi_recv_buf FIFO empty\n");
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static int ath6kl_bmi_send_buf(struct ath6kl *ar, u8 *buf, u32 len)
+{
+ int ret;
+ u32 addr;
+
+ ret = ath6kl_get_bmi_cmd_credits(ar);
+ if (ret)
+ return ret;
+
+ addr = ar->mbox_info.htc_addr;
+
+ ret = hif_read_write_sync(ar, addr, buf, len,
+ HIF_WR_SYNC_BYTE_INC);
+ if (ret)
+ ath6kl_err("unable to send the bmi data to the device\n");
+
+ return ret;
+}
+
+static int ath6kl_bmi_recv_buf(struct ath6kl *ar,
+ u8 *buf, u32 len, bool want_timeout)
+{
+ int ret;
+ u32 addr;
+
+ /*
+ * During normal bootup, small reads may be required.
+ * Rather than issue an HIF Read and then wait as the Target
+ * adds successive bytes to the FIFO, we wait here until
+ * we know that response data is available.
+ *
+ * This allows us to cleanly timeout on an unexpected
+ * Target failure rather than risk problems at the HIF level.
+ * In particular, this avoids SDIO timeouts and possibly garbage
+ * data on some host controllers. And on an interconnect
+ * such as Compact Flash (as well as some SDIO masters) which
+ * does not provide any indication on data timeout, it avoids
+ * a potential hang or garbage response.
+ *
+ * Synchronization is more difficult for reads larger than the
+ * size of the MBOX FIFO (128B), because the Target is unable
+ * to push the 129th byte of data until AFTER the Host posts an
+ * HIF Read and removes some FIFO data. So for large reads the
+ * Host proceeds to post an HIF Read BEFORE all the data is
+ * actually available to read. Fortunately, large BMI reads do
+ * not occur in practice -- they're supported for debug/development.
+ *
+ * So Host/Target BMI synchronization is divided into these cases:
+ * CASE 1: length < 4
+ * Should not happen
+ *
+ * CASE 2: 4 <= length <= 128
+ * Wait for first 4 bytes to be in FIFO
+ * If CONSERVATIVE_BMI_READ is enabled, also wait for
+ * a BMI command credit, which indicates that the ENTIRE
+ * response is available in the the FIFO
+ *
+ * CASE 3: length > 128
+ * Wait for the first 4 bytes to be in FIFO
+ *
+ * For most uses, a small timeout should be sufficient and we will
+ * usually see a response quickly; but there may be some unusual
+ * (debug) cases of BMI_EXECUTE where we want an larger timeout.
+ * For now, we use an unbounded busy loop while waiting for
+ * BMI_EXECUTE.
+ *
+ * If BMI_EXECUTE ever needs to support longer-latency execution,
+ * especially in production, this code needs to be enhanced to sleep
+ * and yield. Also note that BMI_COMMUNICATION_TIMEOUT is currently
+ * a function of Host processor speed.
+ */
+ if (len >= 4) { /* NB: Currently, always true */
+ ret = ath6kl_bmi_get_rx_lkahd(ar, want_timeout);
+ if (ret)
+ return ret;
+ }
+
+ addr = ar->mbox_info.htc_addr;
+ ret = hif_read_write_sync(ar, addr, buf, len,
+ HIF_RD_SYNC_BYTE_INC);
+ if (ret) {
+ ath6kl_err("Unable to read the bmi data from the device: %d\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int ath6kl_bmi_done(struct ath6kl *ar)
+{
+ int ret;
+ u32 cid = BMI_DONE;
+
+ if (ar->bmi.done_sent) {
+ ath6kl_dbg(ATH6KL_DBG_BMI, "bmi done skipped\n");
+ return 0;
+ }
+
+ ar->bmi.done_sent = true;
+
+ ret = ath6kl_bmi_send_buf(ar, (u8 *)&cid, sizeof(cid));
+ if (ret) {
+ ath6kl_err("Unable to send bmi done: %d\n", ret);
+ return ret;
+ }
+
+ ath6kl_bmi_cleanup(ar);
+
+ return 0;
+}
+
+int ath6kl_bmi_get_target_info(struct ath6kl *ar,
+ struct ath6kl_bmi_target_info *targ_info)
+{
+ int ret;
+ u32 cid = BMI_GET_TARGET_INFO;
+
+ if (ar->bmi.done_sent) {
+ ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+ return -EACCES;
+ }
+
+ ret = ath6kl_bmi_send_buf(ar, (u8 *)&cid, sizeof(cid));
+ if (ret) {
+ ath6kl_err("Unable to send get target info: %d\n", ret);
+ return ret;
+ }
+
+ ret = ath6kl_bmi_recv_buf(ar, (u8 *)&targ_info->version,
+ sizeof(targ_info->version), true);
+ if (ret) {
+ ath6kl_err("Unable to recv target info: %d\n", ret);
+ return ret;
+ }
+
+ if (le32_to_cpu(targ_info->version) == TARGET_VERSION_SENTINAL) {
+ /* Determine how many bytes are in the Target's targ_info */
+ ret = ath6kl_bmi_recv_buf(ar,
+ (u8 *)&targ_info->byte_count,
+ sizeof(targ_info->byte_count),
+ true);
+ if (ret) {
+ ath6kl_err("unable to read target info byte count: %d\n",
+ ret);
+ return ret;
+ }
+
+ /*
+ * The target's targ_info doesn't match the host's targ_info.
+ * We need to do some backwards compatibility to make this work.
+ */
+ if (le32_to_cpu(targ_info->byte_count) != sizeof(*targ_info)) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ /* Read the remainder of the targ_info */
+ ret = ath6kl_bmi_recv_buf(ar,
+ ((u8 *)targ_info) +
+ sizeof(targ_info->byte_count),
+ sizeof(*targ_info) -
+ sizeof(targ_info->byte_count),
+ true);
+
+ if (ret) {
+ ath6kl_err("Unable to read target info (%d bytes): %d\n",
+ targ_info->byte_count, ret);
+ return ret;
+ }
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_BMI, "target info (ver: 0x%x type: 0x%x)\n",
+ targ_info->version, targ_info->type);
+
+ return 0;
+}
+
+int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
+{
+ u32 cid = BMI_READ_MEMORY;
+ int ret;
+ u32 offset;
+ u32 len_remain, rx_len;
+ u16 size;
+
+ if (ar->bmi.done_sent) {
+ ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+ return -EACCES;
+ }
+
+ size = BMI_DATASZ_MAX + sizeof(cid) + sizeof(addr) + sizeof(len);
+ if (size > MAX_BMI_CMDBUF_SZ) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ memset(ar->bmi.cmd_buf, 0, size);
+
+ ath6kl_dbg(ATH6KL_DBG_BMI,
+ "bmi read memory: device: addr: 0x%x, len: %d\n",
+ addr, len);
+
+ len_remain = len;
+
+ while (len_remain) {
+ rx_len = (len_remain < BMI_DATASZ_MAX) ?
+ len_remain : BMI_DATASZ_MAX;
+ offset = 0;
+ memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
+ offset += sizeof(addr);
+ memcpy(&(ar->bmi.cmd_buf[offset]), &rx_len, sizeof(rx_len));
+ offset += sizeof(len);
+
+ ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
+ if (ret) {
+ ath6kl_err("Unable to write to the device: %d\n",
+ ret);
+ return ret;
+ }
+ ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, rx_len, true);
+ if (ret) {
+ ath6kl_err("Unable to read from the device: %d\n",
+ ret);
+ return ret;
+ }
+ memcpy(&buf[len - len_remain], ar->bmi.cmd_buf, rx_len);
+ len_remain -= rx_len; addr += rx_len;
+ }
+
+ return 0;
+}
+
+int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
+{
+ u32 cid = BMI_WRITE_MEMORY;
+ int ret;
+ u32 offset;
+ u32 len_remain, tx_len;
+ const u32 header = sizeof(cid) + sizeof(addr) + sizeof(len);
+ u8 aligned_buf[BMI_DATASZ_MAX];
+ u8 *src;
+
+ if (ar->bmi.done_sent) {
+ ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+ return -EACCES;
+ }
+
+ if ((BMI_DATASZ_MAX + header) > MAX_BMI_CMDBUF_SZ) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ memset(ar->bmi.cmd_buf, 0, BMI_DATASZ_MAX + header);
+
+ ath6kl_dbg(ATH6KL_DBG_BMI,
+ "bmi write memory: addr: 0x%x, len: %d\n", addr, len);
+
+ len_remain = len;
+ while (len_remain) {
+ src = &buf[len - len_remain];
+
+ if (len_remain < (BMI_DATASZ_MAX - header)) {
+ if (len_remain & 3) {
+ /* align it with 4 bytes */
+ len_remain = len_remain +
+ (4 - (len_remain & 3));
+ memcpy(aligned_buf, src, len_remain);
+ src = aligned_buf;
+ }
+ tx_len = len_remain;
+ } else {
+ tx_len = (BMI_DATASZ_MAX - header);
+ }
+
+ offset = 0;
+ memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
+ offset += sizeof(addr);
+ memcpy(&(ar->bmi.cmd_buf[offset]), &tx_len, sizeof(tx_len));
+ offset += sizeof(tx_len);
+ memcpy(&(ar->bmi.cmd_buf[offset]), src, tx_len);
+ offset += tx_len;
+
+ ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
+ if (ret) {
+ ath6kl_err("Unable to write to the device: %d\n",
+ ret);
+ return ret;
+ }
+ len_remain -= tx_len; addr += tx_len;
+ }
+
+ return 0;
+}
+
+int ath6kl_bmi_execute(struct ath6kl *ar, u32 addr, u32 *param)
+{
+ u32 cid = BMI_EXECUTE;
+ int ret;
+ u32 offset;
+ u16 size;
+
+ if (ar->bmi.done_sent) {
+ ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+ return -EACCES;
+ }
+
+ size = sizeof(cid) + sizeof(addr) + sizeof(param);
+ if (size > MAX_BMI_CMDBUF_SZ) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ memset(ar->bmi.cmd_buf, 0, size);
+
+ ath6kl_dbg(ATH6KL_DBG_BMI, "bmi execute: addr: 0x%x, param: %d)\n",
+ addr, *param);
+
+ offset = 0;
+ memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
+ offset += sizeof(addr);
+ memcpy(&(ar->bmi.cmd_buf[offset]), param, sizeof(*param));
+ offset += sizeof(*param);
+
+ ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
+ if (ret) {
+ ath6kl_err("Unable to write to the device: %d\n", ret);
+ return ret;
+ }
+
+ ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param), false);
+ if (ret) {
+ ath6kl_err("Unable to read from the device: %d\n", ret);
+ return ret;
+ }
+
+ memcpy(param, ar->bmi.cmd_buf, sizeof(*param));
+
+ return 0;
+}
+
+int ath6kl_bmi_set_app_start(struct ath6kl *ar, u32 addr)
+{
+ u32 cid = BMI_SET_APP_START;
+ int ret;
+ u32 offset;
+ u16 size;
+
+ if (ar->bmi.done_sent) {
+ ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+ return -EACCES;
+ }
+
+ size = sizeof(cid) + sizeof(addr);
+ if (size > MAX_BMI_CMDBUF_SZ) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ memset(ar->bmi.cmd_buf, 0, size);
+
+ ath6kl_dbg(ATH6KL_DBG_BMI, "bmi set app start: addr: 0x%x\n", addr);
+
+ offset = 0;
+ memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
+ offset += sizeof(addr);
+
+ ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
+ if (ret) {
+ ath6kl_err("Unable to write to the device: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param)
+{
+ u32 cid = BMI_READ_SOC_REGISTER;
+ int ret;
+ u32 offset;
+ u16 size;
+
+ if (ar->bmi.done_sent) {
+ ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+ return -EACCES;
+ }
+
+ size = sizeof(cid) + sizeof(addr);
+ if (size > MAX_BMI_CMDBUF_SZ) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ memset(ar->bmi.cmd_buf, 0, size);
+
+ ath6kl_dbg(ATH6KL_DBG_BMI, "bmi read SOC reg: addr: 0x%x\n", addr);
+
+ offset = 0;
+ memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
+ offset += sizeof(addr);
+
+ ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
+ if (ret) {
+ ath6kl_err("Unable to write to the device: %d\n", ret);
+ return ret;
+ }
+
+ ret = ath6kl_bmi_recv_buf(ar, ar->bmi.cmd_buf, sizeof(*param), true);
+ if (ret) {
+ ath6kl_err("Unable to read from the device: %d\n", ret);
+ return ret;
+ }
+ memcpy(param, ar->bmi.cmd_buf, sizeof(*param));
+
+ return 0;
+}
+
+int ath6kl_bmi_reg_write(struct ath6kl *ar, u32 addr, u32 param)
+{
+ u32 cid = BMI_WRITE_SOC_REGISTER;
+ int ret;
+ u32 offset;
+ u16 size;
+
+ if (ar->bmi.done_sent) {
+ ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+ return -EACCES;
+ }
+
+ size = sizeof(cid) + sizeof(addr) + sizeof(param);
+ if (size > MAX_BMI_CMDBUF_SZ) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ memset(ar->bmi.cmd_buf, 0, size);
+
+ ath6kl_dbg(ATH6KL_DBG_BMI,
+ "bmi write SOC reg: addr: 0x%x, param: %d\n",
+ addr, param);
+
+ offset = 0;
+ memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
+ offset += sizeof(addr);
+ memcpy(&(ar->bmi.cmd_buf[offset]), &param, sizeof(param));
+ offset += sizeof(param);
+
+ ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
+ if (ret) {
+ ath6kl_err("Unable to write to the device: %d\n", ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int ath6kl_bmi_lz_data(struct ath6kl *ar, u8 *buf, u32 len)
+{
+ u32 cid = BMI_LZ_DATA;
+ int ret;
+ u32 offset;
+ u32 len_remain, tx_len;
+ const u32 header = sizeof(cid) + sizeof(len);
+ u16 size;
+
+ if (ar->bmi.done_sent) {
+ ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+ return -EACCES;
+ }
+
+ size = BMI_DATASZ_MAX + header;
+ if (size > MAX_BMI_CMDBUF_SZ) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ memset(ar->bmi.cmd_buf, 0, size);
+
+ ath6kl_dbg(ATH6KL_DBG_BMI, "bmi send LZ data: len: %d)\n",
+ len);
+
+ len_remain = len;
+ while (len_remain) {
+ tx_len = (len_remain < (BMI_DATASZ_MAX - header)) ?
+ len_remain : (BMI_DATASZ_MAX - header);
+
+ offset = 0;
+ memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ memcpy(&(ar->bmi.cmd_buf[offset]), &tx_len, sizeof(tx_len));
+ offset += sizeof(tx_len);
+ memcpy(&(ar->bmi.cmd_buf[offset]), &buf[len - len_remain],
+ tx_len);
+ offset += tx_len;
+
+ ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
+ if (ret) {
+ ath6kl_err("Unable to write to the device: %d\n",
+ ret);
+ return ret;
+ }
+
+ len_remain -= tx_len;
+ }
+
+ return 0;
+}
+
+int ath6kl_bmi_lz_stream_start(struct ath6kl *ar, u32 addr)
+{
+ u32 cid = BMI_LZ_STREAM_START;
+ int ret;
+ u32 offset;
+ u16 size;
+
+ if (ar->bmi.done_sent) {
+ ath6kl_err("bmi done sent already, cmd %d disallowed\n", cid);
+ return -EACCES;
+ }
+
+ size = sizeof(cid) + sizeof(addr);
+ if (size > MAX_BMI_CMDBUF_SZ) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+ memset(ar->bmi.cmd_buf, 0, size);
+
+ ath6kl_dbg(ATH6KL_DBG_BMI,
+ "bmi LZ stream start: addr: 0x%x)\n",
+ addr);
+
+ offset = 0;
+ memcpy(&(ar->bmi.cmd_buf[offset]), &cid, sizeof(cid));
+ offset += sizeof(cid);
+ memcpy(&(ar->bmi.cmd_buf[offset]), &addr, sizeof(addr));
+ offset += sizeof(addr);
+
+ ret = ath6kl_bmi_send_buf(ar, ar->bmi.cmd_buf, offset);
+ if (ret) {
+ ath6kl_err("Unable to start LZ stream to the device: %d\n",
+ ret);
+ return ret;
+ }
+
+ return 0;
+}
+
+int ath6kl_bmi_fast_download(struct ath6kl *ar, u32 addr, u8 *buf, u32 len)
+{
+ int ret;
+ u32 last_word = 0;
+ u32 last_word_offset = len & ~0x3;
+ u32 unaligned_bytes = len & 0x3;
+
+ ret = ath6kl_bmi_lz_stream_start(ar, addr);
+ if (ret)
+ return ret;
+
+ if (unaligned_bytes) {
+ /* copy the last word into a zero padded buffer */
+ memcpy(&last_word, &buf[last_word_offset], unaligned_bytes);
+ }
+
+ ret = ath6kl_bmi_lz_data(ar, buf, last_word_offset);
+ if (ret)
+ return ret;
+
+ if (unaligned_bytes)
+ ret = ath6kl_bmi_lz_data(ar, (u8 *)&last_word, 4);
+
+ if (!ret) {
+ /* Close compressed stream and open a new (fake) one.
+ * This serves mainly to flush Target caches. */
+ ret = ath6kl_bmi_lz_stream_start(ar, 0x00);
+ }
+ return ret;
+}
+
+int ath6kl_bmi_init(struct ath6kl *ar)
+{
+ ar->bmi.cmd_buf = kzalloc(MAX_BMI_CMDBUF_SZ, GFP_ATOMIC);
+
+ if (!ar->bmi.cmd_buf)
+ return -ENOMEM;
+
+ return 0;
+}
+
+void ath6kl_bmi_cleanup(struct ath6kl *ar)
+{
+ kfree(ar->bmi.cmd_buf);
+ ar->bmi.cmd_buf = NULL;
+}
diff --git a/drivers/net/wireless/ath/ath6kl/bmi.h b/drivers/net/wireless/ath/ath6kl/bmi.h
new file mode 100644
index 000000000000..83546d76d979
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/bmi.h
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications Inc.
+ *
+ * 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.
+ */
+
+#ifndef BMI_H
+#define BMI_H
+
+/*
+ * Bootloader Messaging Interface (BMI)
+ *
+ * BMI is a very simple messaging interface used during initialization
+ * to read memory, write memory, execute code, and to define an
+ * application entry PC.
+ *
+ * It is used to download an application to ATH6KL, to provide
+ * patches to code that is already resident on ATH6KL, and generally
+ * to examine and modify state. The Host has an opportunity to use
+ * BMI only once during bootup. Once the Host issues a BMI_DONE
+ * command, this opportunity ends.
+ *
+ * The Host writes BMI requests to mailbox0, and reads BMI responses
+ * from mailbox0. BMI requests all begin with a command
+ * (see below for specific commands), and are followed by
+ * command-specific data.
+ *
+ * Flow control:
+ * The Host can only issue a command once the Target gives it a
+ * "BMI Command Credit", using ATH6KL Counter #4. As soon as the
+ * Target has completed a command, it issues another BMI Command
+ * Credit (so the Host can issue the next command).
+ *
+ * BMI handles all required Target-side cache flushing.
+ */
+
+#define MAX_BMI_CMDBUF_SZ (BMI_DATASZ_MAX + \
+ (sizeof(u32) * 3 /* cmd + addr + len */))
+
+/* Maximum data size used for BMI transfers */
+#define BMI_DATASZ_MAX 256
+
+/* BMI Commands */
+
+#define BMI_NO_COMMAND 0
+
+#define BMI_DONE 1
+/*
+ * Semantics: Host is done using BMI
+ * Request format:
+ * u32 command (BMI_DONE)
+ * Response format: none
+ */
+
+#define BMI_READ_MEMORY 2
+/*
+ * Semantics: Host reads ATH6KL memory
+ * Request format:
+ * u32 command (BMI_READ_MEMORY)
+ * u32 address
+ * u32 length, at most BMI_DATASZ_MAX
+ * Response format:
+ * u8 data[length]
+ */
+
+#define BMI_WRITE_MEMORY 3
+/*
+ * Semantics: Host writes ATH6KL memory
+ * Request format:
+ * u32 command (BMI_WRITE_MEMORY)
+ * u32 address
+ * u32 length, at most BMI_DATASZ_MAX
+ * u8 data[length]
+ * Response format: none
+ */
+
+#define BMI_EXECUTE 4
+/*
+ * Semantics: Causes ATH6KL to execute code
+ * Request format:
+ * u32 command (BMI_EXECUTE)
+ * u32 address
+ * u32 parameter
+ * Response format:
+ * u32 return value
+ */
+
+#define BMI_SET_APP_START 5
+/*
+ * Semantics: Set Target application starting address
+ * Request format:
+ * u32 command (BMI_SET_APP_START)
+ * u32 address
+ * Response format: none
+ */
+
+#define BMI_READ_SOC_REGISTER 6
+/*
+ * Semantics: Read a 32-bit Target SOC register.
+ * Request format:
+ * u32 command (BMI_READ_REGISTER)
+ * u32 address
+ * Response format:
+ * u32 value
+ */
+
+#define BMI_WRITE_SOC_REGISTER 7
+/*
+ * Semantics: Write a 32-bit Target SOC register.
+ * Request format:
+ * u32 command (BMI_WRITE_REGISTER)
+ * u32 address
+ * u32 value
+ *
+ * Response format: none
+ */
+
+#define BMI_GET_TARGET_ID 8
+#define BMI_GET_TARGET_INFO 8
+/*
+ * Semantics: Fetch the 4-byte Target information
+ * Request format:
+ * u32 command (BMI_GET_TARGET_ID/INFO)
+ * Response format1 (old firmware):
+ * u32 TargetVersionID
+ * Response format2 (newer firmware):
+ * u32 TARGET_VERSION_SENTINAL
+ * struct bmi_target_info;
+ */
+
+#define TARGET_VERSION_SENTINAL 0xffffffff
+#define TARGET_TYPE_AR6003 3
+
+#define BMI_ROMPATCH_INSTALL 9
+/*
+ * Semantics: Install a ROM Patch.
+ * Request format:
+ * u32 command (BMI_ROMPATCH_INSTALL)
+ * u32 Target ROM Address
+ * u32 Target RAM Address or Value (depending on Target Type)
+ * u32 Size, in bytes
+ * u32 Activate? 1-->activate;
+ * 0-->install but do not activate
+ * Response format:
+ * u32 PatchID
+ */
+
+#define BMI_ROMPATCH_UNINSTALL 10
+/*
+ * Semantics: Uninstall a previously-installed ROM Patch,
+ * automatically deactivating, if necessary.
+ * Request format:
+ * u32 command (BMI_ROMPATCH_UNINSTALL)
+ * u32 PatchID
+ *
+ * Response format: none
+ */
+
+#define BMI_ROMPATCH_ACTIVATE 11
+/*
+ * Semantics: Activate a list of previously-installed ROM Patches.
+ * Request format:
+ * u32 command (BMI_ROMPATCH_ACTIVATE)
+ * u32 rompatch_count
+ * u32 PatchID[rompatch_count]
+ *
+ * Response format: none
+ */
+
+#define BMI_ROMPATCH_DEACTIVATE 12
+/*
+ * Semantics: Deactivate a list of active ROM Patches.
+ * Request format:
+ * u32 command (BMI_ROMPATCH_DEACTIVATE)
+ * u32 rompatch_count
+ * u32 PatchID[rompatch_count]
+ *
+ * Response format: none
+ */
+
+
+#define BMI_LZ_STREAM_START 13
+/*
+ * Semantics: Begin an LZ-compressed stream of input
+ * which is to be uncompressed by the Target to an
+ * output buffer at address. The output buffer must
+ * be sufficiently large to hold the uncompressed
+ * output from the compressed input stream. This BMI
+ * command should be followed by a series of 1 or more
+ * BMI_LZ_DATA commands.
+ * u32 command (BMI_LZ_STREAM_START)
+ * u32 address
+ * Note: Not supported on all versions of ROM firmware.
+ */
+
+#define BMI_LZ_DATA 14
+/*
+ * Semantics: Host writes ATH6KL memory with LZ-compressed
+ * data which is uncompressed by the Target. This command
+ * must be preceded by a BMI_LZ_STREAM_START command. A series
+ * of BMI_LZ_DATA commands are considered part of a single
+ * input stream until another BMI_LZ_STREAM_START is issued.
+ * Request format:
+ * u32 command (BMI_LZ_DATA)
+ * u32 length (of compressed data),
+ * at most BMI_DATASZ_MAX
+ * u8 CompressedData[length]
+ * Response format: none
+ * Note: Not supported on all versions of ROM firmware.
+ */
+
+#define BMI_COMMUNICATION_TIMEOUT 1000 /* in msec */
+
+struct ath6kl;
+struct ath6kl_bmi_target_info {
+ __le32 byte_count; /* size of this structure */
+ __le32 version; /* target version id */
+ __le32 type; /* target type */
+} __packed;
+
+int ath6kl_bmi_init(struct ath6kl *ar);
+void ath6kl_bmi_cleanup(struct ath6kl *ar);
+int ath6kl_bmi_done(struct ath6kl *ar);
+int ath6kl_bmi_get_target_info(struct ath6kl *ar,
+ struct ath6kl_bmi_target_info *targ_info);
+int ath6kl_bmi_read(struct ath6kl *ar, u32 addr, u8 *buf, u32 len);
+int ath6kl_bmi_write(struct ath6kl *ar, u32 addr, u8 *buf, u32 len);
+int ath6kl_bmi_execute(struct ath6kl *ar,
+ u32 addr, u32 *param);
+int ath6kl_bmi_set_app_start(struct ath6kl *ar,
+ u32 addr);
+int ath6kl_bmi_reg_read(struct ath6kl *ar, u32 addr, u32 *param);
+int ath6kl_bmi_reg_write(struct ath6kl *ar, u32 addr, u32 param);
+int ath6kl_bmi_lz_data(struct ath6kl *ar,
+ u8 *buf, u32 len);
+int ath6kl_bmi_lz_stream_start(struct ath6kl *ar,
+ u32 addr);
+int ath6kl_bmi_fast_download(struct ath6kl *ar,
+ u32 addr, u8 *buf, u32 len);
+#endif
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.c b/drivers/net/wireless/ath/ath6kl/cfg80211.c
new file mode 100644
index 000000000000..4284a41ff775
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.c
@@ -0,0 +1,1538 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications Inc.
+ *
+ * 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 "core.h"
+#include "cfg80211.h"
+#include "debug.h"
+
+#define RATETAB_ENT(_rate, _rateid, _flags) { \
+ .bitrate = (_rate), \
+ .flags = (_flags), \
+ .hw_value = (_rateid), \
+}
+
+#define CHAN2G(_channel, _freq, _flags) { \
+ .band = IEEE80211_BAND_2GHZ, \
+ .hw_value = (_channel), \
+ .center_freq = (_freq), \
+ .flags = (_flags), \
+ .max_antenna_gain = 0, \
+ .max_power = 30, \
+}
+
+#define CHAN5G(_channel, _flags) { \
+ .band = IEEE80211_BAND_5GHZ, \
+ .hw_value = (_channel), \
+ .center_freq = 5000 + (5 * (_channel)), \
+ .flags = (_flags), \
+ .max_antenna_gain = 0, \
+ .max_power = 30, \
+}
+
+static struct ieee80211_rate ath6kl_rates[] = {
+ RATETAB_ENT(10, 0x1, 0),
+ RATETAB_ENT(20, 0x2, 0),
+ RATETAB_ENT(55, 0x4, 0),
+ RATETAB_ENT(110, 0x8, 0),
+ RATETAB_ENT(60, 0x10, 0),
+ RATETAB_ENT(90, 0x20, 0),
+ RATETAB_ENT(120, 0x40, 0),
+ RATETAB_ENT(180, 0x80, 0),
+ RATETAB_ENT(240, 0x100, 0),
+ RATETAB_ENT(360, 0x200, 0),
+ RATETAB_ENT(480, 0x400, 0),
+ RATETAB_ENT(540, 0x800, 0),
+};
+
+#define ath6kl_a_rates (ath6kl_rates + 4)
+#define ath6kl_a_rates_size 8
+#define ath6kl_g_rates (ath6kl_rates + 0)
+#define ath6kl_g_rates_size 12
+
+static struct ieee80211_channel ath6kl_2ghz_channels[] = {
+ CHAN2G(1, 2412, 0),
+ CHAN2G(2, 2417, 0),
+ CHAN2G(3, 2422, 0),
+ CHAN2G(4, 2427, 0),
+ CHAN2G(5, 2432, 0),
+ CHAN2G(6, 2437, 0),
+ CHAN2G(7, 2442, 0),
+ CHAN2G(8, 2447, 0),
+ CHAN2G(9, 2452, 0),
+ CHAN2G(10, 2457, 0),
+ CHAN2G(11, 2462, 0),
+ CHAN2G(12, 2467, 0),
+ CHAN2G(13, 2472, 0),
+ CHAN2G(14, 2484, 0),
+};
+
+static struct ieee80211_channel ath6kl_5ghz_a_channels[] = {
+ CHAN5G(34, 0), CHAN5G(36, 0),
+ CHAN5G(38, 0), CHAN5G(40, 0),
+ CHAN5G(42, 0), CHAN5G(44, 0),
+ CHAN5G(46, 0), CHAN5G(48, 0),
+ CHAN5G(52, 0), CHAN5G(56, 0),
+ CHAN5G(60, 0), CHAN5G(64, 0),
+ CHAN5G(100, 0), CHAN5G(104, 0),
+ CHAN5G(108, 0), CHAN5G(112, 0),
+ CHAN5G(116, 0), CHAN5G(120, 0),
+ CHAN5G(124, 0), CHAN5G(128, 0),
+ CHAN5G(132, 0), CHAN5G(136, 0),
+ CHAN5G(140, 0), CHAN5G(149, 0),
+ CHAN5G(153, 0), CHAN5G(157, 0),
+ CHAN5G(161, 0), CHAN5G(165, 0),
+ CHAN5G(184, 0), CHAN5G(188, 0),
+ CHAN5G(192, 0), CHAN5G(196, 0),
+ CHAN5G(200, 0), CHAN5G(204, 0),
+ CHAN5G(208, 0), CHAN5G(212, 0),
+ CHAN5G(216, 0),
+};
+
+static struct ieee80211_supported_band ath6kl_band_2ghz = {
+ .n_channels = ARRAY_SIZE(ath6kl_2ghz_channels),
+ .channels = ath6kl_2ghz_channels,
+ .n_bitrates = ath6kl_g_rates_size,
+ .bitrates = ath6kl_g_rates,
+};
+
+static struct ieee80211_supported_band ath6kl_band_5ghz = {
+ .n_channels = ARRAY_SIZE(ath6kl_5ghz_a_channels),
+ .channels = ath6kl_5ghz_a_channels,
+ .n_bitrates = ath6kl_a_rates_size,
+ .bitrates = ath6kl_a_rates,
+};
+
+static int ath6kl_set_wpa_version(struct ath6kl *ar,
+ enum nl80211_wpa_versions wpa_version)
+{
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
+
+ if (!wpa_version) {
+ ar->auth_mode = NONE_AUTH;
+ } else if (wpa_version & NL80211_WPA_VERSION_2) {
+ ar->auth_mode = WPA2_AUTH;
+ } else if (wpa_version & NL80211_WPA_VERSION_1) {
+ ar->auth_mode = WPA_AUTH;
+ } else {
+ ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
+ return -ENOTSUPP;
+ }
+
+ return 0;
+}
+
+static int ath6kl_set_auth_type(struct ath6kl *ar,
+ enum nl80211_auth_type auth_type)
+{
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
+
+ switch (auth_type) {
+ case NL80211_AUTHTYPE_OPEN_SYSTEM:
+ ar->dot11_auth_mode = OPEN_AUTH;
+ break;
+ case NL80211_AUTHTYPE_SHARED_KEY:
+ ar->dot11_auth_mode = SHARED_AUTH;
+ break;
+ case NL80211_AUTHTYPE_NETWORK_EAP:
+ ar->dot11_auth_mode = LEAP_AUTH;
+ break;
+
+ case NL80211_AUTHTYPE_AUTOMATIC:
+ ar->dot11_auth_mode = OPEN_AUTH;
+ ar->auto_auth_stage = AUTH_OPEN_IN_PROGRESS;
+ break;
+
+ default:
+ ath6kl_err("%s: 0x%x not spported\n", __func__, auth_type);
+ return -ENOTSUPP;
+ }
+
+ return 0;
+}
+
+static int ath6kl_set_cipher(struct ath6kl *ar, u32 cipher, bool ucast)
+{
+ u8 *ar_cipher = ucast ? &ar->prwise_crypto : &ar->grp_crypto;
+ u8 *ar_cipher_len = ucast ? &ar->prwise_crypto_len : &ar->grp_crpto_len;
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
+ __func__, cipher, ucast);
+
+ switch (cipher) {
+ case 0:
+ /* our own hack to use value 0 as no crypto used */
+ *ar_cipher = NONE_CRYPT;
+ *ar_cipher_len = 0;
+ break;
+ case WLAN_CIPHER_SUITE_WEP40:
+ *ar_cipher = WEP_CRYPT;
+ *ar_cipher_len = 5;
+ break;
+ case WLAN_CIPHER_SUITE_WEP104:
+ *ar_cipher = WEP_CRYPT;
+ *ar_cipher_len = 13;
+ break;
+ case WLAN_CIPHER_SUITE_TKIP:
+ *ar_cipher = TKIP_CRYPT;
+ *ar_cipher_len = 0;
+ break;
+ case WLAN_CIPHER_SUITE_CCMP:
+ *ar_cipher = AES_CRYPT;
+ *ar_cipher_len = 0;
+ break;
+ default:
+ ath6kl_err("cipher 0x%x not supported\n", cipher);
+ return -ENOTSUPP;
+ }
+
+ return 0;
+}
+
+static void ath6kl_set_key_mgmt(struct ath6kl *ar, u32 key_mgmt)
+{
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
+
+ if (key_mgmt == WLAN_AKM_SUITE_PSK) {
+ if (ar->auth_mode == WPA_AUTH)
+ ar->auth_mode = WPA_PSK_AUTH;
+ else if (ar->auth_mode == WPA2_AUTH)
+ ar->auth_mode = WPA2_PSK_AUTH;
+ } else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
+ ar->auth_mode = NONE_AUTH;
+ }
+}
+
+static bool ath6kl_cfg80211_ready(struct ath6kl *ar)
+{
+ if (!test_bit(WMI_READY, &ar->flag)) {
+ ath6kl_err("wmi is not ready\n");
+ return false;
+ }
+
+ if (ar->wlan_state == WLAN_DISABLED) {
+ ath6kl_err("wlan disabled\n");
+ return false;
+ }
+
+ return true;
+}
+
+static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
+ struct cfg80211_connect_params *sme)
+{
+ struct ath6kl *ar = ath6kl_priv(dev);
+ int status;
+
+ ar->sme_state = SME_CONNECTING;
+
+ if (!ath6kl_cfg80211_ready(ar))
+ return -EIO;
+
+ if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
+ ath6kl_err("destroy in progress\n");
+ return -EBUSY;
+ }
+
+ if (test_bit(SKIP_SCAN, &ar->flag) &&
+ ((sme->channel && sme->channel->center_freq == 0) ||
+ (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
+ ath6kl_err("SkipScan: channel or bssid invalid\n");
+ return -EINVAL;
+ }
+
+ if (down_interruptible(&ar->sem)) {
+ ath6kl_err("busy, couldn't get access\n");
+ return -ERESTARTSYS;
+ }
+
+ if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
+ ath6kl_err("busy, destroy in progress\n");
+ up(&ar->sem);
+ return -EBUSY;
+ }
+
+ if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
+ /*
+ * sleep until the command queue drains
+ */
+ wait_event_interruptible_timeout(ar->event_wq,
+ ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0,
+ WMI_TIMEOUT);
+ if (signal_pending(current)) {
+ ath6kl_err("cmd queue drain timeout\n");
+ up(&ar->sem);
+ return -EINTR;
+ }
+ }
+
+ if (test_bit(CONNECTED, &ar->flag) &&
+ ar->ssid_len == sme->ssid_len &&
+ !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) {
+ ar->reconnect_flag = true;
+ status = ath6kl_wmi_reconnect_cmd(ar->wmi, ar->req_bssid,
+ ar->ch_hint);
+
+ up(&ar->sem);
+ if (status) {
+ ath6kl_err("wmi_reconnect_cmd failed\n");
+ return -EIO;
+ }
+ return 0;
+ } else if (ar->ssid_len == sme->ssid_len &&
+ !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) {
+ ath6kl_disconnect(ar);
+ }
+
+ memset(ar->ssid, 0, sizeof(ar->ssid));
+ ar->ssid_len = sme->ssid_len;
+ memcpy(ar->ssid, sme->ssid, sme->ssid_len);
+
+ if (sme->channel)
+ ar->ch_hint = sme->channel->center_freq;
+
+ memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
+ if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
+ memcpy(ar->req_bssid, sme->bssid, sizeof(ar->req_bssid));
+
+ ath6kl_set_wpa_version(ar, sme->crypto.wpa_versions);
+
+ status = ath6kl_set_auth_type(ar, sme->auth_type);
+ if (status) {
+ up(&ar->sem);
+ return status;
+ }
+
+ if (sme->crypto.n_ciphers_pairwise)
+ ath6kl_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
+ else
+ ath6kl_set_cipher(ar, 0, true);
+
+ ath6kl_set_cipher(ar, sme->crypto.cipher_group, false);
+
+ if (sme->crypto.n_akm_suites)
+ ath6kl_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
+
+ if ((sme->key_len) &&
+ (ar->auth_mode == NONE_AUTH) && (ar->prwise_crypto == WEP_CRYPT)) {
+ struct ath6kl_key *key = NULL;
+
+ if (sme->key_idx < WMI_MIN_KEY_INDEX ||
+ sme->key_idx > WMI_MAX_KEY_INDEX) {
+ ath6kl_err("key index %d out of bounds\n",
+ sme->key_idx);
+ up(&ar->sem);
+ return -ENOENT;
+ }
+
+ key = &ar->keys[sme->key_idx];
+ key->key_len = sme->key_len;
+ memcpy(key->key, sme->key, key->key_len);
+ key->cipher = ar->prwise_crypto;
+ ar->def_txkey_index = sme->key_idx;
+
+ ath6kl_wmi_addkey_cmd(ar->wmi, sme->key_idx,
+ ar->prwise_crypto,
+ GROUP_USAGE | TX_USAGE,
+ key->key_len,
+ NULL,
+ key->key, KEY_OP_INIT_VAL, NULL,
+ NO_SYNC_WMIFLAG);
+ }
+
+ if (!ar->usr_bss_filter) {
+ if (ath6kl_wmi_bssfilter_cmd(ar->wmi, ALL_BSS_FILTER, 0) != 0) {
+ ath6kl_err("couldn't set bss filtering\n");
+ up(&ar->sem);
+ return -EIO;
+ }
+ }
+
+ ar->nw_type = ar->next_mode;
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: connect called with authmode %d dot11 auth %d"
+ " PW crypto %d PW crypto len %d GRP crypto %d"
+ " GRP crypto len %d channel hint %u\n",
+ __func__,
+ ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
+ ar->prwise_crypto_len, ar->grp_crypto,
+ ar->grp_crpto_len, ar->ch_hint);
+
+ ar->reconnect_flag = 0;
+ status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
+ ar->dot11_auth_mode, ar->auth_mode,
+ ar->prwise_crypto,
+ ar->prwise_crypto_len,
+ ar->grp_crypto, ar->grp_crpto_len,
+ ar->ssid_len, ar->ssid,
+ ar->req_bssid, ar->ch_hint,
+ ar->connect_ctrl_flags);
+
+ up(&ar->sem);
+
+ if (status == -EINVAL) {
+ memset(ar->ssid, 0, sizeof(ar->ssid));
+ ar->ssid_len = 0;
+ ath6kl_err("invalid request\n");
+ return -ENOENT;
+ } else if (status) {
+ ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
+ return -EIO;
+ }
+
+ if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
+ ((ar->auth_mode == WPA_PSK_AUTH)
+ || (ar->auth_mode == WPA2_PSK_AUTH))) {
+ mod_timer(&ar->disconnect_timer,
+ jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
+ }
+
+ ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
+ set_bit(CONNECT_PEND, &ar->flag);
+
+ return 0;
+}
+
+void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
+ u8 *bssid, u16 listen_intvl,
+ u16 beacon_intvl,
+ enum network_type nw_type,
+ u8 beacon_ie_len, u8 assoc_req_len,
+ u8 assoc_resp_len, u8 *assoc_info)
+{
+ u16 size = 0;
+ u16 capability = 0;
+ struct cfg80211_bss *bss = NULL;
+ struct ieee80211_mgmt *mgmt = NULL;
+ struct ieee80211_channel *ibss_ch = NULL;
+ s32 signal = 50 * 100;
+ u8 ie_buf_len = 0;
+ unsigned char ie_buf[256];
+ unsigned char *ptr_ie_buf = ie_buf;
+ unsigned char *ieeemgmtbuf = NULL;
+ u8 source_mac[ETH_ALEN];
+ u16 capa_mask;
+ u16 capa_val;
+
+ /* capinfo + listen interval */
+ u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
+
+ /* capinfo + status code + associd */
+ u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
+
+ u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
+ u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
+ assoc_resp_ie_offset;
+
+ assoc_req_len -= assoc_req_ie_offset;
+ assoc_resp_len -= assoc_resp_ie_offset;
+
+ ar->auto_auth_stage = AUTH_IDLE;
+
+ if (nw_type & ADHOC_NETWORK) {
+ if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: ath6k not in ibss mode\n", __func__);
+ return;
+ }
+ }
+
+ if (nw_type & INFRA_NETWORK) {
+ if (ar->wdev->iftype != NL80211_IFTYPE_STATION) {
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: ath6k not in station mode\n", __func__);
+ return;
+ }
+ }
+
+ if (nw_type & ADHOC_NETWORK) {
+ capa_mask = WLAN_CAPABILITY_IBSS;
+ capa_val = WLAN_CAPABILITY_IBSS;
+ } else {
+ capa_mask = WLAN_CAPABILITY_ESS;
+ capa_val = WLAN_CAPABILITY_ESS;
+ }
+
+ /* Before informing the join/connect event, make sure that
+ * bss entry is present in scan list, if it not present
+ * construct and insert into scan list, otherwise that
+ * event will be dropped on the way by cfg80211, due to
+ * this keys will not be plumbed in case of WEP and
+ * application will not be aware of join/connect status. */
+ bss = cfg80211_get_bss(ar->wdev->wiphy, NULL, bssid,
+ ar->wdev->ssid, ar->wdev->ssid_len,
+ capa_mask, capa_val);
+
+ /*
+ * Earlier we were updating the cfg about bss by making a beacon frame
+ * only if the entry for bss is not there. This can have some issue if
+ * ROAM event is generated and a heavy traffic is ongoing. The ROAM
+ * event is handled through a work queue and by the time it really gets
+ * handled, BSS would have been aged out. So it is better to update the
+ * cfg about BSS irrespective of its entry being present right now or
+ * not.
+ */
+
+ if (nw_type & ADHOC_NETWORK) {
+ /* construct 802.11 mgmt beacon */
+ if (ptr_ie_buf) {
+ *ptr_ie_buf++ = WLAN_EID_SSID;
+ *ptr_ie_buf++ = ar->ssid_len;
+ memcpy(ptr_ie_buf, ar->ssid, ar->ssid_len);
+ ptr_ie_buf += ar->ssid_len;
+
+ *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
+ *ptr_ie_buf++ = 2; /* length */
+ *ptr_ie_buf++ = 0; /* ATIM window */
+ *ptr_ie_buf++ = 0; /* ATIM window */
+
+ /* TODO: update ibss params and include supported rates,
+ * DS param set, extened support rates, wmm. */
+
+ ie_buf_len = ptr_ie_buf - ie_buf;
+ }
+
+ capability |= WLAN_CAPABILITY_IBSS;
+
+ if (ar->prwise_crypto == WEP_CRYPT)
+ capability |= WLAN_CAPABILITY_PRIVACY;
+
+ memcpy(source_mac, ar->net_dev->dev_addr, ETH_ALEN);
+ ptr_ie_buf = ie_buf;
+ } else {
+ capability = *(u16 *) (&assoc_info[beacon_ie_len]);
+ memcpy(source_mac, bssid, ETH_ALEN);
+ ptr_ie_buf = assoc_req_ie;
+ ie_buf_len = assoc_req_len;
+ }
+
+ size = offsetof(struct ieee80211_mgmt, u)
+ + sizeof(mgmt->u.beacon)
+ + ie_buf_len;
+
+ ieeemgmtbuf = kzalloc(size, GFP_ATOMIC);
+ if (!ieeemgmtbuf) {
+ ath6kl_err("ieee mgmt buf alloc error\n");
+ cfg80211_put_bss(bss);
+ return;
+ }
+
+ mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
+ mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_BEACON);
+ memset(mgmt->da, 0xff, ETH_ALEN); /* broadcast addr */
+ memcpy(mgmt->sa, source_mac, ETH_ALEN);
+ memcpy(mgmt->bssid, bssid, ETH_ALEN);
+ mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_intvl);
+ mgmt->u.beacon.capab_info = cpu_to_le16(capability);
+ memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
+
+ ibss_ch = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: inform bss with bssid %pM channel %d beacon_intvl %d capability 0x%x\n",
+ __func__, mgmt->bssid, ibss_ch->hw_value,
+ beacon_intvl, capability);
+
+ bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
+ ibss_ch, mgmt,
+ size, signal, GFP_KERNEL);
+ kfree(ieeemgmtbuf);
+ cfg80211_put_bss(bss);
+
+ if (nw_type & ADHOC_NETWORK) {
+ cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
+ return;
+ }
+
+ if (!test_bit(CONNECTED, &ar->flag)) {
+ /* inform connect result to cfg80211 */
+ ar->sme_state = SME_DISCONNECTED;
+ cfg80211_connect_result(ar->net_dev, bssid,
+ assoc_req_ie, assoc_req_len,
+ assoc_resp_ie, assoc_resp_len,
+ WLAN_STATUS_SUCCESS, GFP_KERNEL);
+ } else {
+ /* inform roam event to cfg80211 */
+ cfg80211_roamed(ar->net_dev, ibss_ch, bssid,
+ assoc_req_ie, assoc_req_len,
+ assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
+ }
+}
+
+static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
+ struct net_device *dev, u16 reason_code)
+{
+ struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
+ reason_code);
+
+ if (!ath6kl_cfg80211_ready(ar))
+ return -EIO;
+
+ if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
+ ath6kl_err("busy, destroy in progress\n");
+ return -EBUSY;
+ }
+
+ if (down_interruptible(&ar->sem)) {
+ ath6kl_err("busy, couldn't get access\n");
+ return -ERESTARTSYS;
+ }
+
+ ar->reconnect_flag = 0;
+ ath6kl_disconnect(ar);
+ memset(ar->ssid, 0, sizeof(ar->ssid));
+ ar->ssid_len = 0;
+
+ if (!test_bit(SKIP_SCAN, &ar->flag))
+ memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
+
+ up(&ar->sem);
+
+ return 0;
+}
+
+void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
+ u8 *bssid, u8 assoc_resp_len,
+ u8 *assoc_info, u16 proto_reason)
+{
+ struct ath6kl_key *key = NULL;
+ u16 status;
+
+ if (ar->scan_req) {
+ cfg80211_scan_done(ar->scan_req, true);
+ ar->scan_req = NULL;
+ }
+
+ if (ar->nw_type & ADHOC_NETWORK) {
+ if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: ath6k not in ibss mode\n", __func__);
+ return;
+ }
+ memset(bssid, 0, ETH_ALEN);
+ cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
+ return;
+ }
+
+ if (ar->nw_type & INFRA_NETWORK) {
+ if (ar->wdev->iftype != NL80211_IFTYPE_STATION) {
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: ath6k not in station mode\n", __func__);
+ return;
+ }
+ }
+
+ if (!test_bit(CONNECT_PEND, &ar->flag)) {
+ if (reason != DISCONNECT_CMD)
+ ath6kl_wmi_disconnect_cmd(ar->wmi);
+
+ return;
+ }
+
+ if (reason == NO_NETWORK_AVAIL) {
+ /* connect cmd failed */
+ ath6kl_wmi_disconnect_cmd(ar->wmi);
+ return;
+ }
+
+ if (reason != DISCONNECT_CMD)
+ return;
+
+ if (!ar->auto_auth_stage) {
+ clear_bit(CONNECT_PEND, &ar->flag);
+
+ if (ar->sme_state == SME_CONNECTING) {
+ cfg80211_connect_result(ar->net_dev,
+ bssid, NULL, 0,
+ NULL, 0,
+ WLAN_STATUS_UNSPECIFIED_FAILURE,
+ GFP_KERNEL);
+ } else {
+ cfg80211_disconnected(ar->net_dev, reason,
+ NULL, 0, GFP_KERNEL);
+ }
+
+ ar->sme_state = SME_DISCONNECTED;
+ return;
+ }
+
+ if (ar->dot11_auth_mode != OPEN_AUTH)
+ return;
+
+ /*
+ * If the current auth algorithm is open, try shared and
+ * make autoAuthStage idle. We do not make it leap for now
+ * being.
+ */
+ key = &ar->keys[ar->def_txkey_index];
+ if (down_interruptible(&ar->sem)) {
+ ath6kl_err("busy, couldn't get access\n");
+ return;
+ }
+
+ ar->dot11_auth_mode = SHARED_AUTH;
+ ar->auto_auth_stage = AUTH_IDLE;
+
+ ath6kl_wmi_addkey_cmd(ar->wmi,
+ ar->def_txkey_index,
+ ar->prwise_crypto,
+ GROUP_USAGE | TX_USAGE,
+ key->key_len, NULL,
+ key->key,
+ KEY_OP_INIT_VAL, NULL,
+ NO_SYNC_WMIFLAG);
+
+ status = ath6kl_wmi_connect_cmd(ar->wmi,
+ ar->nw_type,
+ ar->dot11_auth_mode,
+ ar->auth_mode,
+ ar->prwise_crypto,
+ ar->prwise_crypto_len,
+ ar->grp_crypto,
+ ar->grp_crpto_len,
+ ar->ssid_len,
+ ar->ssid,
+ ar->req_bssid,
+ ar->ch_hint,
+ ar->connect_ctrl_flags);
+ up(&ar->sem);
+}
+
+static inline bool is_ch_11a(u16 ch)
+{
+ return (!((ch >= 2412) && (ch <= 2484)));
+}
+
+static void ath6kl_cfg80211_scan_node(void *arg, struct bss *ni)
+{
+ struct wiphy *wiphy = (struct wiphy *)arg;
+ u16 size;
+ unsigned char *ieeemgmtbuf = NULL;
+ struct ieee80211_mgmt *mgmt;
+ struct ieee80211_channel *channel;
+ struct ieee80211_supported_band *band;
+ struct ath6kl_common_ie *cie;
+ s32 signal;
+ int freq;
+
+ cie = &ni->ni_cie;
+
+ if (is_ch_11a(cie->ie_chan))
+ band = wiphy->bands[IEEE80211_BAND_5GHZ]; /* 11a */
+ else if ((cie->ie_erp) || (cie->ie_xrates))
+ band = wiphy->bands[IEEE80211_BAND_2GHZ]; /* 11g */
+ else
+ band = wiphy->bands[IEEE80211_BAND_2GHZ]; /* 11b */
+
+ size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u);
+ ieeemgmtbuf = kmalloc(size, GFP_ATOMIC);
+ if (!ieeemgmtbuf) {
+ ath6kl_err("ieee mgmt buf alloc error\n");
+ return;
+ }
+
+ /*
+ * TODO: Update target to include 802.11 mac header while sending
+ * bss info. Target removes 802.11 mac header while sending the bss
+ * info to host, cfg80211 needs it, for time being just filling the
+ * da, sa and bssid fields alone.
+ */
+ mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
+ memset(mgmt->da, 0xff, ETH_ALEN); /*broadcast addr */
+ memcpy(mgmt->sa, ni->ni_macaddr, ETH_ALEN);
+ memcpy(mgmt->bssid, ni->ni_macaddr, ETH_ALEN);
+ memcpy(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u),
+ ni->ni_buf, ni->ni_framelen);
+
+ freq = cie->ie_chan;
+ channel = ieee80211_get_channel(wiphy, freq);
+ signal = ni->ni_snr * 100;
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: bssid %pM ch %d freq %d size %d\n", __func__,
+ mgmt->bssid, channel->hw_value, freq, size);
+ cfg80211_inform_bss_frame(wiphy, channel, mgmt,
+ size, signal, GFP_KERNEL);
+
+ kfree(ieeemgmtbuf);
+}
+
+static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
+ struct cfg80211_scan_request *request)
+{
+ struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
+ int ret = 0;
+ u32 force_fg_scan = 0;
+
+ if (!ath6kl_cfg80211_ready(ar))
+ return -EIO;
+
+ if (!ar->usr_bss_filter) {
+ if (ath6kl_wmi_bssfilter_cmd(ar->wmi,
+ (test_bit(CONNECTED, &ar->flag) ?
+ ALL_BUT_BSS_FILTER :
+ ALL_BSS_FILTER), 0) != 0) {
+ ath6kl_err("couldn't set bss filtering\n");
+ return -EIO;
+ }
+ }
+
+ if (request->n_ssids && request->ssids[0].ssid_len) {
+ u8 i;
+
+ if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1))
+ request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
+
+ for (i = 0; i < request->n_ssids; i++)
+ ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
+ SPECIFIC_SSID_FLAG,
+ request->ssids[i].ssid_len,
+ request->ssids[i].ssid);
+ }
+
+ if (test_bit(CONNECTED, &ar->flag))
+ force_fg_scan = 1;
+
+ if (ath6kl_wmi_startscan_cmd(ar->wmi, WMI_LONG_SCAN, force_fg_scan,
+ false, 0, 0, 0, NULL) != 0) {
+ ath6kl_err("wmi_startscan_cmd failed\n");
+ ret = -EIO;
+ }
+
+ ar->scan_req = request;
+
+ return ret;
+}
+
+void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status)
+{
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status %d\n", __func__, status);
+
+ if (ar->scan_req) {
+ /* Translate data to cfg80211 mgmt format */
+ ath6kl_wmi_iterate_nodes(ar->wmi, ath6kl_cfg80211_scan_node,
+ ar->wdev->wiphy);
+
+ cfg80211_scan_done(ar->scan_req, ((status & -ECANCELED)
+ || (status & -EBUSY)) ? true :
+ false);
+
+ if (ar->scan_req->n_ssids && ar->scan_req->ssids[0].ssid_len) {
+ u8 i;
+
+ for (i = 0; i < ar->scan_req->n_ssids; i++) {
+ ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
+ DISABLE_SSID_FLAG,
+ 0, NULL);
+ }
+ }
+ ar->scan_req = NULL;
+ }
+}
+
+static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
+ u8 key_index, bool pairwise,
+ const u8 *mac_addr,
+ struct key_params *params)
+{
+ struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
+ struct ath6kl_key *key = NULL;
+ u8 key_usage;
+ u8 key_type;
+ int status = 0;
+
+ if (!ath6kl_cfg80211_ready(ar))
+ return -EIO;
+
+ if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: key index %d out of bounds\n", __func__,
+ key_index);
+ return -ENOENT;
+ }
+
+ key = &ar->keys[key_index];
+ memset(key, 0, sizeof(struct ath6kl_key));
+
+ if (pairwise)
+ key_usage = PAIRWISE_USAGE;
+ else
+ key_usage = GROUP_USAGE;
+
+ if (params) {
+ if (params->key_len > WLAN_MAX_KEY_LEN ||
+ params->seq_len > sizeof(key->seq))
+ return -EINVAL;
+
+ key->key_len = params->key_len;
+ memcpy(key->key, params->key, key->key_len);
+ key->seq_len = params->seq_len;
+ memcpy(key->seq, params->seq, key->seq_len);
+ key->cipher = params->cipher;
+ }
+
+ switch (key->cipher) {
+ case WLAN_CIPHER_SUITE_WEP40:
+ case WLAN_CIPHER_SUITE_WEP104:
+ key_type = WEP_CRYPT;
+ break;
+
+ case WLAN_CIPHER_SUITE_TKIP:
+ key_type = TKIP_CRYPT;
+ break;
+
+ case WLAN_CIPHER_SUITE_CCMP:
+ key_type = AES_CRYPT;
+ break;
+
+ default:
+ return -ENOTSUPP;
+ }
+
+ if (((ar->auth_mode == WPA_PSK_AUTH)
+ || (ar->auth_mode == WPA2_PSK_AUTH))
+ && (key_usage & GROUP_USAGE))
+ del_timer(&ar->disconnect_timer);
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
+ __func__, key_index, key->key_len, key_type,
+ key_usage, key->seq_len);
+
+ ar->def_txkey_index = key_index;
+ status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
+ key_type, key_usage, key->key_len,
+ key->seq, key->key, KEY_OP_INIT_VAL,
+ (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
+
+ if (status)
+ return -EIO;
+
+ return 0;
+}
+
+static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
+ u8 key_index, bool pairwise,
+ const u8 *mac_addr)
+{
+ struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
+
+ if (!ath6kl_cfg80211_ready(ar))
+ return -EIO;
+
+ if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: key index %d out of bounds\n", __func__,
+ key_index);
+ return -ENOENT;
+ }
+
+ if (!ar->keys[key_index].key_len) {
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: index %d is empty\n", __func__, key_index);
+ return 0;
+ }
+
+ ar->keys[key_index].key_len = 0;
+
+ return ath6kl_wmi_deletekey_cmd(ar->wmi, key_index);
+}
+
+static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
+ u8 key_index, bool pairwise,
+ const u8 *mac_addr, void *cookie,
+ void (*callback) (void *cookie,
+ struct key_params *))
+{
+ struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
+ struct ath6kl_key *key = NULL;
+ struct key_params params;
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
+
+ if (!ath6kl_cfg80211_ready(ar))
+ return -EIO;
+
+ if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: key index %d out of bounds\n", __func__,
+ key_index);
+ return -ENOENT;
+ }
+
+ key = &ar->keys[key_index];
+ memset(&params, 0, sizeof(params));
+ params.cipher = key->cipher;
+ params.key_len = key->key_len;
+ params.seq_len = key->seq_len;
+ params.seq = key->seq;
+ params.key = key->key;
+
+ callback(cookie, &params);
+
+ return key->key_len ? 0 : -ENOENT;
+}
+
+static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
+ struct net_device *ndev,
+ u8 key_index, bool unicast,
+ bool multicast)
+{
+ struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
+ struct ath6kl_key *key = NULL;
+ int status = 0;
+ u8 key_usage;
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
+
+ if (!ath6kl_cfg80211_ready(ar))
+ return -EIO;
+
+ if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: key index %d out of bounds\n",
+ __func__, key_index);
+ return -ENOENT;
+ }
+
+ if (!ar->keys[key_index].key_len) {
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
+ __func__, key_index);
+ return -EINVAL;
+ }
+
+ ar->def_txkey_index = key_index;
+ key = &ar->keys[ar->def_txkey_index];
+ key_usage = GROUP_USAGE;
+ if (ar->prwise_crypto == WEP_CRYPT)
+ key_usage |= TX_USAGE;
+
+ status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
+ ar->prwise_crypto, key_usage,
+ key->key_len, key->seq, key->key,
+ KEY_OP_INIT_VAL, NULL,
+ SYNC_BOTH_WMIFLAG);
+ if (status)
+ return -EIO;
+
+ return 0;
+}
+
+void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl *ar, u8 keyid,
+ bool ismcast)
+{
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
+
+ cfg80211_michael_mic_failure(ar->net_dev, ar->bssid,
+ (ismcast ? NL80211_KEYTYPE_GROUP :
+ NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
+ GFP_KERNEL);
+}
+
+static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
+{
+ struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
+ int ret;
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
+ changed);
+
+ if (!ath6kl_cfg80211_ready(ar))
+ return -EIO;
+
+ if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
+ ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
+ if (ret != 0) {
+ ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
+ return -EIO;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * The type nl80211_tx_power_setting replaces the following
+ * data type from 2.6.36 onwards
+*/
+static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
+ enum nl80211_tx_power_setting type,
+ int dbm)
+{
+ struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
+ u8 ath6kl_dbm;
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
+ type, dbm);
+
+ if (!ath6kl_cfg80211_ready(ar))
+ return -EIO;
+
+ switch (type) {
+ case NL80211_TX_POWER_AUTOMATIC:
+ return 0;
+ case NL80211_TX_POWER_LIMITED:
+ ar->tx_pwr = ath6kl_dbm = dbm;
+ break;
+ default:
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
+ __func__, type);
+ return -EOPNOTSUPP;
+ }
+
+ ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, ath6kl_dbm);
+
+ return 0;
+}
+
+static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
+{
+ struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
+
+ if (!ath6kl_cfg80211_ready(ar))
+ return -EIO;
+
+ if (test_bit(CONNECTED, &ar->flag)) {
+ ar->tx_pwr = 0;
+
+ if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi) != 0) {
+ ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
+ return -EIO;
+ }
+
+ wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0,
+ 5 * HZ);
+
+ if (signal_pending(current)) {
+ ath6kl_err("target did not respond\n");
+ return -EINTR;
+ }
+ }
+
+ *dbm = ar->tx_pwr;
+ return 0;
+}
+
+static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
+ struct net_device *dev,
+ bool pmgmt, int timeout)
+{
+ struct ath6kl *ar = ath6kl_priv(dev);
+ struct wmi_power_mode_cmd mode;
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
+ __func__, pmgmt, timeout);
+
+ if (!ath6kl_cfg80211_ready(ar))
+ return -EIO;
+
+ if (pmgmt) {
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
+ mode.pwr_mode = REC_POWER;
+ } else {
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
+ mode.pwr_mode = MAX_PERF_POWER;
+ }
+
+ if (ath6kl_wmi_powermode_cmd(ar->wmi, mode.pwr_mode) != 0) {
+ ath6kl_err("wmi_powermode_cmd failed\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
+ struct net_device *ndev,
+ enum nl80211_iftype type, u32 *flags,
+ struct vif_params *params)
+{
+ struct ath6kl *ar = ath6kl_priv(ndev);
+ struct wireless_dev *wdev = ar->wdev;
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
+
+ if (!ath6kl_cfg80211_ready(ar))
+ return -EIO;
+
+ switch (type) {
+ case NL80211_IFTYPE_STATION:
+ ar->next_mode = INFRA_NETWORK;
+ break;
+ case NL80211_IFTYPE_ADHOC:
+ ar->next_mode = ADHOC_NETWORK;
+ break;
+ default:
+ ath6kl_err("invalid interface type %u\n", type);
+ return -EOPNOTSUPP;
+ }
+
+ wdev->iftype = type;
+
+ return 0;
+}
+
+static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
+ struct net_device *dev,
+ struct cfg80211_ibss_params *ibss_param)
+{
+ struct ath6kl *ar = ath6kl_priv(dev);
+ int status;
+
+ if (!ath6kl_cfg80211_ready(ar))
+ return -EIO;
+
+ ar->ssid_len = ibss_param->ssid_len;
+ memcpy(ar->ssid, ibss_param->ssid, ar->ssid_len);
+
+ if (ibss_param->channel)
+ ar->ch_hint = ibss_param->channel->center_freq;
+
+ if (ibss_param->channel_fixed) {
+ /*
+ * TODO: channel_fixed: The channel should be fixed, do not
+ * search for IBSSs to join on other channels. Target
+ * firmware does not support this feature, needs to be
+ * updated.
+ */
+ return -EOPNOTSUPP;
+ }
+
+ memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
+ if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
+ memcpy(ar->req_bssid, ibss_param->bssid, sizeof(ar->req_bssid));
+
+ ath6kl_set_wpa_version(ar, 0);
+
+ status = ath6kl_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
+ if (status)
+ return status;
+
+ if (ibss_param->privacy) {
+ ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
+ ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
+ } else {
+ ath6kl_set_cipher(ar, 0, true);
+ ath6kl_set_cipher(ar, 0, false);
+ }
+
+ ar->nw_type = ar->next_mode;
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
+ "%s: connect called with authmode %d dot11 auth %d"
+ " PW crypto %d PW crypto len %d GRP crypto %d"
+ " GRP crypto len %d channel hint %u\n",
+ __func__,
+ ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
+ ar->prwise_crypto_len, ar->grp_crypto,
+ ar->grp_crpto_len, ar->ch_hint);
+
+ status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
+ ar->dot11_auth_mode, ar->auth_mode,
+ ar->prwise_crypto,
+ ar->prwise_crypto_len,
+ ar->grp_crypto, ar->grp_crpto_len,
+ ar->ssid_len, ar->ssid,
+ ar->req_bssid, ar->ch_hint,
+ ar->connect_ctrl_flags);
+ set_bit(CONNECT_PEND, &ar->flag);
+
+ return 0;
+}
+
+static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
+ struct net_device *dev)
+{
+ struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
+
+ if (!ath6kl_cfg80211_ready(ar))
+ return -EIO;
+
+ ath6kl_disconnect(ar);
+ memset(ar->ssid, 0, sizeof(ar->ssid));
+ ar->ssid_len = 0;
+
+ return 0;
+}
+
+static const u32 cipher_suites[] = {
+ WLAN_CIPHER_SUITE_WEP40,
+ WLAN_CIPHER_SUITE_WEP104,
+ WLAN_CIPHER_SUITE_TKIP,
+ WLAN_CIPHER_SUITE_CCMP,
+};
+
+static bool is_rate_legacy(s32 rate)
+{
+ static const s32 legacy[] = { 1000, 2000, 5500, 11000,
+ 6000, 9000, 12000, 18000, 24000,
+ 36000, 48000, 54000
+ };
+ u8 i;
+
+ for (i = 0; i < ARRAY_SIZE(legacy); i++)
+ if (rate == legacy[i])
+ return true;
+
+ return false;
+}
+
+static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
+{
+ static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
+ 52000, 58500, 65000, 72200
+ };
+ u8 i;
+
+ for (i = 0; i < ARRAY_SIZE(ht20); i++) {
+ if (rate == ht20[i]) {
+ if (i == ARRAY_SIZE(ht20) - 1)
+ /* last rate uses sgi */
+ *sgi = true;
+ else
+ *sgi = false;
+
+ *mcs = i;
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
+{
+ static const s32 ht40[] = { 13500, 27000, 40500, 54000,
+ 81000, 108000, 121500, 135000,
+ 150000
+ };
+ u8 i;
+
+ for (i = 0; i < ARRAY_SIZE(ht40); i++) {
+ if (rate == ht40[i]) {
+ if (i == ARRAY_SIZE(ht40) - 1)
+ /* last rate uses sgi */
+ *sgi = true;
+ else
+ *sgi = false;
+
+ *mcs = i;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
+ u8 *mac, struct station_info *sinfo)
+{
+ struct ath6kl *ar = ath6kl_priv(dev);
+ long left;
+ bool sgi;
+ s32 rate;
+ int ret;
+ u8 mcs;
+
+ if (memcmp(mac, ar->bssid, ETH_ALEN) != 0)
+ return -ENOENT;
+
+ if (down_interruptible(&ar->sem))
+ return -EBUSY;
+
+ set_bit(STATS_UPDATE_PEND, &ar->flag);
+
+ ret = ath6kl_wmi_get_stats_cmd(ar->wmi);
+
+ if (ret != 0) {
+ up(&ar->sem);
+ return -EIO;
+ }
+
+ left = wait_event_interruptible_timeout(ar->event_wq,
+ !test_bit(STATS_UPDATE_PEND,
+ &ar->flag),
+ WMI_TIMEOUT);
+
+ up(&ar->sem);
+
+ if (left == 0)
+ return -ETIMEDOUT;
+ else if (left < 0)
+ return left;
+
+ if (ar->target_stats.rx_byte) {
+ sinfo->rx_bytes = ar->target_stats.rx_byte;
+ sinfo->filled |= STATION_INFO_RX_BYTES;
+ sinfo->rx_packets = ar->target_stats.rx_pkt;
+ sinfo->filled |= STATION_INFO_RX_PACKETS;
+ }
+
+ if (ar->target_stats.tx_byte) {
+ sinfo->tx_bytes = ar->target_stats.tx_byte;
+ sinfo->filled |= STATION_INFO_TX_BYTES;
+ sinfo->tx_packets = ar->target_stats.tx_pkt;
+ sinfo->filled |= STATION_INFO_TX_PACKETS;
+ }
+
+ sinfo->signal = ar->target_stats.cs_rssi;
+ sinfo->filled |= STATION_INFO_SIGNAL;
+
+ rate = ar->target_stats.tx_ucast_rate;
+
+ if (is_rate_legacy(rate)) {
+ sinfo->txrate.legacy = rate / 100;
+ } else if (is_rate_ht20(rate, &mcs, &sgi)) {
+ if (sgi) {
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+ sinfo->txrate.mcs = mcs - 1;
+ } else {
+ sinfo->txrate.mcs = mcs;
+ }
+
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+ } else if (is_rate_ht40(rate, &mcs, &sgi)) {
+ if (sgi) {
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
+ sinfo->txrate.mcs = mcs - 1;
+ } else {
+ sinfo->txrate.mcs = mcs;
+ }
+
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
+ sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
+ } else {
+ ath6kl_warn("invalid rate: %d\n", rate);
+ return 0;
+ }
+
+ sinfo->filled |= STATION_INFO_TX_BITRATE;
+
+ return 0;
+}
+
+static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
+ struct cfg80211_pmksa *pmksa)
+{
+ struct ath6kl *ar = ath6kl_priv(netdev);
+ return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
+ pmksa->pmkid, true);
+}
+
+static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
+ struct cfg80211_pmksa *pmksa)
+{
+ struct ath6kl *ar = ath6kl_priv(netdev);
+ return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
+ pmksa->pmkid, false);
+}
+
+static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
+{
+ struct ath6kl *ar = ath6kl_priv(netdev);
+ if (test_bit(CONNECTED, &ar->flag))
+ return ath6kl_wmi_setpmkid_cmd(ar->wmi, ar->bssid, NULL, false);
+ return 0;
+}
+
+static struct cfg80211_ops ath6kl_cfg80211_ops = {
+ .change_virtual_intf = ath6kl_cfg80211_change_iface,
+ .scan = ath6kl_cfg80211_scan,
+ .connect = ath6kl_cfg80211_connect,
+ .disconnect = ath6kl_cfg80211_disconnect,
+ .add_key = ath6kl_cfg80211_add_key,
+ .get_key = ath6kl_cfg80211_get_key,
+ .del_key = ath6kl_cfg80211_del_key,
+ .set_default_key = ath6kl_cfg80211_set_default_key,
+ .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
+ .set_tx_power = ath6kl_cfg80211_set_txpower,
+ .get_tx_power = ath6kl_cfg80211_get_txpower,
+ .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
+ .join_ibss = ath6kl_cfg80211_join_ibss,
+ .leave_ibss = ath6kl_cfg80211_leave_ibss,
+ .get_station = ath6kl_get_station,
+ .set_pmksa = ath6kl_set_pmksa,
+ .del_pmksa = ath6kl_del_pmksa,
+ .flush_pmksa = ath6kl_flush_pmksa,
+};
+
+struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
+{
+ int ret = 0;
+ struct wireless_dev *wdev;
+
+ wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
+ if (!wdev) {
+ ath6kl_err("couldn't allocate wireless device\n");
+ return NULL;
+ }
+
+ /* create a new wiphy for use with cfg80211 */
+ wdev->wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
+ if (!wdev->wiphy) {
+ ath6kl_err("couldn't allocate wiphy device\n");
+ kfree(wdev);
+ return NULL;
+ }
+
+ /* set device pointer for wiphy */
+ set_wiphy_dev(wdev->wiphy, dev);
+
+ wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC);
+ /* max num of ssids that can be probed during scanning */
+ wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
+ wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
+ wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
+ wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
+
+ wdev->wiphy->cipher_suites = cipher_suites;
+ wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
+
+ ret = wiphy_register(wdev->wiphy);
+ if (ret < 0) {
+ ath6kl_err("couldn't register wiphy device\n");
+ wiphy_free(wdev->wiphy);
+ kfree(wdev);
+ return NULL;
+ }
+
+ return wdev;
+}
+
+void ath6kl_cfg80211_deinit(struct ath6kl *ar)
+{
+ struct wireless_dev *wdev = ar->wdev;
+
+ if (ar->scan_req) {
+ cfg80211_scan_done(ar->scan_req, true);
+ ar->scan_req = NULL;
+ }
+
+ if (!wdev)
+ return;
+
+ wiphy_unregister(wdev->wiphy);
+ wiphy_free(wdev->wiphy);
+ kfree(wdev);
+}
diff --git a/drivers/net/wireless/ath/ath6kl/cfg80211.h b/drivers/net/wireless/ath/ath6kl/cfg80211.h
new file mode 100644
index 000000000000..a84adc249c61
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/cfg80211.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2011 Atheros Communications Inc.
+ *
+ * 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.
+ */
+
+#ifndef ATH6KL_CFG80211_H
+#define ATH6KL_CFG80211_H
+
+struct wireless_dev *ath6kl_cfg80211_init(struct device *dev);
+void ath6kl_cfg80211_deinit(struct ath6kl *ar);
+
+void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status);
+
+void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
+ u8 *bssid, u16 listen_intvl,
+ u16 beacon_intvl,
+ enum network_type nw_type,
+ u8 beacon_ie_len, u8 assoc_req_len,
+ u8 assoc_resp_len, u8 *assoc_info);
+
+void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
+ u8 *bssid, u8 assoc_resp_len,
+ u8 *assoc_info, u16 proto_reason);
+
+void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl *ar, u8 keyid,
+ bool ismcast);
+
+#endif /* ATH6KL_CFG80211_H */
diff --git a/drivers/net/wireless/ath/ath6kl/common.h b/drivers/net/wireless/ath/ath6kl/common.h
new file mode 100644
index 000000000000..0a3a1d80d0a4
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/common.h
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
+ *
+ * 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.
+ */
+
+#ifndef COMMON_H
+#define COMMON_H
+
+#include <linux/netdevice.h>
+
+#define ATH6KL_MAX_IE 256
+
+extern int ath6kl_printk(const char *level, const char *fmt, ...);
+
+#define A_CACHE_LINE_PAD 128
+
+/*
+ * Reflects the version of binary interface exposed by ATH6KL target
+ * firmware. Needs to be incremented by 1 for any change in the firmware
+ * that requires upgrade of the driver on the host side for the change to
+ * work correctly
+ */
+#define ATH6KL_ABI_VERSION 1
+
+#define SIGNAL_QUALITY_METRICS_NUM_MAX 2
+
+enum {
+ SIGNAL_QUALITY_METRICS_SNR = 0,
+ SIGNAL_QUALITY_METRICS_RSSI,
+ SIGNAL_QUALITY_METRICS_ALL,
+};
+
+/*
+ * Data Path
+ */
+
+#define WMI_MAX_TX_DATA_FRAME_LENGTH \
+ (1500 + sizeof(struct wmi_data_hdr) + \
+ sizeof(struct ethhdr) + \
+ sizeof(struct ath6kl_llc_snap_hdr))
+
+/* An AMSDU frame */ /* The MAX AMSDU length of AR6003 is 3839 */
+#define WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH \
+ (3840 + sizeof(struct wmi_data_hdr) + \
+ sizeof(struct ethhdr) + \
+ sizeof(struct ath6kl_llc_snap_hdr))
+
+#define EPPING_ALIGNMENT_PAD \
+ (((sizeof(struct htc_frame_hdr) + 3) & (~0x3)) \
+ - sizeof(struct htc_frame_hdr))
+
+struct ath6kl_llc_snap_hdr {
+ u8 dsap;
+ u8 ssap;
+ u8 cntl;
+ u8 org_code[3];
+ __be16 eth_type;
+} __packed;
+
+enum crypto_type {
+ NONE_CRYPT = 0x01,
+ WEP_CRYPT = 0x02,
+ TKIP_CRYPT = 0x04,
+ AES_CRYPT = 0x08,
+};
+
+#define ATH6KL_NODE_HASHSIZE 32
+/* simple hash is enough for variation of macaddr */
+#define ATH6KL_NODE_HASH(addr) \
+ (((const u8 *)(addr))[ETH_ALEN - 1] % \
+ ATH6KL_NODE_HASHSIZE)
+
+/*
+ * Table of ath6kl_node instances. Each ieee80211com
+ * has at least one for holding the scan candidates.
+ * When operating as an access point or in ibss mode there
+ * is a second table for associated stations or neighbors.
+ */
+struct ath6kl_node_table {
+ void *nt_wmi; /* back reference */
+ spinlock_t nt_nodelock; /* on node table */
+ struct bss *nt_node_first; /* information of all nodes */
+ struct bss *nt_node_last; /* information of all nodes */
+ struct bss *nt_hash[ATH6KL_NODE_HASHSIZE];
+ const char *nt_name; /* for debugging */
+ u32 nt_node_age; /* node aging time */
+};
+
+#define WLAN_NODE_INACT_TIMEOUT_MSEC 120000
+#define WLAN_NODE_INACT_CNT 4
+
+struct ath6kl_common_ie {
+ u16 ie_chan;
+ u8 *ie_tstamp;
+ u8 *ie_ssid;
+ u8 *ie_rates;
+ u8 *ie_xrates;
+ u8 *ie_country;
+ u8 *ie_wpa;
+ u8 *ie_rsn;
+ u8 *ie_wmm;
+ u8 *ie_ath;
+ u16 ie_capInfo;
+ u16 ie_beaconInt;
+ u8 *ie_tim;
+ u8 *ie_chswitch;
+ u8 ie_erp;
+ u8 *ie_wsc;
+ u8 *ie_htcap;
+ u8 *ie_htop;
+};
+
+struct bss {
+ u8 ni_macaddr[ETH_ALEN];
+ u8 ni_snr;
+ s16 ni_rssi;
+ struct bss *ni_list_next;
+ struct bss *ni_list_prev;
+ struct bss *ni_hash_next;
+ struct bss *ni_hash_prev;
+ struct ath6kl_common_ie ni_cie;
+ u8 *ni_buf;
+ u16 ni_framelen;
+ struct ath6kl_node_table *ni_table;
+ u32 ni_refcnt;
+
+ u32 ni_tstamp;
+ u32 ni_actcnt;
+};
+
+struct htc_endpoint_credit_dist;
+struct ath6kl;
+enum htc_credit_dist_reason;
+struct htc_credit_state_info;
+
+struct bss *wlan_node_alloc(int wh_size);
+void wlan_node_free(struct bss *ni);
+void wlan_setup_node(struct ath6kl_node_table *nt, struct bss *ni,
+ const u8 *mac_addr);
+struct bss *wlan_find_node(struct ath6kl_node_table *nt,
+ const u8 *mac_addr);
+void wlan_node_reclaim(struct ath6kl_node_table *nt, struct bss *ni);
+void wlan_free_allnodes(struct ath6kl_node_table *nt);
+void wlan_iterate_nodes(struct ath6kl_node_table *nt,
+ void (*f) (void *arg, struct bss *),
+ void *arg);
+
+void wlan_node_table_init(void *wmip, struct ath6kl_node_table *nt);
+void wlan_node_table_cleanup(struct ath6kl_node_table *nt);
+
+void wlan_refresh_inactive_nodes(struct ath6kl_node_table *nt);
+
+struct bss *wlan_find_ssid_node(struct ath6kl_node_table *nt, u8 *ssid,
+ u32 ssid_len, bool is_wpa2, bool match_ssid);
+
+void wlan_node_return(struct ath6kl_node_table *nt, struct bss *ni);
+
+int ath6k_setup_credit_dist(void *htc_handle,
+ struct htc_credit_state_info *cred_info);
+void ath6k_credit_distribute(struct htc_credit_state_info *cred_inf,
+ struct list_head *epdist_list,
+ enum htc_credit_dist_reason reason);
+void ath6k_credit_init(struct htc_credit_state_info *cred_inf,
+ struct list_head *ep_list,
+ int tot_credits);
+void ath6k_seek_credits(struct htc_credit_state_info *cred_inf,
+ struct htc_endpoint_credit_dist *ep_dist);
+struct ath6kl *ath6kl_core_alloc(struct device *sdev);
+int ath6kl_core_init(struct ath6kl *ar);
+int ath6kl_unavail_ev(struct ath6kl *ar);
+struct sk_buff *ath6kl_buf_alloc(int size);
+#endif /* COMMON_H */
diff --git a/drivers/net/wireless/ath/ath6kl/core.h b/drivers/net/wireless/ath/ath6kl/core.h
new file mode 100644
index 000000000000..86177f0b98a5
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/core.h
@@ -0,0 +1,546 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
+ *
+ * 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.
+ */
+
+#ifndef CORE_H
+#define CORE_H
+
+#include <linux/etherdevice.h>
+#include <linux/rtnetlink.h>
+#include <linux/firmware.h>
+#include <linux/sched.h>
+#include <net/cfg80211.h>
+#include "htc.h"
+#include "wmi.h"
+#include "bmi.h"
+
+#define MAX_ATH6KL 1
+#define ATH6KL_MAX_RX_BUFFERS 16
+#define ATH6KL_BUFFER_SIZE 1664
+#define ATH6KL_MAX_AMSDU_RX_BUFFERS 4
+#define ATH6KL_AMSDU_REFILL_THRESHOLD 3
+#define ATH6KL_AMSDU_BUFFER_SIZE (WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH + 128)
+#define MAX_MSDU_SUBFRAME_PAYLOAD_LEN 1508
+#define MIN_MSDU_SUBFRAME_PAYLOAD_LEN 46
+
+#define USER_SAVEDKEYS_STAT_INIT 0
+#define USER_SAVEDKEYS_STAT_RUN 1
+
+#define ATH6KL_TX_TIMEOUT 10
+#define ATH6KL_MAX_ENDPOINTS 4
+#define MAX_NODE_NUM 15
+
+/* MAX_HI_COOKIE_NUM are reserved for high priority traffic */
+#define MAX_DEF_COOKIE_NUM 180
+#define MAX_HI_COOKIE_NUM 18 /* 10% of MAX_COOKIE_NUM */
+#define MAX_COOKIE_NUM (MAX_DEF_COOKIE_NUM + MAX_HI_COOKIE_NUM)
+
+#define MAX_DEFAULT_SEND_QUEUE_DEPTH (MAX_DEF_COOKIE_NUM / WMM_NUM_AC)
+
+#define DISCON_TIMER_INTVAL 10000 /* in msec */
+#define A_DEFAULT_LISTEN_INTERVAL 100
+#define A_MAX_WOW_LISTEN_INTERVAL 1000
+
+/* AR6003 1.0 definitions */
+#define AR6003_REV1_VERSION 0x300002ba
+
+/* AR6003 2.0 definitions */
+#define AR6003_REV2_VERSION 0x30000384
+#define AR6003_REV2_PATCH_DOWNLOAD_ADDRESS 0x57e910
+#define AR6003_REV2_OTP_FILE "ath6k/AR6003/hw2.0/otp.bin.z77"
+#define AR6003_REV2_FIRMWARE_FILE "ath6k/AR6003/hw2.0/athwlan.bin.z77"
+#define AR6003_REV2_PATCH_FILE "ath6k/AR6003/hw2.0/data.patch.bin"
+#define AR6003_REV2_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.bin"
+#define AR6003_REV2_DEFAULT_BOARD_DATA_FILE "ath6k/AR6003/hw2.0/bdata.SD31.bin"
+
+/* AR6003 3.0 definitions */
+#define AR6003_REV3_VERSION 0x30000582
+#define AR6003_REV3_OTP_FILE "ath6k/AR6003/hw2.1.1/otp.bin"
+#define AR6003_REV3_FIRMWARE_FILE "ath6k/AR6003/hw2.1.1/athwlan.bin"
+#define AR6003_REV3_PATCH_FILE "ath6k/AR6003/hw2.1.1/data.patch.bin"
+#define AR6003_REV3_BOARD_DATA_FILE "ath6k/AR6003/hw2.1.1/bdata.bin"
+#define AR6003_REV3_DEFAULT_BOARD_DATA_FILE \
+ "ath6k/AR6003/hw2.1.1/bdata.SD31.bin"
+
+/* Per STA data, used in AP mode */
+#define STA_PS_AWAKE BIT(0)
+#define STA_PS_SLEEP BIT(1)
+#define STA_PS_POLLED BIT(2)
+
+/* HTC TX packet tagging definitions */
+#define ATH6KL_CONTROL_PKT_TAG HTC_TX_PACKET_TAG_USER_DEFINED
+#define ATH6KL_DATA_PKT_TAG (ATH6KL_CONTROL_PKT_TAG + 1)
+
+#define AR6003_CUST_DATA_SIZE 16
+
+#define AGGR_WIN_IDX(x, y) ((x) % (y))
+#define AGGR_INCR_IDX(x, y) AGGR_WIN_IDX(((x) + 1), (y))
+#define AGGR_DCRM_IDX(x, y) AGGR_WIN_IDX(((x) - 1), (y))
+#define ATH6KL_MAX_SEQ_NO 0xFFF
+#define ATH6KL_NEXT_SEQ_NO(x) (((x) + 1) & ATH6KL_MAX_SEQ_NO)
+
+#define NUM_OF_TIDS 8
+#define AGGR_SZ_DEFAULT 8
+
+#define AGGR_WIN_SZ_MIN 2
+#define AGGR_WIN_SZ_MAX 8
+
+#define TID_WINDOW_SZ(_x) ((_x) << 1)
+
+#define AGGR_NUM_OF_FREE_NETBUFS 16
+
+#define AGGR_RX_TIMEOUT 400 /* in ms */
+
+#define WMI_TIMEOUT (2 * HZ)
+
+#define MBOX_YIELD_LIMIT 99
+
+/* configuration lags */
+/*
+ * ATH6KL_CONF_IGNORE_ERP_BARKER: Ignore the barker premable in
+ * ERP IE of beacon to determine the short premable support when
+ * sending (Re)Assoc req.
+ * ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN: Don't send the power
+ * module state transition failure events which happen during
+ * scan, to the host.
+ */
+#define ATH6KL_CONF_IGNORE_ERP_BARKER BIT(0)
+#define ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN BIT(1)
+#define ATH6KL_CONF_ENABLE_11N BIT(2)
+#define ATH6KL_CONF_ENABLE_TX_BURST BIT(3)
+
+enum wlan_low_pwr_state {
+ WLAN_POWER_STATE_ON,
+ WLAN_POWER_STATE_CUT_PWR,
+ WLAN_POWER_STATE_DEEP_SLEEP,
+ WLAN_POWER_STATE_WOW
+};
+
+enum sme_state {
+ SME_DISCONNECTED,
+ SME_CONNECTING,
+ SME_CONNECTED
+};
+
+enum ath6kl_wlan_state {
+ WLAN_DISABLED,
+ WLAN_ENABLED
+};
+
+struct skb_hold_q {
+ struct sk_buff *skb;
+ bool is_amsdu;
+ u16 seq_no;
+};
+
+struct rxtid {
+ bool aggr;
+ bool progress;
+ bool timer_mon;
+ u16 win_sz;
+ u16 seq_next;
+ u32 hold_q_sz;
+ struct skb_hold_q *hold_q;
+ struct sk_buff_head q;
+ spinlock_t lock;
+};
+
+struct rxtid_stats {
+ u32 num_into_aggr;
+ u32 num_dups;
+ u32 num_oow;
+ u32 num_mpdu;
+ u32 num_amsdu;
+ u32 num_delivered;
+ u32 num_timeouts;
+ u32 num_hole;
+ u32 num_bar;
+};
+
+struct aggr_info {
+ u8 aggr_sz;
+ u8 timer_scheduled;
+ struct timer_list timer;
+ struct net_device *dev;
+ struct rxtid rx_tid[NUM_OF_TIDS];
+ struct sk_buff_head free_q;
+ struct rxtid_stats stat[NUM_OF_TIDS];
+};
+
+struct ath6kl_wep_key {
+ u8 key_index;
+ u8 key_len;
+ u8 key[64];
+};
+
+#define ATH6KL_KEY_SEQ_LEN 8
+
+struct ath6kl_key {
+ u8 key[WLAN_MAX_KEY_LEN];
+ u8 key_len;
+ u8 seq[ATH6KL_KEY_SEQ_LEN];
+ u8 seq_len;
+ u32 cipher;
+};
+
+struct ath6kl_node_mapping {
+ u8 mac_addr[ETH_ALEN];
+ u8 ep_id;
+ u8 tx_pend;
+};
+
+struct ath6kl_cookie {
+ struct sk_buff *skb;
+ u32 map_no;
+ struct htc_packet htc_pkt;
+ struct ath6kl_cookie *arc_list_next;
+};
+
+struct ath6kl_sta {
+ u16 sta_flags;
+ u8 mac[ETH_ALEN];
+ u8 aid;
+ u8 keymgmt;
+ u8 ucipher;
+ u8 auth;
+ u8 wpa_ie[ATH6KL_MAX_IE];
+ struct sk_buff_head psq;
+ spinlock_t psq_lock;
+};
+
+struct ath6kl_version {
+ u32 target_ver;
+ u32 wlan_ver;
+ u32 abi_ver;
+};
+
+struct ath6kl_bmi {
+ u32 cmd_credits;
+ bool done_sent;
+ u8 *cmd_buf;
+};
+
+struct target_stats {
+ u64 tx_pkt;
+ u64 tx_byte;
+ u64 tx_ucast_pkt;
+ u64 tx_ucast_byte;
+ u64 tx_mcast_pkt;
+ u64 tx_mcast_byte;
+ u64 tx_bcast_pkt;
+ u64 tx_bcast_byte;
+ u64 tx_rts_success_cnt;
+ u64 tx_pkt_per_ac[4];
+
+ u64 tx_err;
+ u64 tx_fail_cnt;
+ u64 tx_retry_cnt;
+ u64 tx_mult_retry_cnt;
+ u64 tx_rts_fail_cnt;
+
+ u64 rx_pkt;
+ u64 rx_byte;
+ u64 rx_ucast_pkt;
+ u64 rx_ucast_byte;
+ u64 rx_mcast_pkt;
+ u64 rx_mcast_byte;
+ u64 rx_bcast_pkt;
+ u64 rx_bcast_byte;
+ u64 rx_frgment_pkt;
+
+ u64 rx_err;
+ u64 rx_crc_err;
+ u64 rx_key_cache_miss;
+ u64 rx_decrypt_err;
+ u64 rx_dupl_frame;
+
+ u64 tkip_local_mic_fail;
+ u64 tkip_cnter_measures_invoked;
+ u64 tkip_replays;
+ u64 tkip_fmt_err;
+ u64 ccmp_fmt_err;
+ u64 ccmp_replays;
+
+ u64 pwr_save_fail_cnt;
+
+ u64 cs_bmiss_cnt;
+ u64 cs_low_rssi_cnt;
+ u64 cs_connect_cnt;
+ u64 cs_discon_cnt;
+
+ s32 tx_ucast_rate;
+ s32 rx_ucast_rate;
+
+ u32 lq_val;
+
+ u32 wow_pkt_dropped;
+ u16 wow_evt_discarded;
+
+ s16 noise_floor_calib;
+ s16 cs_rssi;
+ s16 cs_ave_beacon_rssi;
+ u8 cs_ave_beacon_snr;
+ u8 cs_last_roam_msec;
+ u8 cs_snr;
+
+ u8 wow_host_pkt_wakeups;
+ u8 wow_host_evt_wakeups;
+
+ u32 arp_received;
+ u32 arp_matched;
+ u32 arp_replied;
+};
+
+struct ath6kl_mbox_info {
+ u32 htc_addr;
+ u32 htc_ext_addr;
+ u32 htc_ext_sz;
+
+ u32 block_size;
+
+ u32 gmbox_addr;
+
+ u32 gmbox_sz;
+};
+
+/*
+ * 802.11i defines an extended IV for use with non-WEP ciphers.
+ * When the EXTIV bit is set in the key id byte an additional
+ * 4 bytes immediately follow the IV for TKIP. For CCMP the
+ * EXTIV bit is likewise set but the 8 bytes represent the
+ * CCMP header rather than IV+extended-IV.
+ */
+
+#define ATH6KL_KEYBUF_SIZE 16
+#define ATH6KL_MICBUF_SIZE (8+8) /* space for both tx and rx */
+
+#define ATH6KL_KEY_XMIT 0x01
+#define ATH6KL_KEY_RECV 0x02
+#define ATH6KL_KEY_DEFAULT 0x80 /* default xmit key */
+
+/*
+ * WPA/RSN get/set key request. Specify the key/cipher
+ * type and whether the key is to be used for sending and/or
+ * receiving. The key index should be set only when working
+ * with global keys (use IEEE80211_KEYIX_NONE for ``no index'').
+ * Otherwise a unicast/pairwise key is specified by the bssid
+ * (on a station) or mac address (on an ap). They key length
+ * must include any MIC key data; otherwise it should be no
+ * more than ATH6KL_KEYBUF_SIZE.
+ */
+struct ath6kl_req_key {
+ u8 ik_type; /* key/cipher type */
+ u8 ik_pad;
+ u16 ik_keyix; /* key index */
+ u8 ik_keylen; /* key length in bytes */
+ u8 ik_flags;
+ u8 ik_macaddr[ETH_ALEN];
+ u64 ik_keyrsc; /* key receive sequence counter */
+ u64 ik_keytsc; /* key transmit sequence counter */
+ u8 ik_keydata[ATH6KL_KEYBUF_SIZE + ATH6KL_MICBUF_SIZE];
+};
+
+/* Flag info */
+#define WMI_ENABLED 0
+#define WMI_READY 1
+#define CONNECTED 2
+#define STATS_UPDATE_PEND 3
+#define CONNECT_PEND 4
+#define WMM_ENABLED 5
+#define NETQ_STOPPED 6
+#define WMI_CTRL_EP_FULL 7
+#define DTIM_EXPIRED 8
+#define DESTROY_IN_PROGRESS 9
+#define NETDEV_REGISTERED 10
+#define SKIP_SCAN 11
+
+struct ath6kl {
+ struct device *dev;
+ struct net_device *net_dev;
+ struct ath6kl_bmi bmi;
+ const struct ath6kl_hif_ops *hif_ops;
+ struct wmi *wmi;
+ int tx_pending[ENDPOINT_MAX];
+ int total_tx_data_pend;
+ struct htc_target *htc_target;
+ void *hif_priv;
+ spinlock_t lock;
+ struct semaphore sem;
+ int ssid_len;
+ u8 ssid[IEEE80211_MAX_SSID_LEN];
+ u8 next_mode;
+ u8 nw_type;
+ u8 dot11_auth_mode;
+ u8 auth_mode;
+ u8 prwise_crypto;
+ u8 prwise_crypto_len;
+ u8 grp_crypto;
+ u8 grp_crpto_len;
+ u8 def_txkey_index;
+ struct ath6kl_wep_key wep_key_list[WMI_MAX_KEY_INDEX + 1];
+ u8 bssid[ETH_ALEN];
+ u8 req_bssid[ETH_ALEN];
+ u16 ch_hint;
+ u16 bss_ch;
+ u16 listen_intvl_b;
+ u16 listen_intvl_t;
+ struct ath6kl_version version;
+ u32 target_type;
+ u8 tx_pwr;
+ struct net_device_stats net_stats;
+ struct target_stats target_stats;
+ enum ath6kl_wlan_state wlan_state;
+ struct ath6kl_node_mapping node_map[MAX_NODE_NUM];
+ u8 ibss_ps_enable;
+ u8 node_num;
+ u8 next_ep_id;
+ struct ath6kl_cookie *cookie_list;
+ u32 cookie_count;
+ enum htc_endpoint_id ac2ep_map[WMM_NUM_AC];
+ bool ac_stream_active[WMM_NUM_AC];
+ u8 ac_stream_pri_map[WMM_NUM_AC];
+ u8 hiac_stream_active_pri;
+ u8 ep2ac_map[ENDPOINT_MAX];
+ enum htc_endpoint_id ctrl_ep;
+ struct htc_credit_state_info credit_state_info;
+ u32 connect_ctrl_flags;
+ u32 user_key_ctrl;
+ u8 usr_bss_filter;
+ struct ath6kl_sta sta_list[AP_MAX_NUM_STA];
+ u8 sta_list_index;
+ struct ath6kl_req_key ap_mode_bkey;
+ struct sk_buff_head mcastpsq;
+ spinlock_t mcastpsq_lock;
+ u8 intra_bss;
+ struct aggr_info *aggr_cntxt;
+ struct wmi_ap_mode_stat ap_stats;
+ u8 ap_country_code[3];
+ struct list_head amsdu_rx_buffer_queue;
+ struct timer_list disconnect_timer;
+ u8 rx_meta_ver;
+ struct wireless_dev *wdev;
+ struct cfg80211_scan_request *scan_req;
+ struct ath6kl_key keys[WMI_MAX_KEY_INDEX + 1];
+ enum sme_state sme_state;
+ enum wlan_low_pwr_state wlan_pwr_state;
+ struct wmi_scan_params_cmd sc_params;
+#define AR_MCAST_FILTER_MAC_ADDR_SIZE 4
+ u8 auto_auth_stage;
+
+ u16 conf_flags;
+ wait_queue_head_t event_wq;
+ struct ath6kl_mbox_info mbox_info;
+
+ struct ath6kl_cookie cookie_mem[MAX_COOKIE_NUM];
+ int reconnect_flag;
+ unsigned long flag;
+
+ u8 *fw_board;
+ size_t fw_board_len;
+
+ u8 *fw_otp;
+ size_t fw_otp_len;
+
+ u8 *fw;
+ size_t fw_len;
+
+ u8 *fw_patch;
+ size_t fw_patch_len;
+
+ struct workqueue_struct *ath6kl_wq;
+};
+
+static inline void *ath6kl_priv(struct net_device *dev)
+{
+ return wdev_priv(dev->ieee80211_ptr);
+}
+
+static inline void ath6kl_deposit_credit_to_ep(struct htc_credit_state_info
+ *cred_info,
+ struct htc_endpoint_credit_dist
+ *ep_dist, int credits)
+{
+ ep_dist->credits += credits;
+ ep_dist->cred_assngd += credits;
+ cred_info->cur_free_credits -= credits;
+}
+
+void ath6kl_destroy(struct net_device *dev, unsigned int unregister);
+int ath6kl_configure_target(struct ath6kl *ar);
+void ath6kl_detect_error(unsigned long ptr);
+void disconnect_timer_handler(unsigned long ptr);
+void init_netdev(struct net_device *dev);
+void ath6kl_cookie_init(struct ath6kl *ar);
+void ath6kl_cookie_cleanup(struct ath6kl *ar);
+void ath6kl_rx(struct htc_target *target, struct htc_packet *packet);
+void ath6kl_tx_complete(void *context, struct list_head *packet_queue);
+enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
+ struct htc_packet *packet);
+void ath6kl_stop_txrx(struct ath6kl *ar);
+void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar);
+int ath6kl_access_datadiag(struct ath6kl *ar, u32 address,
+ u8 *data, u32 length, bool read);
+int ath6kl_read_reg_diag(struct ath6kl *ar, u32 *address, u32 *data);
+void ath6kl_init_profile_info(struct ath6kl *ar);
+void ath6kl_tx_data_cleanup(struct ath6kl *ar);
+void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
+ bool get_dbglogs);
+
+struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar);
+void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie);
+int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev);
+
+struct aggr_info *aggr_init(struct net_device *dev);
+void ath6kl_rx_refill(struct htc_target *target,
+ enum htc_endpoint_id endpoint);
+void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count);
+struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target,
+ enum htc_endpoint_id endpoint,
+ int len);
+void aggr_module_destroy(struct aggr_info *aggr_info);
+void aggr_reset_state(struct aggr_info *aggr_info);
+
+struct ath6kl_sta *ath6kl_find_sta(struct ath6kl *ar, u8 * node_addr);
+struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid);
+
+void ath6kl_ready_event(void *devt, u8 * datap, u32 sw_ver, u32 abi_ver);
+int ath6kl_control_tx(void *devt, struct sk_buff *skb,
+ enum htc_endpoint_id eid);
+void ath6kl_connect_event(struct ath6kl *ar, u16 channel,
+ u8 *bssid, u16 listen_int,
+ u16 beacon_int, enum network_type net_type,
+ u8 beacon_ie_len, u8 assoc_req_len,
+ u8 assoc_resp_len, u8 *assoc_info);
+void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason,
+ u8 *bssid, u8 assoc_resp_len,
+ u8 *assoc_info, u16 prot_reason_status);
+void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast);
+void ath6kl_txpwr_rx_evt(void *devt, u8 tx_pwr);
+void ath6kl_scan_complete_evt(struct ath6kl *ar, int status);
+void ath6kl_tgt_stats_event(struct ath6kl *ar, u8 *ptr, u32 len);
+void ath6kl_indicate_tx_activity(void *devt, u8 traffic_class, bool active);
+enum htc_endpoint_id ath6kl_ac2_endpoint_id(void *devt, u8 ac);
+
+void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid);
+
+void ath6kl_dtimexpiry_event(struct ath6kl *ar);
+void ath6kl_disconnect(struct ath6kl *ar);
+void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid);
+void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no,
+ u8 win_sz);
+void ath6kl_wakeup_event(void *dev);
+void ath6kl_target_failure(struct ath6kl *ar);
+
+#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath/ath6kl/debug.c b/drivers/net/wireless/ath/ath6kl/debug.c
new file mode 100644
index 000000000000..316136c8b903
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/debug.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications Inc.
+ *
+ * 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 "core.h"
+#include "debug.h"
+
+int ath6kl_printk(const char *level, const char *fmt, ...)
+{
+ struct va_format vaf;
+ va_list args;
+ int rtn;
+
+ va_start(args, fmt);
+
+ vaf.fmt = fmt;
+ vaf.va = &args;
+
+ rtn = printk("%sath6kl: %pV", level, &vaf);
+
+ va_end(args);
+
+ return rtn;
+}
+
+#ifdef CONFIG_ATH6KL_DEBUG
+void ath6kl_dump_registers(struct ath6kl_device *dev,
+ struct ath6kl_irq_proc_registers *irq_proc_reg,
+ struct ath6kl_irq_enable_reg *irq_enable_reg)
+{
+
+ ath6kl_dbg(ATH6KL_DBG_ANY, ("<------- Register Table -------->\n"));
+
+ if (irq_proc_reg != NULL) {
+ ath6kl_dbg(ATH6KL_DBG_ANY,
+ "Host Int status: 0x%x\n",
+ irq_proc_reg->host_int_status);
+ ath6kl_dbg(ATH6KL_DBG_ANY,
+ "CPU Int status: 0x%x\n",
+ irq_proc_reg->cpu_int_status);
+ ath6kl_dbg(ATH6KL_DBG_ANY,
+ "Error Int status: 0x%x\n",
+ irq_proc_reg->error_int_status);
+ ath6kl_dbg(ATH6KL_DBG_ANY,
+ "Counter Int status: 0x%x\n",
+ irq_proc_reg->counter_int_status);
+ ath6kl_dbg(ATH6KL_DBG_ANY,
+ "Mbox Frame: 0x%x\n",
+ irq_proc_reg->mbox_frame);
+ ath6kl_dbg(ATH6KL_DBG_ANY,
+ "Rx Lookahead Valid: 0x%x\n",
+ irq_proc_reg->rx_lkahd_valid);
+ ath6kl_dbg(ATH6KL_DBG_ANY,
+ "Rx Lookahead 0: 0x%x\n",
+ irq_proc_reg->rx_lkahd[0]);
+ ath6kl_dbg(ATH6KL_DBG_ANY,
+ "Rx Lookahead 1: 0x%x\n",
+ irq_proc_reg->rx_lkahd[1]);
+
+ if (dev->ar->mbox_info.gmbox_addr != 0) {
+ /*
+ * If the target supports GMBOX hardware, dump some
+ * additional state.
+ */
+ ath6kl_dbg(ATH6KL_DBG_ANY,
+ "GMBOX Host Int status 2: 0x%x\n",
+ irq_proc_reg->host_int_status2);
+ ath6kl_dbg(ATH6KL_DBG_ANY,
+ "GMBOX RX Avail: 0x%x\n",
+ irq_proc_reg->gmbox_rx_avail);
+ ath6kl_dbg(ATH6KL_DBG_ANY,
+ "GMBOX lookahead alias 0: 0x%x\n",
+ irq_proc_reg->rx_gmbox_lkahd_alias[0]);
+ ath6kl_dbg(ATH6KL_DBG_ANY,
+ "GMBOX lookahead alias 1: 0x%x\n",
+ irq_proc_reg->rx_gmbox_lkahd_alias[1]);
+ }
+
+ }
+
+ if (irq_enable_reg != NULL) {
+ ath6kl_dbg(ATH6KL_DBG_ANY,
+ "Int status Enable: 0x%x\n",
+ irq_enable_reg->int_status_en);
+ ath6kl_dbg(ATH6KL_DBG_ANY, "Counter Int status Enable: 0x%x\n",
+ irq_enable_reg->cntr_int_status_en);
+ }
+ ath6kl_dbg(ATH6KL_DBG_ANY, "<------------------------------->\n");
+}
+
+static void dump_cred_dist(struct htc_endpoint_credit_dist *ep_dist)
+{
+ ath6kl_dbg(ATH6KL_DBG_ANY,
+ "--- endpoint: %d svc_id: 0x%X ---\n",
+ ep_dist->endpoint, ep_dist->svc_id);
+ ath6kl_dbg(ATH6KL_DBG_ANY, " dist_flags : 0x%X\n",
+ ep_dist->dist_flags);
+ ath6kl_dbg(ATH6KL_DBG_ANY, " cred_norm : %d\n",
+ ep_dist->cred_norm);
+ ath6kl_dbg(ATH6KL_DBG_ANY, " cred_min : %d\n",
+ ep_dist->cred_min);
+ ath6kl_dbg(ATH6KL_DBG_ANY, " credits : %d\n",
+ ep_dist->credits);
+ ath6kl_dbg(ATH6KL_DBG_ANY, " cred_assngd : %d\n",
+ ep_dist->cred_assngd);
+ ath6kl_dbg(ATH6KL_DBG_ANY, " seek_cred : %d\n",
+ ep_dist->seek_cred);
+ ath6kl_dbg(ATH6KL_DBG_ANY, " cred_sz : %d\n",
+ ep_dist->cred_sz);
+ ath6kl_dbg(ATH6KL_DBG_ANY, " cred_per_msg : %d\n",
+ ep_dist->cred_per_msg);
+ ath6kl_dbg(ATH6KL_DBG_ANY, " cred_to_dist : %d\n",
+ ep_dist->cred_to_dist);
+ ath6kl_dbg(ATH6KL_DBG_ANY, " txq_depth : %d\n",
+ get_queue_depth(&((struct htc_endpoint *)
+ ep_dist->htc_rsvd)->txq));
+ ath6kl_dbg(ATH6KL_DBG_ANY,
+ "----------------------------------\n");
+}
+
+void dump_cred_dist_stats(struct htc_target *target)
+{
+ struct htc_endpoint_credit_dist *ep_list;
+
+ if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_TRC))
+ return;
+
+ list_for_each_entry(ep_list, &target->cred_dist_list, list)
+ dump_cred_dist(ep_list);
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:%p dist:%p\n",
+ target->cred_dist_cntxt, NULL);
+ ath6kl_dbg(ATH6KL_DBG_TRC, "credit distribution, total : %d, free : %d\n",
+ target->cred_dist_cntxt->total_avail_credits,
+ target->cred_dist_cntxt->cur_free_credits);
+}
+
+#endif
diff --git a/drivers/net/wireless/ath/ath6kl/debug.h b/drivers/net/wireless/ath/ath6kl/debug.h
new file mode 100644
index 000000000000..2e6058856a6a
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/debug.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2011 Atheros Communications Inc.
+ *
+ * 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.
+ */
+
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#include "htc_hif.h"
+
+enum ATH6K_DEBUG_MASK {
+ ATH6KL_DBG_WLAN_CONNECT = BIT(0), /* wlan connect */
+ ATH6KL_DBG_WLAN_SCAN = BIT(1), /* wlan scan */
+ ATH6KL_DBG_WLAN_TX = BIT(2), /* wlan tx */
+ ATH6KL_DBG_WLAN_RX = BIT(3), /* wlan rx */
+ ATH6KL_DBG_BMI = BIT(4), /* bmi tracing */
+ ATH6KL_DBG_HTC_SEND = BIT(5), /* htc send */
+ ATH6KL_DBG_HTC_RECV = BIT(6), /* htc recv */
+ ATH6KL_DBG_IRQ = BIT(7), /* interrupt processing */
+ ATH6KL_DBG_PM = BIT(8), /* power management */
+ ATH6KL_DBG_WLAN_NODE = BIT(9), /* general wlan node tracing */
+ ATH6KL_DBG_WMI = BIT(10), /* wmi tracing */
+ ATH6KL_DBG_TRC = BIT(11), /* generic func tracing */
+ ATH6KL_DBG_SCATTER = BIT(12), /* hif scatter tracing */
+ ATH6KL_DBG_WLAN_CFG = BIT(13), /* cfg80211 i/f file tracing */
+ ATH6KL_DBG_RAW_BYTES = BIT(14), /* dump tx/rx and wmi frames */
+ ATH6KL_DBG_ANY = 0xffffffff /* enable all logs */
+};
+
+extern unsigned int debug_mask;
+extern int ath6kl_printk(const char *level, const char *fmt, ...)
+ __attribute__ ((format (printf, 2, 3)));
+
+#define ath6kl_info(fmt, ...) \
+ ath6kl_printk(KERN_INFO, fmt, ##__VA_ARGS__)
+#define ath6kl_err(fmt, ...) \
+ ath6kl_printk(KERN_ERR, fmt, ##__VA_ARGS__)
+#define ath6kl_warn(fmt, ...) \
+ ath6kl_printk(KERN_WARNING, fmt, ##__VA_ARGS__)
+
+#define AR_DBG_LVL_CHECK(mask) (debug_mask & mask)
+
+#ifdef CONFIG_ATH6KL_DEBUG
+#define ath6kl_dbg(mask, fmt, ...) \
+ ({ \
+ int rtn; \
+ if (debug_mask & mask) \
+ rtn = ath6kl_printk(KERN_DEBUG, fmt, ##__VA_ARGS__); \
+ else \
+ rtn = 0; \
+ \
+ rtn; \
+ })
+
+static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
+ const char *msg, const void *buf,
+ size_t len)
+{
+ if (debug_mask & mask) {
+ ath6kl_dbg(mask, "%s\n", msg);
+ print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, buf, len);
+ }
+}
+
+void ath6kl_dump_registers(struct ath6kl_device *dev,
+ struct ath6kl_irq_proc_registers *irq_proc_reg,
+ struct ath6kl_irq_enable_reg *irq_en_reg);
+void dump_cred_dist_stats(struct htc_target *target);
+#else
+static inline int ath6kl_dbg(enum ATH6K_DEBUG_MASK dbg_mask,
+ const char *fmt, ...)
+{
+ return 0;
+}
+
+static inline void ath6kl_dbg_dump(enum ATH6K_DEBUG_MASK mask,
+ const char *msg, const void *buf,
+ size_t len)
+{
+}
+
+static inline void ath6kl_dump_registers(struct ath6kl_device *dev,
+ struct ath6kl_irq_proc_registers *irq_proc_reg,
+ struct ath6kl_irq_enable_reg *irq_en_reg)
+{
+
+}
+static inline void dump_cred_dist_stats(struct htc_target *target)
+{
+}
+#endif
+
+#endif
diff --git a/drivers/net/wireless/ath/ath6kl/hif-ops.h b/drivers/net/wireless/ath/ath6kl/hif-ops.h
new file mode 100644
index 000000000000..ad4966917e84
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/hif-ops.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications Inc.
+ *
+ * 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.
+ */
+
+#ifndef HIF_OPS_H
+#define HIF_OPS_H
+
+#include "hif.h"
+
+static inline int hif_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf,
+ u32 len, u32 request)
+{
+ return ar->hif_ops->read_write_sync(ar, addr, buf, len, request);
+}
+
+static inline int hif_write_async(struct ath6kl *ar, u32 address, u8 *buffer,
+ u32 length, u32 request,
+ struct htc_packet *packet)
+{
+ return ar->hif_ops->write_async(ar, address, buffer, length,
+ request, packet);
+}
+static inline void ath6kl_hif_irq_enable(struct ath6kl *ar)
+{
+ return ar->hif_ops->irq_enable(ar);
+}
+
+static inline void ath6kl_hif_irq_disable(struct ath6kl *ar)
+{
+ return ar->hif_ops->irq_disable(ar);
+}
+
+static inline struct hif_scatter_req *hif_scatter_req_get(struct ath6kl *ar)
+{
+ return ar->hif_ops->scatter_req_get(ar);
+}
+
+static inline void hif_scatter_req_add(struct ath6kl *ar,
+ struct hif_scatter_req *s_req)
+{
+ return ar->hif_ops->scatter_req_add(ar, s_req);
+}
+
+static inline int ath6kl_hif_enable_scatter(struct ath6kl *ar,
+ struct hif_dev_scat_sup_info *info)
+{
+ return ar->hif_ops->enable_scatter(ar, info);
+}
+
+static inline void ath6kl_hif_cleanup_scatter(struct ath6kl *ar)
+{
+ return ar->hif_ops->cleanup_scatter(ar);
+}
+
+#endif
diff --git a/drivers/net/wireless/ath/ath6kl/hif.h b/drivers/net/wireless/ath/ath6kl/hif.h
new file mode 100644
index 000000000000..7d39c1769fe4
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/hif.h
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications Inc.
+ *
+ * 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.
+ */
+
+#ifndef HIF_H
+#define HIF_H
+
+#include "common.h"
+#include "core.h"
+
+#include <linux/scatterlist.h>
+
+#define BUS_REQUEST_MAX_NUM 64
+#define HIF_MBOX_BLOCK_SIZE 128
+#define HIF_MBOX0_BLOCK_SIZE 1
+
+#define HIF_DMA_BUFFER_SIZE (32 * 1024)
+#define CMD53_FIXED_ADDRESS 1
+#define CMD53_INCR_ADDRESS 2
+
+#define MAX_SCATTER_REQUESTS 4
+#define MAX_SCATTER_ENTRIES_PER_REQ 16
+#define MAX_SCATTER_REQ_TRANSFER_SIZE (32 * 1024)
+
+#define MANUFACTURER_ID_AR6003_BASE 0x300
+ /* SDIO manufacturer ID and Codes */
+#define MANUFACTURER_ID_ATH6KL_BASE_MASK 0xFF00
+#define MANUFACTURER_CODE 0x271 /* Atheros */
+
+/* Mailbox address in SDIO address space */
+#define HIF_MBOX_BASE_ADDR 0x800
+#define HIF_MBOX_WIDTH 0x800
+
+#define HIF_MBOX_END_ADDR (HTC_MAILBOX_NUM_MAX * HIF_MBOX_WIDTH - 1)
+
+/* version 1 of the chip has only a 12K extended mbox range */
+#define HIF_MBOX0_EXT_BASE_ADDR 0x4000
+#define HIF_MBOX0_EXT_WIDTH (12*1024)
+
+/* GMBOX addresses */
+#define HIF_GMBOX_BASE_ADDR 0x7000
+#define HIF_GMBOX_WIDTH 0x4000
+
+/* interrupt mode register */
+#define CCCR_SDIO_IRQ_MODE_REG 0xF0
+
+/* mode to enable special 4-bit interrupt assertion without clock */
+#define SDIO_IRQ_MODE_ASYNC_4BIT_IRQ (1 << 0)
+
+struct bus_request {
+ struct list_head list;
+
+ /* request data */
+ u32 address;
+
+ u8 *buffer;
+ u32 length;
+ u32 request;
+ struct htc_packet *packet;
+ int status;
+
+ /* this is a scatter request */
+ struct hif_scatter_req *scat_req;
+};
+
+/* direction of transfer (read/write) */
+#define HIF_READ 0x00000001
+#define HIF_WRITE 0x00000002
+#define HIF_DIR_MASK (HIF_READ | HIF_WRITE)
+
+/*
+ * emode - This indicates the whether the command is to be executed in a
+ * blocking or non-blocking fashion (HIF_SYNCHRONOUS/
+ * HIF_ASYNCHRONOUS). The read/write data paths in HTC have been
+ * implemented using the asynchronous mode allowing the the bus
+ * driver to indicate the completion of operation through the
+ * registered callback routine. The requirement primarily comes
+ * from the contexts these operations get called from (a driver's
+ * transmit context or the ISR context in case of receive).
+ * Support for both of these modes is essential.
+ */
+#define HIF_SYNCHRONOUS 0x00000010
+#define HIF_ASYNCHRONOUS 0x00000020
+#define HIF_EMODE_MASK (HIF_SYNCHRONOUS | HIF_ASYNCHRONOUS)
+
+/*
+ * dmode - An interface may support different kinds of commands based on
+ * the tradeoff between the amount of data it can carry and the
+ * setup time. Byte and Block modes are supported (HIF_BYTE_BASIS/
+ * HIF_BLOCK_BASIS). In case of latter, the data is rounded off
+ * to the nearest block size by padding. The size of the block is
+ * configurable at compile time using the HIF_BLOCK_SIZE and is
+ * negotiated with the target during initialization after the
+ * ATH6KL interrupts are enabled.
+ */
+#define HIF_BYTE_BASIS 0x00000040
+#define HIF_BLOCK_BASIS 0x00000080
+#define HIF_DMODE_MASK (HIF_BYTE_BASIS | HIF_BLOCK_BASIS)
+
+/*
+ * amode - This indicates if the address has to be incremented on ATH6KL
+ * after every read/write operation (HIF?FIXED_ADDRESS/
+ * HIF_INCREMENTAL_ADDRESS).
+ */
+#define HIF_FIXED_ADDRESS 0x00000100
+#define HIF_INCREMENTAL_ADDRESS 0x00000200
+#define HIF_AMODE_MASK (HIF_FIXED_ADDRESS | HIF_INCREMENTAL_ADDRESS)
+
+#define HIF_WR_ASYNC_BYTE_INC \
+ (HIF_WRITE | HIF_ASYNCHRONOUS | \
+ HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
+
+#define HIF_WR_ASYNC_BLOCK_INC \
+ (HIF_WRITE | HIF_ASYNCHRONOUS | \
+ HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
+
+#define HIF_WR_SYNC_BYTE_FIX \
+ (HIF_WRITE | HIF_SYNCHRONOUS | \
+ HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
+
+#define HIF_WR_SYNC_BYTE_INC \
+ (HIF_WRITE | HIF_SYNCHRONOUS | \
+ HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
+
+#define HIF_WR_SYNC_BLOCK_INC \
+ (HIF_WRITE | HIF_SYNCHRONOUS | \
+ HIF_BLOCK_BASIS | HIF_INCREMENTAL_ADDRESS)
+
+#define HIF_RD_SYNC_BYTE_INC \
+ (HIF_READ | HIF_SYNCHRONOUS | \
+ HIF_BYTE_BASIS | HIF_INCREMENTAL_ADDRESS)
+
+#define HIF_RD_SYNC_BYTE_FIX \
+ (HIF_READ | HIF_SYNCHRONOUS | \
+ HIF_BYTE_BASIS | HIF_FIXED_ADDRESS)
+
+#define HIF_RD_ASYNC_BLOCK_FIX \
+ (HIF_READ | HIF_ASYNCHRONOUS | \
+ HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
+
+#define HIF_RD_SYNC_BLOCK_FIX \
+ (HIF_READ | HIF_SYNCHRONOUS | \
+ HIF_BLOCK_BASIS | HIF_FIXED_ADDRESS)
+
+struct hif_scatter_item {
+ u8 *buf;
+ int len;
+ struct htc_packet *packet;
+};
+
+struct hif_scatter_req {
+ struct list_head list;
+ /* address for the read/write operation */
+ u32 addr;
+
+ /* request flags */
+ u32 req;
+
+ /* total length of entire transfer */
+ u32 len;
+
+ u32 flags;
+ void (*complete) (struct hif_scatter_req *);
+ int status;
+ struct htc_endpoint *ep;
+ int scat_entries;
+
+ struct hif_scatter_req_priv *req_priv;
+
+ /* bounce buffer for upper layers to copy to/from */
+ u8 *virt_dma_buf;
+
+ struct hif_scatter_item scat_list[1];
+};
+
+struct hif_dev_scat_sup_info {
+ int (*rw_scat_func) (struct ath6kl *ar, struct hif_scatter_req *);
+ int max_scat_entries;
+ int max_xfer_szper_scatreq;
+};
+
+struct hif_scatter_req_priv {
+ struct bus_request *busrequest;
+ struct scatterlist sgentries[MAX_SCATTER_ENTRIES_PER_REQ];
+};
+
+struct ath6kl_hif_ops {
+ int (*read_write_sync)(struct ath6kl *ar, u32 addr, u8 *buf,
+ u32 len, u32 request);
+ int (*write_async)(struct ath6kl *ar, u32 address, u8 *buffer,
+ u32 length, u32 request, struct htc_packet *packet);
+
+ void (*irq_enable)(struct ath6kl *ar);
+ void (*irq_disable)(struct ath6kl *ar);
+
+ struct hif_scatter_req *(*scatter_req_get)(struct ath6kl *ar);
+ void (*scatter_req_add)(struct ath6kl *ar,
+ struct hif_scatter_req *s_req);
+ int (*enable_scatter)(struct ath6kl *ar,
+ struct hif_dev_scat_sup_info *info);
+ void (*cleanup_scatter)(struct ath6kl *ar);
+};
+
+#endif
diff --git a/drivers/net/wireless/ath/ath6kl/htc.c b/drivers/net/wireless/ath/ath6kl/htc.c
new file mode 100644
index 000000000000..95c47bbd1d78
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/htc.c
@@ -0,0 +1,2466 @@
+/*
+ * Copyright (c) 2007-2011 Atheros Communications Inc.
+ *
+ * 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 "core.h"
+#include "htc_hif.h"
+#include "debug.h"
+#include "hif-ops.h"
+#include <asm/unaligned.h>
+
+#define CALC_TXRX_PADDED_LEN(dev, len) (__ALIGN_MASK((len), (dev)->block_mask))
+
+static void htc_prep_send_pkt(struct htc_packet *packet, u8 flags, int ctrl0,
+ int ctrl1)
+{
+ struct htc_frame_hdr *hdr;
+
+ packet->buf -= HTC_HDR_LENGTH;
+ hdr = (struct htc_frame_hdr *)packet->buf;
+
+ /* Endianess? */
+ put_unaligned((u16)packet->act_len, &hdr->payld_len);
+ hdr->flags = flags;
+ hdr->eid = packet->endpoint;
+ hdr->ctrl[0] = ctrl0;
+ hdr->ctrl[1] = ctrl1;
+}
+
+static void htc_reclaim_txctrl_buf(struct htc_target *target,
+ struct htc_packet *pkt)
+{
+ spin_lock_bh(&target->htc_lock);
+ list_add_tail(&pkt->list, &target->free_ctrl_txbuf);
+ spin_unlock_bh(&target->htc_lock);
+}
+
+static struct htc_packet *htc_get_control_buf(struct htc_target *target,
+ bool tx)
+{
+ struct htc_packet *packet = NULL;
+ struct list_head *buf_list;
+
+ buf_list = tx ? &target->free_ctrl_txbuf : &target->free_ctrl_rxbuf;
+
+ spin_lock_bh(&target->htc_lock);
+
+ if (list_empty(buf_list)) {
+ spin_unlock_bh(&target->htc_lock);
+ return NULL;
+ }
+
+ packet = list_first_entry(buf_list, struct htc_packet, list);
+ list_del(&packet->list);
+ spin_unlock_bh(&target->htc_lock);
+
+ if (tx)
+ packet->buf = packet->buf_start + HTC_HDR_LENGTH;
+
+ return packet;
+}
+
+static void htc_tx_comp_update(struct htc_target *target,
+ struct htc_endpoint *endpoint,
+ struct htc_packet *packet)
+{
+ packet->completion = NULL;
+ packet->buf += HTC_HDR_LENGTH;
+
+ if (!packet->status)
+ return;
+
+ ath6kl_err("req failed (status:%d, ep:%d, len:%d creds:%d)\n",
+ packet->status, packet->endpoint, packet->act_len,
+ packet->info.tx.cred_used);
+
+ /* on failure to submit, reclaim credits for this packet */
+ spin_lock_bh(&target->tx_lock);
+ endpoint->cred_dist.cred_to_dist +=
+ packet->info.tx.cred_used;
+ endpoint->cred_dist.txq_depth = get_queue_depth(&endpoint->txq);
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n",
+ target->cred_dist_cntxt, &target->cred_dist_list);
+
+ ath6k_credit_distribute(target->cred_dist_cntxt,
+ &target->cred_dist_list,
+ HTC_CREDIT_DIST_SEND_COMPLETE);
+
+ spin_unlock_bh(&target->tx_lock);
+}
+
+static void htc_tx_complete(struct htc_endpoint *endpoint,
+ struct list_head *txq)
+{
+ if (list_empty(txq))
+ return;
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+ "send complete ep %d, (%d pkts)\n",
+ endpoint->eid, get_queue_depth(txq));
+
+ ath6kl_tx_complete(endpoint->target->dev->ar, txq);
+}
+
+static void htc_tx_comp_handler(struct htc_target *target,
+ struct htc_packet *packet)
+{
+ struct htc_endpoint *endpoint = &target->endpoint[packet->endpoint];
+ struct list_head container;
+
+ htc_tx_comp_update(target, endpoint, packet);
+ INIT_LIST_HEAD(&container);
+ list_add_tail(&packet->list, &container);
+ /* do completion */
+ htc_tx_complete(endpoint, &container);
+}
+
+static void htc_async_tx_scat_complete(struct hif_scatter_req *scat_req)
+{
+ struct htc_endpoint *endpoint = scat_req->ep;
+ struct htc_target *target = endpoint->target;
+ struct htc_packet *packet;
+ struct list_head tx_compq;
+ int i;
+
+ INIT_LIST_HEAD(&tx_compq);
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+ "htc_async_tx_scat_complete total len: %d entries: %d\n",
+ scat_req->len, scat_req->scat_entries);
+
+ if (scat_req->status)
+ ath6kl_err("send scatter req failed: %d\n", scat_req->status);
+
+ /* walk through the scatter list and process */
+ for (i = 0; i < scat_req->scat_entries; i++) {
+ packet = scat_req->scat_list[i].packet;
+ if (!packet) {
+ WARN_ON(1);
+ return;
+ }
+
+ packet->status = scat_req->status;
+ htc_tx_comp_update(target, endpoint, packet);
+ list_add_tail(&packet->list, &tx_compq);
+ }
+
+ /* free scatter request */
+ hif_scatter_req_add(target->dev->ar, scat_req);
+
+ /* complete all packets */
+ htc_tx_complete(endpoint, &tx_compq);
+}
+
+static int htc_issue_send(struct htc_target *target, struct htc_packet *packet)
+{
+ int status;
+ bool sync = false;
+ u32 padded_len, send_len;
+
+ if (!packet->completion)
+ sync = true;
+
+ send_len = packet->act_len + HTC_HDR_LENGTH;
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "%s: transmit len : %d (%s)\n",
+ __func__, send_len, sync ? "sync" : "async");
+
+ padded_len = CALC_TXRX_PADDED_LEN(target->dev, send_len);
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+ "DevSendPacket, padded len: %d mbox:0x%X (mode:%s)\n",
+ padded_len,
+ target->dev->ar->mbox_info.htc_addr,
+ sync ? "sync" : "async");
+
+ if (sync) {
+ status = hif_read_write_sync(target->dev->ar,
+ target->dev->ar->mbox_info.htc_addr,
+ packet->buf, padded_len,
+ HIF_WR_SYNC_BLOCK_INC);
+
+ packet->status = status;
+ packet->buf += HTC_HDR_LENGTH;
+ } else
+ status = hif_write_async(target->dev->ar,
+ target->dev->ar->mbox_info.htc_addr,
+ packet->buf, padded_len,
+ HIF_WR_ASYNC_BLOCK_INC, packet);
+
+ return status;
+}
+
+static int htc_check_credits(struct htc_target *target,
+ struct htc_endpoint *ep, u8 *flags,
+ enum htc_endpoint_id eid, unsigned int len,
+ int *req_cred)
+{
+
+ *req_cred = (len > target->tgt_cred_sz) ?
+ DIV_ROUND_UP(len, target->tgt_cred_sz) : 1;
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "creds required:%d got:%d\n",
+ *req_cred, ep->cred_dist.credits);
+
+ if (ep->cred_dist.credits < *req_cred) {
+ if (eid == ENDPOINT_0)
+ return -EINVAL;
+
+ /* Seek more credits */
+ ep->cred_dist.seek_cred = *req_cred - ep->cred_dist.credits;
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n",
+ target->cred_dist_cntxt, &ep->cred_dist);
+
+ ath6k_seek_credits(target->cred_dist_cntxt, &ep->cred_dist);
+
+ ep->cred_dist.seek_cred = 0;
+
+ if (ep->cred_dist.credits < *req_cred) {
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+ "not enough credits for ep %d - leaving packet in queue\n",
+ eid);
+ return -EINVAL;
+ }
+ }
+
+ ep->cred_dist.credits -= *req_cred;
+ ep->ep_st.cred_cosumd += *req_cred;
+
+ /* When we are getting low on credits, ask for more */
+ if (ep->cred_dist.credits < ep->cred_dist.cred_per_msg) {
+ ep->cred_dist.seek_cred =
+ ep->cred_dist.cred_per_msg - ep->cred_dist.credits;
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n",
+ target->cred_dist_cntxt, &ep->cred_dist);
+
+ ath6k_seek_credits(target->cred_dist_cntxt, &ep->cred_dist);
+
+ /* see if we were successful in getting more */
+ if (ep->cred_dist.credits < ep->cred_dist.cred_per_msg) {
+ /* tell the target we need credits ASAP! */
+ *flags |= HTC_FLAGS_NEED_CREDIT_UPDATE;
+ ep->ep_st.cred_low_indicate += 1;
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "host needs credits\n");
+ }
+ }
+
+ return 0;
+}
+
+static void htc_tx_pkts_get(struct htc_target *target,
+ struct htc_endpoint *endpoint,
+ struct list_head *queue)
+{
+ int req_cred;
+ u8 flags;
+ struct htc_packet *packet;
+ unsigned int len;
+
+ while (true) {
+
+ flags = 0;
+
+ if (list_empty(&endpoint->txq))
+ break;
+ packet = list_first_entry(&endpoint->txq, struct htc_packet,
+ list);
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+ "got head pkt:0x%p , queue depth: %d\n",
+ packet, get_queue_depth(&endpoint->txq));
+
+ len = CALC_TXRX_PADDED_LEN(target->dev,
+ packet->act_len + HTC_HDR_LENGTH);
+
+ if (htc_check_credits(target, endpoint, &flags,
+ packet->endpoint, len, &req_cred))
+ break;
+
+ /* now we can fully move onto caller's queue */
+ packet = list_first_entry(&endpoint->txq, struct htc_packet,
+ list);
+ list_move_tail(&packet->list, queue);
+
+ /* save the number of credits this packet consumed */
+ packet->info.tx.cred_used = req_cred;
+
+ /* all TX packets are handled asynchronously */
+ packet->completion = htc_tx_comp_handler;
+ packet->context = target;
+ endpoint->ep_st.tx_issued += 1;
+
+ /* save send flags */
+ packet->info.tx.flags = flags;
+ packet->info.tx.seqno = endpoint->seqno;
+ endpoint->seqno++;
+ }
+}
+
+/* See if the padded tx length falls on a credit boundary */
+static int htc_get_credit_padding(unsigned int cred_sz, int *len,
+ struct htc_endpoint *ep)
+{
+ int rem_cred, cred_pad;
+
+ rem_cred = *len % cred_sz;
+
+ /* No padding needed */
+ if (!rem_cred)
+ return 0;
+
+ if (!(ep->conn_flags & HTC_FLGS_TX_BNDL_PAD_EN))
+ return -1;
+
+ /*
+ * The transfer consumes a "partial" credit, this
+ * packet cannot be bundled unless we add
+ * additional "dummy" padding (max 255 bytes) to
+ * consume the entire credit.
+ */
+ cred_pad = *len < cred_sz ? (cred_sz - *len) : rem_cred;
+
+ if ((cred_pad > 0) && (cred_pad <= 255))
+ *len += cred_pad;
+ else
+ /* The amount of padding is too large, send as non-bundled */
+ return -1;
+
+ return cred_pad;
+}
+
+static int htc_setup_send_scat_list(struct htc_target *target,
+ struct htc_endpoint *endpoint,
+ struct hif_scatter_req *scat_req,
+ int n_scat,
+ struct list_head *queue)
+{
+ struct htc_packet *packet;
+ int i, len, rem_scat, cred_pad;
+ int status = 0;
+
+ rem_scat = target->dev->max_tx_bndl_sz;
+
+ for (i = 0; i < n_scat; i++) {
+ scat_req->scat_list[i].packet = NULL;
+
+ if (list_empty(queue))
+ break;
+
+ packet = list_first_entry(queue, struct htc_packet, list);
+ len = CALC_TXRX_PADDED_LEN(target->dev,
+ packet->act_len + HTC_HDR_LENGTH);
+
+ cred_pad = htc_get_credit_padding(target->tgt_cred_sz,
+ &len, endpoint);
+ if (cred_pad < 0) {
+ status = -EINVAL;
+ break;
+ }
+
+ if (rem_scat < len) {
+ /* exceeds what we can transfer */
+ status = -ENOSPC;
+ break;
+ }
+
+ rem_scat -= len;
+ /* now remove it from the queue */
+ packet = list_first_entry(queue, struct htc_packet, list);
+ list_del(&packet->list);
+
+ scat_req->scat_list[i].packet = packet;
+ /* prepare packet and flag message as part of a send bundle */
+ htc_prep_send_pkt(packet,
+ packet->info.tx.flags | HTC_FLAGS_SEND_BUNDLE,
+ cred_pad, packet->info.tx.seqno);
+ scat_req->scat_list[i].buf = packet->buf;
+ scat_req->scat_list[i].len = len;
+
+ scat_req->len += len;
+ scat_req->scat_entries++;
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+ "%d, adding pkt : 0x%p len:%d (remaining space:%d)\n",
+ i, packet, len, rem_scat);
+ }
+
+ /* Roll back scatter setup in case of any failure */
+ if (status || (scat_req->scat_entries < HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
+ for (i = scat_req->scat_entries - 1; i >= 0; i--) {
+ packet = scat_req->scat_list[i].packet;
+ if (packet) {
+ packet->buf += HTC_HDR_LENGTH;
+ list_add(&packet->list, queue);
+ }
+ }
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/*
+ * htc_issue_send_bundle: drain a queue and send as bundles
+ * this function may return without fully draining the queue
+ * when
+ *
+ * 1. scatter resources are exhausted
+ * 2. a message that will consume a partial credit will stop the
+ * bundling process early
+ * 3. we drop below the minimum number of messages for a bundle
+ */
+static void htc_issue_send_bundle(struct htc_endpoint *endpoint,
+ struct list_head *queue,
+ int *sent_bundle, int *n_bundle_pkts)
+{
+ struct htc_target *target = endpoint->target;
+ struct hif_scatter_req *scat_req = NULL;
+ struct hif_dev_scat_sup_info hif_info;
+ int n_scat, n_sent_bundle = 0, tot_pkts_bundle = 0;
+
+ hif_info = target->dev->hif_scat_info;
+
+ while (true) {
+ n_scat = get_queue_depth(queue);
+ n_scat = min(n_scat, target->msg_per_bndl_max);
+
+ if (n_scat < HTC_MIN_HTC_MSGS_TO_BUNDLE)
+ /* not enough to bundle */
+ break;
+
+ scat_req = hif_scatter_req_get(target->dev->ar);
+
+ if (!scat_req) {
+ /* no scatter resources */
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+ "no more scatter resources\n");
+ break;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "pkts to scatter: %d\n",
+ n_scat);
+
+ scat_req->len = 0;
+ scat_req->scat_entries = 0;
+
+ if (htc_setup_send_scat_list(target, endpoint, scat_req,
+ n_scat, queue)) {
+ hif_scatter_req_add(target->dev->ar, scat_req);
+ break;
+ }
+
+ /* send path is always asynchronous */
+ scat_req->complete = htc_async_tx_scat_complete;
+ scat_req->ep = endpoint;
+ n_sent_bundle++;
+ tot_pkts_bundle += scat_req->scat_entries;
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+ "send scatter total bytes: %d , entries: %d\n",
+ scat_req->len, scat_req->scat_entries);
+ ath6kldev_submit_scat_req(target->dev, scat_req, false);
+ }
+
+ *sent_bundle = n_sent_bundle;
+ *n_bundle_pkts = tot_pkts_bundle;
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "htc_issue_send_bundle (sent:%d)\n",
+ n_sent_bundle);
+
+ return;
+}
+
+static void htc_tx_from_ep_txq(struct htc_target *target,
+ struct htc_endpoint *endpoint)
+{
+ struct list_head txq;
+ struct htc_packet *packet;
+ int bundle_sent;
+ int n_pkts_bundle;
+
+ spin_lock_bh(&target->tx_lock);
+
+ endpoint->tx_proc_cnt++;
+ if (endpoint->tx_proc_cnt > 1) {
+ endpoint->tx_proc_cnt--;
+ spin_unlock_bh(&target->tx_lock);
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "htc_try_send (busy)\n");
+ return;
+ }
+
+ /*
+ * drain the endpoint TX queue for transmission as long
+ * as we have enough credits.
+ */
+ INIT_LIST_HEAD(&txq);
+
+ while (true) {
+
+ if (list_empty(&endpoint->txq))
+ break;
+
+ htc_tx_pkts_get(target, endpoint, &txq);
+
+ if (list_empty(&txq))
+ break;
+
+ spin_unlock_bh(&target->tx_lock);
+
+ bundle_sent = 0;
+ n_pkts_bundle = 0;
+
+ while (true) {
+ /* try to send a bundle on each pass */
+ if ((target->tx_bndl_enable) &&
+ (get_queue_depth(&txq) >=
+ HTC_MIN_HTC_MSGS_TO_BUNDLE)) {
+ int temp1 = 0, temp2 = 0;
+
+ htc_issue_send_bundle(endpoint, &txq,
+ &temp1, &temp2);
+ bundle_sent += temp1;
+ n_pkts_bundle += temp2;
+ }
+
+ if (list_empty(&txq))
+ break;
+
+ packet = list_first_entry(&txq, struct htc_packet,
+ list);
+ list_del(&packet->list);
+
+ htc_prep_send_pkt(packet, packet->info.tx.flags,
+ 0, packet->info.tx.seqno);
+ htc_issue_send(target, packet);
+ }
+
+ spin_lock_bh(&target->tx_lock);
+
+ endpoint->ep_st.tx_bundles += bundle_sent;
+ endpoint->ep_st.tx_pkt_bundled += n_pkts_bundle;
+ }
+
+ endpoint->tx_proc_cnt = 0;
+ spin_unlock_bh(&target->tx_lock);
+}
+
+static bool htc_try_send(struct htc_target *target,
+ struct htc_endpoint *endpoint,
+ struct htc_packet *tx_pkt)
+{
+ struct htc_ep_callbacks ep_cb;
+ int txq_depth;
+ bool overflow = false;
+
+ ep_cb = endpoint->ep_cb;
+
+ spin_lock_bh(&target->tx_lock);
+ txq_depth = get_queue_depth(&endpoint->txq);
+ spin_unlock_bh(&target->tx_lock);
+
+ if (txq_depth >= endpoint->max_txq_depth)
+ overflow = true;
+
+ if (overflow)
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+ "ep %d, tx queue will overflow :%d , tx depth:%d, max:%d\n",
+ endpoint->eid, overflow, txq_depth,
+ endpoint->max_txq_depth);
+
+ if (overflow && ep_cb.tx_full) {
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+ "indicating overflowed tx packet: 0x%p\n", tx_pkt);
+
+ if (ep_cb.tx_full(endpoint->target, tx_pkt) ==
+ HTC_SEND_FULL_DROP) {
+ endpoint->ep_st.tx_dropped += 1;
+ return false;
+ }
+ }
+
+ spin_lock_bh(&target->tx_lock);
+ list_add_tail(&tx_pkt->list, &endpoint->txq);
+ spin_unlock_bh(&target->tx_lock);
+
+ htc_tx_from_ep_txq(target, endpoint);
+
+ return true;
+}
+
+static void htc_chk_ep_txq(struct htc_target *target)
+{
+ struct htc_endpoint *endpoint;
+ struct htc_endpoint_credit_dist *cred_dist;
+
+ /*
+ * Run through the credit distribution list to see if there are
+ * packets queued. NOTE: no locks need to be taken since the
+ * distribution list is not dynamic (cannot be re-ordered) and we
+ * are not modifying any state.
+ */
+ list_for_each_entry(cred_dist, &target->cred_dist_list, list) {
+ endpoint = (struct htc_endpoint *)cred_dist->htc_rsvd;
+
+ spin_lock_bh(&target->tx_lock);
+ if (!list_empty(&endpoint->txq)) {
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+ "ep %d has %d credits and %d packets in tx queue\n",
+ cred_dist->endpoint,
+ endpoint->cred_dist.credits,
+ get_queue_depth(&endpoint->txq));
+ spin_unlock_bh(&target->tx_lock);
+ /*
+ * Try to start the stalled queue, this list is
+ * ordered by priority. If there are credits
+ * available the highest priority queue will get a
+ * chance to reclaim credits from lower priority
+ * ones.
+ */
+ htc_tx_from_ep_txq(target, endpoint);
+ spin_lock_bh(&target->tx_lock);
+ }
+ spin_unlock_bh(&target->tx_lock);
+ }
+}
+
+static int htc_setup_tx_complete(struct htc_target *target)
+{
+ struct htc_packet *send_pkt = NULL;
+ int status;
+
+ send_pkt = htc_get_control_buf(target, true);
+
+ if (!send_pkt)
+ return -ENOMEM;
+
+ if (target->htc_tgt_ver >= HTC_VERSION_2P1) {
+ struct htc_setup_comp_ext_msg *setup_comp_ext;
+ u32 flags = 0;
+
+ setup_comp_ext =
+ (struct htc_setup_comp_ext_msg *)send_pkt->buf;
+ memset(setup_comp_ext, 0, sizeof(*setup_comp_ext));
+ setup_comp_ext->msg_id =
+ cpu_to_le16(HTC_MSG_SETUP_COMPLETE_EX_ID);
+
+ if (target->msg_per_bndl_max > 0) {
+ /* Indicate HTC bundling to the target */
+ flags |= HTC_SETUP_COMP_FLG_RX_BNDL_EN;
+ setup_comp_ext->msg_per_rxbndl =
+ target->msg_per_bndl_max;
+ }
+
+ memcpy(&setup_comp_ext->flags, &flags,
+ sizeof(setup_comp_ext->flags));
+ set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp_ext,
+ sizeof(struct htc_setup_comp_ext_msg),
+ ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
+
+ } else {
+ struct htc_setup_comp_msg *setup_comp;
+ setup_comp = (struct htc_setup_comp_msg *)send_pkt->buf;
+ memset(setup_comp, 0, sizeof(struct htc_setup_comp_msg));
+ setup_comp->msg_id = cpu_to_le16(HTC_MSG_SETUP_COMPLETE_ID);
+ set_htc_pkt_info(send_pkt, NULL, (u8 *) setup_comp,
+ sizeof(struct htc_setup_comp_msg),
+ ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
+ }
+
+ /* we want synchronous operation */
+ send_pkt->completion = NULL;
+ htc_prep_send_pkt(send_pkt, 0, 0, 0);
+ status = htc_issue_send(target, send_pkt);
+
+ if (send_pkt != NULL)
+ htc_reclaim_txctrl_buf(target, send_pkt);
+
+ return status;
+}
+
+void htc_set_credit_dist(struct htc_target *target,
+ struct htc_credit_state_info *cred_dist_cntxt,
+ u16 srvc_pri_order[], int list_len)
+{
+ struct htc_endpoint *endpoint;
+ int i, ep;
+
+ target->cred_dist_cntxt = cred_dist_cntxt;
+
+ list_add_tail(&target->endpoint[ENDPOINT_0].cred_dist.list,
+ &target->cred_dist_list);
+
+ for (i = 0; i < list_len; i++) {
+ for (ep = ENDPOINT_1; ep < ENDPOINT_MAX; ep++) {
+ endpoint = &target->endpoint[ep];
+ if (endpoint->svc_id == srvc_pri_order[i]) {
+ list_add_tail(&endpoint->cred_dist.list,
+ &target->cred_dist_list);
+ break;
+ }
+ }
+ if (ep >= ENDPOINT_MAX) {
+ WARN_ON(1);
+ return;
+ }
+ }
+}
+
+int htc_tx(struct htc_target *target, struct htc_packet *packet)
+{
+ struct htc_endpoint *endpoint;
+ struct list_head queue;
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+ "htc_tx: ep id: %d, buf: 0x%p, len: %d\n",
+ packet->endpoint, packet->buf, packet->act_len);
+
+ if (packet->endpoint >= ENDPOINT_MAX) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ endpoint = &target->endpoint[packet->endpoint];
+
+ if (!htc_try_send(target, endpoint, packet)) {
+ packet->status = (target->htc_flags & HTC_OP_STATE_STOPPING) ?
+ -ECANCELED : -ENOSPC;
+ INIT_LIST_HEAD(&queue);
+ list_add(&packet->list, &queue);
+ htc_tx_complete(endpoint, &queue);
+ }
+
+ return 0;
+}
+
+/* flush endpoint TX queue */
+void htc_flush_txep(struct htc_target *target,
+ enum htc_endpoint_id eid, u16 tag)
+{
+ struct htc_packet *packet, *tmp_pkt;
+ struct list_head discard_q, container;
+ struct htc_endpoint *endpoint = &target->endpoint[eid];
+
+ if (!endpoint->svc_id) {
+ WARN_ON(1);
+ return;
+ }
+
+ /* initialize the discard queue */
+ INIT_LIST_HEAD(&discard_q);
+
+ spin_lock_bh(&target->tx_lock);
+
+ list_for_each_entry_safe(packet, tmp_pkt, &endpoint->txq, list) {
+ if ((tag == HTC_TX_PACKET_TAG_ALL) ||
+ (tag == packet->info.tx.tag))
+ list_move_tail(&packet->list, &discard_q);
+ }
+
+ spin_unlock_bh(&target->tx_lock);
+
+ list_for_each_entry_safe(packet, tmp_pkt, &discard_q, list) {
+ packet->status = -ECANCELED;
+ list_del(&packet->list);
+ ath6kl_dbg(ATH6KL_DBG_TRC,
+ "flushing tx pkt:0x%p, len:%d, ep:%d tag:0x%X\n",
+ packet, packet->act_len,
+ packet->endpoint, packet->info.tx.tag);
+
+ INIT_LIST_HEAD(&container);
+ list_add_tail(&packet->list, &container);
+ htc_tx_complete(endpoint, &container);
+ }
+
+}
+
+static void htc_flush_txep_all(struct htc_target *target)
+{
+ struct htc_endpoint *endpoint;
+ int i;
+
+ dump_cred_dist_stats(target);
+
+ for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
+ endpoint = &target->endpoint[i];
+ if (endpoint->svc_id == 0)
+ /* not in use.. */
+ continue;
+ htc_flush_txep(target, i, HTC_TX_PACKET_TAG_ALL);
+ }
+}
+
+void htc_indicate_activity_change(struct htc_target *target,
+ enum htc_endpoint_id eid, bool active)
+{
+ struct htc_endpoint *endpoint = &target->endpoint[eid];
+ bool dist = false;
+
+ if (endpoint->svc_id == 0) {
+ WARN_ON(1);
+ return;
+ }
+
+ spin_lock_bh(&target->tx_lock);
+
+ if (active) {
+ if (!(endpoint->cred_dist.dist_flags & HTC_EP_ACTIVE)) {
+ endpoint->cred_dist.dist_flags |= HTC_EP_ACTIVE;
+ dist = true;
+ }
+ } else {
+ if (endpoint->cred_dist.dist_flags & HTC_EP_ACTIVE) {
+ endpoint->cred_dist.dist_flags &= ~HTC_EP_ACTIVE;
+ dist = true;
+ }
+ }
+
+ if (dist) {
+ endpoint->cred_dist.txq_depth =
+ get_queue_depth(&endpoint->txq);
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n",
+ target->cred_dist_cntxt, &target->cred_dist_list);
+
+ ath6k_credit_distribute(target->cred_dist_cntxt,
+ &target->cred_dist_list,
+ HTC_CREDIT_DIST_ACTIVITY_CHANGE);
+ }
+
+ spin_unlock_bh(&target->tx_lock);
+
+ if (dist && !active)
+ htc_chk_ep_txq(target);
+}
+
+/* HTC Rx */
+
+static inline void htc_update_rx_stats(struct htc_endpoint *endpoint,
+ int n_look_ahds)
+{
+ endpoint->ep_st.rx_pkts++;
+ if (n_look_ahds == 1)
+ endpoint->ep_st.rx_lkahds++;
+ else if (n_look_ahds > 1)
+ endpoint->ep_st.rx_bundle_lkahd++;
+}
+
+static inline bool htc_valid_rx_frame_len(struct htc_target *target,
+ enum htc_endpoint_id eid, int len)
+{
+ return (eid == target->dev->ar->ctrl_ep) ?
+ len <= ATH6KL_BUFFER_SIZE : len <= ATH6KL_AMSDU_BUFFER_SIZE;
+}
+
+static int htc_add_rxbuf(struct htc_target *target, struct htc_packet *packet)
+{
+ struct list_head queue;
+
+ INIT_LIST_HEAD(&queue);
+ list_add_tail(&packet->list, &queue);
+ return htc_add_rxbuf_multiple(target, &queue);
+}
+
+static void htc_reclaim_rxbuf(struct htc_target *target,
+ struct htc_packet *packet,
+ struct htc_endpoint *ep)
+{
+ if (packet->info.rx.rx_flags & HTC_RX_PKT_NO_RECYCLE) {
+ htc_rxpkt_reset(packet);
+ packet->status = -ECANCELED;
+ ep->ep_cb.rx(ep->target, packet);
+ } else {
+ htc_rxpkt_reset(packet);
+ htc_add_rxbuf((void *)(target), packet);
+ }
+}
+
+static void reclaim_rx_ctrl_buf(struct htc_target *target,
+ struct htc_packet *packet)
+{
+ spin_lock_bh(&target->htc_lock);
+ list_add_tail(&packet->list, &target->free_ctrl_rxbuf);
+ spin_unlock_bh(&target->htc_lock);
+}
+
+static int dev_rx_pkt(struct htc_target *target, struct htc_packet *packet,
+ u32 rx_len)
+{
+ struct ath6kl_device *dev = target->dev;
+ u32 padded_len;
+ int status;
+
+ padded_len = CALC_TXRX_PADDED_LEN(dev, rx_len);
+
+ if (padded_len > packet->buf_len) {
+ ath6kl_err("not enough receive space for packet - padlen:%d recvlen:%d bufferlen:%d\n",
+ padded_len, rx_len, packet->buf_len);
+ return -ENOMEM;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+ "dev_rx_pkt (0x%p : hdr:0x%X) padded len: %d mbox:0x%X (mode:%s)\n",
+ packet, packet->info.rx.exp_hdr,
+ padded_len, dev->ar->mbox_info.htc_addr, "sync");
+
+ status = hif_read_write_sync(dev->ar,
+ dev->ar->mbox_info.htc_addr,
+ packet->buf, padded_len,
+ HIF_RD_SYNC_BLOCK_FIX);
+
+ packet->status = status;
+
+ return status;
+}
+
+/*
+ * optimization for recv packets, we can indicate a
+ * "hint" that there are more single-packets to fetch
+ * on this endpoint.
+ */
+static void set_rxpkt_indication_flag(u32 lk_ahd,
+ struct htc_endpoint *endpoint,
+ struct htc_packet *packet)
+{
+ struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)&lk_ahd;
+
+ if (htc_hdr->eid == packet->endpoint) {
+ if (!list_empty(&endpoint->rx_bufq))
+ packet->info.rx.indicat_flags |=
+ HTC_RX_FLAGS_INDICATE_MORE_PKTS;
+ }
+}
+
+static void chk_rx_water_mark(struct htc_endpoint *endpoint)
+{
+ struct htc_ep_callbacks ep_cb = endpoint->ep_cb;
+
+ if (ep_cb.rx_refill_thresh > 0) {
+ spin_lock_bh(&endpoint->target->rx_lock);
+ if (get_queue_depth(&endpoint->rx_bufq)
+ < ep_cb.rx_refill_thresh) {
+ spin_unlock_bh(&endpoint->target->rx_lock);
+ ep_cb.rx_refill(endpoint->target, endpoint->eid);
+ return;
+ }
+ spin_unlock_bh(&endpoint->target->rx_lock);
+ }
+}
+
+/* This function is called with rx_lock held */
+static int htc_setup_rxpkts(struct htc_target *target, struct htc_endpoint *ep,
+ u32 *lk_ahds, struct list_head *queue, int n_msg)
+{
+ struct htc_packet *packet;
+ /* FIXME: type of lk_ahds can't be right */
+ struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)lk_ahds;
+ struct htc_ep_callbacks ep_cb;
+ int status = 0, j, full_len;
+ bool no_recycle;
+
+ full_len = CALC_TXRX_PADDED_LEN(target->dev,
+ le16_to_cpu(htc_hdr->payld_len) +
+ sizeof(*htc_hdr));
+
+ if (!htc_valid_rx_frame_len(target, ep->eid, full_len)) {
+ ath6kl_warn("Rx buffer requested with invalid length\n");
+ return -EINVAL;
+ }
+
+ ep_cb = ep->ep_cb;
+ for (j = 0; j < n_msg; j++) {
+
+ /*
+ * Reset flag, any packets allocated using the
+ * rx_alloc() API cannot be recycled on
+ * cleanup,they must be explicitly returned.
+ */
+ no_recycle = false;
+
+ if (ep_cb.rx_allocthresh &&
+ (full_len > ep_cb.rx_alloc_thresh)) {
+ ep->ep_st.rx_alloc_thresh_hit += 1;
+ ep->ep_st.rxalloc_thresh_byte +=
+ le16_to_cpu(htc_hdr->payld_len);
+
+ spin_unlock_bh(&target->rx_lock);
+ no_recycle = true;
+
+ packet = ep_cb.rx_allocthresh(ep->target, ep->eid,
+ full_len);
+ spin_lock_bh(&target->rx_lock);
+ } else {
+ /* refill handler is being used */
+ if (list_empty(&ep->rx_bufq)) {
+ if (ep_cb.rx_refill) {
+ spin_unlock_bh(&target->rx_lock);
+ ep_cb.rx_refill(ep->target, ep->eid);
+ spin_lock_bh(&target->rx_lock);
+ }
+ }
+
+ if (list_empty(&ep->rx_bufq))
+ packet = NULL;
+ else {
+ packet = list_first_entry(&ep->rx_bufq,
+ struct htc_packet, list);
+ list_del(&packet->list);
+ }
+ }
+
+ if (!packet) {
+ target->rx_st_flags |= HTC_RECV_WAIT_BUFFERS;
+ target->ep_waiting = ep->eid;
+ return -ENOSPC;
+ }
+
+ /* clear flags */
+ packet->info.rx.rx_flags = 0;
+ packet->info.rx.indicat_flags = 0;
+ packet->status = 0;
+
+ if (no_recycle)
+ /*
+ * flag that these packets cannot be
+ * recycled, they have to be returned to
+ * the user
+ */
+ packet->info.rx.rx_flags |= HTC_RX_PKT_NO_RECYCLE;
+
+ /* Caller needs to free this upon any failure */
+ list_add_tail(&packet->list, queue);
+
+ if (target->htc_flags & HTC_OP_STATE_STOPPING) {
+ status = -ECANCELED;
+ break;
+ }
+
+ if (j) {
+ packet->info.rx.rx_flags |= HTC_RX_PKT_REFRESH_HDR;
+ packet->info.rx.exp_hdr = 0xFFFFFFFF;
+ } else
+ /* set expected look ahead */
+ packet->info.rx.exp_hdr = *lk_ahds;
+
+ packet->act_len = le16_to_cpu(htc_hdr->payld_len) +
+ HTC_HDR_LENGTH;
+ }
+
+ return status;
+}
+
+static int alloc_and_prep_rxpkts(struct htc_target *target,
+ u32 lk_ahds[], int msg,
+ struct htc_endpoint *endpoint,
+ struct list_head *queue)
+{
+ int status = 0;
+ struct htc_packet *packet, *tmp_pkt;
+ struct htc_frame_hdr *htc_hdr;
+ int i, n_msg;
+
+ spin_lock_bh(&target->rx_lock);
+
+ for (i = 0; i < msg; i++) {
+
+ htc_hdr = (struct htc_frame_hdr *)&lk_ahds[i];
+
+ if (htc_hdr->eid >= ENDPOINT_MAX) {
+ ath6kl_err("invalid ep in look-ahead: %d\n",
+ htc_hdr->eid);
+ status = -ENOMEM;
+ break;
+ }
+
+ if (htc_hdr->eid != endpoint->eid) {
+ ath6kl_err("invalid ep in look-ahead: %d should be : %d (index:%d)\n",
+ htc_hdr->eid, endpoint->eid, i);
+ status = -ENOMEM;
+ break;
+ }
+
+ if (le16_to_cpu(htc_hdr->payld_len) > HTC_MAX_PAYLOAD_LENGTH) {
+ ath6kl_err("payload len %d exceeds max htc : %d !\n",
+ htc_hdr->payld_len,
+ (u32) HTC_MAX_PAYLOAD_LENGTH);
+ status = -ENOMEM;
+ break;
+ }
+
+ if (endpoint->svc_id == 0) {
+ ath6kl_err("ep %d is not connected !\n", htc_hdr->eid);
+ status = -ENOMEM;
+ break;
+ }
+
+ if (htc_hdr->flags & HTC_FLG_RX_BNDL_CNT) {
+ /*
+ * HTC header indicates that every packet to follow
+ * has the same padded length so that it can be
+ * optimally fetched as a full bundle.
+ */
+ n_msg = (htc_hdr->flags & HTC_FLG_RX_BNDL_CNT) >>
+ HTC_FLG_RX_BNDL_CNT_S;
+
+ /* the count doesn't include the starter frame */
+ n_msg++;
+ if (n_msg > target->msg_per_bndl_max) {
+ status = -ENOMEM;
+ break;
+ }
+
+ endpoint->ep_st.rx_bundle_from_hdr += 1;
+ ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+ "htc hdr indicates :%d msg can be fetched as a bundle\n",
+ n_msg);
+ } else
+ /* HTC header only indicates 1 message to fetch */
+ n_msg = 1;
+
+ /* Setup packet buffers for each message */
+ status = htc_setup_rxpkts(target, endpoint, &lk_ahds[i], queue,
+ n_msg);
+
+ /*
+ * This is due to unavailabilty of buffers to rx entire data.
+ * Return no error so that free buffers from queue can be used
+ * to receive partial data.
+ */
+ if (status == -ENOSPC) {
+ spin_unlock_bh(&target->rx_lock);
+ return 0;
+ }
+
+ if (status)
+ break;
+ }
+
+ spin_unlock_bh(&target->rx_lock);
+
+ if (status) {
+ list_for_each_entry_safe(packet, tmp_pkt, queue, list) {
+ list_del(&packet->list);
+ htc_reclaim_rxbuf(target, packet,
+ &target->endpoint[packet->endpoint]);
+ }
+ }
+
+ return status;
+}
+
+static void htc_ctrl_rx(struct htc_target *context, struct htc_packet *packets)
+{
+ if (packets->endpoint != ENDPOINT_0) {
+ WARN_ON(1);
+ return;
+ }
+
+ if (packets->status == -ECANCELED) {
+ reclaim_rx_ctrl_buf(context, packets);
+ return;
+ }
+
+ if (packets->act_len > 0) {
+ ath6kl_err("htc_ctrl_rx, got message with len:%zu\n",
+ packets->act_len + HTC_HDR_LENGTH);
+
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES,
+ "Unexpected ENDPOINT 0 Message",
+ packets->buf - HTC_HDR_LENGTH,
+ packets->act_len + HTC_HDR_LENGTH);
+ }
+
+ htc_reclaim_rxbuf(context, packets, &context->endpoint[0]);
+}
+
+static void htc_proc_cred_rpt(struct htc_target *target,
+ struct htc_credit_report *rpt,
+ int n_entries,
+ enum htc_endpoint_id from_ep)
+{
+ struct htc_endpoint *endpoint;
+ int tot_credits = 0, i;
+ bool dist = false;
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+ "htc_proc_cred_rpt, credit report entries:%d\n", n_entries);
+
+ spin_lock_bh(&target->tx_lock);
+
+ for (i = 0; i < n_entries; i++, rpt++) {
+ if (rpt->eid >= ENDPOINT_MAX) {
+ WARN_ON(1);
+ spin_unlock_bh(&target->tx_lock);
+ return;
+ }
+
+ endpoint = &target->endpoint[rpt->eid];
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND, " ep %d got %d credits\n",
+ rpt->eid, rpt->credits);
+
+ endpoint->ep_st.tx_cred_rpt += 1;
+ endpoint->ep_st.cred_retnd += rpt->credits;
+
+ if (from_ep == rpt->eid) {
+ /*
+ * This credit report arrived on the same endpoint
+ * indicating it arrived in an RX packet.
+ */
+ endpoint->ep_st.cred_from_rx += rpt->credits;
+ endpoint->ep_st.cred_rpt_from_rx += 1;
+ } else if (from_ep == ENDPOINT_0) {
+ /* credit arrived on endpoint 0 as a NULL message */
+ endpoint->ep_st.cred_from_ep0 += rpt->credits;
+ endpoint->ep_st.cred_rpt_ep0 += 1;
+ } else {
+ endpoint->ep_st.cred_from_other += rpt->credits;
+ endpoint->ep_st.cred_rpt_from_other += 1;
+ }
+
+ if (ENDPOINT_0 == rpt->eid)
+ /* always give endpoint 0 credits back */
+ endpoint->cred_dist.credits += rpt->credits;
+ else {
+ endpoint->cred_dist.cred_to_dist += rpt->credits;
+ dist = true;
+ }
+
+ /*
+ * Refresh tx depth for distribution function that will
+ * recover these credits NOTE: this is only valid when
+ * there are credits to recover!
+ */
+ endpoint->cred_dist.txq_depth =
+ get_queue_depth(&endpoint->txq);
+
+ tot_credits += rpt->credits;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND,
+ "report indicated %d credits to distribute\n",
+ tot_credits);
+
+ if (dist) {
+ /*
+ * This was a credit return based on a completed send
+ * operations note, this is done with the lock held
+ */
+ ath6kl_dbg(ATH6KL_DBG_HTC_SEND, "ctxt:0x%p dist:0x%p\n",
+ target->cred_dist_cntxt, &target->cred_dist_list);
+
+ ath6k_credit_distribute(target->cred_dist_cntxt,
+ &target->cred_dist_list,
+ HTC_CREDIT_DIST_SEND_COMPLETE);
+ }
+
+ spin_unlock_bh(&target->tx_lock);
+
+ if (tot_credits)
+ htc_chk_ep_txq(target);
+}
+
+static int htc_parse_trailer(struct htc_target *target,
+ struct htc_record_hdr *record,
+ u8 *record_buf, u32 *next_lk_ahds,
+ enum htc_endpoint_id endpoint,
+ int *n_lk_ahds)
+{
+ struct htc_bundle_lkahd_rpt *bundle_lkahd_rpt;
+ struct htc_lookahead_report *lk_ahd;
+ int len;
+
+ switch (record->rec_id) {
+ case HTC_RECORD_CREDITS:
+ len = record->len / sizeof(struct htc_credit_report);
+ if (!len) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ htc_proc_cred_rpt(target,
+ (struct htc_credit_report *) record_buf,
+ len, endpoint);
+ break;
+ case HTC_RECORD_LOOKAHEAD:
+ len = record->len / sizeof(*lk_ahd);
+ if (!len) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ lk_ahd = (struct htc_lookahead_report *) record_buf;
+ if ((lk_ahd->pre_valid == ((~lk_ahd->post_valid) & 0xFF))
+ && next_lk_ahds) {
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+ "lk_ahd report found (pre valid:0x%X, post valid:0x%X)\n",
+ lk_ahd->pre_valid, lk_ahd->post_valid);
+
+ /* look ahead bytes are valid, copy them over */
+ memcpy((u8 *)&next_lk_ahds[0], lk_ahd->lk_ahd, 4);
+
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Next Look Ahead",
+ next_lk_ahds, 4);
+
+ *n_lk_ahds = 1;
+ }
+ break;
+ case HTC_RECORD_LOOKAHEAD_BUNDLE:
+ len = record->len / sizeof(*bundle_lkahd_rpt);
+ if (!len || (len > HTC_HOST_MAX_MSG_PER_BUNDLE)) {
+ WARN_ON(1);
+ return -EINVAL;
+ }
+
+ if (next_lk_ahds) {
+ int i;
+
+ bundle_lkahd_rpt =
+ (struct htc_bundle_lkahd_rpt *) record_buf;
+
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Bundle lk_ahd",
+ record_buf, record->len);
+
+ for (i = 0; i < len; i++) {
+ memcpy((u8 *)&next_lk_ahds[i],
+ bundle_lkahd_rpt->lk_ahd, 4);
+ bundle_lkahd_rpt++;
+ }
+
+ *n_lk_ahds = i;
+ }
+ break;
+ default:
+ ath6kl_err("unhandled record: id:%d len:%d\n",
+ record->rec_id, record->len);
+ break;
+ }
+
+ return 0;
+
+}
+
+static int htc_proc_trailer(struct htc_target *target,
+ u8 *buf, int len, u32 *next_lk_ahds,
+ int *n_lk_ahds, enum htc_endpoint_id endpoint)
+{
+ struct htc_record_hdr *record;
+ int orig_len;
+ int status;
+ u8 *record_buf;
+ u8 *orig_buf;
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_RECV, "+htc_proc_trailer (len:%d)\n", len);
+
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Recv Trailer", buf, len);
+
+ orig_buf = buf;
+ orig_len = len;
+ status = 0;
+
+ while (len > 0) {
+
+ if (len < sizeof(struct htc_record_hdr)) {
+ status = -ENOMEM;
+ break;
+ }
+ /* these are byte aligned structs */
+ record = (struct htc_record_hdr *) buf;
+ len -= sizeof(struct htc_record_hdr);
+ buf += sizeof(struct htc_record_hdr);
+
+ if (record->len > len) {
+ ath6kl_err("invalid record len: %d (id:%d) buf has: %d bytes left\n",
+ record->len, record->rec_id, len);
+ status = -ENOMEM;
+ break;
+ }
+ record_buf = buf;
+
+ status = htc_parse_trailer(target, record, record_buf,
+ next_lk_ahds, endpoint, n_lk_ahds);
+
+ if (status)
+ break;
+
+ /* advance buffer past this record for next time around */
+ buf += record->len;
+ len -= record->len;
+ }
+
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "BAD Recv Trailer",
+ orig_buf, orig_len);
+
+ return status;
+}
+
+static int htc_proc_rxhdr(struct htc_target *target,
+ struct htc_packet *packet,
+ u32 *next_lkahds, int *n_lkahds)
+{
+ int status = 0;
+ u16 payload_len;
+ u32 lk_ahd;
+ struct htc_frame_hdr *htc_hdr = (struct htc_frame_hdr *)packet->buf;
+
+ if (n_lkahds != NULL)
+ *n_lkahds = 0;
+
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "HTC Recv PKT", packet->buf,
+ packet->act_len);
+
+ /*
+ * NOTE: we cannot assume the alignment of buf, so we use the safe
+ * macros to retrieve 16 bit fields.
+ */
+ payload_len = le16_to_cpu(get_unaligned(&htc_hdr->payld_len));
+
+ memcpy((u8 *)&lk_ahd, packet->buf, sizeof(lk_ahd));
+
+ if (packet->info.rx.rx_flags & HTC_RX_PKT_REFRESH_HDR) {
+ /*
+ * Refresh the expected header and the actual length as it
+ * was unknown when this packet was grabbed as part of the
+ * bundle.
+ */
+ packet->info.rx.exp_hdr = lk_ahd;
+ packet->act_len = payload_len + HTC_HDR_LENGTH;
+
+ /* validate the actual header that was refreshed */
+ if (packet->act_len > packet->buf_len) {
+ ath6kl_err("refreshed hdr payload len (%d) in bundled recv is invalid (hdr: 0x%X)\n",
+ payload_len, lk_ahd);
+ /*
+ * Limit this to max buffer just to print out some
+ * of the buffer.
+ */
+ packet->act_len = min(packet->act_len, packet->buf_len);
+ status = -ENOMEM;
+ goto fail_rx;
+ }
+
+ if (packet->endpoint != htc_hdr->eid) {
+ ath6kl_err("refreshed hdr ep (%d) does not match expected ep (%d)\n",
+ htc_hdr->eid, packet->endpoint);
+ status = -ENOMEM;
+ goto fail_rx;
+ }
+ }
+
+ if (lk_ahd != packet->info.rx.exp_hdr) {
+ ath6kl_err("htc_proc_rxhdr, lk_ahd mismatch! (pPkt:0x%p flags:0x%X)\n",
+ packet, packet->info.rx.rx_flags);
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Expected Message lk_ahd",
+ &packet->info.rx.exp_hdr, 4);
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "Current Frame Header",
+ (u8 *)&lk_ahd, sizeof(lk_ahd));
+ status = -ENOMEM;
+ goto fail_rx;
+ }
+
+ if (htc_hdr->flags & HTC_FLG_RX_TRAILER) {
+ if (htc_hdr->ctrl[0] < sizeof(struct htc_record_hdr) ||
+ htc_hdr->ctrl[0] > payload_len) {
+ ath6kl_err("htc_proc_rxhdr, invalid hdr (payload len should be :%d, CB[0] is:%d)\n",
+ payload_len, htc_hdr->ctrl[0]);
+ status = -ENOMEM;
+ goto fail_rx;
+ }
+
+ if (packet->info.rx.rx_flags & HTC_RX_PKT_IGNORE_LOOKAHEAD) {
+ next_lkahds = NULL;
+ n_lkahds = NULL;
+ }
+
+ status = htc_proc_trailer(target, packet->buf + HTC_HDR_LENGTH
+ + payload_len - htc_hdr->ctrl[0],
+ htc_hdr->ctrl[0], next_lkahds,
+ n_lkahds, packet->endpoint);
+
+ if (status)
+ goto fail_rx;
+
+ packet->act_len -= htc_hdr->ctrl[0];
+ }
+
+ packet->buf += HTC_HDR_LENGTH;
+ packet->act_len -= HTC_HDR_LENGTH;
+
+fail_rx:
+ if (status)
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "BAD HTC Recv PKT",
+ packet->buf,
+ packet->act_len < 256 ? packet->act_len : 256);
+ else {
+ if (packet->act_len > 0)
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES,
+ "HTC - Application Msg",
+ packet->buf, packet->act_len);
+ }
+
+ return status;
+}
+
+static void do_rx_completion(struct htc_endpoint *endpoint,
+ struct htc_packet *packet)
+{
+ ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+ "htc calling ep %d recv callback on packet 0x%p\n",
+ endpoint->eid, packet);
+ endpoint->ep_cb.rx(endpoint->target, packet);
+}
+
+static int htc_issue_rxpkt_bundle(struct htc_target *target,
+ struct list_head *rxq,
+ struct list_head *sync_compq,
+ int *n_pkt_fetched, bool part_bundle)
+{
+ struct hif_scatter_req *scat_req;
+ struct htc_packet *packet;
+ int rem_space = target->dev->max_rx_bndl_sz;
+ int n_scat_pkt, status = 0, i, len;
+
+ n_scat_pkt = get_queue_depth(rxq);
+ n_scat_pkt = min(n_scat_pkt, target->msg_per_bndl_max);
+
+ if ((get_queue_depth(rxq) - n_scat_pkt) > 0) {
+ /*
+ * We were forced to split this bundle receive operation
+ * all packets in this partial bundle must have their
+ * lookaheads ignored.
+ */
+ part_bundle = true;
+
+ /*
+ * This would only happen if the target ignored our max
+ * bundle limit.
+ */
+ ath6kl_warn("htc_issue_rxpkt_bundle : partial bundle detected num:%d , %d\n",
+ get_queue_depth(rxq), n_scat_pkt);
+ }
+
+ len = 0;
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+ "htc_issue_rxpkt_bundle (numpackets: %d , actual : %d)\n",
+ get_queue_depth(rxq), n_scat_pkt);
+
+ scat_req = hif_scatter_req_get(target->dev->ar);
+
+ if (scat_req == NULL)
+ goto fail_rx_pkt;
+
+ scat_req->flags = 0;
+
+ if (part_bundle)
+ scat_req->flags |=
+ HTC_SCAT_REQ_FLG_PART_BNDL;
+
+ for (i = 0; i < n_scat_pkt; i++) {
+ int pad_len;
+
+ packet = list_first_entry(rxq, struct htc_packet, list);
+ list_del(&packet->list);
+
+ pad_len = CALC_TXRX_PADDED_LEN(target->dev,
+ packet->act_len);
+
+ if ((rem_space - pad_len) < 0) {
+ list_add(&packet->list, rxq);
+ break;
+ }
+
+ rem_space -= pad_len;
+
+ if (part_bundle || (i < (n_scat_pkt - 1)))
+ /*
+ * Packet 0..n-1 cannot be checked for look-aheads
+ * since we are fetching a bundle the last packet
+ * however can have it's lookahead used
+ */
+ packet->info.rx.rx_flags |=
+ HTC_RX_PKT_IGNORE_LOOKAHEAD;
+
+ /* NOTE: 1 HTC packet per scatter entry */
+ scat_req->scat_list[i].buf = packet->buf;
+ scat_req->scat_list[i].len = pad_len;
+
+ packet->info.rx.rx_flags |= HTC_RX_PKT_PART_OF_BUNDLE;
+
+ list_add_tail(&packet->list, sync_compq);
+
+ WARN_ON(!scat_req->scat_list[i].len);
+ len += scat_req->scat_list[i].len;
+ }
+
+ scat_req->len = len;
+ scat_req->scat_entries = i;
+
+ status = ath6kldev_submit_scat_req(target->dev, scat_req, true);
+
+ if (!status)
+ *n_pkt_fetched = i;
+
+ /* free scatter request */
+ hif_scatter_req_add(target->dev->ar, scat_req);
+
+fail_rx_pkt:
+
+ return status;
+}
+
+static int htc_proc_fetched_rxpkts(struct htc_target *target,
+ struct list_head *comp_pktq, u32 lk_ahds[],
+ int *n_lk_ahd)
+{
+ struct htc_packet *packet, *tmp_pkt;
+ struct htc_endpoint *ep;
+ int status = 0;
+
+ list_for_each_entry_safe(packet, tmp_pkt, comp_pktq, list) {
+ list_del(&packet->list);
+ ep = &target->endpoint[packet->endpoint];
+
+ /* process header for each of the recv packet */
+ status = htc_proc_rxhdr(target, packet, lk_ahds, n_lk_ahd);
+ if (status)
+ return status;
+
+ if (list_empty(comp_pktq)) {
+ /*
+ * Last packet's more packet flag is set
+ * based on the lookahead.
+ */
+ if (*n_lk_ahd > 0)
+ set_rxpkt_indication_flag(lk_ahds[0],
+ ep, packet);
+ } else
+ /*
+ * Packets in a bundle automatically have
+ * this flag set.
+ */
+ packet->info.rx.indicat_flags |=
+ HTC_RX_FLAGS_INDICATE_MORE_PKTS;
+
+ htc_update_rx_stats(ep, *n_lk_ahd);
+
+ if (packet->info.rx.rx_flags & HTC_RX_PKT_PART_OF_BUNDLE)
+ ep->ep_st.rx_bundl += 1;
+
+ do_rx_completion(ep, packet);
+ }
+
+ return status;
+}
+
+static int htc_fetch_rxpkts(struct htc_target *target,
+ struct list_head *rx_pktq,
+ struct list_head *comp_pktq)
+{
+ int fetched_pkts;
+ bool part_bundle = false;
+ int status = 0;
+
+ /* now go fetch the list of HTC packets */
+ while (!list_empty(rx_pktq)) {
+ fetched_pkts = 0;
+
+ if (target->rx_bndl_enable && (get_queue_depth(rx_pktq) > 1)) {
+ /*
+ * There are enough packets to attempt a
+ * bundle transfer and recv bundling is
+ * allowed.
+ */
+ status = htc_issue_rxpkt_bundle(target, rx_pktq,
+ comp_pktq,
+ &fetched_pkts,
+ part_bundle);
+ if (status)
+ return status;
+
+ if (!list_empty(rx_pktq))
+ part_bundle = true;
+ }
+
+ if (!fetched_pkts) {
+ struct htc_packet *packet;
+
+ packet = list_first_entry(rx_pktq, struct htc_packet,
+ list);
+
+ list_del(&packet->list);
+
+ /* fully synchronous */
+ packet->completion = NULL;
+
+ if (!list_empty(rx_pktq))
+ /*
+ * look_aheads in all packet
+ * except the last one in the
+ * bundle must be ignored
+ */
+ packet->info.rx.rx_flags |=
+ HTC_RX_PKT_IGNORE_LOOKAHEAD;
+
+ /* go fetch the packet */
+ status = dev_rx_pkt(target, packet, packet->act_len);
+ if (status)
+ return status;
+
+ list_add_tail(&packet->list, comp_pktq);
+ }
+ }
+
+ return status;
+}
+
+static int htc_rxmsg_pending_handler(struct htc_target *target,
+ u32 msg_look_ahead[],
+ int *num_pkts)
+{
+ struct htc_packet *packets, *tmp_pkt;
+ struct htc_endpoint *endpoint;
+ struct list_head rx_pktq, comp_pktq;
+ int status = 0;
+ u32 look_aheads[HTC_HOST_MAX_MSG_PER_BUNDLE];
+ int num_look_ahead = 1;
+ enum htc_endpoint_id id;
+ int n_fetched = 0;
+
+ *num_pkts = 0;
+
+ /*
+ * On first entry copy the look_aheads into our temp array for
+ * processing
+ */
+ memcpy(look_aheads, msg_look_ahead, sizeof(look_aheads));
+
+ while (true) {
+
+ /*
+ * First lookahead sets the expected endpoint IDs for all
+ * packets in a bundle.
+ */
+ id = ((struct htc_frame_hdr *)&look_aheads[0])->eid;
+ endpoint = &target->endpoint[id];
+
+ if (id >= ENDPOINT_MAX) {
+ ath6kl_err("MsgPend, invalid endpoint in look-ahead: %d\n",
+ id);
+ status = -ENOMEM;
+ break;
+ }
+
+ INIT_LIST_HEAD(&rx_pktq);
+ INIT_LIST_HEAD(&comp_pktq);
+
+ /*
+ * Try to allocate as many HTC RX packets indicated by the
+ * look_aheads.
+ */
+ status = alloc_and_prep_rxpkts(target, look_aheads,
+ num_look_ahead, endpoint,
+ &rx_pktq);
+ if (status)
+ break;
+
+ if (get_queue_depth(&rx_pktq) >= 2)
+ /*
+ * A recv bundle was detected, force IRQ status
+ * re-check again
+ */
+ target->dev->chk_irq_status_cnt = 1;
+
+ n_fetched += get_queue_depth(&rx_pktq);
+
+ num_look_ahead = 0;
+
+ status = htc_fetch_rxpkts(target, &rx_pktq, &comp_pktq);
+
+ if (!status)
+ chk_rx_water_mark(endpoint);
+
+ /* Process fetched packets */
+ status = htc_proc_fetched_rxpkts(target, &comp_pktq,
+ look_aheads, &num_look_ahead);
+
+ if (!num_look_ahead || status)
+ break;
+
+ /*
+ * For SYNCH processing, if we get here, we are running
+ * through the loop again due to a detected lookahead. Set
+ * flag that we should re-check IRQ status registers again
+ * before leaving IRQ processing, this can net better
+ * performance in high throughput situations.
+ */
+ target->dev->chk_irq_status_cnt = 1;
+ }
+
+ if (status) {
+ ath6kl_err("failed to get pending recv messages: %d\n",
+ status);
+ /*
+ * Cleanup any packets we allocated but didn't use to
+ * actually fetch any packets.
+ */
+ list_for_each_entry_safe(packets, tmp_pkt, &rx_pktq, list) {
+ list_del(&packets->list);
+ htc_reclaim_rxbuf(target, packets,
+ &target->endpoint[packets->endpoint]);
+ }
+
+ /* cleanup any packets in sync completion queue */
+ list_for_each_entry_safe(packets, tmp_pkt, &comp_pktq, list) {
+ list_del(&packets->list);
+ htc_reclaim_rxbuf(target, packets,
+ &target->endpoint[packets->endpoint]);
+ }
+
+ if (target->htc_flags & HTC_OP_STATE_STOPPING) {
+ ath6kl_warn("host is going to stop blocking receiver for htc_stop\n");
+ ath6kldev_rx_control(target->dev, false);
+ }
+ }
+
+ /*
+ * Before leaving, check to see if host ran out of buffers and
+ * needs to stop the receiver.
+ */
+ if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) {
+ ath6kl_warn("host has no rx buffers blocking receiver to prevent overrun\n");
+ ath6kldev_rx_control(target->dev, false);
+ }
+ *num_pkts = n_fetched;
+
+ return status;
+}
+
+/*
+ * Synchronously wait for a control message from the target,
+ * This function is used at initialization time ONLY. At init messages
+ * on ENDPOINT 0 are expected.
+ */
+static struct htc_packet *htc_wait_for_ctrl_msg(struct htc_target *target)
+{
+ struct htc_packet *packet = NULL;
+ struct htc_frame_hdr *htc_hdr;
+ u32 look_ahead;
+
+ if (ath6kldev_poll_mboxmsg_rx(target->dev, &look_ahead,
+ HTC_TARGET_RESPONSE_TIMEOUT))
+ return NULL;
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+ "htc_wait_for_ctrl_msg: look_ahead : 0x%X\n", look_ahead);
+
+ htc_hdr = (struct htc_frame_hdr *)&look_ahead;
+
+ if (htc_hdr->eid != ENDPOINT_0)
+ return NULL;
+
+ packet = htc_get_control_buf(target, false);
+
+ if (!packet)
+ return NULL;
+
+ packet->info.rx.rx_flags = 0;
+ packet->info.rx.exp_hdr = look_ahead;
+ packet->act_len = le16_to_cpu(htc_hdr->payld_len) + HTC_HDR_LENGTH;
+
+ if (packet->act_len > packet->buf_len)
+ goto fail_ctrl_rx;
+
+ /* we want synchronous operation */
+ packet->completion = NULL;
+
+ /* get the message from the device, this will block */
+ if (dev_rx_pkt(target, packet, packet->act_len))
+ goto fail_ctrl_rx;
+
+ /* process receive header */
+ packet->status = htc_proc_rxhdr(target, packet, NULL, NULL);
+
+ if (packet->status) {
+ ath6kl_err("htc_wait_for_ctrl_msg, htc_proc_rxhdr failed (status = %d)\n",
+ packet->status);
+ goto fail_ctrl_rx;
+ }
+
+ return packet;
+
+fail_ctrl_rx:
+ if (packet != NULL) {
+ htc_rxpkt_reset(packet);
+ reclaim_rx_ctrl_buf(target, packet);
+ }
+
+ return NULL;
+}
+
+int htc_add_rxbuf_multiple(struct htc_target *target,
+ struct list_head *pkt_queue)
+{
+ struct htc_endpoint *endpoint;
+ struct htc_packet *first_pkt;
+ bool rx_unblock = false;
+ int status = 0, depth;
+
+ if (list_empty(pkt_queue))
+ return -ENOMEM;
+
+ first_pkt = list_first_entry(pkt_queue, struct htc_packet, list);
+
+ if (first_pkt->endpoint >= ENDPOINT_MAX)
+ return status;
+
+ depth = get_queue_depth(pkt_queue);
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+ "htc_add_rxbuf_multiple: ep id: %d, cnt:%d, len: %d\n",
+ first_pkt->endpoint, depth, first_pkt->buf_len);
+
+ endpoint = &target->endpoint[first_pkt->endpoint];
+
+ if (target->htc_flags & HTC_OP_STATE_STOPPING) {
+ struct htc_packet *packet, *tmp_pkt;
+
+ /* walk through queue and mark each one canceled */
+ list_for_each_entry_safe(packet, tmp_pkt, pkt_queue, list) {
+ packet->status = -ECANCELED;
+ list_del(&packet->list);
+ do_rx_completion(endpoint, packet);
+ }
+
+ return status;
+ }
+
+ spin_lock_bh(&target->rx_lock);
+
+ list_splice_tail_init(pkt_queue, &endpoint->rx_bufq);
+
+ /* check if we are blocked waiting for a new buffer */
+ if (target->rx_st_flags & HTC_RECV_WAIT_BUFFERS) {
+ if (target->ep_waiting == first_pkt->endpoint) {
+ ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+ "receiver was blocked on ep:%d, unblocking.\n",
+ target->ep_waiting);
+ target->rx_st_flags &= ~HTC_RECV_WAIT_BUFFERS;
+ target->ep_waiting = ENDPOINT_MAX;
+ rx_unblock = true;
+ }
+ }
+
+ spin_unlock_bh(&target->rx_lock);
+
+ if (rx_unblock && !(target->htc_flags & HTC_OP_STATE_STOPPING))
+ /* TODO : implement a buffer threshold count? */
+ ath6kldev_rx_control(target->dev, true);
+
+ return status;
+}
+
+void htc_flush_rx_buf(struct htc_target *target)
+{
+ struct htc_endpoint *endpoint;
+ struct htc_packet *packet, *tmp_pkt;
+ int i;
+
+ for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
+ endpoint = &target->endpoint[i];
+ if (!endpoint->svc_id)
+ /* not in use.. */
+ continue;
+
+ spin_lock_bh(&target->rx_lock);
+ list_for_each_entry_safe(packet, tmp_pkt,
+ &endpoint->rx_bufq, list) {
+ list_del(&packet->list);
+ spin_unlock_bh(&target->rx_lock);
+ ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+ "flushing rx pkt:0x%p, len:%d, ep:%d\n",
+ packet, packet->buf_len,
+ packet->endpoint);
+ dev_kfree_skb(packet->pkt_cntxt);
+ spin_lock_bh(&target->rx_lock);
+ }
+ spin_unlock_bh(&target->rx_lock);
+ }
+}
+
+int htc_conn_service(struct htc_target *target,
+ struct htc_service_connect_req *conn_req,
+ struct htc_service_connect_resp *conn_resp)
+{
+ struct htc_packet *rx_pkt = NULL;
+ struct htc_packet *tx_pkt = NULL;
+ struct htc_conn_service_resp *resp_msg;
+ struct htc_conn_service_msg *conn_msg;
+ struct htc_endpoint *endpoint;
+ enum htc_endpoint_id assigned_ep = ENDPOINT_MAX;
+ unsigned int max_msg_sz = 0;
+ int status = 0;
+
+ ath6kl_dbg(ATH6KL_DBG_TRC,
+ "htc_conn_service, target:0x%p service id:0x%X\n",
+ target, conn_req->svc_id);
+
+ if (conn_req->svc_id == HTC_CTRL_RSVD_SVC) {
+ /* special case for pseudo control service */
+ assigned_ep = ENDPOINT_0;
+ max_msg_sz = HTC_MAX_CTRL_MSG_LEN;
+ } else {
+ /* allocate a packet to send to the target */
+ tx_pkt = htc_get_control_buf(target, true);
+
+ if (!tx_pkt)
+ return -ENOMEM;
+
+ conn_msg = (struct htc_conn_service_msg *)tx_pkt->buf;
+ memset(conn_msg, 0, sizeof(*conn_msg));
+ conn_msg->msg_id = cpu_to_le16(HTC_MSG_CONN_SVC_ID);
+ conn_msg->svc_id = cpu_to_le16(conn_req->svc_id);
+ conn_msg->conn_flags = cpu_to_le16(conn_req->conn_flags);
+
+ set_htc_pkt_info(tx_pkt, NULL, (u8 *) conn_msg,
+ sizeof(*conn_msg) + conn_msg->svc_meta_len,
+ ENDPOINT_0, HTC_SERVICE_TX_PACKET_TAG);
+
+ /* we want synchronous operation */
+ tx_pkt->completion = NULL;
+ htc_prep_send_pkt(tx_pkt, 0, 0, 0);
+ status = htc_issue_send(target, tx_pkt);
+
+ if (status)
+ goto fail_tx;
+
+ /* wait for response */
+ rx_pkt = htc_wait_for_ctrl_msg(target);
+
+ if (!rx_pkt) {
+ status = -ENOMEM;
+ goto fail_tx;
+ }
+
+ resp_msg = (struct htc_conn_service_resp *)rx_pkt->buf;
+
+ if ((le16_to_cpu(resp_msg->msg_id) != HTC_MSG_CONN_SVC_RESP_ID)
+ || (rx_pkt->act_len < sizeof(*resp_msg))) {
+ status = -ENOMEM;
+ goto fail_tx;
+ }
+
+ conn_resp->resp_code = resp_msg->status;
+ /* check response status */
+ if (resp_msg->status != HTC_SERVICE_SUCCESS) {
+ ath6kl_err("target failed service 0x%X connect request (status:%d)\n",
+ resp_msg->svc_id, resp_msg->status);
+ status = -ENOMEM;
+ goto fail_tx;
+ }
+
+ assigned_ep = (enum htc_endpoint_id)resp_msg->eid;
+ max_msg_sz = le16_to_cpu(resp_msg->max_msg_sz);
+ }
+
+ if (assigned_ep >= ENDPOINT_MAX || !max_msg_sz) {
+ status = -ENOMEM;
+ goto fail_tx;
+ }
+
+ endpoint = &target->endpoint[assigned_ep];
+ endpoint->eid = assigned_ep;
+ if (endpoint->svc_id) {
+ status = -ENOMEM;
+ goto fail_tx;
+ }
+
+ /* return assigned endpoint to caller */
+ conn_resp->endpoint = assigned_ep;
+ conn_resp->len_max = max_msg_sz;
+
+ /* setup the endpoint */
+
+ /* this marks the endpoint in use */
+ endpoint->svc_id = conn_req->svc_id;
+
+ endpoint->max_txq_depth = conn_req->max_txq_depth;
+ endpoint->len_max = max_msg_sz;
+ endpoint->ep_cb = conn_req->ep_cb;
+ endpoint->cred_dist.svc_id = conn_req->svc_id;
+ endpoint->cred_dist.htc_rsvd = endpoint;
+ endpoint->cred_dist.endpoint = assigned_ep;
+ endpoint->cred_dist.cred_sz = target->tgt_cred_sz;
+
+ if (conn_req->max_rxmsg_sz) {
+ /*
+ * Override cred_per_msg calculation, this optimizes
+ * the credit-low indications since the host will actually
+ * issue smaller messages in the Send path.
+ */
+ if (conn_req->max_rxmsg_sz > max_msg_sz) {
+ status = -ENOMEM;
+ goto fail_tx;
+ }
+ endpoint->cred_dist.cred_per_msg =
+ conn_req->max_rxmsg_sz / target->tgt_cred_sz;
+ } else
+ endpoint->cred_dist.cred_per_msg =
+ max_msg_sz / target->tgt_cred_sz;
+
+ if (!endpoint->cred_dist.cred_per_msg)
+ endpoint->cred_dist.cred_per_msg = 1;
+
+ /* save local connection flags */
+ endpoint->conn_flags = conn_req->flags;
+
+fail_tx:
+ if (tx_pkt)
+ htc_reclaim_txctrl_buf(target, tx_pkt);
+
+ if (rx_pkt) {
+ htc_rxpkt_reset(rx_pkt);
+ reclaim_rx_ctrl_buf(target, rx_pkt);
+ }
+
+ return status;
+}
+
+static void reset_ep_state(struct htc_target *target)
+{
+ struct htc_endpoint *endpoint;
+ int i;
+
+ for (i = ENDPOINT_0; i < ENDPOINT_MAX; i++) {
+ endpoint = &target->endpoint[i];
+ memset(&endpoint->cred_dist, 0, sizeof(endpoint->cred_dist));
+ endpoint->svc_id = 0;
+ endpoint->len_max = 0;
+ endpoint->max_txq_depth = 0;
+ memset(&endpoint->ep_st, 0,
+ sizeof(endpoint->ep_st));
+ INIT_LIST_HEAD(&endpoint->rx_bufq);
+ INIT_LIST_HEAD(&endpoint->txq);
+ endpoint->target = target;
+ }
+
+ /* reset distribution list */
+ INIT_LIST_HEAD(&target->cred_dist_list);
+}
+
+int htc_get_rxbuf_num(struct htc_target *target, enum htc_endpoint_id endpoint)
+{
+ int num;
+
+ spin_lock_bh(&target->rx_lock);
+ num = get_queue_depth(&(target->endpoint[endpoint].rx_bufq));
+ spin_unlock_bh(&target->rx_lock);
+ return num;
+}
+
+static void htc_setup_msg_bndl(struct htc_target *target)
+{
+ struct hif_dev_scat_sup_info *scat_info = &target->dev->hif_scat_info;
+
+ /* limit what HTC can handle */
+ target->msg_per_bndl_max = min(HTC_HOST_MAX_MSG_PER_BUNDLE,
+ target->msg_per_bndl_max);
+
+ if (ath6kldev_setup_msg_bndl(target->dev, target->msg_per_bndl_max)) {
+ target->msg_per_bndl_max = 0;
+ return;
+ }
+
+ /* limit bundle what the device layer can handle */
+ target->msg_per_bndl_max = min(scat_info->max_scat_entries,
+ target->msg_per_bndl_max);
+
+ ath6kl_dbg(ATH6KL_DBG_TRC,
+ "htc bundling allowed. max msg per htc bundle: %d\n",
+ target->msg_per_bndl_max);
+
+ /* Max rx bundle size is limited by the max tx bundle size */
+ target->dev->max_rx_bndl_sz = scat_info->max_xfer_szper_scatreq;
+ /* Max tx bundle size if limited by the extended mbox address range */
+ target->dev->max_tx_bndl_sz = min(HIF_MBOX0_EXT_WIDTH,
+ scat_info->max_xfer_szper_scatreq);
+
+ ath6kl_dbg(ATH6KL_DBG_ANY, "max recv: %d max send: %d\n",
+ target->dev->max_rx_bndl_sz, target->dev->max_tx_bndl_sz);
+
+ if (target->dev->max_tx_bndl_sz)
+ target->tx_bndl_enable = true;
+
+ if (target->dev->max_rx_bndl_sz)
+ target->rx_bndl_enable = true;
+
+ if ((target->tgt_cred_sz % target->dev->block_sz) != 0) {
+ ath6kl_warn("credit size: %d is not block aligned! Disabling send bundling\n",
+ target->tgt_cred_sz);
+
+ /*
+ * Disallow send bundling since the credit size is
+ * not aligned to a block size the I/O block
+ * padding will spill into the next credit buffer
+ * which is fatal.
+ */
+ target->tx_bndl_enable = false;
+ }
+}
+
+int htc_wait_target(struct htc_target *target)
+{
+ struct htc_packet *packet = NULL;
+ struct htc_ready_ext_msg *rdy_msg;
+ struct htc_service_connect_req connect;
+ struct htc_service_connect_resp resp;
+ int status;
+
+ /* we should be getting 1 control message that the target is ready */
+ packet = htc_wait_for_ctrl_msg(target);
+
+ if (!packet)
+ return -ENOMEM;
+
+ /* we controlled the buffer creation so it's properly aligned */
+ rdy_msg = (struct htc_ready_ext_msg *)packet->buf;
+
+ if ((le16_to_cpu(rdy_msg->ver2_0_info.msg_id) != HTC_MSG_READY_ID) ||
+ (packet->act_len < sizeof(struct htc_ready_msg))) {
+ status = -ENOMEM;
+ goto fail_wait_target;
+ }
+
+ if (!rdy_msg->ver2_0_info.cred_cnt || !rdy_msg->ver2_0_info.cred_sz) {
+ status = -ENOMEM;
+ goto fail_wait_target;
+ }
+
+ target->tgt_creds = le16_to_cpu(rdy_msg->ver2_0_info.cred_cnt);
+ target->tgt_cred_sz = le16_to_cpu(rdy_msg->ver2_0_info.cred_sz);
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+ "target ready: credits: %d credit size: %d\n",
+ target->tgt_creds, target->tgt_cred_sz);
+
+ /* check if this is an extended ready message */
+ if (packet->act_len >= sizeof(struct htc_ready_ext_msg)) {
+ /* this is an extended message */
+ target->htc_tgt_ver = rdy_msg->htc_ver;
+ target->msg_per_bndl_max = rdy_msg->msg_per_htc_bndl;
+ } else {
+ /* legacy */
+ target->htc_tgt_ver = HTC_VERSION_2P0;
+ target->msg_per_bndl_max = 0;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_TRC, "using htc protocol version : %s (%d)\n",
+ (target->htc_tgt_ver == HTC_VERSION_2P0) ? "2.0" : ">= 2.1",
+ target->htc_tgt_ver);
+
+ if (target->msg_per_bndl_max > 0)
+ htc_setup_msg_bndl(target);
+
+ /* setup our pseudo HTC control endpoint connection */
+ memset(&connect, 0, sizeof(connect));
+ memset(&resp, 0, sizeof(resp));
+ connect.ep_cb.rx = htc_ctrl_rx;
+ connect.ep_cb.rx_refill = NULL;
+ connect.ep_cb.tx_full = NULL;
+ connect.max_txq_depth = NUM_CONTROL_BUFFERS;
+ connect.svc_id = HTC_CTRL_RSVD_SVC;
+
+ /* connect fake service */
+ status = htc_conn_service((void *)target, &connect, &resp);
+
+ if (status)
+ ath6kl_hif_cleanup_scatter(target->dev->ar);
+
+fail_wait_target:
+ if (packet) {
+ htc_rxpkt_reset(packet);
+ reclaim_rx_ctrl_buf(target, packet);
+ }
+
+ return status;
+}
+
+/*
+ * Start HTC, enable interrupts and let the target know
+ * host has finished setup.
+ */
+int htc_start(struct htc_target *target)
+{
+ struct htc_packet *packet;
+ int status;
+
+ /* Disable interrupts at the chip level */
+ ath6kldev_disable_intrs(target->dev);
+
+ target->htc_flags = 0;
+ target->rx_st_flags = 0;
+
+ /* Push control receive buffers into htc control endpoint */
+ while ((packet = htc_get_control_buf(target, false)) != NULL) {
+ status = htc_add_rxbuf(target, packet);
+ if (status)
+ return status;
+ }
+
+ /* NOTE: the first entry in the distribution list is ENDPOINT_0 */
+ ath6k_credit_init(target->cred_dist_cntxt, &target->cred_dist_list,
+ target->tgt_creds);
+
+ dump_cred_dist_stats(target);
+
+ /* Indicate to the target of the setup completion */
+ status = htc_setup_tx_complete(target);
+
+ if (status)
+ return status;
+
+ /* unmask interrupts */
+ status = ath6kldev_unmask_intrs(target->dev);
+
+ if (status)
+ htc_stop(target);
+
+ return status;
+}
+
+/* htc_stop: stop interrupt reception, and flush all queued buffers */
+void htc_stop(struct htc_target *target)
+{
+ spin_lock_bh(&target->htc_lock);
+ target->htc_flags |= HTC_OP_STATE_STOPPING;
+ spin_unlock_bh(&target->htc_lock);
+
+ /*
+ * Masking interrupts is a synchronous operation, when this
+ * function returns all pending HIF I/O has completed, we can
+ * safely flush the queues.
+ */
+ ath6kldev_mask_intrs(target->dev);
+
+ htc_flush_txep_all(target);
+
+ htc_flush_rx_buf(target);
+
+ reset_ep_state(target);
+}
+
+void *htc_create(struct ath6kl *ar)
+{
+ struct htc_target *target = NULL;
+ struct htc_packet *packet;
+ int status = 0, i = 0;
+ u32 block_size, ctrl_bufsz;
+
+ target = kzalloc(sizeof(*target), GFP_KERNEL);
+ if (!target) {
+ ath6kl_err("unable to allocate memory\n");
+ return NULL;
+ }
+
+ target->dev = kzalloc(sizeof(*target->dev), GFP_KERNEL);
+ if (!target->dev) {
+ ath6kl_err("unable to allocate memory\n");
+ status = -ENOMEM;
+ goto fail_create_htc;
+ }
+
+ spin_lock_init(&target->htc_lock);
+ spin_lock_init(&target->rx_lock);
+ spin_lock_init(&target->tx_lock);
+
+ INIT_LIST_HEAD(&target->free_ctrl_txbuf);
+ INIT_LIST_HEAD(&target->free_ctrl_rxbuf);
+ INIT_LIST_HEAD(&target->cred_dist_list);
+
+ target->dev->ar = ar;
+ target->dev->htc_cnxt = target;
+ target->dev->msg_pending = htc_rxmsg_pending_handler;
+ target->ep_waiting = ENDPOINT_MAX;
+
+ reset_ep_state(target);
+
+ status = ath6kldev_setup(target->dev);
+
+ if (status)
+ goto fail_create_htc;
+
+ block_size = ar->mbox_info.block_size;
+
+ ctrl_bufsz = (block_size > HTC_MAX_CTRL_MSG_LEN) ?
+ (block_size + HTC_HDR_LENGTH) :
+ (HTC_MAX_CTRL_MSG_LEN + HTC_HDR_LENGTH);
+
+ for (i = 0; i < NUM_CONTROL_BUFFERS; i++) {
+ packet = kzalloc(sizeof(*packet), GFP_KERNEL);
+ if (!packet)
+ break;
+
+ packet->buf_start = kzalloc(ctrl_bufsz, GFP_KERNEL);
+ if (!packet->buf_start) {
+ kfree(packet);
+ break;
+ }
+
+ packet->buf_len = ctrl_bufsz;
+ if (i < NUM_CONTROL_RX_BUFFERS) {
+ packet->act_len = 0;
+ packet->buf = packet->buf_start;
+ packet->endpoint = ENDPOINT_0;
+ list_add_tail(&packet->list, &target->free_ctrl_rxbuf);
+ } else
+ list_add_tail(&packet->list, &target->free_ctrl_txbuf);
+ }
+
+fail_create_htc:
+ if (i != NUM_CONTROL_BUFFERS || status) {
+ if (target) {
+ htc_cleanup(target);
+ target = NULL;
+ }
+ }
+
+ return target;
+}
+
+/* cleanup the HTC instance */
+void htc_cleanup(struct htc_target *target)
+{
+ struct htc_packet *packet, *tmp_packet;
+
+ ath6kl_hif_cleanup_scatter(target->dev->ar);
+
+ list_for_each_entry_safe(packet, tmp_packet,
+ &target->free_ctrl_txbuf, list) {
+ list_del(&packet->list);
+ kfree(packet->buf_start);
+ kfree(packet);
+ }
+
+ list_for_each_entry_safe(packet, tmp_packet,
+ &target->free_ctrl_rxbuf, list) {
+ list_del(&packet->list);
+ kfree(packet->buf_start);
+ kfree(packet);
+ }
+
+ kfree(target->dev);
+ kfree(target);
+}
diff --git a/drivers/net/wireless/ath/ath6kl/htc.h b/drivers/net/wireless/ath/ath6kl/htc.h
new file mode 100644
index 000000000000..16fa7a84a231
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/htc.h
@@ -0,0 +1,596 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications Inc.
+ *
+ * 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.
+ */
+
+#ifndef HTC_H
+#define HTC_H
+
+#include "common.h"
+
+/* frame header flags */
+
+/* send direction */
+#define HTC_FLAGS_NEED_CREDIT_UPDATE (1 << 0)
+#define HTC_FLAGS_SEND_BUNDLE (1 << 1)
+
+/* receive direction */
+#define HTC_FLG_RX_UNUSED (1 << 0)
+#define HTC_FLG_RX_TRAILER (1 << 1)
+/* Bundle count maske and shift */
+#define HTC_FLG_RX_BNDL_CNT (0xF0)
+#define HTC_FLG_RX_BNDL_CNT_S 4
+
+#define HTC_HDR_LENGTH (sizeof(struct htc_frame_hdr))
+#define HTC_MAX_PAYLOAD_LENGTH (4096 - sizeof(struct htc_frame_hdr))
+
+/* HTC control message IDs */
+
+#define HTC_MSG_READY_ID 1
+#define HTC_MSG_CONN_SVC_ID 2
+#define HTC_MSG_CONN_SVC_RESP_ID 3
+#define HTC_MSG_SETUP_COMPLETE_ID 4
+#define HTC_MSG_SETUP_COMPLETE_EX_ID 5
+
+#define HTC_MAX_CTRL_MSG_LEN 256
+
+#define HTC_VERSION_2P0 0x00
+#define HTC_VERSION_2P1 0x01
+
+#define HTC_SERVICE_META_DATA_MAX_LENGTH 128
+
+#define HTC_CONN_FLGS_THRESH_LVL_QUAT 0x0
+#define HTC_CONN_FLGS_THRESH_LVL_HALF 0x1
+#define HTC_CONN_FLGS_THRESH_LVL_THREE_QUAT 0x2
+#define HTC_CONN_FLGS_REDUCE_CRED_DRIB 0x4
+#define HTC_CONN_FLGS_THRESH_MASK 0x3
+
+/* connect response status codes */
+#define HTC_SERVICE_SUCCESS 0
+#define HTC_SERVICE_NOT_FOUND 1
+#define HTC_SERVICE_FAILED 2
+
+/* no resources (i.e. no more endpoints) */
+#define HTC_SERVICE_NO_RESOURCES 3
+
+/* specific service is not allowing any more endpoints */
+#define HTC_SERVICE_NO_MORE_EP 4
+
+/* report record IDs */
+#define HTC_RECORD_NULL 0
+#define HTC_RECORD_CREDITS 1
+#define HTC_RECORD_LOOKAHEAD 2
+#define HTC_RECORD_LOOKAHEAD_BUNDLE 3
+
+#define HTC_SETUP_COMP_FLG_RX_BNDL_EN (1 << 0)
+
+#define MAKE_SERVICE_ID(group, index) \
+ (int)(((int)group << 8) | (int)(index))
+
+/* NOTE: service ID of 0x0000 is reserved and should never be used */
+#define HTC_CTRL_RSVD_SVC MAKE_SERVICE_ID(RSVD_SERVICE_GROUP, 1)
+#define WMI_CONTROL_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 0)
+#define WMI_DATA_BE_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 1)
+#define WMI_DATA_BK_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 2)
+#define WMI_DATA_VI_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 3)
+#define WMI_DATA_VO_SVC MAKE_SERVICE_ID(WMI_SERVICE_GROUP, 4)
+#define WMI_MAX_SERVICES 5
+
+/* reserved and used to flush ALL packets */
+#define HTC_TX_PACKET_TAG_ALL 0
+#define HTC_SERVICE_TX_PACKET_TAG 1
+#define HTC_TX_PACKET_TAG_USER_DEFINED (HTC_SERVICE_TX_PACKET_TAG + 9)
+
+/* more packets on this endpoint are being fetched */
+#define HTC_RX_FLAGS_INDICATE_MORE_PKTS (1 << 0)
+
+/* TODO.. for BMI */
+#define ENDPOINT1 0
+/* TODO -remove me, but we have to fix BMI first */
+#define HTC_MAILBOX_NUM_MAX 4
+
+/* enable send bundle padding for this endpoint */
+#define HTC_FLGS_TX_BNDL_PAD_EN (1 << 0)
+#define HTC_EP_ACTIVE ((u32) (1u << 31))
+
+/* HTC operational parameters */
+#define HTC_TARGET_RESPONSE_TIMEOUT 2000 /* in ms */
+#define HTC_TARGET_DEBUG_INTR_MASK 0x01
+#define HTC_TARGET_CREDIT_INTR_MASK 0xF0
+
+#define HTC_HOST_MAX_MSG_PER_BUNDLE 8
+#define HTC_MIN_HTC_MSGS_TO_BUNDLE 2
+
+/* packet flags */
+
+#define HTC_RX_PKT_IGNORE_LOOKAHEAD (1 << 0)
+#define HTC_RX_PKT_REFRESH_HDR (1 << 1)
+#define HTC_RX_PKT_PART_OF_BUNDLE (1 << 2)
+#define HTC_RX_PKT_NO_RECYCLE (1 << 3)
+
+/* scatter request flags */
+
+#define HTC_SCAT_REQ_FLG_PART_BNDL (1 << 0)
+
+#define NUM_CONTROL_BUFFERS 8
+#define NUM_CONTROL_TX_BUFFERS 2
+#define NUM_CONTROL_RX_BUFFERS (NUM_CONTROL_BUFFERS - NUM_CONTROL_TX_BUFFERS)
+
+#define HTC_RECV_WAIT_BUFFERS (1 << 0)
+#define HTC_OP_STATE_STOPPING (1 << 0)
+
+/*
+ * The frame header length and message formats defined herein were selected
+ * to accommodate optimal alignment for target processing. This reduces
+ * code size and improves performance. Any changes to the header length may
+ * alter the alignment and cause exceptions on the target. When adding to
+ * the messagestructures insure that fields are properly aligned.
+ */
+
+/* HTC frame header
+ *
+ * NOTE: do not remove or re-arrange the fields, these are minimally
+ * required to take advantage of 4-byte lookaheads in some hardware
+ * implementations.
+ */
+struct htc_frame_hdr {
+ u8 eid;
+ u8 flags;
+
+ /* length of data (including trailer) that follows the header */
+ __le16 payld_len;
+
+ /* end of 4-byte lookahead */
+
+ u8 ctrl[2];
+} __packed;
+
+/* HTC ready message */
+struct htc_ready_msg {
+ __le16 msg_id;
+ __le16 cred_cnt;
+ __le16 cred_sz;
+ u8 max_ep;
+ u8 pad;
+} __packed;
+
+/* extended HTC ready message */
+struct htc_ready_ext_msg {
+ struct htc_ready_msg ver2_0_info;
+ u8 htc_ver;
+ u8 msg_per_htc_bndl;
+} __packed;
+
+/* connect service */
+struct htc_conn_service_msg {
+ __le16 msg_id;
+ __le16 svc_id;
+ __le16 conn_flags;
+ u8 svc_meta_len;
+ u8 pad;
+} __packed;
+
+/* connect response */
+struct htc_conn_service_resp {
+ __le16 msg_id;
+ __le16 svc_id;
+ u8 status;
+ u8 eid;
+ __le16 max_msg_sz;
+ u8 svc_meta_len;
+ u8 pad;
+} __packed;
+
+struct htc_setup_comp_msg {
+ __le16 msg_id;
+} __packed;
+
+/* extended setup completion message */
+struct htc_setup_comp_ext_msg {
+ __le16 msg_id;
+ __le32 flags;
+ u8 msg_per_rxbndl;
+ u8 Rsvd[3];
+} __packed;
+
+struct htc_record_hdr {
+ u8 rec_id;
+ u8 len;
+} __packed;
+
+struct htc_credit_report {
+ u8 eid;
+ u8 credits;
+} __packed;
+
+/*
+ * NOTE: The lk_ahd array is guarded by a pre_valid
+ * and Post Valid guard bytes. The pre_valid bytes must
+ * equal the inverse of the post_valid byte.
+ */
+struct htc_lookahead_report {
+ u8 pre_valid;
+ u8 lk_ahd[4];
+ u8 post_valid;
+} __packed;
+
+struct htc_bundle_lkahd_rpt {
+ u8 lk_ahd[4];
+} __packed;
+
+/* Current service IDs */
+
+enum htc_service_grp_ids {
+ RSVD_SERVICE_GROUP = 0,
+ WMI_SERVICE_GROUP = 1,
+
+ HTC_TEST_GROUP = 254,
+ HTC_SERVICE_GROUP_LAST = 255
+};
+
+/* ------ endpoint IDS ------ */
+
+enum htc_endpoint_id {
+ ENDPOINT_UNUSED = -1,
+ ENDPOINT_0 = 0,
+ ENDPOINT_1 = 1,
+ ENDPOINT_2 = 2,
+ ENDPOINT_3,
+ ENDPOINT_4,
+ ENDPOINT_5,
+ ENDPOINT_6,
+ ENDPOINT_7,
+ ENDPOINT_8,
+ ENDPOINT_MAX,
+};
+
+struct htc_tx_packet_info {
+ u16 tag;
+ int cred_used;
+ u8 flags;
+ int seqno;
+};
+
+struct htc_rx_packet_info {
+ u32 exp_hdr;
+ u32 rx_flags;
+ u32 indicat_flags;
+};
+
+struct htc_target;
+
+/* wrapper around endpoint-specific packets */
+struct htc_packet {
+ struct list_head list;
+
+ /* caller's per packet specific context */
+ void *pkt_cntxt;
+
+ /*
+ * the true buffer start , the caller can store the real
+ * buffer start here. In receive callbacks, the HTC layer
+ * sets buf to the start of the payload past the header.
+ * This field allows the caller to reset buf when it recycles
+ * receive packets back to HTC.
+ */
+ u8 *buf_start;
+
+ /*
+ * Pointer to the start of the buffer. In the transmit
+ * direction this points to the start of the payload. In the
+ * receive direction, however, the buffer when queued up
+ * points to the start of the HTC header but when returned
+ * to the caller points to the start of the payload
+ */
+ u8 *buf;
+ u32 buf_len;
+
+ /* actual length of payload */
+ u32 act_len;
+
+ /* endpoint that this packet was sent/recv'd from */
+ enum htc_endpoint_id endpoint;
+
+ /* completion status */
+
+ int status;
+ union {
+ struct htc_tx_packet_info tx;
+ struct htc_rx_packet_info rx;
+ } info;
+
+ void (*completion) (struct htc_target *, struct htc_packet *);
+ struct htc_target *context;
+};
+
+enum htc_send_full_action {
+ HTC_SEND_FULL_KEEP = 0,
+ HTC_SEND_FULL_DROP = 1,
+};
+
+struct htc_ep_callbacks {
+ void (*rx) (struct htc_target *, struct htc_packet *);
+ void (*rx_refill) (struct htc_target *, enum htc_endpoint_id endpoint);
+ enum htc_send_full_action (*tx_full) (struct htc_target *,
+ struct htc_packet *);
+ struct htc_packet *(*rx_allocthresh) (struct htc_target *,
+ enum htc_endpoint_id, int);
+ int rx_alloc_thresh;
+ int rx_refill_thresh;
+};
+
+/* service connection information */
+struct htc_service_connect_req {
+ u16 svc_id;
+ u16 conn_flags;
+ struct htc_ep_callbacks ep_cb;
+ int max_txq_depth;
+ u32 flags;
+ unsigned int max_rxmsg_sz;
+};
+
+/* service connection response information */
+struct htc_service_connect_resp {
+ u8 buf_len;
+ u8 act_len;
+ enum htc_endpoint_id endpoint;
+ unsigned int len_max;
+ u8 resp_code;
+};
+
+/* endpoint distributionstructure */
+struct htc_endpoint_credit_dist {
+ struct list_head list;
+
+ /* Service ID (set by HTC) */
+ u16 svc_id;
+
+ /* endpoint for this distributionstruct (set by HTC) */
+ enum htc_endpoint_id endpoint;
+
+ u32 dist_flags;
+
+ /*
+ * credits for normal operation, anything above this
+ * indicates the endpoint is over-subscribed.
+ */
+ int cred_norm;
+
+ /* floor for credit distribution */
+ int cred_min;
+
+ int cred_assngd;
+
+ /* current credits available */
+ int credits;
+
+ /*
+ * pending credits to distribute on this endpoint, this
+ * is set by HTC when credit reports arrive. The credit
+ * distribution functions sets this to zero when it distributes
+ * the credits.
+ */
+ int cred_to_dist;
+
+ /*
+ * the number of credits that the current pending TX packet needs
+ * to transmit. This is set by HTC when endpoint needs credits in
+ * order to transmit.
+ */
+ int seek_cred;
+
+ /* size in bytes of each credit */
+ int cred_sz;
+
+ /* credits required for a maximum sized messages */
+ int cred_per_msg;
+
+ /* reserved for HTC use */
+ void *htc_rsvd;
+
+ /*
+ * current depth of TX queue , i.e. messages waiting for credits
+ * This field is valid only when HTC_CREDIT_DIST_ACTIVITY_CHANGE
+ * or HTC_CREDIT_DIST_SEND_COMPLETE is indicated on an endpoint
+ * that has non-zero credits to recover.
+ */
+ int txq_depth;
+};
+
+/*
+ * credit distibution code that is passed into the distrbution function,
+ * there are mandatory and optional codes that must be handled
+ */
+enum htc_credit_dist_reason {
+ HTC_CREDIT_DIST_SEND_COMPLETE = 0,
+ HTC_CREDIT_DIST_ACTIVITY_CHANGE = 1,
+ HTC_CREDIT_DIST_SEEK_CREDITS,
+};
+
+struct htc_credit_state_info {
+ int total_avail_credits;
+ int cur_free_credits;
+ struct list_head lowestpri_ep_dist;
+};
+
+/* endpoint statistics */
+struct htc_endpoint_stats {
+ /*
+ * number of times the host set the credit-low flag in a send
+ * message on this endpoint
+ */
+ u32 cred_low_indicate;
+
+ u32 tx_issued;
+ u32 tx_pkt_bundled;
+ u32 tx_bundles;
+ u32 tx_dropped;
+
+ /* running count of total credit reports received for this endpoint */
+ u32 tx_cred_rpt;
+
+ /* credit reports received from this endpoint's RX packets */
+ u32 cred_rpt_from_rx;
+
+ /* credit reports received from RX packets of other endpoints */
+ u32 cred_rpt_from_other;
+
+ /* credit reports received from endpoint 0 RX packets */
+ u32 cred_rpt_ep0;
+
+ /* count of credits received via Rx packets on this endpoint */
+ u32 cred_from_rx;
+
+ /* count of credits received via another endpoint */
+ u32 cred_from_other;
+
+ /* count of credits received via another endpoint */
+ u32 cred_from_ep0;
+
+ /* count of consummed credits */
+ u32 cred_cosumd;
+
+ /* count of credits returned */
+ u32 cred_retnd;
+
+ u32 rx_pkts;
+
+ /* count of lookahead records found in Rx msg */
+ u32 rx_lkahds;
+
+ /* count of recv packets received in a bundle */
+ u32 rx_bundl;
+
+ /* count of number of bundled lookaheads */
+ u32 rx_bundle_lkahd;
+
+ /* count of the number of bundle indications from the HTC header */
+ u32 rx_bundle_from_hdr;
+
+ /* the number of times the recv allocation threshold was hit */
+ u32 rx_alloc_thresh_hit;
+
+ /* total number of bytes */
+ u32 rxalloc_thresh_byte;
+};
+
+struct htc_endpoint {
+ enum htc_endpoint_id eid;
+ u16 svc_id;
+ struct list_head txq;
+ struct list_head rx_bufq;
+ struct htc_endpoint_credit_dist cred_dist;
+ struct htc_ep_callbacks ep_cb;
+ int max_txq_depth;
+ int len_max;
+ int tx_proc_cnt;
+ int rx_proc_cnt;
+ struct htc_target *target;
+ u8 seqno;
+ u32 conn_flags;
+ struct htc_endpoint_stats ep_st;
+};
+
+struct htc_control_buffer {
+ struct htc_packet packet;
+ u8 *buf;
+};
+
+struct ath6kl_device;
+
+/* our HTC target state */
+struct htc_target {
+ struct htc_endpoint endpoint[ENDPOINT_MAX];
+ struct list_head cred_dist_list;
+ struct list_head free_ctrl_txbuf;
+ struct list_head free_ctrl_rxbuf;
+ struct htc_credit_state_info *cred_dist_cntxt;
+ int tgt_creds;
+ unsigned int tgt_cred_sz;
+ spinlock_t htc_lock;
+ spinlock_t rx_lock;
+ spinlock_t tx_lock;
+ struct ath6kl_device *dev;
+ u32 htc_flags;
+ u32 rx_st_flags;
+ enum htc_endpoint_id ep_waiting;
+ u8 htc_tgt_ver;
+
+ /* max messages per bundle for HTC */
+ int msg_per_bndl_max;
+
+ bool tx_bndl_enable;
+ int rx_bndl_enable;
+};
+
+void *htc_create(struct ath6kl *ar);
+void htc_set_credit_dist(struct htc_target *target,
+ struct htc_credit_state_info *cred_info,
+ u16 svc_pri_order[], int len);
+int htc_wait_target(struct htc_target *target);
+int htc_start(struct htc_target *target);
+int htc_conn_service(struct htc_target *target,
+ struct htc_service_connect_req *req,
+ struct htc_service_connect_resp *resp);
+int htc_tx(struct htc_target *target, struct htc_packet *packet);
+void htc_stop(struct htc_target *target);
+void htc_cleanup(struct htc_target *target);
+void htc_flush_txep(struct htc_target *target,
+ enum htc_endpoint_id endpoint, u16 tag);
+void htc_flush_rx_buf(struct htc_target *target);
+void htc_indicate_activity_change(struct htc_target *target,
+ enum htc_endpoint_id endpoint, bool active);
+int htc_get_rxbuf_num(struct htc_target *target, enum htc_endpoint_id endpoint);
+int htc_add_rxbuf_multiple(struct htc_target *target, struct list_head *pktq);
+
+static inline void set_htc_pkt_info(struct htc_packet *packet, void *context,
+ u8 *buf, unsigned int len,
+ enum htc_endpoint_id eid, u16 tag)
+{
+ packet->pkt_cntxt = context;
+ packet->buf = buf;
+ packet->act_len = len;
+ packet->endpoint = eid;
+ packet->info.tx.tag = tag;
+}
+
+static inline void htc_rxpkt_reset(struct htc_packet *packet)
+{
+ packet->buf = packet->buf_start;
+ packet->act_len = 0;
+}
+
+static inline void set_htc_rxpkt_info(struct htc_packet *packet, void *context,
+ u8 *buf, unsigned long len,
+ enum htc_endpoint_id eid)
+{
+ packet->pkt_cntxt = context;
+ packet->buf = buf;
+ packet->buf_start = buf;
+ packet->buf_len = len;
+ packet->endpoint = eid;
+}
+
+static inline int get_queue_depth(struct list_head *queue)
+{
+ struct list_head *tmp_list;
+ int depth = 0;
+
+ list_for_each(tmp_list, queue)
+ depth++;
+
+ return depth;
+}
+
+#endif
diff --git a/drivers/net/wireless/ath/ath6kl/htc_hif.c b/drivers/net/wireless/ath/ath6kl/htc_hif.c
new file mode 100644
index 000000000000..1bcaaec579c5
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/htc_hif.c
@@ -0,0 +1,811 @@
+/*
+ * Copyright (c) 2007-2011 Atheros Communications Inc.
+ *
+ * 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 "core.h"
+#include "target.h"
+#include "hif-ops.h"
+#include "htc_hif.h"
+#include "debug.h"
+
+#define MAILBOX_FOR_BLOCK_SIZE 1
+
+#define ATH6KL_TIME_QUANTUM 10 /* in ms */
+
+static void ath6kl_add_io_pkt(struct ath6kl_device *dev,
+ struct htc_packet *packet)
+{
+ spin_lock_bh(&dev->lock);
+ list_add_tail(&packet->list, &dev->reg_io);
+ spin_unlock_bh(&dev->lock);
+}
+
+static struct htc_packet *ath6kl_get_io_pkt(struct ath6kl_device *dev)
+{
+ struct htc_packet *packet = NULL;
+
+ spin_lock_bh(&dev->lock);
+ if (!list_empty(&dev->reg_io)) {
+ packet = list_first_entry(&dev->reg_io,
+ struct htc_packet, list);
+ list_del(&packet->list);
+ }
+ spin_unlock_bh(&dev->lock);
+
+ return packet;
+}
+
+static int ath6kldev_cp_scat_dma_buf(struct hif_scatter_req *req, bool from_dma)
+{
+ u8 *buf;
+ int i;
+
+ buf = req->virt_dma_buf;
+
+ for (i = 0; i < req->scat_entries; i++) {
+
+ if (from_dma)
+ memcpy(req->scat_list[i].buf, buf,
+ req->scat_list[i].len);
+ else
+ memcpy(buf, req->scat_list[i].buf,
+ req->scat_list[i].len);
+
+ buf += req->scat_list[i].len;
+ }
+
+ return 0;
+}
+
+int ath6kldev_rw_comp_handler(void *context, int status)
+{
+ struct htc_packet *packet = context;
+
+ ath6kl_dbg(ATH6KL_DBG_HTC_RECV,
+ "ath6kldev_rw_comp_handler (pkt:0x%p , status: %d\n",
+ packet, status);
+
+ packet->status = status;
+ packet->completion(packet->context, packet);
+
+ return 0;
+}
+
+static int ath6kldev_proc_dbg_intr(struct ath6kl_device *dev)
+{
+ u32 dummy;
+ int status;
+
+ ath6kl_err("target debug interrupt\n");
+
+ ath6kl_target_failure(dev->ar);
+
+ /*
+ * read counter to clear the interrupt, the debug error interrupt is
+ * counter 0.
+ */
+ status = hif_read_write_sync(dev->ar, COUNT_DEC_ADDRESS,
+ (u8 *)&dummy, 4, HIF_RD_SYNC_BYTE_INC);
+ if (status)
+ WARN_ON(1);
+
+ return status;
+}
+
+/* mailbox recv message polling */
+int ath6kldev_poll_mboxmsg_rx(struct ath6kl_device *dev, u32 *lk_ahd,
+ int timeout)
+{
+ struct ath6kl_irq_proc_registers *rg;
+ int status = 0, i;
+ u8 htc_mbox = 1 << HTC_MAILBOX;
+
+ for (i = timeout / ATH6KL_TIME_QUANTUM; i > 0; i--) {
+ /* this is the standard HIF way, load the reg table */
+ status = hif_read_write_sync(dev->ar, HOST_INT_STATUS_ADDRESS,
+ (u8 *) &dev->irq_proc_reg,
+ sizeof(dev->irq_proc_reg),
+ HIF_RD_SYNC_BYTE_INC);
+
+ if (status) {
+ ath6kl_err("failed to read reg table\n");
+ return status;
+ }
+
+ /* check for MBOX data and valid lookahead */
+ if (dev->irq_proc_reg.host_int_status & htc_mbox) {
+ if (dev->irq_proc_reg.rx_lkahd_valid &
+ htc_mbox) {
+ /*
+ * Mailbox has a message and the look ahead
+ * is valid.
+ */
+ rg = &dev->irq_proc_reg;
+ *lk_ahd =
+ le32_to_cpu(rg->rx_lkahd[HTC_MAILBOX]);
+ break;
+ }
+ }
+
+ /* delay a little */
+ mdelay(ATH6KL_TIME_QUANTUM);
+ ath6kl_dbg(ATH6KL_DBG_HTC_RECV, "retry mbox poll : %d\n", i);
+ }
+
+ if (i == 0) {
+ ath6kl_err("timeout waiting for recv message\n");
+ status = -ETIME;
+ /* check if the target asserted */
+ if (dev->irq_proc_reg.counter_int_status &
+ ATH6KL_TARGET_DEBUG_INTR_MASK)
+ /*
+ * Target failure handler will be called in case of
+ * an assert.
+ */
+ ath6kldev_proc_dbg_intr(dev);
+ }
+
+ return status;
+}
+
+/*
+ * Disable packet reception (used in case the host runs out of buffers)
+ * using the interrupt enable registers through the host I/F
+ */
+int ath6kldev_rx_control(struct ath6kl_device *dev, bool enable_rx)
+{
+ struct ath6kl_irq_enable_reg regs;
+ int status = 0;
+
+ /* take the lock to protect interrupt enable shadows */
+ spin_lock_bh(&dev->lock);
+
+ if (enable_rx)
+ dev->irq_en_reg.int_status_en |=
+ SM(INT_STATUS_ENABLE_MBOX_DATA, 0x01);
+ else
+ dev->irq_en_reg.int_status_en &=
+ ~SM(INT_STATUS_ENABLE_MBOX_DATA, 0x01);
+
+ memcpy(&regs, &dev->irq_en_reg, sizeof(regs));
+
+ spin_unlock_bh(&dev->lock);
+
+ status = hif_read_write_sync(dev->ar, INT_STATUS_ENABLE_ADDRESS,
+ &regs.int_status_en,
+ sizeof(struct ath6kl_irq_enable_reg),
+ HIF_WR_SYNC_BYTE_INC);
+
+ return status;
+}
+
+static void ath6kldev_rw_async_handler(struct htc_target *target,
+ struct htc_packet *packet)
+{
+ struct ath6kl_device *dev = target->dev;
+ struct hif_scatter_req *req = packet->pkt_cntxt;
+
+ req->status = packet->status;
+
+ ath6kl_add_io_pkt(dev, packet);
+
+ req->complete(req);
+}
+
+static int ath6kldev_rw_scatter(struct ath6kl *ar, struct hif_scatter_req *req)
+{
+ struct ath6kl_device *dev = ar->htc_target->dev;
+ struct htc_packet *packet = NULL;
+ int status = 0;
+ u32 request = req->req;
+ u8 *virt_dma_buf;
+
+ if (!req->len)
+ return 0;
+
+ if (request & HIF_ASYNCHRONOUS) {
+ /* use an I/O packet to carry this request */
+ packet = ath6kl_get_io_pkt(dev);
+ if (!packet) {
+ status = -ENOMEM;
+ goto out;
+ }
+
+ packet->pkt_cntxt = req;
+ packet->completion = ath6kldev_rw_async_handler;
+ packet->context = ar->htc_target;
+ }
+
+ virt_dma_buf = req->virt_dma_buf;
+
+ if (request & HIF_ASYNCHRONOUS)
+ status = hif_write_async(dev->ar, req->addr, virt_dma_buf,
+ req->len, request, packet);
+ else
+ status = hif_read_write_sync(dev->ar, req->addr, virt_dma_buf,
+ req->len, request);
+
+out:
+ if (status)
+ if (request & HIF_ASYNCHRONOUS) {
+ if (packet != NULL)
+ ath6kl_add_io_pkt(dev, packet);
+ req->status = status;
+ req->complete(req);
+ status = 0;
+ }
+
+ return status;
+}
+
+int ath6kldev_submit_scat_req(struct ath6kl_device *dev,
+ struct hif_scatter_req *scat_req, bool read)
+{
+ int status = 0;
+
+ if (read) {
+ scat_req->req = HIF_RD_SYNC_BLOCK_FIX;
+ scat_req->addr = dev->ar->mbox_info.htc_addr;
+ } else {
+ scat_req->req = HIF_WR_ASYNC_BLOCK_INC;
+
+ scat_req->addr =
+ (scat_req->len > HIF_MBOX_WIDTH) ?
+ dev->ar->mbox_info.htc_ext_addr :
+ dev->ar->mbox_info.htc_addr;
+ }
+
+ ath6kl_dbg((ATH6KL_DBG_HTC_RECV | ATH6KL_DBG_HTC_SEND),
+ "ath6kldev_submit_scat_req, entries: %d, total len: %d mbox:0x%X (mode: %s : %s)\n",
+ scat_req->scat_entries, scat_req->len,
+ scat_req->addr, !read ? "async" : "sync",
+ (read) ? "rd" : "wr");
+
+ if (!read && dev->virt_scat)
+ status = ath6kldev_cp_scat_dma_buf(scat_req, false);
+
+ if (status) {
+ if (!read) {
+ scat_req->status = status;
+ scat_req->complete(scat_req);
+ return 0;
+ }
+ return status;
+ }
+
+ status = dev->hif_scat_info.rw_scat_func(dev->ar, scat_req);
+
+ if (read) {
+ /* in sync mode, we can touch the scatter request */
+ scat_req->status = status;
+ if (!status && dev->virt_scat)
+ scat_req->status =
+ ath6kldev_cp_scat_dma_buf(scat_req, true);
+ }
+
+ return status;
+}
+
+/*
+ * function to set up virtual scatter support if HIF
+ * layer has not implemented the interface.
+ */
+static int ath6kldev_setup_virt_scat_sup(struct ath6kl_device *dev)
+{
+ struct hif_scatter_req *scat_req;
+ int buf_sz, scat_req_sz, scat_list_sz;
+ int i, status = 0;
+ u8 *virt_dma_buf;
+
+ buf_sz = 2 * L1_CACHE_BYTES + ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER;
+
+ scat_list_sz = (ATH6KL_SCATTER_ENTRIES_PER_REQ - 1) *
+ sizeof(struct hif_scatter_item);
+ scat_req_sz = sizeof(*scat_req) + scat_list_sz;
+
+ for (i = 0; i < ATH6KL_SCATTER_REQS; i++) {
+ scat_req = kzalloc(scat_req_sz, GFP_KERNEL);
+
+ if (!scat_req) {
+ status = -ENOMEM;
+ break;
+ }
+
+ virt_dma_buf = kzalloc(buf_sz, GFP_KERNEL);
+ if (!virt_dma_buf) {
+ kfree(scat_req);
+ status = -ENOMEM;
+ break;
+ }
+
+ scat_req->virt_dma_buf =
+ (u8 *)L1_CACHE_ALIGN((unsigned long)virt_dma_buf);
+
+ /* we emulate a DMA bounce interface */
+ hif_scatter_req_add(dev->ar, scat_req);
+ }
+
+ if (status)
+ ath6kl_hif_cleanup_scatter(dev->ar);
+ else {
+ dev->hif_scat_info.rw_scat_func = ath6kldev_rw_scatter;
+ dev->hif_scat_info.max_scat_entries =
+ ATH6KL_SCATTER_ENTRIES_PER_REQ;
+ dev->hif_scat_info.max_xfer_szper_scatreq =
+ ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER;
+ dev->virt_scat = true;
+ }
+
+ return status;
+}
+
+int ath6kldev_setup_msg_bndl(struct ath6kl_device *dev, int max_msg_per_trans)
+{
+ int status;
+
+ status = ath6kl_hif_enable_scatter(dev->ar, &dev->hif_scat_info);
+
+ if (status) {
+ ath6kl_warn("hif does not support scatter requests (%d)\n",
+ status);
+
+ /* we can try to use a virtual DMA scatter mechanism */
+ status = ath6kldev_setup_virt_scat_sup(dev);
+ }
+
+ if (!status)
+ ath6kl_dbg(ATH6KL_DBG_ANY, "max scatter items:%d: maxlen:%d\n",
+ dev->hif_scat_info.max_scat_entries,
+ dev->hif_scat_info.max_xfer_szper_scatreq);
+
+ return status;
+}
+
+static int ath6kldev_proc_counter_intr(struct ath6kl_device *dev)
+{
+ u8 counter_int_status;
+
+ ath6kl_dbg(ATH6KL_DBG_IRQ, "counter interrupt\n");
+
+ counter_int_status = dev->irq_proc_reg.counter_int_status &
+ dev->irq_en_reg.cntr_int_status_en;
+
+ ath6kl_dbg(ATH6KL_DBG_IRQ,
+ "valid interrupt source(s) in COUNTER_INT_STATUS: 0x%x\n",
+ counter_int_status);
+
+ /*
+ * NOTE: other modules like GMBOX may use the counter interrupt for
+ * credit flow control on other counters, we only need to check for
+ * the debug assertion counter interrupt.
+ */
+ if (counter_int_status & ATH6KL_TARGET_DEBUG_INTR_MASK)
+ return ath6kldev_proc_dbg_intr(dev);
+
+ return 0;
+}
+
+static int ath6kldev_proc_err_intr(struct ath6kl_device *dev)
+{
+ int status;
+ u8 error_int_status;
+ u8 reg_buf[4];
+
+ ath6kl_dbg(ATH6KL_DBG_IRQ, "error interrupt\n");
+
+ error_int_status = dev->irq_proc_reg.error_int_status & 0x0F;
+ if (!error_int_status) {
+ WARN_ON(1);
+ return -EIO;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_IRQ,
+ "valid interrupt source(s) in ERROR_INT_STATUS: 0x%x\n",
+ error_int_status);
+
+ if (MS(ERROR_INT_STATUS_WAKEUP, error_int_status))
+ ath6kl_dbg(ATH6KL_DBG_IRQ, "error : wakeup\n");
+
+ if (MS(ERROR_INT_STATUS_RX_UNDERFLOW, error_int_status))
+ ath6kl_err("rx underflow\n");
+
+ if (MS(ERROR_INT_STATUS_TX_OVERFLOW, error_int_status))
+ ath6kl_err("tx overflow\n");
+
+ /* Clear the interrupt */
+ dev->irq_proc_reg.error_int_status &= ~error_int_status;
+
+ /* set W1C value to clear the interrupt, this hits the register first */
+ reg_buf[0] = error_int_status;
+ reg_buf[1] = 0;
+ reg_buf[2] = 0;
+ reg_buf[3] = 0;
+
+ status = hif_read_write_sync(dev->ar, ERROR_INT_STATUS_ADDRESS,
+ reg_buf, 4, HIF_WR_SYNC_BYTE_FIX);
+
+ if (status)
+ WARN_ON(1);
+
+ return status;
+}
+
+static int ath6kldev_proc_cpu_intr(struct ath6kl_device *dev)
+{
+ int status;
+ u8 cpu_int_status;
+ u8 reg_buf[4];
+
+ ath6kl_dbg(ATH6KL_DBG_IRQ, "cpu interrupt\n");
+
+ cpu_int_status = dev->irq_proc_reg.cpu_int_status &
+ dev->irq_en_reg.cpu_int_status_en;
+ if (!cpu_int_status) {
+ WARN_ON(1);
+ return -EIO;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_IRQ,
+ "valid interrupt source(s) in CPU_INT_STATUS: 0x%x\n",
+ cpu_int_status);
+
+ /* Clear the interrupt */
+ dev->irq_proc_reg.cpu_int_status &= ~cpu_int_status;
+
+ /*
+ * Set up the register transfer buffer to hit the register 4 times ,
+ * this is done to make the access 4-byte aligned to mitigate issues
+ * with host bus interconnects that restrict bus transfer lengths to
+ * be a multiple of 4-bytes.
+ */
+
+ /* set W1C value to clear the interrupt, this hits the register first */
+ reg_buf[0] = cpu_int_status;
+ /* the remaining are set to zero which have no-effect */
+ reg_buf[1] = 0;
+ reg_buf[2] = 0;
+ reg_buf[3] = 0;
+
+ status = hif_read_write_sync(dev->ar, CPU_INT_STATUS_ADDRESS,
+ reg_buf, 4, HIF_WR_SYNC_BYTE_FIX);
+
+ if (status)
+ WARN_ON(1);
+
+ return status;
+}
+
+/* process pending interrupts synchronously */
+static int proc_pending_irqs(struct ath6kl_device *dev, bool *done)
+{
+ struct ath6kl_irq_proc_registers *rg;
+ int status = 0;
+ u8 host_int_status = 0;
+ u32 lk_ahd = 0;
+ u8 htc_mbox = 1 << HTC_MAILBOX;
+
+ ath6kl_dbg(ATH6KL_DBG_IRQ, "proc_pending_irqs: (dev: 0x%p)\n", dev);
+
+ /*
+ * NOTE: HIF implementation guarantees that the context of this
+ * call allows us to perform SYNCHRONOUS I/O, that is we can block,
+ * sleep or call any API that can block or switch thread/task
+ * contexts. This is a fully schedulable context.
+ */
+
+ /*
+ * Process pending intr only when int_status_en is clear, it may
+ * result in unnecessary bus transaction otherwise. Target may be
+ * unresponsive at the time.
+ */
+ if (dev->irq_en_reg.int_status_en) {
+ /*
+ * Read the first 28 bytes of the HTC register table. This
+ * will yield us the value of different int status
+ * registers and the lookahead registers.
+ *
+ * length = sizeof(int_status) + sizeof(cpu_int_status)
+ * + sizeof(error_int_status) +
+ * sizeof(counter_int_status) +
+ * sizeof(mbox_frame) + sizeof(rx_lkahd_valid)
+ * + sizeof(hole) + sizeof(rx_lkahd) +
+ * sizeof(int_status_en) +
+ * sizeof(cpu_int_status_en) +
+ * sizeof(err_int_status_en) +
+ * sizeof(cntr_int_status_en);
+ */
+ status = hif_read_write_sync(dev->ar, HOST_INT_STATUS_ADDRESS,
+ (u8 *) &dev->irq_proc_reg,
+ sizeof(dev->irq_proc_reg),
+ HIF_RD_SYNC_BYTE_INC);
+ if (status)
+ goto out;
+
+ if (AR_DBG_LVL_CHECK(ATH6KL_DBG_IRQ))
+ ath6kl_dump_registers(dev, &dev->irq_proc_reg,
+ &dev->irq_en_reg);
+
+ /* Update only those registers that are enabled */
+ host_int_status = dev->irq_proc_reg.host_int_status &
+ dev->irq_en_reg.int_status_en;
+
+ /* Look at mbox status */
+ if (host_int_status & htc_mbox) {
+ /*
+ * Mask out pending mbox value, we use "lookAhead as
+ * the real flag for mbox processing.
+ */
+ host_int_status &= ~htc_mbox;
+ if (dev->irq_proc_reg.rx_lkahd_valid &
+ htc_mbox) {
+ rg = &dev->irq_proc_reg;
+ lk_ahd = le32_to_cpu(rg->rx_lkahd[HTC_MAILBOX]);
+ if (!lk_ahd)
+ ath6kl_err("lookAhead is zero!\n");
+ }
+ }
+ }
+
+ if (!host_int_status && !lk_ahd) {
+ *done = true;
+ goto out;
+ }
+
+ if (lk_ahd) {
+ int fetched = 0;
+
+ ath6kl_dbg(ATH6KL_DBG_IRQ,
+ "pending mailbox msg, lk_ahd: 0x%X\n", lk_ahd);
+ /*
+ * Mailbox Interrupt, the HTC layer may issue async
+ * requests to empty the mailbox. When emptying the recv
+ * mailbox we use the async handler above called from the
+ * completion routine of the callers read request. This can
+ * improve performance by reducing context switching when
+ * we rapidly pull packets.
+ */
+ status = dev->msg_pending(dev->htc_cnxt, &lk_ahd, &fetched);
+ if (status)
+ goto out;
+
+ if (!fetched)
+ /*
+ * HTC could not pull any messages out due to lack
+ * of resources.
+ */
+ dev->chk_irq_status_cnt = 0;
+ }
+
+ /* now handle the rest of them */
+ ath6kl_dbg(ATH6KL_DBG_IRQ,
+ "valid interrupt source(s) for other interrupts: 0x%x\n",
+ host_int_status);
+
+ if (MS(HOST_INT_STATUS_CPU, host_int_status)) {
+ /* CPU Interrupt */
+ status = ath6kldev_proc_cpu_intr(dev);
+ if (status)
+ goto out;
+ }
+
+ if (MS(HOST_INT_STATUS_ERROR, host_int_status)) {
+ /* Error Interrupt */
+ status = ath6kldev_proc_err_intr(dev);
+ if (status)
+ goto out;
+ }
+
+ if (MS(HOST_INT_STATUS_COUNTER, host_int_status))
+ /* Counter Interrupt */
+ status = ath6kldev_proc_counter_intr(dev);
+
+out:
+ /*
+ * An optimization to bypass reading the IRQ status registers
+ * unecessarily which can re-wake the target, if upper layers
+ * determine that we are in a low-throughput mode, we can rely on
+ * taking another interrupt rather than re-checking the status
+ * registers which can re-wake the target.
+ *
+ * NOTE : for host interfaces that makes use of detecting pending
+ * mbox messages at hif can not use this optimization due to
+ * possible side effects, SPI requires the host to drain all
+ * messages from the mailbox before exiting the ISR routine.
+ */
+
+ ath6kl_dbg(ATH6KL_DBG_IRQ,
+ "bypassing irq status re-check, forcing done\n");
+
+ *done = true;
+
+ ath6kl_dbg(ATH6KL_DBG_IRQ,
+ "proc_pending_irqs: (done:%d, status=%d\n", *done, status);
+
+ return status;
+}
+
+/* interrupt handler, kicks off all interrupt processing */
+int ath6kldev_intr_bh_handler(struct ath6kl *ar)
+{
+ struct ath6kl_device *dev = ar->htc_target->dev;
+ int status = 0;
+ bool done = false;
+
+ /*
+ * Reset counter used to flag a re-scan of IRQ status registers on
+ * the target.
+ */
+ dev->chk_irq_status_cnt = 0;
+
+ /*
+ * IRQ processing is synchronous, interrupt status registers can be
+ * re-read.
+ */
+ while (!done) {
+ status = proc_pending_irqs(dev, &done);
+ if (status)
+ break;
+ }
+
+ return status;
+}
+
+static int ath6kldev_enable_intrs(struct ath6kl_device *dev)
+{
+ struct ath6kl_irq_enable_reg regs;
+ int status;
+
+ spin_lock_bh(&dev->lock);
+
+ /* Enable all but ATH6KL CPU interrupts */
+ dev->irq_en_reg.int_status_en =
+ SM(INT_STATUS_ENABLE_ERROR, 0x01) |
+ SM(INT_STATUS_ENABLE_CPU, 0x01) |
+ SM(INT_STATUS_ENABLE_COUNTER, 0x01);
+
+ /*
+ * NOTE: There are some cases where HIF can do detection of
+ * pending mbox messages which is disabled now.
+ */
+ dev->irq_en_reg.int_status_en |= SM(INT_STATUS_ENABLE_MBOX_DATA, 0x01);
+
+ /* Set up the CPU Interrupt status Register */
+ dev->irq_en_reg.cpu_int_status_en = 0;
+
+ /* Set up the Error Interrupt status Register */
+ dev->irq_en_reg.err_int_status_en =
+ SM(ERROR_STATUS_ENABLE_RX_UNDERFLOW, 0x01) |
+ SM(ERROR_STATUS_ENABLE_TX_OVERFLOW, 0x1);
+
+ /*
+ * Enable Counter interrupt status register to get fatal errors for
+ * debugging.
+ */
+ dev->irq_en_reg.cntr_int_status_en = SM(COUNTER_INT_STATUS_ENABLE_BIT,
+ ATH6KL_TARGET_DEBUG_INTR_MASK);
+ memcpy(&regs, &dev->irq_en_reg, sizeof(regs));
+
+ spin_unlock_bh(&dev->lock);
+
+ status = hif_read_write_sync(dev->ar, INT_STATUS_ENABLE_ADDRESS,
+ &regs.int_status_en, sizeof(regs),
+ HIF_WR_SYNC_BYTE_INC);
+
+ if (status)
+ ath6kl_err("failed to update interrupt ctl reg err: %d\n",
+ status);
+
+ return status;
+}
+
+int ath6kldev_disable_intrs(struct ath6kl_device *dev)
+{
+ struct ath6kl_irq_enable_reg regs;
+
+ spin_lock_bh(&dev->lock);
+ /* Disable all interrupts */
+ dev->irq_en_reg.int_status_en = 0;
+ dev->irq_en_reg.cpu_int_status_en = 0;
+ dev->irq_en_reg.err_int_status_en = 0;
+ dev->irq_en_reg.cntr_int_status_en = 0;
+ memcpy(&regs, &dev->irq_en_reg, sizeof(regs));
+ spin_unlock_bh(&dev->lock);
+
+ return hif_read_write_sync(dev->ar, INT_STATUS_ENABLE_ADDRESS,
+ &regs.int_status_en, sizeof(regs),
+ HIF_WR_SYNC_BYTE_INC);
+}
+
+/* enable device interrupts */
+int ath6kldev_unmask_intrs(struct ath6kl_device *dev)
+{
+ int status = 0;
+
+ /*
+ * Make sure interrupt are disabled before unmasking at the HIF
+ * layer. The rationale here is that between device insertion
+ * (where we clear the interrupts the first time) and when HTC
+ * is finally ready to handle interrupts, other software can perform
+ * target "soft" resets. The ATH6KL interrupt enables reset back to an
+ * "enabled" state when this happens.
+ */
+ ath6kldev_disable_intrs(dev);
+
+ /* unmask the host controller interrupts */
+ ath6kl_hif_irq_enable(dev->ar);
+ status = ath6kldev_enable_intrs(dev);
+
+ return status;
+}
+
+/* disable all device interrupts */
+int ath6kldev_mask_intrs(struct ath6kl_device *dev)
+{
+ /*
+ * Mask the interrupt at the HIF layer to avoid any stray interrupt
+ * taken while we zero out our shadow registers in
+ * ath6kldev_disable_intrs().
+ */
+ ath6kl_hif_irq_disable(dev->ar);
+
+ return ath6kldev_disable_intrs(dev);
+}
+
+int ath6kldev_setup(struct ath6kl_device *dev)
+{
+ int status = 0;
+ int i;
+ struct htc_packet *packet;
+
+ /* initialize our free list of IO packets */
+ INIT_LIST_HEAD(&dev->reg_io);
+ spin_lock_init(&dev->lock);
+
+ /* carve up register I/O packets (these are for ASYNC register I/O ) */
+ for (i = 0; i < ATH6KL_MAX_REG_IO_BUFFERS; i++) {
+ packet = &dev->reg_io_buf[i].packet;
+ set_htc_rxpkt_info(packet, dev, dev->reg_io_buf[i].buf,
+ ATH6KL_REG_IO_BUFFER_SIZE, 0);
+ ath6kl_add_io_pkt(dev, packet);
+ }
+
+ /*
+ * NOTE: we actually get the block size of a mailbox other than 0,
+ * for SDIO the block size on mailbox 0 is artificially set to 1.
+ * So we use the block size that is set for the other 3 mailboxes.
+ */
+ dev->block_sz = dev->ar->mbox_info.block_size;
+
+ /* must be a power of 2 */
+ if ((dev->block_sz & (dev->block_sz - 1)) != 0) {
+ WARN_ON(1);
+ goto fail_setup;
+ }
+
+ /* assemble mask, used for padding to a block */
+ dev->block_mask = dev->block_sz - 1;
+
+ ath6kl_dbg(ATH6KL_DBG_TRC, "block size: %d, mbox addr:0x%X\n",
+ dev->block_sz, dev->ar->mbox_info.htc_addr);
+
+ ath6kl_dbg(ATH6KL_DBG_TRC,
+ "hif interrupt processing is sync only\n");
+
+ status = ath6kldev_disable_intrs(dev);
+
+fail_setup:
+ return status;
+
+}
diff --git a/drivers/net/wireless/ath/ath6kl/htc_hif.h b/drivers/net/wireless/ath/ath6kl/htc_hif.h
new file mode 100644
index 000000000000..d770d4ec612e
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/htc_hif.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2007-2011 Atheros Communications Inc.
+ *
+ * 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.
+ */
+
+#ifndef HTC_HIF_H
+#define HTC_HIF_H
+
+#include "htc.h"
+#include "hif.h"
+
+#define ATH6KL_MAILBOXES 4
+
+/* HTC runs over mailbox 0 */
+#define HTC_MAILBOX 0
+
+#define ATH6KL_TARGET_DEBUG_INTR_MASK 0x01
+
+#define OTHER_INTS_ENABLED (INT_STATUS_ENABLE_ERROR_MASK | \
+ INT_STATUS_ENABLE_CPU_MASK | \
+ INT_STATUS_ENABLE_COUNTER_MASK)
+
+#define ATH6KL_REG_IO_BUFFER_SIZE 32
+#define ATH6KL_MAX_REG_IO_BUFFERS 8
+#define ATH6KL_SCATTER_ENTRIES_PER_REQ 16
+#define ATH6KL_MAX_TRANSFER_SIZE_PER_SCATTER (16 * 1024)
+#define ATH6KL_SCATTER_REQS 4
+
+#ifndef A_CACHE_LINE_PAD
+#define A_CACHE_LINE_PAD 128
+#endif
+#define ATH6KL_MIN_SCATTER_ENTRIES_PER_REQ 2
+#define ATH6KL_MIN_TRANSFER_SIZE_PER_SCATTER (4 * 1024)
+
+struct ath6kl_irq_proc_registers {
+ u8 host_int_status;
+ u8 cpu_int_status;
+ u8 error_int_status;
+ u8 counter_int_status;
+ u8 mbox_frame;
+ u8 rx_lkahd_valid;
+ u8 host_int_status2;
+ u8 gmbox_rx_avail;
+ __le32 rx_lkahd[2];
+ __le32 rx_gmbox_lkahd_alias[2];
+} __packed;
+
+struct ath6kl_irq_enable_reg {
+ u8 int_status_en;
+ u8 cpu_int_status_en;
+ u8 err_int_status_en;
+ u8 cntr_int_status_en;
+} __packed;
+
+/* buffers for ASYNC I/O */
+struct ath6kl_async_reg_io_buffer {
+ struct htc_packet packet;
+ u8 pad1[A_CACHE_LINE_PAD];
+ /* cache-line safe with pads around */
+ u8 buf[ATH6KL_REG_IO_BUFFER_SIZE];
+ u8 pad2[A_CACHE_LINE_PAD];
+};
+
+struct ath6kl_device {
+ spinlock_t lock;
+ u8 pad1[A_CACHE_LINE_PAD];
+ struct ath6kl_irq_proc_registers irq_proc_reg;
+ u8 pad2[A_CACHE_LINE_PAD];
+ struct ath6kl_irq_enable_reg irq_en_reg;
+ u8 pad3[A_CACHE_LINE_PAD];
+ u32 block_sz;
+ u32 block_mask;
+ struct htc_target *htc_cnxt;
+ struct list_head reg_io;
+ struct ath6kl_async_reg_io_buffer reg_io_buf[ATH6KL_MAX_REG_IO_BUFFERS];
+ int (*msg_pending) (struct htc_target *target, u32 lk_ahds[],
+ int *npkts_fetched);
+ struct hif_dev_scat_sup_info hif_scat_info;
+ bool virt_scat;
+ int max_rx_bndl_sz;
+ int max_tx_bndl_sz;
+ int chk_irq_status_cnt;
+ struct ath6kl *ar;
+};
+
+int ath6kldev_setup(struct ath6kl_device *dev);
+int ath6kldev_unmask_intrs(struct ath6kl_device *dev);
+int ath6kldev_mask_intrs(struct ath6kl_device *dev);
+int ath6kldev_poll_mboxmsg_rx(struct ath6kl_device *dev,
+ u32 *lk_ahd, int timeout);
+int ath6kldev_rx_control(struct ath6kl_device *dev, bool enable_rx);
+int ath6kldev_disable_intrs(struct ath6kl_device *dev);
+
+int ath6kldev_rw_comp_handler(void *context, int status);
+int ath6kldev_intr_bh_handler(struct ath6kl *ar);
+
+/* Scatter Function and Definitions */
+int ath6kldev_setup_msg_bndl(struct ath6kl_device *dev, int max_msg_per_xfer);
+int ath6kldev_submit_scat_req(struct ath6kl_device *dev,
+ struct hif_scatter_req *scat_req, bool read);
+
+#endif /*ATH6KL_H_ */
diff --git a/drivers/net/wireless/ath/ath6kl/init.c b/drivers/net/wireless/ath/ath6kl/init.c
new file mode 100644
index 000000000000..fe61871e9874
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/init.c
@@ -0,0 +1,1293 @@
+
+/*
+ * Copyright (c) 2011 Atheros Communications Inc.
+ *
+ * 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 <linux/mmc/sdio_func.h>
+#include "core.h"
+#include "cfg80211.h"
+#include "target.h"
+#include "debug.h"
+#include "hif-ops.h"
+
+unsigned int debug_mask;
+
+module_param(debug_mask, uint, 0644);
+
+/*
+ * Include definitions here that can be used to tune the WLAN module
+ * behavior. Different customers can tune the behavior as per their needs,
+ * here.
+ */
+
+/*
+ * This configuration item enable/disable keepalive support.
+ * Keepalive support: In the absence of any data traffic to AP, null
+ * frames will be sent to the AP at periodic interval, to keep the association
+ * active. This configuration item defines the periodic interval.
+ * Use value of zero to disable keepalive support
+ * Default: 60 seconds
+ */
+#define WLAN_CONFIG_KEEP_ALIVE_INTERVAL 60
+
+/*
+ * This configuration item sets the value of disconnect timeout
+ * Firmware delays sending the disconnec event to the host for this
+ * timeout after is gets disconnected from the current AP.
+ * If the firmware successly roams within the disconnect timeout
+ * it sends a new connect event
+ */
+#define WLAN_CONFIG_DISCONNECT_TIMEOUT 10
+
+#define CONFIG_AR600x_DEBUG_UART_TX_PIN 8
+
+enum addr_type {
+ DATASET_PATCH_ADDR,
+ APP_LOAD_ADDR,
+ APP_START_OVERRIDE_ADDR,
+};
+
+#define ATH6KL_DATA_OFFSET 64
+struct sk_buff *ath6kl_buf_alloc(int size)
+{
+ struct sk_buff *skb;
+ u16 reserved;
+
+ /* Add chacheline space at front and back of buffer */
+ reserved = (2 * L1_CACHE_BYTES) + ATH6KL_DATA_OFFSET +
+ sizeof(struct htc_packet);
+ skb = dev_alloc_skb(size + reserved);
+
+ if (skb)
+ skb_reserve(skb, reserved - L1_CACHE_BYTES);
+ return skb;
+}
+
+void ath6kl_init_profile_info(struct ath6kl *ar)
+{
+ ar->ssid_len = 0;
+ memset(ar->ssid, 0, sizeof(ar->ssid));
+
+ ar->dot11_auth_mode = OPEN_AUTH;
+ ar->auth_mode = NONE_AUTH;
+ ar->prwise_crypto = NONE_CRYPT;
+ ar->prwise_crypto_len = 0;
+ ar->grp_crypto = NONE_CRYPT;
+ ar->grp_crpto_len = 0;
+ memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
+ memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
+ memset(ar->bssid, 0, sizeof(ar->bssid));
+ ar->bss_ch = 0;
+ ar->nw_type = ar->next_mode = INFRA_NETWORK;
+}
+
+static u8 ath6kl_get_fw_iftype(struct ath6kl *ar)
+{
+ switch (ar->nw_type) {
+ case INFRA_NETWORK:
+ return HI_OPTION_FW_MODE_BSS_STA;
+ case ADHOC_NETWORK:
+ return HI_OPTION_FW_MODE_IBSS;
+ case AP_NETWORK:
+ return HI_OPTION_FW_MODE_AP;
+ default:
+ ath6kl_err("Unsupported interface type :%d\n", ar->nw_type);
+ return 0xff;
+ }
+}
+
+static inline u32 ath6kl_get_hi_item_addr(struct ath6kl *ar,
+ u32 item_offset)
+{
+ u32 addr = 0;
+
+ if (ar->target_type == TARGET_TYPE_AR6003)
+ addr = ATH6KL_HI_START_ADDR + item_offset;
+
+ return addr;
+}
+
+static int ath6kl_set_host_app_area(struct ath6kl *ar)
+{
+ u32 address, data;
+ struct host_app_area host_app_area;
+
+ /* Fetch the address of the host_app_area_s
+ * instance in the host interest area */
+ address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_app_host_interest));
+ address = TARG_VTOP(address);
+
+ if (ath6kl_read_reg_diag(ar, &address, &data))
+ return -EIO;
+
+ address = TARG_VTOP(data);
+ host_app_area.wmi_protocol_ver = WMI_PROTOCOL_VERSION;
+ if (ath6kl_access_datadiag(ar, address,
+ (u8 *)&host_app_area,
+ sizeof(struct host_app_area), false))
+ return -EIO;
+
+ return 0;
+}
+
+static inline void set_ac2_ep_map(struct ath6kl *ar,
+ u8 ac,
+ enum htc_endpoint_id ep)
+{
+ ar->ac2ep_map[ac] = ep;
+ ar->ep2ac_map[ep] = ac;
+}
+
+/* connect to a service */
+static int ath6kl_connectservice(struct ath6kl *ar,
+ struct htc_service_connect_req *con_req,
+ char *desc)
+{
+ int status;
+ struct htc_service_connect_resp response;
+
+ memset(&response, 0, sizeof(response));
+
+ status = htc_conn_service(ar->htc_target, con_req, &response);
+ if (status) {
+ ath6kl_err("failed to connect to %s service status:%d\n",
+ desc, status);
+ return status;
+ }
+
+ switch (con_req->svc_id) {
+ case WMI_CONTROL_SVC:
+ if (test_bit(WMI_ENABLED, &ar->flag))
+ ath6kl_wmi_set_control_ep(ar->wmi, response.endpoint);
+ ar->ctrl_ep = response.endpoint;
+ break;
+ case WMI_DATA_BE_SVC:
+ set_ac2_ep_map(ar, WMM_AC_BE, response.endpoint);
+ break;
+ case WMI_DATA_BK_SVC:
+ set_ac2_ep_map(ar, WMM_AC_BK, response.endpoint);
+ break;
+ case WMI_DATA_VI_SVC:
+ set_ac2_ep_map(ar, WMM_AC_VI, response.endpoint);
+ break;
+ case WMI_DATA_VO_SVC:
+ set_ac2_ep_map(ar, WMM_AC_VO, response.endpoint);
+ break;
+ default:
+ ath6kl_err("service id is not mapped %d\n", con_req->svc_id);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int ath6kl_init_service_ep(struct ath6kl *ar)
+{
+ struct htc_service_connect_req connect;
+
+ memset(&connect, 0, sizeof(connect));
+
+ /* these fields are the same for all service endpoints */
+ connect.ep_cb.rx = ath6kl_rx;
+ connect.ep_cb.rx_refill = ath6kl_rx_refill;
+ connect.ep_cb.tx_full = ath6kl_tx_queue_full;
+
+ /*
+ * Set the max queue depth so that our ath6kl_tx_queue_full handler
+ * gets called.
+ */
+ connect.max_txq_depth = MAX_DEFAULT_SEND_QUEUE_DEPTH;
+ connect.ep_cb.rx_refill_thresh = ATH6KL_MAX_RX_BUFFERS / 4;
+ if (!connect.ep_cb.rx_refill_thresh)
+ connect.ep_cb.rx_refill_thresh++;
+
+ /* connect to control service */
+ connect.svc_id = WMI_CONTROL_SVC;
+ if (ath6kl_connectservice(ar, &connect, "WMI CONTROL"))
+ return -EIO;
+
+ connect.flags |= HTC_FLGS_TX_BNDL_PAD_EN;
+
+ /*
+ * Limit the HTC message size on the send path, although e can
+ * receive A-MSDU frames of 4K, we will only send ethernet-sized
+ * (802.3) frames on the send path.
+ */
+ connect.max_rxmsg_sz = WMI_MAX_TX_DATA_FRAME_LENGTH;
+
+ /*
+ * To reduce the amount of committed memory for larger A_MSDU
+ * frames, use the recv-alloc threshold mechanism for larger
+ * packets.
+ */
+ connect.ep_cb.rx_alloc_thresh = ATH6KL_BUFFER_SIZE;
+ connect.ep_cb.rx_allocthresh = ath6kl_alloc_amsdu_rxbuf;
+
+ /*
+ * For the remaining data services set the connection flag to
+ * reduce dribbling, if configured to do so.
+ */
+ connect.conn_flags |= HTC_CONN_FLGS_REDUCE_CRED_DRIB;
+ connect.conn_flags &= ~HTC_CONN_FLGS_THRESH_MASK;
+ connect.conn_flags |= HTC_CONN_FLGS_THRESH_LVL_HALF;
+
+ connect.svc_id = WMI_DATA_BE_SVC;
+
+ if (ath6kl_connectservice(ar, &connect, "WMI DATA BE"))
+ return -EIO;
+
+ /* connect to back-ground map this to WMI LOW_PRI */
+ connect.svc_id = WMI_DATA_BK_SVC;
+ if (ath6kl_connectservice(ar, &connect, "WMI DATA BK"))
+ return -EIO;
+
+ /* connect to Video service, map this to to HI PRI */
+ connect.svc_id = WMI_DATA_VI_SVC;
+ if (ath6kl_connectservice(ar, &connect, "WMI DATA VI"))
+ return -EIO;
+
+ /*
+ * Connect to VO service, this is currently not mapped to a WMI
+ * priority stream due to historical reasons. WMI originally
+ * defined 3 priorities over 3 mailboxes We can change this when
+ * WMI is reworked so that priorities are not dependent on
+ * mailboxes.
+ */
+ connect.svc_id = WMI_DATA_VO_SVC;
+ if (ath6kl_connectservice(ar, &connect, "WMI DATA VO"))
+ return -EIO;
+
+ return 0;
+}
+
+static void ath6kl_init_control_info(struct ath6kl *ar)
+{
+ u8 ctr;
+
+ clear_bit(WMI_ENABLED, &ar->flag);
+ ath6kl_init_profile_info(ar);
+ ar->def_txkey_index = 0;
+ memset(ar->wep_key_list, 0, sizeof(ar->wep_key_list));
+ ar->ch_hint = 0;
+ ar->listen_intvl_t = A_DEFAULT_LISTEN_INTERVAL;
+ ar->listen_intvl_b = 0;
+ ar->tx_pwr = 0;
+ clear_bit(SKIP_SCAN, &ar->flag);
+ set_bit(WMM_ENABLED, &ar->flag);
+ ar->intra_bss = 1;
+ memset(&ar->sc_params, 0, sizeof(ar->sc_params));
+ ar->sc_params.short_scan_ratio = WMI_SHORTSCANRATIO_DEFAULT;
+ ar->sc_params.scan_ctrl_flags = DEFAULT_SCAN_CTRL_FLAGS;
+
+ memset((u8 *)ar->sta_list, 0,
+ AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
+
+ spin_lock_init(&ar->mcastpsq_lock);
+
+ /* Init the PS queues */
+ for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
+ spin_lock_init(&ar->sta_list[ctr].psq_lock);
+ skb_queue_head_init(&ar->sta_list[ctr].psq);
+ }
+
+ skb_queue_head_init(&ar->mcastpsq);
+
+ memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
+}
+
+/*
+ * Set HTC/Mbox operational parameters, this can only be called when the
+ * target is in the BMI phase.
+ */
+static int ath6kl_set_htc_params(struct ath6kl *ar, u32 mbox_isr_yield_val,
+ u8 htc_ctrl_buf)
+{
+ int status;
+ u32 blk_size;
+
+ blk_size = ar->mbox_info.block_size;
+
+ if (htc_ctrl_buf)
+ blk_size |= ((u32)htc_ctrl_buf) << 16;
+
+ /* set the host interest area for the block size */
+ status = ath6kl_bmi_write(ar,
+ ath6kl_get_hi_item_addr(ar,
+ HI_ITEM(hi_mbox_io_block_sz)),
+ (u8 *)&blk_size,
+ 4);
+ if (status) {
+ ath6kl_err("bmi_write_memory for IO block size failed\n");
+ goto out;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_TRC, "block size set: %d (target addr:0x%X)\n",
+ blk_size,
+ ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_mbox_io_block_sz)));
+
+ if (mbox_isr_yield_val) {
+ /* set the host interest area for the mbox ISR yield limit */
+ status = ath6kl_bmi_write(ar,
+ ath6kl_get_hi_item_addr(ar,
+ HI_ITEM(hi_mbox_isr_yield_limit)),
+ (u8 *)&mbox_isr_yield_val,
+ 4);
+ if (status) {
+ ath6kl_err("bmi_write_memory for yield limit failed\n");
+ goto out;
+ }
+ }
+
+out:
+ return status;
+}
+
+#define REG_DUMP_COUNT_AR6003 60
+#define REGISTER_DUMP_LEN_MAX 60
+
+static void ath6kl_dump_target_assert_info(struct ath6kl *ar)
+{
+ u32 address;
+ u32 regdump_loc = 0;
+ int status;
+ u32 regdump_val[REGISTER_DUMP_LEN_MAX];
+ u32 i;
+
+ if (ar->target_type != TARGET_TYPE_AR6003)
+ return;
+
+ /* the reg dump pointer is copied to the host interest area */
+ address = ath6kl_get_hi_item_addr(ar, HI_ITEM(hi_failure_state));
+ address = TARG_VTOP(address);
+
+ /* read RAM location through diagnostic window */
+ status = ath6kl_read_reg_diag(ar, &address, &regdump_loc);
+
+ if (status || !regdump_loc) {
+ ath6kl_err("failed to get ptr to register dump area\n");
+ return;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_TRC, "location of register dump data: 0x%X\n",
+ regdump_loc);
+
+ regdump_loc = TARG_VTOP(regdump_loc);
+
+ /* fetch register dump data */
+ status = ath6kl_access_datadiag(ar,
+ regdump_loc,
+ (u8 *)&regdump_val[0],
+ REG_DUMP_COUNT_AR6003 * (sizeof(u32)),
+ true);
+
+ if (status) {
+ ath6kl_err("failed to get register dump\n");
+ return;
+ }
+ ath6kl_dbg(ATH6KL_DBG_TRC, "Register Dump:\n");
+
+ for (i = 0; i < REG_DUMP_COUNT_AR6003; i++)
+ ath6kl_dbg(ATH6KL_DBG_TRC, " %d : 0x%8.8X\n",
+ i, regdump_val[i]);
+
+}
+
+void ath6kl_target_failure(struct ath6kl *ar)
+{
+ ath6kl_err("target asserted\n");
+
+ /* try dumping target assertion information (if any) */
+ ath6kl_dump_target_assert_info(ar);
+
+}
+
+static int ath6kl_target_config_wlan_params(struct ath6kl *ar)
+{
+ int status = 0;
+
+ /*
+ * Configure the device for rx dot11 header rules. "0,0" are the
+ * default values. Required if checksum offload is needed. Set
+ * RxMetaVersion to 2.
+ */
+ if (ath6kl_wmi_set_rx_frame_format_cmd(ar->wmi,
+ ar->rx_meta_ver, 0, 0)) {
+ ath6kl_err("unable to set the rx frame format\n");
+ status = -EIO;
+ }
+
+ if (ar->conf_flags & ATH6KL_CONF_IGNORE_PS_FAIL_EVT_IN_SCAN)
+ if ((ath6kl_wmi_pmparams_cmd(ar->wmi, 0, 1, 0, 0, 1,
+ IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN)) != 0) {
+ ath6kl_err("unable to set power save fail event policy\n");
+ status = -EIO;
+ }
+
+ if (!(ar->conf_flags & ATH6KL_CONF_IGNORE_ERP_BARKER))
+ if ((ath6kl_wmi_set_lpreamble_cmd(ar->wmi, 0,
+ WMI_DONOT_IGNORE_BARKER_IN_ERP)) != 0) {
+ ath6kl_err("unable to set barker preamble policy\n");
+ status = -EIO;
+ }
+
+ if (ath6kl_wmi_set_keepalive_cmd(ar->wmi,
+ WLAN_CONFIG_KEEP_ALIVE_INTERVAL)) {
+ ath6kl_err("unable to set keep alive interval\n");
+ status = -EIO;
+ }
+
+ if (ath6kl_wmi_disctimeout_cmd(ar->wmi,
+ WLAN_CONFIG_DISCONNECT_TIMEOUT)) {
+ ath6kl_err("unable to set disconnect timeout\n");
+ status = -EIO;
+ }
+
+ if (!(ar->conf_flags & ATH6KL_CONF_ENABLE_TX_BURST))
+ if (ath6kl_wmi_set_wmm_txop(ar->wmi, WMI_TXOP_DISABLED)) {
+ ath6kl_err("unable to set txop bursting\n");
+ status = -EIO;
+ }
+
+ return status;
+}
+
+int ath6kl_configure_target(struct ath6kl *ar)
+{
+ u32 param, ram_reserved_size;
+ u8 fw_iftype;
+
+ fw_iftype = ath6kl_get_fw_iftype(ar);
+ if (fw_iftype == 0xff)
+ return -EINVAL;
+
+ /* Tell target which HTC version it is used*/
+ param = HTC_PROTOCOL_VERSION;
+ if (ath6kl_bmi_write(ar,
+ ath6kl_get_hi_item_addr(ar,
+ HI_ITEM(hi_app_host_interest)),
+ (u8 *)&param, 4) != 0) {
+ ath6kl_err("bmi_write_memory for htc version failed\n");
+ return -EIO;
+ }
+
+ /* set the firmware mode to STA/IBSS/AP */
+ param = 0;
+
+ if (ath6kl_bmi_read(ar,
+ ath6kl_get_hi_item_addr(ar,
+ HI_ITEM(hi_option_flag)),
+ (u8 *)&param, 4) != 0) {
+ ath6kl_err("bmi_read_memory for setting fwmode failed\n");
+ return -EIO;
+ }
+
+ param |= (1 << HI_OPTION_NUM_DEV_SHIFT);
+ param |= (fw_iftype << HI_OPTION_FW_MODE_SHIFT);
+ param |= (0 << HI_OPTION_MAC_ADDR_METHOD_SHIFT);
+ param |= (0 << HI_OPTION_FW_BRIDGE_SHIFT);
+
+ if (ath6kl_bmi_write(ar,
+ ath6kl_get_hi_item_addr(ar,
+ HI_ITEM(hi_option_flag)),
+ (u8 *)&param,
+ 4) != 0) {
+ ath6kl_err("bmi_write_memory for setting fwmode failed\n");
+ return -EIO;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_TRC, "firmware mode set\n");
+
+ /*
+ * Hardcode the address use for the extended board data
+ * Ideally this should be pre-allocate by the OS at boot time
+ * But since it is a new feature and board data is loaded
+ * at init time, we have to workaround this from host.
+ * It is difficult to patch the firmware boot code,
+ * but possible in theory.
+ */
+
+ if (ar->target_type == TARGET_TYPE_AR6003) {
+ if (ar->version.target_ver == AR6003_REV2_VERSION) {
+ param = AR6003_REV2_BOARD_EXT_DATA_ADDRESS;
+ ram_reserved_size = AR6003_REV2_RAM_RESERVE_SIZE;
+ } else {
+ param = AR6003_REV3_BOARD_EXT_DATA_ADDRESS;
+ ram_reserved_size = AR6003_REV3_RAM_RESERVE_SIZE;
+ }
+
+ if (ath6kl_bmi_write(ar,
+ ath6kl_get_hi_item_addr(ar,
+ HI_ITEM(hi_board_ext_data)),
+ (u8 *)&param, 4) != 0) {
+ ath6kl_err("bmi_write_memory for hi_board_ext_data failed\n");
+ return -EIO;
+ }
+ if (ath6kl_bmi_write(ar,
+ ath6kl_get_hi_item_addr(ar,
+ HI_ITEM(hi_end_ram_reserve_sz)),
+ (u8 *)&ram_reserved_size, 4) != 0) {
+ ath6kl_err("bmi_write_memory for hi_end_ram_reserve_sz failed\n");
+ return -EIO;
+ }
+ }
+
+ /* set the block size for the target */
+ if (ath6kl_set_htc_params(ar, MBOX_YIELD_LIMIT, 0))
+ /* use default number of control buffers */
+ return -EIO;
+
+ return 0;
+}
+
+struct ath6kl *ath6kl_core_alloc(struct device *sdev)
+{
+ struct net_device *dev;
+ struct ath6kl *ar;
+ struct wireless_dev *wdev;
+
+ wdev = ath6kl_cfg80211_init(sdev);
+ if (!wdev) {
+ ath6kl_err("ath6kl_cfg80211_init failed\n");
+ return NULL;
+ }
+
+ ar = wdev_priv(wdev);
+ ar->dev = sdev;
+ ar->wdev = wdev;
+ wdev->iftype = NL80211_IFTYPE_STATION;
+
+ dev = alloc_netdev(0, "wlan%d", ether_setup);
+ if (!dev) {
+ ath6kl_err("no memory for network device instance\n");
+ ath6kl_cfg80211_deinit(ar);
+ return NULL;
+ }
+
+ dev->ieee80211_ptr = wdev;
+ SET_NETDEV_DEV(dev, wiphy_dev(wdev->wiphy));
+ wdev->netdev = dev;
+ ar->sme_state = SME_DISCONNECTED;
+ ar->auto_auth_stage = AUTH_IDLE;
+
+ init_netdev(dev);
+
+ ar->net_dev = dev;
+ ar->wlan_state = WLAN_ENABLED;
+
+ ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
+
+ spin_lock_init(&ar->lock);
+
+ ath6kl_init_control_info(ar);
+ init_waitqueue_head(&ar->event_wq);
+ sema_init(&ar->sem, 1);
+ clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
+
+ INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
+
+ setup_timer(&ar->disconnect_timer, disconnect_timer_handler,
+ (unsigned long) dev);
+
+ return ar;
+}
+
+int ath6kl_unavail_ev(struct ath6kl *ar)
+{
+ ath6kl_destroy(ar->net_dev, 1);
+
+ return 0;
+}
+
+/* firmware upload */
+static u32 ath6kl_get_load_address(u32 target_ver, enum addr_type type)
+{
+ WARN_ON(target_ver != AR6003_REV2_VERSION &&
+ target_ver != AR6003_REV3_VERSION);
+
+ switch (type) {
+ case DATASET_PATCH_ADDR:
+ return (target_ver == AR6003_REV2_VERSION) ?
+ AR6003_REV2_DATASET_PATCH_ADDRESS :
+ AR6003_REV3_DATASET_PATCH_ADDRESS;
+ case APP_LOAD_ADDR:
+ return (target_ver == AR6003_REV2_VERSION) ?
+ AR6003_REV2_APP_LOAD_ADDRESS :
+ 0x1234;
+ case APP_START_OVERRIDE_ADDR:
+ return (target_ver == AR6003_REV2_VERSION) ?
+ AR6003_REV2_APP_START_OVERRIDE :
+ AR6003_REV3_APP_START_OVERRIDE;
+ default:
+ return 0;
+ }
+}
+
+static int ath6kl_get_fw(struct ath6kl *ar, const char *filename,
+ u8 **fw, size_t *fw_len)
+{
+ const struct firmware *fw_entry;
+ int ret;
+
+ ret = request_firmware(&fw_entry, filename, ar->dev);
+ if (ret)
+ return ret;
+
+ *fw_len = fw_entry->size;
+ *fw = kmemdup(fw_entry->data, fw_entry->size, GFP_KERNEL);
+
+ if (*fw == NULL)
+ ret = -ENOMEM;
+
+ release_firmware(fw_entry);
+
+ return ret;
+}
+
+static int ath6kl_fetch_board_file(struct ath6kl *ar)
+{
+ const char *filename;
+ int ret;
+
+ switch (ar->version.target_ver) {
+ case AR6003_REV2_VERSION:
+ filename = AR6003_REV2_BOARD_DATA_FILE;
+ break;
+ default:
+ filename = AR6003_REV3_BOARD_DATA_FILE;
+ break;
+ }
+
+ ret = ath6kl_get_fw(ar, filename, &ar->fw_board,
+ &ar->fw_board_len);
+ if (ret == 0) {
+ /* managed to get proper board file */
+ return 0;
+ }
+
+ /* there was no proper board file, try to use default instead */
+ ath6kl_warn("Failed to get board file %s (%d), trying to find default board file.\n",
+ filename, ret);
+
+ switch (ar->version.target_ver) {
+ case AR6003_REV2_VERSION:
+ filename = AR6003_REV2_DEFAULT_BOARD_DATA_FILE;
+ break;
+ default:
+ filename = AR6003_REV3_DEFAULT_BOARD_DATA_FILE;
+ break;
+ }
+
+ ret = ath6kl_get_fw(ar, filename, &ar->fw_board,
+ &ar->fw_board_len);
+ if (ret) {
+ ath6kl_err("Failed to get default board file %s: %d\n",
+ filename, ret);
+ return ret;
+ }
+
+ ath6kl_warn("WARNING! No proper board file was not found, instead using a default board file.\n");
+ ath6kl_warn("Most likely your hardware won't work as specified. Install correct board file!\n");
+
+ return 0;
+}
+
+
+static int ath6kl_upload_board_file(struct ath6kl *ar)
+{
+ u32 board_address, board_ext_address, param;
+ int ret;
+
+ if (ar->fw_board == NULL) {
+ ret = ath6kl_fetch_board_file(ar);
+ if (ret)
+ return ret;
+ }
+
+ /* Determine where in Target RAM to write Board Data */
+ ath6kl_bmi_read(ar,
+ ath6kl_get_hi_item_addr(ar,
+ HI_ITEM(hi_board_data)),
+ (u8 *) &board_address, 4);
+ ath6kl_dbg(ATH6KL_DBG_TRC, "board data download addr: 0x%x\n",
+ board_address);
+
+ /* determine where in target ram to write extended board data */
+ ath6kl_bmi_read(ar,
+ ath6kl_get_hi_item_addr(ar,
+ HI_ITEM(hi_board_ext_data)),
+ (u8 *) &board_ext_address, 4);
+
+ ath6kl_dbg(ATH6KL_DBG_TRC, "board file download addr: 0x%x\n",
+ board_ext_address);
+
+ if (board_ext_address == 0) {
+ ath6kl_err("Failed to get board file target address.\n");
+ return -EINVAL;
+ }
+
+ if (ar->fw_board_len == (AR6003_BOARD_DATA_SZ +
+ AR6003_BOARD_EXT_DATA_SZ)) {
+ /* write extended board data */
+ ret = ath6kl_bmi_write(ar, board_ext_address,
+ ar->fw_board + AR6003_BOARD_DATA_SZ,
+ AR6003_BOARD_EXT_DATA_SZ);
+
+ if (ret) {
+ ath6kl_err("Failed to write extended board data: %d\n",
+ ret);
+ return ret;
+ }
+
+ /* record that extended board data is initialized */
+ param = (AR6003_BOARD_EXT_DATA_SZ << 16) | 1;
+ ath6kl_bmi_write(ar,
+ ath6kl_get_hi_item_addr(ar,
+ HI_ITEM(hi_board_ext_data_config)),
+ (unsigned char *) &param, 4);
+ }
+
+ if (ar->fw_board_len < AR6003_BOARD_DATA_SZ) {
+ ath6kl_err("Too small board file: %zu\n", ar->fw_board_len);
+ ret = -EINVAL;
+ return ret;
+ }
+
+ ret = ath6kl_bmi_write(ar, board_address, ar->fw_board,
+ AR6003_BOARD_DATA_SZ);
+
+ if (ret) {
+ ath6kl_err("Board file bmi write failed: %d\n", ret);
+ return ret;
+ }
+
+ /* record the fact that Board Data IS initialized */
+ param = 1;
+ ath6kl_bmi_write(ar,
+ ath6kl_get_hi_item_addr(ar,
+ HI_ITEM(hi_board_data_initialized)),
+ (u8 *)&param, 4);
+
+ return ret;
+}
+
+static int ath6kl_upload_otp(struct ath6kl *ar)
+{
+ const char *filename;
+ u32 address, param;
+ int ret;
+
+ switch (ar->version.target_ver) {
+ case AR6003_REV2_VERSION:
+ filename = AR6003_REV2_OTP_FILE;
+ break;
+ default:
+ filename = AR6003_REV3_OTP_FILE;
+ break;
+ }
+
+ if (ar->fw_otp == NULL) {
+ ret = ath6kl_get_fw(ar, filename, &ar->fw_otp,
+ &ar->fw_otp_len);
+ if (ret) {
+ ath6kl_err("Failed to get OTP file %s: %d\n",
+ filename, ret);
+ return ret;
+ }
+ }
+
+ address = ath6kl_get_load_address(ar->version.target_ver,
+ APP_LOAD_ADDR);
+
+ ret = ath6kl_bmi_fast_download(ar, address, ar->fw_otp,
+ ar->fw_otp_len);
+ if (ret) {
+ ath6kl_err("Failed to upload OTP file: %d\n", ret);
+ return ret;
+ }
+
+ /* execute the OTP code */
+ param = 0;
+ address = ath6kl_get_load_address(ar->version.target_ver,
+ APP_START_OVERRIDE_ADDR);
+ ath6kl_bmi_execute(ar, address, &param);
+
+ return ret;
+}
+
+static int ath6kl_upload_firmware(struct ath6kl *ar)
+{
+ const char *filename;
+ u32 address;
+ int ret;
+
+ switch (ar->version.target_ver) {
+ case AR6003_REV2_VERSION:
+ filename = AR6003_REV2_FIRMWARE_FILE;
+ break;
+ default:
+ filename = AR6003_REV3_FIRMWARE_FILE;
+ break;
+ }
+
+ if (ar->fw == NULL) {
+ ret = ath6kl_get_fw(ar, filename, &ar->fw, &ar->fw_len);
+ if (ret) {
+ ath6kl_err("Failed to get firmware file %s: %d\n",
+ filename, ret);
+ return ret;
+ }
+ }
+
+ address = ath6kl_get_load_address(ar->version.target_ver,
+ APP_LOAD_ADDR);
+
+ ret = ath6kl_bmi_fast_download(ar, address, ar->fw, ar->fw_len);
+
+ if (ret) {
+ ath6kl_err("Failed to write firmware: %d\n", ret);
+ return ret;
+ }
+
+ /* Set starting address for firmware */
+ address = ath6kl_get_load_address(ar->version.target_ver,
+ APP_START_OVERRIDE_ADDR);
+ ath6kl_bmi_set_app_start(ar, address);
+
+ return ret;
+}
+
+static int ath6kl_upload_patch(struct ath6kl *ar)
+{
+ const char *filename;
+ u32 address, param;
+ int ret;
+
+ switch (ar->version.target_ver) {
+ case AR6003_REV2_VERSION:
+ filename = AR6003_REV2_PATCH_FILE;
+ break;
+ default:
+ filename = AR6003_REV3_PATCH_FILE;
+ break;
+ }
+
+ if (ar->fw_patch == NULL) {
+ ret = ath6kl_get_fw(ar, filename, &ar->fw_patch,
+ &ar->fw_patch_len);
+ if (ret) {
+ ath6kl_err("Failed to get patch file %s: %d\n",
+ filename, ret);
+ return ret;
+ }
+ }
+
+ address = ath6kl_get_load_address(ar->version.target_ver,
+ DATASET_PATCH_ADDR);
+
+ ret = ath6kl_bmi_write(ar, address, ar->fw_patch, ar->fw_patch_len);
+ if (ret) {
+ ath6kl_err("Failed to write patch file: %d\n", ret);
+ return ret;
+ }
+
+ param = address;
+ ath6kl_bmi_write(ar,
+ ath6kl_get_hi_item_addr(ar,
+ HI_ITEM(hi_dset_list_head)),
+ (unsigned char *) &param, 4);
+
+ return 0;
+}
+
+static int ath6kl_init_upload(struct ath6kl *ar)
+{
+ u32 param, options, sleep, address;
+ int status = 0;
+
+ if (ar->target_type != TARGET_TYPE_AR6003)
+ return -EINVAL;
+
+ /* temporarily disable system sleep */
+ address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
+ status = ath6kl_bmi_reg_read(ar, address, &param);
+ if (status)
+ return status;
+
+ options = param;
+
+ param |= ATH6KL_OPTION_SLEEP_DISABLE;
+ status = ath6kl_bmi_reg_write(ar, address, param);
+ if (status)
+ return status;
+
+ address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
+ status = ath6kl_bmi_reg_read(ar, address, &param);
+ if (status)
+ return status;
+
+ sleep = param;
+
+ param |= SM(SYSTEM_SLEEP_DISABLE, 1);
+ status = ath6kl_bmi_reg_write(ar, address, param);
+ if (status)
+ return status;
+
+ ath6kl_dbg(ATH6KL_DBG_TRC, "old options: %d, old sleep: %d\n",
+ options, sleep);
+
+ /* program analog PLL register */
+ status = ath6kl_bmi_reg_write(ar, ATH6KL_ANALOG_PLL_REGISTER,
+ 0xF9104001);
+ if (status)
+ return status;
+
+ /* Run at 80/88MHz by default */
+ param = SM(CPU_CLOCK_STANDARD, 1);
+
+ address = RTC_BASE_ADDRESS + CPU_CLOCK_ADDRESS;
+ status = ath6kl_bmi_reg_write(ar, address, param);
+ if (status)
+ return status;
+
+ param = 0;
+ address = RTC_BASE_ADDRESS + LPO_CAL_ADDRESS;
+ param = SM(LPO_CAL_ENABLE, 1);
+ status = ath6kl_bmi_reg_write(ar, address, param);
+ if (status)
+ return status;
+
+ /* WAR to avoid SDIO CRC err */
+ if (ar->version.target_ver == AR6003_REV2_VERSION) {
+ ath6kl_err("temporary war to avoid sdio crc error\n");
+
+ param = 0x20;
+
+ address = GPIO_BASE_ADDRESS + GPIO_PIN10_ADDRESS;
+ status = ath6kl_bmi_reg_write(ar, address, param);
+ if (status)
+ return status;
+
+ address = GPIO_BASE_ADDRESS + GPIO_PIN11_ADDRESS;
+ status = ath6kl_bmi_reg_write(ar, address, param);
+ if (status)
+ return status;
+
+ address = GPIO_BASE_ADDRESS + GPIO_PIN12_ADDRESS;
+ status = ath6kl_bmi_reg_write(ar, address, param);
+ if (status)
+ return status;
+
+ address = GPIO_BASE_ADDRESS + GPIO_PIN13_ADDRESS;
+ status = ath6kl_bmi_reg_write(ar, address, param);
+ if (status)
+ return status;
+ }
+
+ /* write EEPROM data to Target RAM */
+ status = ath6kl_upload_board_file(ar);
+ if (status)
+ return status;
+
+ /* transfer One time Programmable data */
+ status = ath6kl_upload_otp(ar);
+ if (status)
+ return status;
+
+ /* Download Target firmware */
+ status = ath6kl_upload_firmware(ar);
+ if (status)
+ return status;
+
+ status = ath6kl_upload_patch(ar);
+ if (status)
+ return status;
+
+ /* Restore system sleep */
+ address = RTC_BASE_ADDRESS + SYSTEM_SLEEP_ADDRESS;
+ status = ath6kl_bmi_reg_write(ar, address, sleep);
+ if (status)
+ return status;
+
+ address = MBOX_BASE_ADDRESS + LOCAL_SCRATCH_ADDRESS;
+ param = options | 0x20;
+ status = ath6kl_bmi_reg_write(ar, address, param);
+ if (status)
+ return status;
+
+ /* Configure GPIO AR6003 UART */
+ param = CONFIG_AR600x_DEBUG_UART_TX_PIN;
+ status = ath6kl_bmi_write(ar,
+ ath6kl_get_hi_item_addr(ar,
+ HI_ITEM(hi_dbg_uart_txpin)),
+ (u8 *)&param, 4);
+
+ return status;
+}
+
+static int ath6kl_init(struct net_device *dev)
+{
+ struct ath6kl *ar = ath6kl_priv(dev);
+ int status = 0;
+ s32 timeleft;
+
+ if (!ar)
+ return -EIO;
+
+ /* Do we need to finish the BMI phase */
+ if (ath6kl_bmi_done(ar)) {
+ status = -EIO;
+ goto ath6kl_init_done;
+ }
+
+ /* Indicate that WMI is enabled (although not ready yet) */
+ set_bit(WMI_ENABLED, &ar->flag);
+ ar->wmi = ath6kl_wmi_init((void *) ar);
+ if (!ar->wmi) {
+ ath6kl_err("failed to initialize wmi\n");
+ status = -EIO;
+ goto ath6kl_init_done;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_TRC, "%s: got wmi @ 0x%p.\n", __func__, ar->wmi);
+
+ /*
+ * The reason we have to wait for the target here is that the
+ * driver layer has to init BMI in order to set the host block
+ * size.
+ */
+ if (htc_wait_target(ar->htc_target)) {
+ status = -EIO;
+ goto err_wmi_cleanup;
+ }
+
+ if (ath6kl_init_service_ep(ar)) {
+ status = -EIO;
+ goto err_cleanup_scatter;
+ }
+
+ /* setup access class priority mappings */
+ ar->ac_stream_pri_map[WMM_AC_BK] = 0; /* lowest */
+ ar->ac_stream_pri_map[WMM_AC_BE] = 1;
+ ar->ac_stream_pri_map[WMM_AC_VI] = 2;
+ ar->ac_stream_pri_map[WMM_AC_VO] = 3; /* highest */
+
+ /* give our connected endpoints some buffers */
+ ath6kl_rx_refill(ar->htc_target, ar->ctrl_ep);
+ ath6kl_rx_refill(ar->htc_target, ar->ac2ep_map[WMM_AC_BE]);
+
+ /* allocate some buffers that handle larger AMSDU frames */
+ ath6kl_refill_amsdu_rxbufs(ar, ATH6KL_MAX_AMSDU_RX_BUFFERS);
+
+ /* setup credit distribution */
+ ath6k_setup_credit_dist(ar->htc_target, &ar->credit_state_info);
+
+ ath6kl_cookie_init(ar);
+
+ /* start HTC */
+ status = htc_start(ar->htc_target);
+
+ if (status) {
+ ath6kl_cookie_cleanup(ar);
+ goto err_rxbuf_cleanup;
+ }
+
+ /* Wait for Wmi event to be ready */
+ timeleft = wait_event_interruptible_timeout(ar->event_wq,
+ test_bit(WMI_READY,
+ &ar->flag),
+ WMI_TIMEOUT);
+
+ if (ar->version.abi_ver != ATH6KL_ABI_VERSION) {
+ ath6kl_err("abi version mismatch: host(0x%x), target(0x%x)\n",
+ ATH6KL_ABI_VERSION, ar->version.abi_ver);
+ status = -EIO;
+ goto err_htc_stop;
+ }
+
+ if (!timeleft || signal_pending(current)) {
+ ath6kl_err("wmi is not ready or wait was interrupted\n");
+ status = -EIO;
+ goto err_htc_stop;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_TRC, "%s: wmi is ready\n", __func__);
+
+ /* communicate the wmi protocol verision to the target */
+ if ((ath6kl_set_host_app_area(ar)) != 0)
+ ath6kl_err("unable to set the host app area\n");
+
+ ar->conf_flags = ATH6KL_CONF_IGNORE_ERP_BARKER |
+ ATH6KL_CONF_ENABLE_11N | ATH6KL_CONF_ENABLE_TX_BURST;
+
+ status = ath6kl_target_config_wlan_params(ar);
+ if (!status)
+ goto ath6kl_init_done;
+
+err_htc_stop:
+ htc_stop(ar->htc_target);
+err_rxbuf_cleanup:
+ htc_flush_rx_buf(ar->htc_target);
+ ath6kl_cleanup_amsdu_rxbufs(ar);
+err_cleanup_scatter:
+ ath6kl_hif_cleanup_scatter(ar);
+err_wmi_cleanup:
+ ath6kl_wmi_shutdown(ar->wmi);
+ clear_bit(WMI_ENABLED, &ar->flag);
+ ar->wmi = NULL;
+
+ath6kl_init_done:
+ return status;
+}
+
+int ath6kl_core_init(struct ath6kl *ar)
+{
+ int ret = 0;
+ struct ath6kl_bmi_target_info targ_info;
+
+ ar->ath6kl_wq = create_singlethread_workqueue("ath6kl");
+ if (!ar->ath6kl_wq)
+ return -ENOMEM;
+
+ ret = ath6kl_bmi_init(ar);
+ if (ret)
+ goto err_wq;
+
+ ret = ath6kl_bmi_get_target_info(ar, &targ_info);
+ if (ret)
+ goto err_bmi_cleanup;
+
+ ar->version.target_ver = le32_to_cpu(targ_info.version);
+ ar->target_type = le32_to_cpu(targ_info.type);
+ ar->wdev->wiphy->hw_version = le32_to_cpu(targ_info.version);
+
+ ret = ath6kl_configure_target(ar);
+ if (ret)
+ goto err_bmi_cleanup;
+
+ ar->htc_target = htc_create(ar);
+
+ if (!ar->htc_target) {
+ ret = -ENOMEM;
+ goto err_bmi_cleanup;
+ }
+
+ ar->aggr_cntxt = aggr_init(ar->net_dev);
+ if (!ar->aggr_cntxt) {
+ ath6kl_err("failed to initialize aggr\n");
+ ret = -ENOMEM;
+ goto err_htc_cleanup;
+ }
+
+ ret = ath6kl_init_upload(ar);
+ if (ret)
+ goto err_htc_cleanup;
+
+ ret = ath6kl_init(ar->net_dev);
+ if (ret)
+ goto err_htc_cleanup;
+
+ /* This runs the init function if registered */
+ ret = register_netdev(ar->net_dev);
+ if (ret) {
+ ath6kl_err("register_netdev failed\n");
+ ath6kl_destroy(ar->net_dev, 0);
+ return ret;
+ }
+
+ set_bit(NETDEV_REGISTERED, &ar->flag);
+
+ ath6kl_dbg(ATH6KL_DBG_TRC, "%s: name=%s dev=0x%p, ar=0x%p\n",
+ __func__, ar->net_dev->name, ar->net_dev, ar);
+
+ return ret;
+
+err_htc_cleanup:
+ htc_cleanup(ar->htc_target);
+err_bmi_cleanup:
+ ath6kl_bmi_cleanup(ar);
+err_wq:
+ destroy_workqueue(ar->ath6kl_wq);
+ return ret;
+}
+
+void ath6kl_stop_txrx(struct ath6kl *ar)
+{
+ struct net_device *ndev = ar->net_dev;
+
+ if (!ndev)
+ return;
+
+ set_bit(DESTROY_IN_PROGRESS, &ar->flag);
+
+ if (down_interruptible(&ar->sem)) {
+ ath6kl_err("down_interruptible failed\n");
+ return;
+ }
+
+ if (ar->wlan_pwr_state != WLAN_POWER_STATE_CUT_PWR)
+ ath6kl_stop_endpoint(ndev, false, true);
+
+ ar->wlan_state = WLAN_DISABLED;
+}
+
+/*
+ * We need to differentiate between the surprise and planned removal of the
+ * device because of the following consideration:
+ *
+ * - In case of surprise removal, the hcd already frees up the pending
+ * for the device and hence there is no need to unregister the function
+ * driver inorder to get these requests. For planned removal, the function
+ * driver has to explicitly unregister itself to have the hcd return all the
+ * pending requests before the data structures for the devices are freed up.
+ * Note that as per the current implementation, the function driver will
+ * end up releasing all the devices since there is no API to selectively
+ * release a particular device.
+ *
+ * - Certain commands issued to the target can be skipped for surprise
+ * removal since they will anyway not go through.
+ */
+void ath6kl_destroy(struct net_device *dev, unsigned int unregister)
+{
+ struct ath6kl *ar;
+
+ if (!dev || !ath6kl_priv(dev)) {
+ ath6kl_err("failed to get device structure\n");
+ return;
+ }
+
+ ar = ath6kl_priv(dev);
+
+ destroy_workqueue(ar->ath6kl_wq);
+
+ if (ar->htc_target)
+ htc_cleanup(ar->htc_target);
+
+ aggr_module_destroy(ar->aggr_cntxt);
+
+ ath6kl_cookie_cleanup(ar);
+
+ ath6kl_cleanup_amsdu_rxbufs(ar);
+
+ ath6kl_bmi_cleanup(ar);
+
+ if (unregister && test_bit(NETDEV_REGISTERED, &ar->flag)) {
+ unregister_netdev(dev);
+ clear_bit(NETDEV_REGISTERED, &ar->flag);
+ }
+
+ free_netdev(dev);
+
+ ath6kl_cfg80211_deinit(ar);
+}
diff --git a/drivers/net/wireless/ath/ath6kl/main.c b/drivers/net/wireless/ath/ath6kl/main.c
new file mode 100644
index 000000000000..f325a23dfff0
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/main.c
@@ -0,0 +1,1337 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications Inc.
+ *
+ * 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 "core.h"
+#include "hif-ops.h"
+#include "cfg80211.h"
+#include "target.h"
+#include "debug.h"
+
+struct ath6kl_sta *ath6kl_find_sta(struct ath6kl *ar, u8 *node_addr)
+{
+ struct ath6kl_sta *conn = NULL;
+ u8 i, max_conn;
+
+ max_conn = (ar->nw_type == AP_NETWORK) ? AP_MAX_NUM_STA : 0;
+
+ for (i = 0; i < max_conn; i++) {
+ if (memcmp(node_addr, ar->sta_list[i].mac, ETH_ALEN) == 0) {
+ conn = &ar->sta_list[i];
+ break;
+ }
+ }
+
+ return conn;
+}
+
+struct ath6kl_sta *ath6kl_find_sta_by_aid(struct ath6kl *ar, u8 aid)
+{
+ struct ath6kl_sta *conn = NULL;
+ u8 ctr;
+
+ for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
+ if (ar->sta_list[ctr].aid == aid) {
+ conn = &ar->sta_list[ctr];
+ break;
+ }
+ }
+ return conn;
+}
+
+static void ath6kl_add_new_sta(struct ath6kl *ar, u8 *mac, u16 aid, u8 *wpaie,
+ u8 ielen, u8 keymgmt, u8 ucipher, u8 auth)
+{
+ struct ath6kl_sta *sta;
+ u8 free_slot;
+
+ free_slot = aid - 1;
+
+ sta = &ar->sta_list[free_slot];
+ memcpy(sta->mac, mac, ETH_ALEN);
+ memcpy(sta->wpa_ie, wpaie, ielen);
+ sta->aid = aid;
+ sta->keymgmt = keymgmt;
+ sta->ucipher = ucipher;
+ sta->auth = auth;
+
+ ar->sta_list_index = ar->sta_list_index | (1 << free_slot);
+ ar->ap_stats.sta[free_slot].aid = cpu_to_le32(aid);
+}
+
+static void ath6kl_sta_cleanup(struct ath6kl *ar, u8 i)
+{
+ struct ath6kl_sta *sta = &ar->sta_list[i];
+
+ /* empty the queued pkts in the PS queue if any */
+ spin_lock_bh(&sta->psq_lock);
+ skb_queue_purge(&sta->psq);
+ spin_unlock_bh(&sta->psq_lock);
+
+ memset(&ar->ap_stats.sta[sta->aid - 1], 0,
+ sizeof(struct wmi_per_sta_stat));
+ memset(sta->mac, 0, ETH_ALEN);
+ memset(sta->wpa_ie, 0, ATH6KL_MAX_IE);
+ sta->aid = 0;
+ sta->sta_flags = 0;
+
+ ar->sta_list_index = ar->sta_list_index & ~(1 << i);
+
+}
+
+static u8 ath6kl_remove_sta(struct ath6kl *ar, u8 *mac, u16 reason)
+{
+ u8 i, removed = 0;
+
+ if (is_zero_ether_addr(mac))
+ return removed;
+
+ if (is_broadcast_ether_addr(mac)) {
+ ath6kl_dbg(ATH6KL_DBG_TRC, "deleting all station\n");
+
+ for (i = 0; i < AP_MAX_NUM_STA; i++) {
+ if (!is_zero_ether_addr(ar->sta_list[i].mac)) {
+ ath6kl_sta_cleanup(ar, i);
+ removed = 1;
+ }
+ }
+ } else {
+ for (i = 0; i < AP_MAX_NUM_STA; i++) {
+ if (memcmp(ar->sta_list[i].mac, mac, ETH_ALEN) == 0) {
+ ath6kl_dbg(ATH6KL_DBG_TRC,
+ "deleting station %pM aid=%d reason=%d\n",
+ mac, ar->sta_list[i].aid, reason);
+ ath6kl_sta_cleanup(ar, i);
+ removed = 1;
+ break;
+ }
+ }
+ }
+
+ return removed;
+}
+
+enum htc_endpoint_id ath6kl_ac2_endpoint_id(void *devt, u8 ac)
+{
+ struct ath6kl *ar = devt;
+ return ar->ac2ep_map[ac];
+}
+
+struct ath6kl_cookie *ath6kl_alloc_cookie(struct ath6kl *ar)
+{
+ struct ath6kl_cookie *cookie;
+
+ cookie = ar->cookie_list;
+ if (cookie != NULL) {
+ ar->cookie_list = cookie->arc_list_next;
+ ar->cookie_count--;
+ }
+
+ return cookie;
+}
+
+void ath6kl_cookie_init(struct ath6kl *ar)
+{
+ u32 i;
+
+ ar->cookie_list = NULL;
+ ar->cookie_count = 0;
+
+ memset(ar->cookie_mem, 0, sizeof(ar->cookie_mem));
+
+ for (i = 0; i < MAX_COOKIE_NUM; i++)
+ ath6kl_free_cookie(ar, &ar->cookie_mem[i]);
+}
+
+void ath6kl_cookie_cleanup(struct ath6kl *ar)
+{
+ ar->cookie_list = NULL;
+ ar->cookie_count = 0;
+}
+
+void ath6kl_free_cookie(struct ath6kl *ar, struct ath6kl_cookie *cookie)
+{
+ /* Insert first */
+
+ if (!ar || !cookie)
+ return;
+
+ cookie->arc_list_next = ar->cookie_list;
+ ar->cookie_list = cookie;
+ ar->cookie_count++;
+}
+
+/* set the window address register (using 4-byte register access ). */
+static int ath6kl_set_addrwin_reg(struct ath6kl *ar, u32 reg_addr, u32 addr)
+{
+ int status;
+ u8 addr_val[4];
+ s32 i;
+
+ /*
+ * Write bytes 1,2,3 of the register to set the upper address bytes,
+ * the LSB is written last to initiate the access cycle
+ */
+
+ for (i = 1; i <= 3; i++) {
+ /*
+ * Fill the buffer with the address byte value we want to
+ * hit 4 times.
+ */
+ memset(addr_val, ((u8 *)&addr)[i], 4);
+
+ /*
+ * Hit each byte of the register address with a 4-byte
+ * write operation to the same address, this is a harmless
+ * operation.
+ */
+ status = hif_read_write_sync(ar, reg_addr + i, addr_val,
+ 4, HIF_WR_SYNC_BYTE_FIX);
+ if (status)
+ break;
+ }
+
+ if (status) {
+ ath6kl_err("failed to write initial bytes of 0x%x to window reg: 0x%X\n",
+ addr, reg_addr);
+ return status;
+ }
+
+ /*
+ * Write the address register again, this time write the whole
+ * 4-byte value. The effect here is that the LSB write causes the
+ * cycle to start, the extra 3 byte write to bytes 1,2,3 has no
+ * effect since we are writing the same values again
+ */
+ status = hif_read_write_sync(ar, reg_addr, (u8 *)(&addr),
+ 4, HIF_WR_SYNC_BYTE_INC);
+
+ if (status) {
+ ath6kl_err("failed to write 0x%x to window reg: 0x%X\n",
+ addr, reg_addr);
+ return status;
+ }
+
+ return 0;
+}
+
+/*
+ * Read from the ATH6KL through its diagnostic window. No cooperation from
+ * the Target is required for this.
+ */
+int ath6kl_read_reg_diag(struct ath6kl *ar, u32 *address, u32 *data)
+{
+ int status;
+
+ /* set window register to start read cycle */
+ status = ath6kl_set_addrwin_reg(ar, WINDOW_READ_ADDR_ADDRESS,
+ *address);
+
+ if (status)
+ return status;
+
+ /* read the data */
+ status = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *)data,
+ sizeof(u32), HIF_RD_SYNC_BYTE_INC);
+ if (status) {
+ ath6kl_err("failed to read from window data addr\n");
+ return status;
+ }
+
+ return status;
+}
+
+
+/*
+ * Write to the ATH6KL through its diagnostic window. No cooperation from
+ * the Target is required for this.
+ */
+static int ath6kl_write_reg_diag(struct ath6kl *ar, u32 *address, u32 *data)
+{
+ int status;
+
+ /* set write data */
+ status = hif_read_write_sync(ar, WINDOW_DATA_ADDRESS, (u8 *)data,
+ sizeof(u32), HIF_WR_SYNC_BYTE_INC);
+ if (status) {
+ ath6kl_err("failed to write 0x%x to window data addr\n", *data);
+ return status;
+ }
+
+ /* set window register, which starts the write cycle */
+ return ath6kl_set_addrwin_reg(ar, WINDOW_WRITE_ADDR_ADDRESS,
+ *address);
+}
+
+int ath6kl_access_datadiag(struct ath6kl *ar, u32 address,
+ u8 *data, u32 length, bool read)
+{
+ u32 count;
+ int status = 0;
+
+ for (count = 0; count < length; count += 4, address += 4) {
+ if (read) {
+ status = ath6kl_read_reg_diag(ar, &address,
+ (u32 *) &data[count]);
+ if (status)
+ break;
+ } else {
+ status = ath6kl_write_reg_diag(ar, &address,
+ (u32 *) &data[count]);
+ if (status)
+ break;
+ }
+ }
+
+ return status;
+}
+
+static void ath6kl_reset_device(struct ath6kl *ar, u32 target_type,
+ bool wait_fot_compltn, bool cold_reset)
+{
+ int status = 0;
+ u32 address;
+ u32 data;
+
+ if (target_type != TARGET_TYPE_AR6003)
+ return;
+
+ data = cold_reset ? RESET_CONTROL_COLD_RST : RESET_CONTROL_MBOX_RST;
+
+ address = RTC_BASE_ADDRESS;
+ status = ath6kl_write_reg_diag(ar, &address, &data);
+
+ if (status)
+ ath6kl_err("failed to reset target\n");
+}
+
+void ath6kl_stop_endpoint(struct net_device *dev, bool keep_profile,
+ bool get_dbglogs)
+{
+ struct ath6kl *ar = ath6kl_priv(dev);
+ static u8 bcast_mac[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
+ bool discon_issued;
+
+ netif_stop_queue(dev);
+
+ /* disable the target and the interrupts associated with it */
+ if (test_bit(WMI_READY, &ar->flag)) {
+ discon_issued = (test_bit(CONNECTED, &ar->flag) ||
+ test_bit(CONNECT_PEND, &ar->flag));
+ ath6kl_disconnect(ar);
+ if (!keep_profile)
+ ath6kl_init_profile_info(ar);
+
+ del_timer(&ar->disconnect_timer);
+
+ clear_bit(WMI_READY, &ar->flag);
+ ath6kl_wmi_shutdown(ar->wmi);
+ clear_bit(WMI_ENABLED, &ar->flag);
+ ar->wmi = NULL;
+
+ /*
+ * After wmi_shudown all WMI events will be dropped. We
+ * need to cleanup the buffers allocated in AP mode and
+ * give disconnect notification to stack, which usually
+ * happens in the disconnect_event. Simulate the disconnect
+ * event by calling the function directly. Sometimes
+ * disconnect_event will be received when the debug logs
+ * are collected.
+ */
+ if (discon_issued)
+ ath6kl_disconnect_event(ar, DISCONNECT_CMD,
+ (ar->nw_type & AP_NETWORK) ?
+ bcast_mac : ar->bssid,
+ 0, NULL, 0);
+
+ ar->user_key_ctrl = 0;
+
+ } else {
+ ath6kl_dbg(ATH6KL_DBG_TRC,
+ "%s: wmi is not ready 0x%p 0x%p\n",
+ __func__, ar, ar->wmi);
+
+ /* Shut down WMI if we have started it */
+ if (test_bit(WMI_ENABLED, &ar->flag)) {
+ ath6kl_dbg(ATH6KL_DBG_TRC,
+ "%s: shut down wmi\n", __func__);
+ ath6kl_wmi_shutdown(ar->wmi);
+ clear_bit(WMI_ENABLED, &ar->flag);
+ ar->wmi = NULL;
+ }
+ }
+
+ if (ar->htc_target) {
+ ath6kl_dbg(ATH6KL_DBG_TRC, "%s: shut down htc\n", __func__);
+ htc_stop(ar->htc_target);
+ }
+
+ /*
+ * Try to reset the device if we can. The driver may have been
+ * configure NOT to reset the target during a debug session.
+ */
+ ath6kl_dbg(ATH6KL_DBG_TRC,
+ "attempting to reset target on instance destroy\n");
+ ath6kl_reset_device(ar, ar->target_type, true, true);
+}
+
+static void ath6kl_install_static_wep_keys(struct ath6kl *ar)
+{
+ u8 index;
+ u8 keyusage;
+
+ for (index = WMI_MIN_KEY_INDEX; index <= WMI_MAX_KEY_INDEX; index++) {
+ if (ar->wep_key_list[index].key_len) {
+ keyusage = GROUP_USAGE;
+ if (index == ar->def_txkey_index)
+ keyusage |= TX_USAGE;
+
+ ath6kl_wmi_addkey_cmd(ar->wmi,
+ index,
+ WEP_CRYPT,
+ keyusage,
+ ar->wep_key_list[index].key_len,
+ NULL,
+ ar->wep_key_list[index].key,
+ KEY_OP_INIT_VAL, NULL,
+ NO_SYNC_WMIFLAG);
+ }
+ }
+}
+
+static void ath6kl_connect_ap_mode(struct ath6kl *ar, u16 channel, u8 *bssid,
+ u16 listen_int, u16 beacon_int,
+ u8 assoc_resp_len, u8 *assoc_info)
+{
+ struct net_device *dev = ar->net_dev;
+ struct station_info sinfo;
+ struct ath6kl_req_key *ik;
+ enum crypto_type keyType = NONE_CRYPT;
+
+ if (memcmp(dev->dev_addr, bssid, ETH_ALEN) == 0) {
+ ik = &ar->ap_mode_bkey;
+
+ switch (ar->auth_mode) {
+ case NONE_AUTH:
+ if (ar->prwise_crypto == WEP_CRYPT)
+ ath6kl_install_static_wep_keys(ar);
+ break;
+ case WPA_PSK_AUTH:
+ case WPA2_PSK_AUTH:
+ case (WPA_PSK_AUTH|WPA2_PSK_AUTH):
+ switch (ik->ik_type) {
+ case ATH6KL_CIPHER_TKIP:
+ keyType = TKIP_CRYPT;
+ break;
+ case ATH6KL_CIPHER_AES_CCM:
+ keyType = AES_CRYPT;
+ break;
+ default:
+ goto skip_key;
+ }
+ ath6kl_wmi_addkey_cmd(ar->wmi, ik->ik_keyix, keyType,
+ GROUP_USAGE, ik->ik_keylen,
+ (u8 *)&ik->ik_keyrsc,
+ ik->ik_keydata,
+ KEY_OP_INIT_VAL, ik->ik_macaddr,
+ SYNC_BOTH_WMIFLAG);
+ break;
+ }
+skip_key:
+ set_bit(CONNECTED, &ar->flag);
+ return;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_TRC, "new station %pM aid=%d\n",
+ bssid, channel);
+
+ ath6kl_add_new_sta(ar, bssid, channel, assoc_info, assoc_resp_len,
+ listen_int & 0xFF, beacon_int,
+ (listen_int >> 8) & 0xFF);
+
+ /* send event to application */
+ memset(&sinfo, 0, sizeof(sinfo));
+
+ /* TODO: sinfo.generation */
+ /* TODO: need to deliver (Re)AssocReq IEs somehow.. change in
+ * cfg80211 needed, e.g., by adding those into sinfo
+ */
+ cfg80211_new_sta(ar->net_dev, bssid, &sinfo, GFP_KERNEL);
+
+ netif_wake_queue(ar->net_dev);
+
+ return;
+}
+
+/* Functions for Tx credit handling */
+void ath6k_credit_init(struct htc_credit_state_info *cred_info,
+ struct list_head *ep_list,
+ int tot_credits)
+{
+ struct htc_endpoint_credit_dist *cur_ep_dist;
+ int count;
+
+ cred_info->cur_free_credits = tot_credits;
+ cred_info->total_avail_credits = tot_credits;
+
+ list_for_each_entry(cur_ep_dist, ep_list, list) {
+ if (cur_ep_dist->endpoint == ENDPOINT_0)
+ continue;
+
+ cur_ep_dist->cred_min = cur_ep_dist->cred_per_msg;
+
+ if (tot_credits > 4)
+ if ((cur_ep_dist->svc_id == WMI_DATA_BK_SVC) ||
+ (cur_ep_dist->svc_id == WMI_DATA_BE_SVC)) {
+ ath6kl_deposit_credit_to_ep(cred_info,
+ cur_ep_dist,
+ cur_ep_dist->cred_min);
+ cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
+ }
+
+ if (cur_ep_dist->svc_id == WMI_CONTROL_SVC) {
+ ath6kl_deposit_credit_to_ep(cred_info, cur_ep_dist,
+ cur_ep_dist->cred_min);
+ /*
+ * Control service is always marked active, it
+ * never goes inactive EVER.
+ */
+ cur_ep_dist->dist_flags |= HTC_EP_ACTIVE;
+ } else if (cur_ep_dist->svc_id == WMI_DATA_BK_SVC)
+ /* this is the lowest priority data endpoint */
+ cred_info->lowestpri_ep_dist = cur_ep_dist->list;
+
+ /*
+ * Streams have to be created (explicit | implicit) for all
+ * kinds of traffic. BE endpoints are also inactive in the
+ * beginning. When BE traffic starts it creates implicit
+ * streams that redistributes credits.
+ *
+ * Note: all other endpoints have minimums set but are
+ * initially given NO credits. credits will be distributed
+ * as traffic activity demands
+ */
+ }
+
+ WARN_ON(cred_info->cur_free_credits <= 0);
+
+ list_for_each_entry(cur_ep_dist, ep_list, list) {
+ if (cur_ep_dist->endpoint == ENDPOINT_0)
+ continue;
+
+ if (cur_ep_dist->svc_id == WMI_CONTROL_SVC)
+ cur_ep_dist->cred_norm = cur_ep_dist->cred_per_msg;
+ else {
+ /*
+ * For the remaining data endpoints, we assume that
+ * each cred_per_msg are the same. We use a simple
+ * calculation here, we take the remaining credits
+ * and determine how many max messages this can
+ * cover and then set each endpoint's normal value
+ * equal to 3/4 this amount.
+ */
+ count = (cred_info->cur_free_credits /
+ cur_ep_dist->cred_per_msg)
+ * cur_ep_dist->cred_per_msg;
+ count = (count * 3) >> 2;
+ count = max(count, cur_ep_dist->cred_per_msg);
+ cur_ep_dist->cred_norm = count;
+
+ }
+ }
+}
+
+/* initialize and setup credit distribution */
+int ath6k_setup_credit_dist(void *htc_handle,
+ struct htc_credit_state_info *cred_info)
+{
+ u16 servicepriority[5];
+
+ memset(cred_info, 0, sizeof(struct htc_credit_state_info));
+
+ servicepriority[0] = WMI_CONTROL_SVC; /* highest */
+ servicepriority[1] = WMI_DATA_VO_SVC;
+ servicepriority[2] = WMI_DATA_VI_SVC;
+ servicepriority[3] = WMI_DATA_BE_SVC;
+ servicepriority[4] = WMI_DATA_BK_SVC; /* lowest */
+
+ /* set priority list */
+ htc_set_credit_dist(htc_handle, cred_info, servicepriority, 5);
+
+ return 0;
+}
+
+/* reduce an ep's credits back to a set limit */
+static void ath6k_reduce_credits(struct htc_credit_state_info *cred_info,
+ struct htc_endpoint_credit_dist *ep_dist,
+ int limit)
+{
+ int credits;
+
+ ep_dist->cred_assngd = limit;
+
+ if (ep_dist->credits <= limit)
+ return;
+
+ credits = ep_dist->credits - limit;
+ ep_dist->credits -= credits;
+ cred_info->cur_free_credits += credits;
+}
+
+static void ath6k_credit_update(struct htc_credit_state_info *cred_info,
+ struct list_head *epdist_list)
+{
+ struct htc_endpoint_credit_dist *cur_dist_list;
+
+ list_for_each_entry(cur_dist_list, epdist_list, list) {
+ if (cur_dist_list->endpoint == ENDPOINT_0)
+ continue;
+
+ if (cur_dist_list->cred_to_dist > 0) {
+ cur_dist_list->credits +=
+ cur_dist_list->cred_to_dist;
+ cur_dist_list->cred_to_dist = 0;
+ if (cur_dist_list->credits >
+ cur_dist_list->cred_assngd)
+ ath6k_reduce_credits(cred_info,
+ cur_dist_list,
+ cur_dist_list->cred_assngd);
+
+ if (cur_dist_list->credits >
+ cur_dist_list->cred_norm)
+ ath6k_reduce_credits(cred_info, cur_dist_list,
+ cur_dist_list->cred_norm);
+
+ if (!(cur_dist_list->dist_flags & HTC_EP_ACTIVE)) {
+ if (cur_dist_list->txq_depth == 0)
+ ath6k_reduce_credits(cred_info,
+ cur_dist_list, 0);
+ }
+ }
+ }
+}
+
+/*
+ * HTC has an endpoint that needs credits, ep_dist is the endpoint in
+ * question.
+ */
+void ath6k_seek_credits(struct htc_credit_state_info *cred_info,
+ struct htc_endpoint_credit_dist *ep_dist)
+{
+ struct htc_endpoint_credit_dist *curdist_list;
+ int credits = 0;
+ int need;
+
+ if (ep_dist->svc_id == WMI_CONTROL_SVC)
+ goto out;
+
+ if ((ep_dist->svc_id == WMI_DATA_VI_SVC) ||
+ (ep_dist->svc_id == WMI_DATA_VO_SVC))
+ if ((ep_dist->cred_assngd >= ep_dist->cred_norm))
+ goto out;
+
+ /*
+ * For all other services, we follow a simple algorithm of:
+ *
+ * 1. checking the free pool for credits
+ * 2. checking lower priority endpoints for credits to take
+ */
+
+ credits = min(cred_info->cur_free_credits, ep_dist->seek_cred);
+
+ if (credits >= ep_dist->seek_cred)
+ goto out;
+
+ /*
+ * We don't have enough in the free pool, try taking away from
+ * lower priority services The rule for taking away credits:
+ *
+ * 1. Only take from lower priority endpoints
+ * 2. Only take what is allocated above the minimum (never
+ * starve an endpoint completely)
+ * 3. Only take what you need.
+ */
+
+ list_for_each_entry_reverse(curdist_list,
+ &cred_info->lowestpri_ep_dist,
+ list) {
+ if (curdist_list == ep_dist)
+ break;
+
+ need = ep_dist->seek_cred - cred_info->cur_free_credits;
+
+ if ((curdist_list->cred_assngd - need) >=
+ curdist_list->cred_min) {
+ /*
+ * The current one has been allocated more than
+ * it's minimum and it has enough credits assigned
+ * above it's minimum to fulfill our need try to
+ * take away just enough to fulfill our need.
+ */
+ ath6k_reduce_credits(cred_info, curdist_list,
+ curdist_list->cred_assngd - need);
+
+ if (cred_info->cur_free_credits >=
+ ep_dist->seek_cred)
+ break;
+ }
+
+ if (curdist_list->endpoint == ENDPOINT_0)
+ break;
+ }
+
+ credits = min(cred_info->cur_free_credits, ep_dist->seek_cred);
+
+out:
+ /* did we find some credits? */
+ if (credits)
+ ath6kl_deposit_credit_to_ep(cred_info, ep_dist, credits);
+
+ ep_dist->seek_cred = 0;
+}
+
+/* redistribute credits based on activity change */
+static void ath6k_redistribute_credits(struct htc_credit_state_info *info,
+ struct list_head *ep_dist_list)
+{
+ struct htc_endpoint_credit_dist *curdist_list;
+
+ list_for_each_entry(curdist_list, ep_dist_list, list) {
+ if (curdist_list->endpoint == ENDPOINT_0)
+ continue;
+
+ if ((curdist_list->svc_id == WMI_DATA_BK_SVC) ||
+ (curdist_list->svc_id == WMI_DATA_BE_SVC))
+ curdist_list->dist_flags |= HTC_EP_ACTIVE;
+
+ if ((curdist_list->svc_id != WMI_CONTROL_SVC) &&
+ !(curdist_list->dist_flags & HTC_EP_ACTIVE)) {
+ if (curdist_list->txq_depth == 0)
+ ath6k_reduce_credits(info,
+ curdist_list, 0);
+ else
+ ath6k_reduce_credits(info,
+ curdist_list,
+ curdist_list->cred_min);
+ }
+ }
+}
+
+/*
+ *
+ * This function is invoked whenever endpoints require credit
+ * distributions. A lock is held while this function is invoked, this
+ * function shall NOT block. The ep_dist_list is a list of distribution
+ * structures in prioritized order as defined by the call to the
+ * htc_set_credit_dist() api.
+ */
+void ath6k_credit_distribute(struct htc_credit_state_info *cred_info,
+ struct list_head *ep_dist_list,
+ enum htc_credit_dist_reason reason)
+{
+ switch (reason) {
+ case HTC_CREDIT_DIST_SEND_COMPLETE:
+ ath6k_credit_update(cred_info, ep_dist_list);
+ break;
+ case HTC_CREDIT_DIST_ACTIVITY_CHANGE:
+ ath6k_redistribute_credits(cred_info, ep_dist_list);
+ break;
+ default:
+ break;
+ }
+
+ WARN_ON(cred_info->cur_free_credits > cred_info->total_avail_credits);
+ WARN_ON(cred_info->cur_free_credits < 0);
+}
+
+void disconnect_timer_handler(unsigned long ptr)
+{
+ struct net_device *dev = (struct net_device *)ptr;
+ struct ath6kl *ar = ath6kl_priv(dev);
+
+ ath6kl_init_profile_info(ar);
+ ath6kl_disconnect(ar);
+}
+
+void ath6kl_disconnect(struct ath6kl *ar)
+{
+ if (test_bit(CONNECTED, &ar->flag) ||
+ test_bit(CONNECT_PEND, &ar->flag)) {
+ ath6kl_wmi_disconnect_cmd(ar->wmi);
+ /*
+ * Disconnect command is issued, clear the connect pending
+ * flag. The connected flag will be cleared in
+ * disconnect event notification.
+ */
+ clear_bit(CONNECT_PEND, &ar->flag);
+ }
+}
+
+/* WMI Event handlers */
+
+static const char *get_hw_id_string(u32 id)
+{
+ switch (id) {
+ case AR6003_REV1_VERSION:
+ return "1.0";
+ case AR6003_REV2_VERSION:
+ return "2.0";
+ case AR6003_REV3_VERSION:
+ return "2.1.1";
+ default:
+ return "unknown";
+ }
+}
+
+void ath6kl_ready_event(void *devt, u8 *datap, u32 sw_ver, u32 abi_ver)
+{
+ struct ath6kl *ar = devt;
+ struct net_device *dev = ar->net_dev;
+
+ memcpy(dev->dev_addr, datap, ETH_ALEN);
+ ath6kl_dbg(ATH6KL_DBG_TRC, "%s: mac addr = %pM\n",
+ __func__, dev->dev_addr);
+
+ ar->version.wlan_ver = sw_ver;
+ ar->version.abi_ver = abi_ver;
+
+ snprintf(ar->wdev->wiphy->fw_version,
+ sizeof(ar->wdev->wiphy->fw_version),
+ "%u.%u.%u.%u",
+ (ar->version.wlan_ver & 0xf0000000) >> 28,
+ (ar->version.wlan_ver & 0x0f000000) >> 24,
+ (ar->version.wlan_ver & 0x00ff0000) >> 16,
+ (ar->version.wlan_ver & 0x0000ffff));
+
+ /* indicate to the waiting thread that the ready event was received */
+ set_bit(WMI_READY, &ar->flag);
+ wake_up(&ar->event_wq);
+
+ ath6kl_info("hw %s fw %s\n",
+ get_hw_id_string(ar->wdev->wiphy->hw_version),
+ ar->wdev->wiphy->fw_version);
+}
+
+void ath6kl_scan_complete_evt(struct ath6kl *ar, int status)
+{
+ ath6kl_cfg80211_scan_complete_event(ar, status);
+
+ if (!ar->usr_bss_filter)
+ ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_SCAN, "scan complete: %d\n", status);
+}
+
+void ath6kl_connect_event(struct ath6kl *ar, u16 channel, u8 *bssid,
+ u16 listen_int, u16 beacon_int,
+ enum network_type net_type, u8 beacon_ie_len,
+ u8 assoc_req_len, u8 assoc_resp_len,
+ u8 *assoc_info)
+{
+ unsigned long flags;
+
+ if (ar->nw_type == AP_NETWORK) {
+ ath6kl_connect_ap_mode(ar, channel, bssid, listen_int,
+ beacon_int, assoc_resp_len,
+ assoc_info);
+ return;
+ }
+
+ ath6kl_cfg80211_connect_event(ar, channel, bssid,
+ listen_int, beacon_int,
+ net_type, beacon_ie_len,
+ assoc_req_len, assoc_resp_len,
+ assoc_info);
+
+ memcpy(ar->bssid, bssid, sizeof(ar->bssid));
+ ar->bss_ch = channel;
+
+ if ((ar->nw_type == INFRA_NETWORK))
+ ath6kl_wmi_listeninterval_cmd(ar->wmi, ar->listen_intvl_t,
+ ar->listen_intvl_b);
+
+ netif_wake_queue(ar->net_dev);
+
+ /* Update connect & link status atomically */
+ spin_lock_irqsave(&ar->lock, flags);
+ set_bit(CONNECTED, &ar->flag);
+ clear_bit(CONNECT_PEND, &ar->flag);
+ netif_carrier_on(ar->net_dev);
+ spin_unlock_irqrestore(&ar->lock, flags);
+
+ aggr_reset_state(ar->aggr_cntxt);
+ ar->reconnect_flag = 0;
+
+ if ((ar->nw_type == ADHOC_NETWORK) && ar->ibss_ps_enable) {
+ memset(ar->node_map, 0, sizeof(ar->node_map));
+ ar->node_num = 0;
+ ar->next_ep_id = ENDPOINT_2;
+ }
+
+ if (!ar->usr_bss_filter)
+ ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
+}
+
+void ath6kl_tkip_micerr_event(struct ath6kl *ar, u8 keyid, bool ismcast)
+{
+ struct ath6kl_sta *sta;
+ u8 tsc[6];
+ /*
+ * For AP case, keyid will have aid of STA which sent pkt with
+ * MIC error. Use this aid to get MAC & send it to hostapd.
+ */
+ if (ar->nw_type == AP_NETWORK) {
+ sta = ath6kl_find_sta_by_aid(ar, (keyid >> 2));
+ if (!sta)
+ return;
+
+ ath6kl_dbg(ATH6KL_DBG_TRC,
+ "ap tkip mic error received from aid=%d\n", keyid);
+
+ memset(tsc, 0, sizeof(tsc)); /* FIX: get correct TSC */
+ cfg80211_michael_mic_failure(ar->net_dev, sta->mac,
+ NL80211_KEYTYPE_PAIRWISE, keyid,
+ tsc, GFP_KERNEL);
+ } else
+ ath6kl_cfg80211_tkip_micerr_event(ar, keyid, ismcast);
+
+}
+
+static void ath6kl_update_target_stats(struct ath6kl *ar, u8 *ptr, u32 len)
+{
+ struct wmi_target_stats *tgt_stats =
+ (struct wmi_target_stats *) ptr;
+ struct target_stats *stats = &ar->target_stats;
+ struct tkip_ccmp_stats *ccmp_stats;
+ struct bss *conn_bss = NULL;
+ struct cserv_stats *c_stats;
+ u8 ac;
+
+ if (len < sizeof(*tgt_stats))
+ return;
+
+ /* update the RSSI of the connected bss */
+ if (test_bit(CONNECTED, &ar->flag)) {
+ conn_bss = ath6kl_wmi_find_node(ar->wmi, ar->bssid);
+ if (conn_bss) {
+ c_stats = &tgt_stats->cserv_stats;
+ conn_bss->ni_rssi =
+ a_sle16_to_cpu(c_stats->cs_ave_beacon_rssi);
+ conn_bss->ni_snr =
+ tgt_stats->cserv_stats.cs_ave_beacon_snr;
+ ath6kl_wmi_node_return(ar->wmi, conn_bss);
+ }
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_TRC, "updating target stats\n");
+
+ stats->tx_pkt += le32_to_cpu(tgt_stats->stats.tx.pkt);
+ stats->tx_byte += le32_to_cpu(tgt_stats->stats.tx.byte);
+ stats->tx_ucast_pkt += le32_to_cpu(tgt_stats->stats.tx.ucast_pkt);
+ stats->tx_ucast_byte += le32_to_cpu(tgt_stats->stats.tx.ucast_byte);
+ stats->tx_mcast_pkt += le32_to_cpu(tgt_stats->stats.tx.mcast_pkt);
+ stats->tx_mcast_byte += le32_to_cpu(tgt_stats->stats.tx.mcast_byte);
+ stats->tx_bcast_pkt += le32_to_cpu(tgt_stats->stats.tx.bcast_pkt);
+ stats->tx_bcast_byte += le32_to_cpu(tgt_stats->stats.tx.bcast_byte);
+ stats->tx_rts_success_cnt +=
+ le32_to_cpu(tgt_stats->stats.tx.rts_success_cnt);
+
+ for (ac = 0; ac < WMM_NUM_AC; ac++)
+ stats->tx_pkt_per_ac[ac] +=
+ le32_to_cpu(tgt_stats->stats.tx.pkt_per_ac[ac]);
+
+ stats->tx_err += le32_to_cpu(tgt_stats->stats.tx.err);
+ stats->tx_fail_cnt += le32_to_cpu(tgt_stats->stats.tx.fail_cnt);
+ stats->tx_retry_cnt += le32_to_cpu(tgt_stats->stats.tx.retry_cnt);
+ stats->tx_mult_retry_cnt +=
+ le32_to_cpu(tgt_stats->stats.tx.mult_retry_cnt);
+ stats->tx_rts_fail_cnt +=
+ le32_to_cpu(tgt_stats->stats.tx.rts_fail_cnt);
+ stats->tx_ucast_rate =
+ ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.tx.ucast_rate));
+
+ stats->rx_pkt += le32_to_cpu(tgt_stats->stats.rx.pkt);
+ stats->rx_byte += le32_to_cpu(tgt_stats->stats.rx.byte);
+ stats->rx_ucast_pkt += le32_to_cpu(tgt_stats->stats.rx.ucast_pkt);
+ stats->rx_ucast_byte += le32_to_cpu(tgt_stats->stats.rx.ucast_byte);
+ stats->rx_mcast_pkt += le32_to_cpu(tgt_stats->stats.rx.mcast_pkt);
+ stats->rx_mcast_byte += le32_to_cpu(tgt_stats->stats.rx.mcast_byte);
+ stats->rx_bcast_pkt += le32_to_cpu(tgt_stats->stats.rx.bcast_pkt);
+ stats->rx_bcast_byte += le32_to_cpu(tgt_stats->stats.rx.bcast_byte);
+ stats->rx_frgment_pkt += le32_to_cpu(tgt_stats->stats.rx.frgment_pkt);
+ stats->rx_err += le32_to_cpu(tgt_stats->stats.rx.err);
+ stats->rx_crc_err += le32_to_cpu(tgt_stats->stats.rx.crc_err);
+ stats->rx_key_cache_miss +=
+ le32_to_cpu(tgt_stats->stats.rx.key_cache_miss);
+ stats->rx_decrypt_err += le32_to_cpu(tgt_stats->stats.rx.decrypt_err);
+ stats->rx_dupl_frame += le32_to_cpu(tgt_stats->stats.rx.dupl_frame);
+ stats->rx_ucast_rate =
+ ath6kl_wmi_get_rate(a_sle32_to_cpu(tgt_stats->stats.rx.ucast_rate));
+
+ ccmp_stats = &tgt_stats->stats.tkip_ccmp_stats;
+
+ stats->tkip_local_mic_fail +=
+ le32_to_cpu(ccmp_stats->tkip_local_mic_fail);
+ stats->tkip_cnter_measures_invoked +=
+ le32_to_cpu(ccmp_stats->tkip_cnter_measures_invoked);
+ stats->tkip_fmt_err += le32_to_cpu(ccmp_stats->tkip_fmt_err);
+
+ stats->ccmp_fmt_err += le32_to_cpu(ccmp_stats->ccmp_fmt_err);
+ stats->ccmp_replays += le32_to_cpu(ccmp_stats->ccmp_replays);
+
+ stats->pwr_save_fail_cnt +=
+ le32_to_cpu(tgt_stats->pm_stats.pwr_save_failure_cnt);
+ stats->noise_floor_calib =
+ a_sle32_to_cpu(tgt_stats->noise_floor_calib);
+
+ stats->cs_bmiss_cnt +=
+ le32_to_cpu(tgt_stats->cserv_stats.cs_bmiss_cnt);
+ stats->cs_low_rssi_cnt +=
+ le32_to_cpu(tgt_stats->cserv_stats.cs_low_rssi_cnt);
+ stats->cs_connect_cnt +=
+ le16_to_cpu(tgt_stats->cserv_stats.cs_connect_cnt);
+ stats->cs_discon_cnt +=
+ le16_to_cpu(tgt_stats->cserv_stats.cs_discon_cnt);
+
+ stats->cs_ave_beacon_rssi =
+ a_sle16_to_cpu(tgt_stats->cserv_stats.cs_ave_beacon_rssi);
+
+ stats->cs_last_roam_msec =
+ tgt_stats->cserv_stats.cs_last_roam_msec;
+ stats->cs_snr = tgt_stats->cserv_stats.cs_snr;
+ stats->cs_rssi = a_sle16_to_cpu(tgt_stats->cserv_stats.cs_rssi);
+
+ stats->lq_val = le32_to_cpu(tgt_stats->lq_val);
+
+ stats->wow_pkt_dropped +=
+ le32_to_cpu(tgt_stats->wow_stats.wow_pkt_dropped);
+ stats->wow_host_pkt_wakeups +=
+ tgt_stats->wow_stats.wow_host_pkt_wakeups;
+ stats->wow_host_evt_wakeups +=
+ tgt_stats->wow_stats.wow_host_evt_wakeups;
+ stats->wow_evt_discarded +=
+ le16_to_cpu(tgt_stats->wow_stats.wow_evt_discarded);
+
+ if (test_bit(STATS_UPDATE_PEND, &ar->flag)) {
+ clear_bit(STATS_UPDATE_PEND, &ar->flag);
+ wake_up(&ar->event_wq);
+ }
+}
+
+static void ath6kl_add_le32(__le32 *var, __le32 val)
+{
+ *var = cpu_to_le32(le32_to_cpu(*var) + le32_to_cpu(val));
+}
+
+void ath6kl_tgt_stats_event(struct ath6kl *ar, u8 *ptr, u32 len)
+{
+ struct wmi_ap_mode_stat *p = (struct wmi_ap_mode_stat *) ptr;
+ struct wmi_ap_mode_stat *ap = &ar->ap_stats;
+ struct wmi_per_sta_stat *st_ap, *st_p;
+ u8 ac;
+
+ if (ar->nw_type == AP_NETWORK) {
+ if (len < sizeof(*p))
+ return;
+
+ for (ac = 0; ac < AP_MAX_NUM_STA; ac++) {
+ st_ap = &ap->sta[ac];
+ st_p = &p->sta[ac];
+
+ ath6kl_add_le32(&st_ap->tx_bytes, st_p->tx_bytes);
+ ath6kl_add_le32(&st_ap->tx_pkts, st_p->tx_pkts);
+ ath6kl_add_le32(&st_ap->tx_error, st_p->tx_error);
+ ath6kl_add_le32(&st_ap->tx_discard, st_p->tx_discard);
+ ath6kl_add_le32(&st_ap->rx_bytes, st_p->rx_bytes);
+ ath6kl_add_le32(&st_ap->rx_pkts, st_p->rx_pkts);
+ ath6kl_add_le32(&st_ap->rx_error, st_p->rx_error);
+ ath6kl_add_le32(&st_ap->rx_discard, st_p->rx_discard);
+ }
+
+ } else {
+ ath6kl_update_target_stats(ar, ptr, len);
+ }
+}
+
+void ath6kl_wakeup_event(void *dev)
+{
+ struct ath6kl *ar = (struct ath6kl *) dev;
+
+ wake_up(&ar->event_wq);
+}
+
+void ath6kl_txpwr_rx_evt(void *devt, u8 tx_pwr)
+{
+ struct ath6kl *ar = (struct ath6kl *) devt;
+
+ ar->tx_pwr = tx_pwr;
+ wake_up(&ar->event_wq);
+}
+
+void ath6kl_pspoll_event(struct ath6kl *ar, u8 aid)
+{
+ struct ath6kl_sta *conn;
+ struct sk_buff *skb;
+ bool psq_empty = false;
+
+ conn = ath6kl_find_sta_by_aid(ar, aid);
+
+ if (!conn)
+ return;
+ /*
+ * Send out a packet queued on ps queue. When the ps queue
+ * becomes empty update the PVB for this station.
+ */
+ spin_lock_bh(&conn->psq_lock);
+ psq_empty = skb_queue_empty(&conn->psq);
+ spin_unlock_bh(&conn->psq_lock);
+
+ if (psq_empty)
+ /* TODO: Send out a NULL data frame */
+ return;
+
+ spin_lock_bh(&conn->psq_lock);
+ skb = skb_dequeue(&conn->psq);
+ spin_unlock_bh(&conn->psq_lock);
+
+ conn->sta_flags |= STA_PS_POLLED;
+ ath6kl_data_tx(skb, ar->net_dev);
+ conn->sta_flags &= ~STA_PS_POLLED;
+
+ spin_lock_bh(&conn->psq_lock);
+ psq_empty = skb_queue_empty(&conn->psq);
+ spin_unlock_bh(&conn->psq_lock);
+
+ if (psq_empty)
+ ath6kl_wmi_set_pvb_cmd(ar->wmi, conn->aid, 0);
+}
+
+void ath6kl_dtimexpiry_event(struct ath6kl *ar)
+{
+ bool mcastq_empty = false;
+ struct sk_buff *skb;
+
+ /*
+ * If there are no associated STAs, ignore the DTIM expiry event.
+ * There can be potential race conditions where the last associated
+ * STA may disconnect & before the host could clear the 'Indicate
+ * DTIM' request to the firmware, the firmware would have just
+ * indicated a DTIM expiry event. The race is between 'clear DTIM
+ * expiry cmd' going from the host to the firmware & the DTIM
+ * expiry event happening from the firmware to the host.
+ */
+ if (!ar->sta_list_index)
+ return;
+
+ spin_lock_bh(&ar->mcastpsq_lock);
+ mcastq_empty = skb_queue_empty(&ar->mcastpsq);
+ spin_unlock_bh(&ar->mcastpsq_lock);
+
+ if (mcastq_empty)
+ return;
+
+ /* set the STA flag to dtim_expired for the frame to go out */
+ set_bit(DTIM_EXPIRED, &ar->flag);
+
+ spin_lock_bh(&ar->mcastpsq_lock);
+ while ((skb = skb_dequeue(&ar->mcastpsq)) != NULL) {
+ spin_unlock_bh(&ar->mcastpsq_lock);
+
+ ath6kl_data_tx(skb, ar->net_dev);
+
+ spin_lock_bh(&ar->mcastpsq_lock);
+ }
+ spin_unlock_bh(&ar->mcastpsq_lock);
+
+ clear_bit(DTIM_EXPIRED, &ar->flag);
+
+ /* clear the LSB of the BitMapCtl field of the TIM IE */
+ ath6kl_wmi_set_pvb_cmd(ar->wmi, MCAST_AID, 0);
+}
+
+void ath6kl_disconnect_event(struct ath6kl *ar, u8 reason, u8 *bssid,
+ u8 assoc_resp_len, u8 *assoc_info,
+ u16 prot_reason_status)
+{
+ struct bss *wmi_ssid_node = NULL;
+ unsigned long flags;
+
+ if (ar->nw_type == AP_NETWORK) {
+ if (!ath6kl_remove_sta(ar, bssid, prot_reason_status))
+ return;
+
+ /* if no more associated STAs, empty the mcast PS q */
+ if (ar->sta_list_index == 0) {
+ spin_lock_bh(&ar->mcastpsq_lock);
+ skb_queue_purge(&ar->mcastpsq);
+ spin_unlock_bh(&ar->mcastpsq_lock);
+
+ /* clear the LSB of the TIM IE's BitMapCtl field */
+ if (test_bit(WMI_READY, &ar->flag))
+ ath6kl_wmi_set_pvb_cmd(ar->wmi, MCAST_AID, 0);
+ }
+
+ if (!is_broadcast_ether_addr(bssid)) {
+ /* send event to application */
+ cfg80211_del_sta(ar->net_dev, bssid, GFP_KERNEL);
+ }
+
+ clear_bit(CONNECTED, &ar->flag);
+ return;
+ }
+
+ ath6kl_cfg80211_disconnect_event(ar, reason, bssid,
+ assoc_resp_len, assoc_info,
+ prot_reason_status);
+
+ aggr_reset_state(ar->aggr_cntxt);
+
+ del_timer(&ar->disconnect_timer);
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_CONNECT,
+ "disconnect reason is %d\n", reason);
+
+ /*
+ * If the event is due to disconnect cmd from the host, only they
+ * the target would stop trying to connect. Under any other
+ * condition, target would keep trying to connect.
+ */
+ if (reason == DISCONNECT_CMD) {
+ if (!ar->usr_bss_filter && test_bit(WMI_READY, &ar->flag))
+ ath6kl_wmi_bssfilter_cmd(ar->wmi, NONE_BSS_FILTER, 0);
+ } else {
+ set_bit(CONNECT_PEND, &ar->flag);
+ if (((reason == ASSOC_FAILED) &&
+ (prot_reason_status == 0x11)) ||
+ ((reason == ASSOC_FAILED) && (prot_reason_status == 0x0)
+ && (ar->reconnect_flag == 1))) {
+ set_bit(CONNECTED, &ar->flag);
+ return;
+ }
+ }
+
+ if ((reason == NO_NETWORK_AVAIL) && test_bit(WMI_READY, &ar->flag)) {
+ ath6kl_wmi_node_free(ar->wmi, bssid);
+
+ /*
+ * In case any other same SSID nodes are present remove it,
+ * since those nodes also not available now.
+ */
+ do {
+ /*
+ * Find the nodes based on SSID and remove it
+ *
+ * Note: This case will not work out for
+ * Hidden-SSID
+ */
+ wmi_ssid_node = ath6kl_wmi_find_ssid_node(ar->wmi,
+ ar->ssid,
+ ar->ssid_len,
+ false,
+ true);
+
+ if (wmi_ssid_node)
+ ath6kl_wmi_node_free(ar->wmi,
+ wmi_ssid_node->ni_macaddr);
+
+ } while (wmi_ssid_node);
+ }
+
+ /* update connect & link status atomically */
+ spin_lock_irqsave(&ar->lock, flags);
+ clear_bit(CONNECTED, &ar->flag);
+ netif_carrier_off(ar->net_dev);
+ spin_unlock_irqrestore(&ar->lock, flags);
+
+ if ((reason != CSERV_DISCONNECT) || (ar->reconnect_flag != 1))
+ ar->reconnect_flag = 0;
+
+ if (reason != CSERV_DISCONNECT)
+ ar->user_key_ctrl = 0;
+
+ netif_stop_queue(ar->net_dev);
+ memset(ar->bssid, 0, sizeof(ar->bssid));
+ ar->bss_ch = 0;
+
+ ath6kl_tx_data_cleanup(ar);
+}
+
+static int ath6kl_open(struct net_device *dev)
+{
+ struct ath6kl *ar = ath6kl_priv(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&ar->lock, flags);
+
+ ar->wlan_state = WLAN_ENABLED;
+
+ if (test_bit(CONNECTED, &ar->flag)) {
+ netif_carrier_on(dev);
+ netif_wake_queue(dev);
+ } else
+ netif_carrier_off(dev);
+
+ spin_unlock_irqrestore(&ar->lock, flags);
+
+ return 0;
+}
+
+static int ath6kl_close(struct net_device *dev)
+{
+ struct ath6kl *ar = ath6kl_priv(dev);
+
+ netif_stop_queue(dev);
+
+ ath6kl_disconnect(ar);
+
+ if (test_bit(WMI_READY, &ar->flag)) {
+ if (ath6kl_wmi_scanparams_cmd(ar->wmi, 0xFFFF, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0))
+ return -EIO;
+
+ ar->wlan_state = WLAN_DISABLED;
+ }
+
+ ath6kl_cfg80211_scan_complete_event(ar, -ECANCELED);
+
+ return 0;
+}
+
+static struct net_device_stats *ath6kl_get_stats(struct net_device *dev)
+{
+ struct ath6kl *ar = ath6kl_priv(dev);
+
+ return &ar->net_stats;
+}
+
+static struct net_device_ops ath6kl_netdev_ops = {
+ .ndo_open = ath6kl_open,
+ .ndo_stop = ath6kl_close,
+ .ndo_start_xmit = ath6kl_data_tx,
+ .ndo_get_stats = ath6kl_get_stats,
+};
+
+void init_netdev(struct net_device *dev)
+{
+ dev->netdev_ops = &ath6kl_netdev_ops;
+ dev->watchdog_timeo = ATH6KL_TX_TIMEOUT;
+
+ dev->needed_headroom = ETH_HLEN;
+ dev->needed_headroom += sizeof(struct ath6kl_llc_snap_hdr) +
+ sizeof(struct wmi_data_hdr) + HTC_HDR_LENGTH
+ + WMI_MAX_TX_META_SZ;
+
+ return;
+}
diff --git a/drivers/net/wireless/ath/ath6kl/node.c b/drivers/net/wireless/ath/ath6kl/node.c
new file mode 100644
index 000000000000..b0f9ba2e463c
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/node.c
@@ -0,0 +1,238 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications Inc.
+ *
+ * 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 "htc.h"
+#include "wmi.h"
+#include "debug.h"
+
+struct bss *wlan_node_alloc(int wh_size)
+{
+ struct bss *ni;
+
+ ni = kzalloc(sizeof(struct bss), GFP_ATOMIC);
+
+ if ((ni != NULL) && wh_size) {
+ ni->ni_buf = kmalloc(wh_size, GFP_ATOMIC);
+ if (ni->ni_buf == NULL) {
+ kfree(ni);
+ return NULL;
+ }
+ }
+
+ return ni;
+}
+
+void wlan_node_free(struct bss *ni)
+{
+ kfree(ni->ni_buf);
+ kfree(ni);
+}
+
+void wlan_setup_node(struct ath6kl_node_table *nt, struct bss *ni,
+ const u8 *mac_addr)
+{
+ int hash;
+
+ memcpy(ni->ni_macaddr, mac_addr, ETH_ALEN);
+ hash = ATH6KL_NODE_HASH(mac_addr);
+ ni->ni_refcnt = 1;
+
+ ni->ni_tstamp = jiffies_to_msecs(jiffies);
+ ni->ni_actcnt = WLAN_NODE_INACT_CNT;
+
+ spin_lock_bh(&nt->nt_nodelock);
+
+ /* insert at the end of the node list */
+ ni->ni_list_next = NULL;
+ ni->ni_list_prev = nt->nt_node_last;
+ if (nt->nt_node_last != NULL)
+ nt->nt_node_last->ni_list_next = ni;
+
+ nt->nt_node_last = ni;
+ if (nt->nt_node_first == NULL)
+ nt->nt_node_first = ni;
+
+ /* insert into the hash list */
+ ni->ni_hash_next = nt->nt_hash[hash];
+ if (ni->ni_hash_next != NULL)
+ nt->nt_hash[hash]->ni_hash_prev = ni;
+
+ ni->ni_hash_prev = NULL;
+ nt->nt_hash[hash] = ni;
+
+ spin_unlock_bh(&nt->nt_nodelock);
+}
+
+struct bss *wlan_find_node(struct ath6kl_node_table *nt,
+ const u8 *mac_addr)
+{
+ struct bss *ni, *found_ni = NULL;
+ int hash;
+
+ spin_lock_bh(&nt->nt_nodelock);
+
+ hash = ATH6KL_NODE_HASH(mac_addr);
+ for (ni = nt->nt_hash[hash]; ni; ni = ni->ni_hash_next) {
+ if (memcmp(ni->ni_macaddr, mac_addr, ETH_ALEN) == 0) {
+ ni->ni_refcnt++;
+ found_ni = ni;
+ break;
+ }
+ }
+
+ spin_unlock_bh(&nt->nt_nodelock);
+
+ return found_ni;
+}
+
+void wlan_node_reclaim(struct ath6kl_node_table *nt, struct bss *ni)
+{
+ int hash;
+
+ spin_lock_bh(&nt->nt_nodelock);
+
+ if (ni->ni_list_prev == NULL)
+ /* fix list head */
+ nt->nt_node_first = ni->ni_list_next;
+ else
+ ni->ni_list_prev->ni_list_next = ni->ni_list_next;
+
+ if (ni->ni_list_next == NULL)
+ /* fix list tail */
+ nt->nt_node_last = ni->ni_list_prev;
+ else
+ ni->ni_list_next->ni_list_prev = ni->ni_list_prev;
+
+ if (ni->ni_hash_prev == NULL) {
+ /* first in list so fix the list head */
+ hash = ATH6KL_NODE_HASH(ni->ni_macaddr);
+ nt->nt_hash[hash] = ni->ni_hash_next;
+ } else {
+ ni->ni_hash_prev->ni_hash_next = ni->ni_hash_next;
+ }
+
+ if (ni->ni_hash_next != NULL)
+ ni->ni_hash_next->ni_hash_prev = ni->ni_hash_prev;
+
+ wlan_node_free(ni);
+
+ spin_unlock_bh(&nt->nt_nodelock);
+}
+
+static void wlan_node_dec_free(struct bss *ni)
+{
+ if ((ni->ni_refcnt--) == 1)
+ wlan_node_free(ni);
+}
+
+void wlan_free_allnodes(struct ath6kl_node_table *nt)
+{
+ struct bss *ni;
+
+ while ((ni = nt->nt_node_first) != NULL)
+ wlan_node_reclaim(nt, ni);
+}
+
+void wlan_iterate_nodes(struct ath6kl_node_table *nt,
+ void (*f) (void *arg, struct bss *), void *arg)
+{
+ struct bss *ni;
+
+ spin_lock_bh(&nt->nt_nodelock);
+ for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
+ ni->ni_refcnt++;
+ (*f) (arg, ni);
+ wlan_node_dec_free(ni);
+ }
+ spin_unlock_bh(&nt->nt_nodelock);
+}
+
+void wlan_node_table_init(void *wmi, struct ath6kl_node_table *nt)
+{
+ ath6kl_dbg(ATH6KL_DBG_WLAN_NODE, "node table = 0x%lx\n",
+ (unsigned long)nt);
+
+ memset(nt, 0, sizeof(struct ath6kl_node_table));
+
+ spin_lock_init(&nt->nt_nodelock);
+
+ nt->nt_wmi = wmi;
+ nt->nt_node_age = WLAN_NODE_INACT_TIMEOUT_MSEC;
+}
+
+void wlan_refresh_inactive_nodes(struct ath6kl_node_table *nt)
+{
+ struct bss *bss;
+ u8 my_bssid[ETH_ALEN];
+ u32 now;
+
+ ath6kl_wmi_get_current_bssid(nt->nt_wmi, my_bssid);
+
+ now = jiffies_to_msecs(jiffies);
+ bss = nt->nt_node_first;
+ while (bss != NULL) {
+ /* refresh all nodes except the current bss */
+ if (memcmp(my_bssid, bss->ni_macaddr, sizeof(my_bssid)) != 0) {
+ if (((now - bss->ni_tstamp) > nt->nt_node_age)
+ || --bss->ni_actcnt == 0) {
+ wlan_node_reclaim(nt, bss);
+ }
+ }
+ bss = bss->ni_list_next;
+ }
+}
+
+void wlan_node_table_cleanup(struct ath6kl_node_table *nt)
+{
+ wlan_free_allnodes(nt);
+}
+
+struct bss *wlan_find_ssid_node(struct ath6kl_node_table *nt, u8 * ssid,
+ u32 ssid_len, bool is_wpa2, bool match_ssid)
+{
+ struct bss *ni, *found_ni = NULL;
+ u8 *ie_ssid;
+
+ spin_lock_bh(&nt->nt_nodelock);
+
+ for (ni = nt->nt_node_first; ni; ni = ni->ni_list_next) {
+
+ ie_ssid = ni->ni_cie.ie_ssid;
+
+ if ((ie_ssid[1] <= IEEE80211_MAX_SSID_LEN) &&
+ (memcmp(ssid, &ie_ssid[2], ssid_len) == 0)) {
+
+ if (match_ssid ||
+ (is_wpa2 && ni->ni_cie.ie_rsn != NULL) ||
+ (!is_wpa2 && ni->ni_cie.ie_wpa != NULL)) {
+ ni->ni_refcnt++;
+ found_ni = ni;
+ break;
+ }
+ }
+ }
+
+ spin_unlock_bh(&nt->nt_nodelock);
+
+ return found_ni;
+}
+
+void wlan_node_return(struct ath6kl_node_table *nt, struct bss *ni)
+{
+ spin_lock_bh(&nt->nt_nodelock);
+ wlan_node_dec_free(ni);
+ spin_unlock_bh(&nt->nt_nodelock);
+}
diff --git a/drivers/net/wireless/ath/ath6kl/sdio.c b/drivers/net/wireless/ath/ath6kl/sdio.c
new file mode 100644
index 000000000000..b38732aaf41a
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/sdio.c
@@ -0,0 +1,853 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications Inc.
+ *
+ * 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 <linux/mmc/card.h>
+#include <linux/mmc/mmc.h>
+#include <linux/mmc/host.h>
+#include <linux/mmc/sdio_func.h>
+#include <linux/mmc/sdio_ids.h>
+#include <linux/mmc/sdio.h>
+#include <linux/mmc/sd.h>
+#include "htc_hif.h"
+#include "hif-ops.h"
+#include "target.h"
+#include "debug.h"
+
+struct ath6kl_sdio {
+ struct sdio_func *func;
+
+ spinlock_t lock;
+
+ /* free list */
+ struct list_head bus_req_freeq;
+
+ /* available bus requests */
+ struct bus_request bus_req[BUS_REQUEST_MAX_NUM];
+
+ struct ath6kl *ar;
+ u8 *dma_buffer;
+
+ /* scatter request list head */
+ struct list_head scat_req;
+
+ spinlock_t scat_lock;
+ bool is_disabled;
+ atomic_t irq_handling;
+ const struct sdio_device_id *id;
+ struct work_struct wr_async_work;
+ struct list_head wr_asyncq;
+ spinlock_t wr_async_lock;
+};
+
+#define CMD53_ARG_READ 0
+#define CMD53_ARG_WRITE 1
+#define CMD53_ARG_BLOCK_BASIS 1
+#define CMD53_ARG_FIXED_ADDRESS 0
+#define CMD53_ARG_INCR_ADDRESS 1
+
+static inline struct ath6kl_sdio *ath6kl_sdio_priv(struct ath6kl *ar)
+{
+ return ar->hif_priv;
+}
+
+/*
+ * Macro to check if DMA buffer is WORD-aligned and DMA-able.
+ * Most host controllers assume the buffer is DMA'able and will
+ * bug-check otherwise (i.e. buffers on the stack). virt_addr_valid
+ * check fails on stack memory.
+ */
+static inline bool buf_needs_bounce(u8 *buf)
+{
+ return ((unsigned long) buf & 0x3) || !virt_addr_valid(buf);
+}
+
+static void ath6kl_sdio_set_mbox_info(struct ath6kl *ar)
+{
+ struct ath6kl_mbox_info *mbox_info = &ar->mbox_info;
+
+ /* EP1 has an extended range */
+ mbox_info->htc_addr = HIF_MBOX_BASE_ADDR;
+ mbox_info->htc_ext_addr = HIF_MBOX0_EXT_BASE_ADDR;
+ mbox_info->htc_ext_sz = HIF_MBOX0_EXT_WIDTH;
+ mbox_info->block_size = HIF_MBOX_BLOCK_SIZE;
+ mbox_info->gmbox_addr = HIF_GMBOX_BASE_ADDR;
+ mbox_info->gmbox_sz = HIF_GMBOX_WIDTH;
+}
+
+static inline void ath6kl_sdio_set_cmd53_arg(u32 *arg, u8 rw, u8 func,
+ u8 mode, u8 opcode, u32 addr,
+ u16 blksz)
+{
+ *arg = (((rw & 1) << 31) |
+ ((func & 0x7) << 28) |
+ ((mode & 1) << 27) |
+ ((opcode & 1) << 26) |
+ ((addr & 0x1FFFF) << 9) |
+ (blksz & 0x1FF));
+}
+
+static inline void ath6kl_sdio_set_cmd52_arg(u32 *arg, u8 write, u8 raw,
+ unsigned int address,
+ unsigned char val)
+{
+ const u8 func = 0;
+
+ *arg = ((write & 1) << 31) |
+ ((func & 0x7) << 28) |
+ ((raw & 1) << 27) |
+ (1 << 26) |
+ ((address & 0x1FFFF) << 9) |
+ (1 << 8) |
+ (val & 0xFF);
+}
+
+static int ath6kl_sdio_func0_cmd52_wr_byte(struct mmc_card *card,
+ unsigned int address,
+ unsigned char byte)
+{
+ struct mmc_command io_cmd;
+
+ memset(&io_cmd, 0, sizeof(io_cmd));
+ ath6kl_sdio_set_cmd52_arg(&io_cmd.arg, 1, 0, address, byte);
+ io_cmd.opcode = SD_IO_RW_DIRECT;
+ io_cmd.flags = MMC_RSP_R5 | MMC_CMD_AC;
+
+ return mmc_wait_for_cmd(card->host, &io_cmd, 0);
+}
+
+static struct bus_request *ath6kl_sdio_alloc_busreq(struct ath6kl_sdio *ar_sdio)
+{
+ struct bus_request *bus_req;
+ unsigned long flag;
+
+ spin_lock_irqsave(&ar_sdio->lock, flag);
+
+ if (list_empty(&ar_sdio->bus_req_freeq)) {
+ spin_unlock_irqrestore(&ar_sdio->lock, flag);
+ return NULL;
+ }
+
+ bus_req = list_first_entry(&ar_sdio->bus_req_freeq,
+ struct bus_request, list);
+ list_del(&bus_req->list);
+
+ spin_unlock_irqrestore(&ar_sdio->lock, flag);
+ ath6kl_dbg(ATH6KL_DBG_TRC, "%s: bus request 0x%p\n", __func__, bus_req);
+
+ return bus_req;
+}
+
+static void ath6kl_sdio_free_bus_req(struct ath6kl_sdio *ar_sdio,
+ struct bus_request *bus_req)
+{
+ unsigned long flag;
+
+ ath6kl_dbg(ATH6KL_DBG_TRC, "%s: bus request 0x%p\n", __func__, bus_req);
+
+ spin_lock_irqsave(&ar_sdio->lock, flag);
+ list_add_tail(&bus_req->list, &ar_sdio->bus_req_freeq);
+ spin_unlock_irqrestore(&ar_sdio->lock, flag);
+}
+
+static void ath6kl_sdio_setup_scat_data(struct hif_scatter_req *scat_req,
+ struct hif_scatter_req_priv *s_req_priv,
+ struct mmc_data *data)
+{
+ struct scatterlist *sg;
+ int i;
+
+ data->blksz = HIF_MBOX_BLOCK_SIZE;
+ data->blocks = scat_req->len / HIF_MBOX_BLOCK_SIZE;
+
+ ath6kl_dbg(ATH6KL_DBG_SCATTER,
+ "hif-scatter: (%s) addr: 0x%X, (block len: %d, block count: %d) , (tot:%d,sg:%d)\n",
+ (scat_req->req & HIF_WRITE) ? "WR" : "RD", scat_req->addr,
+ data->blksz, data->blocks, scat_req->len,
+ scat_req->scat_entries);
+
+ data->flags = (scat_req->req & HIF_WRITE) ? MMC_DATA_WRITE :
+ MMC_DATA_READ;
+
+ /* fill SG entries */
+ sg = s_req_priv->sgentries;
+ sg_init_table(sg, scat_req->scat_entries);
+
+ /* assemble SG list */
+ for (i = 0; i < scat_req->scat_entries; i++, sg++) {
+ if ((unsigned long)scat_req->scat_list[i].buf & 0x3)
+ /*
+ * Some scatter engines can handle unaligned
+ * buffers, print this as informational only.
+ */
+ ath6kl_dbg(ATH6KL_DBG_SCATTER,
+ "(%s) scatter buffer is unaligned 0x%p\n",
+ scat_req->req & HIF_WRITE ? "WR" : "RD",
+ scat_req->scat_list[i].buf);
+
+ ath6kl_dbg(ATH6KL_DBG_SCATTER, "%d: addr:0x%p, len:%d\n",
+ i, scat_req->scat_list[i].buf,
+ scat_req->scat_list[i].len);
+
+ sg_set_buf(sg, scat_req->scat_list[i].buf,
+ scat_req->scat_list[i].len);
+ }
+
+ /* set scatter-gather table for request */
+ data->sg = s_req_priv->sgentries;
+ data->sg_len = scat_req->scat_entries;
+}
+
+static int ath6kl_sdio_scat_rw(struct ath6kl_sdio *ar_sdio,
+ struct bus_request *req)
+{
+ struct mmc_request mmc_req;
+ struct mmc_command cmd;
+ struct mmc_data data;
+ struct hif_scatter_req *scat_req;
+ u8 opcode, rw;
+ int status;
+
+ scat_req = req->scat_req;
+
+ memset(&mmc_req, 0, sizeof(struct mmc_request));
+ memset(&cmd, 0, sizeof(struct mmc_command));
+ memset(&data, 0, sizeof(struct mmc_data));
+
+ ath6kl_sdio_setup_scat_data(scat_req, scat_req->req_priv, &data);
+
+ opcode = (scat_req->req & HIF_FIXED_ADDRESS) ?
+ CMD53_ARG_FIXED_ADDRESS : CMD53_ARG_INCR_ADDRESS;
+
+ rw = (scat_req->req & HIF_WRITE) ? CMD53_ARG_WRITE : CMD53_ARG_READ;
+
+ /* Fixup the address so that the last byte will fall on MBOX EOM */
+ if (scat_req->req & HIF_WRITE) {
+ if (scat_req->addr == HIF_MBOX_BASE_ADDR)
+ scat_req->addr += HIF_MBOX_WIDTH - scat_req->len;
+ else
+ /* Uses extended address range */
+ scat_req->addr += HIF_MBOX0_EXT_WIDTH - scat_req->len;
+ }
+
+ /* set command argument */
+ ath6kl_sdio_set_cmd53_arg(&cmd.arg, rw, ar_sdio->func->num,
+ CMD53_ARG_BLOCK_BASIS, opcode, scat_req->addr,
+ data.blocks);
+
+ cmd.opcode = SD_IO_RW_EXTENDED;
+ cmd.flags = MMC_RSP_SPI_R5 | MMC_RSP_R5 | MMC_CMD_ADTC;
+
+ mmc_req.cmd = &cmd;
+ mmc_req.data = &data;
+
+ mmc_set_data_timeout(&data, ar_sdio->func->card);
+ /* synchronous call to process request */
+ mmc_wait_for_req(ar_sdio->func->card->host, &mmc_req);
+
+ status = cmd.error ? cmd.error : data.error;
+ scat_req->status = status;
+
+ if (scat_req->status)
+ ath6kl_err("Scatter write request failed:%d\n",
+ scat_req->status);
+
+ if (scat_req->req & HIF_ASYNCHRONOUS)
+ scat_req->complete(scat_req);
+
+ return status;
+}
+
+
+/* callback to issue a read-write scatter request */
+static int ath6kl_sdio_async_rw_scatter(struct ath6kl *ar,
+ struct hif_scatter_req *scat_req)
+{
+ struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+ struct hif_scatter_req_priv *req_priv = scat_req->req_priv;
+ u32 request = scat_req->req;
+ int status = 0;
+ unsigned long flags;
+
+ if (!scat_req->len)
+ return -EINVAL;
+
+ ath6kl_dbg(ATH6KL_DBG_SCATTER,
+ "hif-scatter: total len: %d scatter entries: %d\n",
+ scat_req->len, scat_req->scat_entries);
+
+ if (request & HIF_SYNCHRONOUS) {
+ sdio_claim_host(ar_sdio->func);
+ status = ath6kl_sdio_scat_rw(ar_sdio, req_priv->busrequest);
+ sdio_release_host(ar_sdio->func);
+ } else {
+ spin_lock_irqsave(&ar_sdio->wr_async_lock, flags);
+ list_add_tail(&req_priv->busrequest->list, &ar_sdio->wr_asyncq);
+ spin_unlock_irqrestore(&ar_sdio->wr_async_lock, flags);
+ queue_work(ar->ath6kl_wq, &ar_sdio->wr_async_work);
+ }
+
+ return status;
+}
+
+/* clean up scatter support */
+static void ath6kl_sdio_cleanup_scat_resource(struct ath6kl_sdio *ar_sdio)
+{
+ struct hif_scatter_req *s_req, *tmp_req;
+ unsigned long flag;
+
+ /* empty the free list */
+ spin_lock_irqsave(&ar_sdio->scat_lock, flag);
+ list_for_each_entry_safe(s_req, tmp_req, &ar_sdio->scat_req, list) {
+ list_del(&s_req->list);
+ spin_unlock_irqrestore(&ar_sdio->scat_lock, flag);
+
+ if (s_req->req_priv && s_req->req_priv->busrequest)
+ ath6kl_sdio_free_bus_req(ar_sdio,
+ s_req->req_priv->busrequest);
+ kfree(s_req->virt_dma_buf);
+ kfree(s_req->req_priv);
+ kfree(s_req);
+
+ spin_lock_irqsave(&ar_sdio->scat_lock, flag);
+ }
+ spin_unlock_irqrestore(&ar_sdio->scat_lock, flag);
+}
+
+/* setup of HIF scatter resources */
+static int ath6kl_sdio_setup_scat_resource(struct ath6kl_sdio *ar_sdio,
+ struct hif_dev_scat_sup_info *pinfo)
+{
+ struct hif_scatter_req *s_req;
+ struct bus_request *bus_req;
+ int i, scat_req_sz, scat_list_sz;
+
+ /* check if host supports scatter and it meets our requirements */
+ if (ar_sdio->func->card->host->max_segs < MAX_SCATTER_ENTRIES_PER_REQ) {
+ ath6kl_err("hif-scatter: host only supports scatter of : %d entries, need: %d\n",
+ ar_sdio->func->card->host->max_segs,
+ MAX_SCATTER_ENTRIES_PER_REQ);
+ return -EINVAL;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_ANY,
+ "hif-scatter enabled: max scatter req : %d entries: %d\n",
+ MAX_SCATTER_REQUESTS, MAX_SCATTER_ENTRIES_PER_REQ);
+
+ scat_list_sz = (MAX_SCATTER_ENTRIES_PER_REQ - 1) *
+ sizeof(struct hif_scatter_item);
+ scat_req_sz = sizeof(*s_req) + scat_list_sz;
+
+ for (i = 0; i < MAX_SCATTER_REQUESTS; i++) {
+ /* allocate the scatter request */
+ s_req = kzalloc(scat_req_sz, GFP_KERNEL);
+ if (!s_req)
+ goto fail_setup_scat;
+
+ /* allocate the private request blob */
+ s_req->req_priv = kzalloc(sizeof(*s_req->req_priv), GFP_KERNEL);
+
+ if (!s_req->req_priv) {
+ kfree(s_req);
+ goto fail_setup_scat;
+ }
+
+ /* allocate a bus request for this scatter request */
+ bus_req = ath6kl_sdio_alloc_busreq(ar_sdio);
+ if (!bus_req) {
+ kfree(s_req->req_priv);
+ kfree(s_req);
+ goto fail_setup_scat;
+ }
+
+ /* assign the scatter request to this bus request */
+ bus_req->scat_req = s_req;
+ s_req->req_priv->busrequest = bus_req;
+ /* add it to the scatter pool */
+ hif_scatter_req_add(ar_sdio->ar, s_req);
+ }
+
+ /* set scatter function pointers */
+ pinfo->rw_scat_func = ath6kl_sdio_async_rw_scatter;
+ pinfo->max_scat_entries = MAX_SCATTER_ENTRIES_PER_REQ;
+ pinfo->max_xfer_szper_scatreq = MAX_SCATTER_REQ_TRANSFER_SIZE;
+
+ return 0;
+
+fail_setup_scat:
+ ath6kl_err("hif-scatter: failed to alloc scatter resources !\n");
+ ath6kl_sdio_cleanup_scat_resource(ar_sdio);
+
+ return -ENOMEM;
+}
+
+static int ath6kl_sdio_read_write_sync(struct ath6kl *ar, u32 addr, u8 *buf,
+ u32 len, u32 request)
+{
+ struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+ u8 *tbuf = NULL;
+ int ret;
+ bool bounced = false;
+
+ if (request & HIF_BLOCK_BASIS)
+ len = round_down(len, HIF_MBOX_BLOCK_SIZE);
+
+ if (buf_needs_bounce(buf)) {
+ if (!ar_sdio->dma_buffer)
+ return -ENOMEM;
+ tbuf = ar_sdio->dma_buffer;
+ memcpy(tbuf, buf, len);
+ bounced = true;
+ } else
+ tbuf = buf;
+
+ sdio_claim_host(ar_sdio->func);
+ if (request & HIF_WRITE) {
+ if (addr >= HIF_MBOX_BASE_ADDR &&
+ addr <= HIF_MBOX_END_ADDR)
+ addr += (HIF_MBOX_WIDTH - len);
+
+ if (addr == HIF_MBOX0_EXT_BASE_ADDR)
+ addr += HIF_MBOX0_EXT_WIDTH - len;
+
+ if (request & HIF_FIXED_ADDRESS)
+ ret = sdio_writesb(ar_sdio->func, addr, tbuf, len);
+ else
+ ret = sdio_memcpy_toio(ar_sdio->func, addr, tbuf, len);
+ } else {
+ if (request & HIF_FIXED_ADDRESS)
+ ret = sdio_readsb(ar_sdio->func, tbuf, addr, len);
+ else
+ ret = sdio_memcpy_fromio(ar_sdio->func, tbuf,
+ addr, len);
+ if (bounced)
+ memcpy(buf, tbuf, len);
+ }
+ sdio_release_host(ar_sdio->func);
+
+ return ret;
+}
+
+static void __ath6kl_sdio_write_async(struct ath6kl_sdio *ar_sdio,
+ struct bus_request *req)
+{
+ if (req->scat_req)
+ ath6kl_sdio_scat_rw(ar_sdio, req);
+ else {
+ void *context;
+ int status;
+
+ status = ath6kl_sdio_read_write_sync(ar_sdio->ar, req->address,
+ req->buffer, req->length,
+ req->request);
+ context = req->packet;
+ ath6kl_sdio_free_bus_req(ar_sdio, req);
+ ath6kldev_rw_comp_handler(context, status);
+ }
+}
+
+static void ath6kl_sdio_write_async_work(struct work_struct *work)
+{
+ struct ath6kl_sdio *ar_sdio;
+ unsigned long flags;
+ struct bus_request *req, *tmp_req;
+
+ ar_sdio = container_of(work, struct ath6kl_sdio, wr_async_work);
+ sdio_claim_host(ar_sdio->func);
+
+ spin_lock_irqsave(&ar_sdio->wr_async_lock, flags);
+ list_for_each_entry_safe(req, tmp_req, &ar_sdio->wr_asyncq, list) {
+ list_del(&req->list);
+ spin_unlock_irqrestore(&ar_sdio->wr_async_lock, flags);
+ __ath6kl_sdio_write_async(ar_sdio, req);
+ spin_lock_irqsave(&ar_sdio->wr_async_lock, flags);
+ }
+ spin_unlock_irqrestore(&ar_sdio->wr_async_lock, flags);
+
+ sdio_release_host(ar_sdio->func);
+}
+
+static void ath6kl_sdio_irq_handler(struct sdio_func *func)
+{
+ int status;
+ struct ath6kl_sdio *ar_sdio;
+
+ ar_sdio = sdio_get_drvdata(func);
+ atomic_set(&ar_sdio->irq_handling, 1);
+
+ /*
+ * Release the host during interrups so we can pick it back up when
+ * we process commands.
+ */
+ sdio_release_host(ar_sdio->func);
+
+ status = ath6kldev_intr_bh_handler(ar_sdio->ar);
+ sdio_claim_host(ar_sdio->func);
+ atomic_set(&ar_sdio->irq_handling, 0);
+ WARN_ON(status && status != -ECANCELED);
+}
+
+static int ath6kl_sdio_power_on(struct ath6kl_sdio *ar_sdio)
+{
+ struct sdio_func *func = ar_sdio->func;
+ int ret = 0;
+
+ if (!ar_sdio->is_disabled)
+ return 0;
+
+ sdio_claim_host(func);
+
+ ret = sdio_enable_func(func);
+ if (ret) {
+ ath6kl_err("Unable to enable sdio func: %d)\n", ret);
+ sdio_release_host(func);
+ return ret;
+ }
+
+ sdio_release_host(func);
+
+ /*
+ * Wait for hardware to initialise. It should take a lot less than
+ * 10 ms but let's be conservative here.
+ */
+ msleep(10);
+
+ ar_sdio->is_disabled = false;
+
+ return ret;
+}
+
+static int ath6kl_sdio_power_off(struct ath6kl_sdio *ar_sdio)
+{
+ int ret;
+
+ if (ar_sdio->is_disabled)
+ return 0;
+
+ /* Disable the card */
+ sdio_claim_host(ar_sdio->func);
+ ret = sdio_disable_func(ar_sdio->func);
+ sdio_release_host(ar_sdio->func);
+
+ if (ret)
+ return ret;
+
+ ar_sdio->is_disabled = true;
+
+ return ret;
+}
+
+static int ath6kl_sdio_write_async(struct ath6kl *ar, u32 address, u8 *buffer,
+ u32 length, u32 request,
+ struct htc_packet *packet)
+{
+ struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+ struct bus_request *bus_req;
+ unsigned long flags;
+
+ bus_req = ath6kl_sdio_alloc_busreq(ar_sdio);
+
+ if (!bus_req)
+ return -ENOMEM;
+
+ bus_req->address = address;
+ bus_req->buffer = buffer;
+ bus_req->length = length;
+ bus_req->request = request;
+ bus_req->packet = packet;
+
+ spin_lock_irqsave(&ar_sdio->wr_async_lock, flags);
+ list_add_tail(&bus_req->list, &ar_sdio->wr_asyncq);
+ spin_unlock_irqrestore(&ar_sdio->wr_async_lock, flags);
+ queue_work(ar->ath6kl_wq, &ar_sdio->wr_async_work);
+
+ return 0;
+}
+
+static void ath6kl_sdio_irq_enable(struct ath6kl *ar)
+{
+ struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+ int ret;
+
+ sdio_claim_host(ar_sdio->func);
+
+ /* Register the isr */
+ ret = sdio_claim_irq(ar_sdio->func, ath6kl_sdio_irq_handler);
+ if (ret)
+ ath6kl_err("Failed to claim sdio irq: %d\n", ret);
+
+ sdio_release_host(ar_sdio->func);
+}
+
+static void ath6kl_sdio_irq_disable(struct ath6kl *ar)
+{
+ struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+ int ret;
+
+ sdio_claim_host(ar_sdio->func);
+
+ /* Mask our function IRQ */
+ while (atomic_read(&ar_sdio->irq_handling)) {
+ sdio_release_host(ar_sdio->func);
+ schedule_timeout(HZ / 10);
+ sdio_claim_host(ar_sdio->func);
+ }
+
+ ret = sdio_release_irq(ar_sdio->func);
+ if (ret)
+ ath6kl_err("Failed to release sdio irq: %d\n", ret);
+
+ sdio_release_host(ar_sdio->func);
+}
+
+static struct hif_scatter_req *ath6kl_sdio_scatter_req_get(struct ath6kl *ar)
+{
+ struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+ struct hif_scatter_req *node = NULL;
+ unsigned long flag;
+
+ spin_lock_irqsave(&ar_sdio->scat_lock, flag);
+
+ if (!list_empty(&ar_sdio->scat_req)) {
+ node = list_first_entry(&ar_sdio->scat_req,
+ struct hif_scatter_req, list);
+ list_del(&node->list);
+ }
+
+ spin_unlock_irqrestore(&ar_sdio->scat_lock, flag);
+
+ return node;
+}
+
+static void ath6kl_sdio_scatter_req_add(struct ath6kl *ar,
+ struct hif_scatter_req *s_req)
+{
+ struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+ unsigned long flag;
+
+ spin_lock_irqsave(&ar_sdio->scat_lock, flag);
+
+ list_add_tail(&s_req->list, &ar_sdio->scat_req);
+
+ spin_unlock_irqrestore(&ar_sdio->scat_lock, flag);
+
+}
+
+static int ath6kl_sdio_enable_scatter(struct ath6kl *ar,
+ struct hif_dev_scat_sup_info *info)
+{
+ struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+ int ret;
+
+ ret = ath6kl_sdio_setup_scat_resource(ar_sdio, info);
+
+ return ret;
+}
+
+static void ath6kl_sdio_cleanup_scatter(struct ath6kl *ar)
+{
+ struct ath6kl_sdio *ar_sdio = ath6kl_sdio_priv(ar);
+
+ ath6kl_sdio_cleanup_scat_resource(ar_sdio);
+}
+
+static const struct ath6kl_hif_ops ath6kl_sdio_ops = {
+ .read_write_sync = ath6kl_sdio_read_write_sync,
+ .write_async = ath6kl_sdio_write_async,
+ .irq_enable = ath6kl_sdio_irq_enable,
+ .irq_disable = ath6kl_sdio_irq_disable,
+ .scatter_req_get = ath6kl_sdio_scatter_req_get,
+ .scatter_req_add = ath6kl_sdio_scatter_req_add,
+ .enable_scatter = ath6kl_sdio_enable_scatter,
+ .cleanup_scatter = ath6kl_sdio_cleanup_scatter,
+};
+
+static int ath6kl_sdio_probe(struct sdio_func *func,
+ const struct sdio_device_id *id)
+{
+ int ret;
+ struct ath6kl_sdio *ar_sdio;
+ struct ath6kl *ar;
+ int count;
+
+ ath6kl_dbg(ATH6KL_DBG_TRC,
+ "%s: func: 0x%X, vendor id: 0x%X, dev id: 0x%X, block size: 0x%X/0x%X\n",
+ __func__, func->num, func->vendor,
+ func->device, func->max_blksize, func->cur_blksize);
+
+ ar_sdio = kzalloc(sizeof(struct ath6kl_sdio), GFP_KERNEL);
+ if (!ar_sdio)
+ return -ENOMEM;
+
+ ar_sdio->dma_buffer = kzalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL);
+ if (!ar_sdio->dma_buffer) {
+ ret = -ENOMEM;
+ goto err_hif;
+ }
+
+ ar_sdio->func = func;
+ sdio_set_drvdata(func, ar_sdio);
+
+ ar_sdio->id = id;
+ ar_sdio->is_disabled = true;
+
+ spin_lock_init(&ar_sdio->lock);
+ spin_lock_init(&ar_sdio->scat_lock);
+ spin_lock_init(&ar_sdio->wr_async_lock);
+
+ INIT_LIST_HEAD(&ar_sdio->scat_req);
+ INIT_LIST_HEAD(&ar_sdio->bus_req_freeq);
+ INIT_LIST_HEAD(&ar_sdio->wr_asyncq);
+
+ INIT_WORK(&ar_sdio->wr_async_work, ath6kl_sdio_write_async_work);
+
+ for (count = 0; count < BUS_REQUEST_MAX_NUM; count++)
+ ath6kl_sdio_free_bus_req(ar_sdio, &ar_sdio->bus_req[count]);
+
+ ar = ath6kl_core_alloc(&ar_sdio->func->dev);
+ if (!ar) {
+ ath6kl_err("Failed to alloc ath6kl core\n");
+ ret = -ENOMEM;
+ goto err_dma;
+ }
+
+ ar_sdio->ar = ar;
+ ar->hif_priv = ar_sdio;
+ ar->hif_ops = &ath6kl_sdio_ops;
+
+ ath6kl_sdio_set_mbox_info(ar);
+
+ sdio_claim_host(func);
+
+ if ((ar_sdio->id->device & MANUFACTURER_ID_ATH6KL_BASE_MASK) >=
+ MANUFACTURER_ID_AR6003_BASE) {
+ /* enable 4-bit ASYNC interrupt on AR6003 or later */
+ ret = ath6kl_sdio_func0_cmd52_wr_byte(func->card,
+ CCCR_SDIO_IRQ_MODE_REG,
+ SDIO_IRQ_MODE_ASYNC_4BIT_IRQ);
+ if (ret) {
+ ath6kl_err("Failed to enable 4-bit async irq mode %d\n",
+ ret);
+ sdio_release_host(func);
+ goto err_dma;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_TRC, "4-bit async irq mode enabled\n");
+ }
+
+ /* give us some time to enable, in ms */
+ func->enable_timeout = 100;
+
+ sdio_release_host(func);
+
+ ret = ath6kl_sdio_power_on(ar_sdio);
+ if (ret)
+ goto err_dma;
+
+ sdio_claim_host(func);
+
+ ret = sdio_set_block_size(func, HIF_MBOX_BLOCK_SIZE);
+ if (ret) {
+ ath6kl_err("Set sdio block size %d failed: %d)\n",
+ HIF_MBOX_BLOCK_SIZE, ret);
+ sdio_release_host(func);
+ goto err_off;
+ }
+
+ sdio_release_host(func);
+
+ ret = ath6kl_core_init(ar);
+ if (ret) {
+ ath6kl_err("Failed to init ath6kl core\n");
+ goto err_off;
+ }
+
+ return ret;
+
+err_off:
+ ath6kl_sdio_power_off(ar_sdio);
+err_dma:
+ kfree(ar_sdio->dma_buffer);
+err_hif:
+ kfree(ar_sdio);
+
+ return ret;
+}
+
+static void ath6kl_sdio_remove(struct sdio_func *func)
+{
+ struct ath6kl_sdio *ar_sdio;
+
+ ar_sdio = sdio_get_drvdata(func);
+
+ ath6kl_stop_txrx(ar_sdio->ar);
+ cancel_work_sync(&ar_sdio->wr_async_work);
+
+ ath6kl_unavail_ev(ar_sdio->ar);
+
+ ath6kl_sdio_power_off(ar_sdio);
+
+ kfree(ar_sdio->dma_buffer);
+ kfree(ar_sdio);
+}
+
+static const struct sdio_device_id ath6kl_sdio_devices[] = {
+ {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x0))},
+ {SDIO_DEVICE(MANUFACTURER_CODE, (MANUFACTURER_ID_AR6003_BASE | 0x1))},
+ {},
+};
+
+MODULE_DEVICE_TABLE(sdio, ath6kl_sdio_devices);
+
+static struct sdio_driver ath6kl_sdio_driver = {
+ .name = "ath6kl_sdio",
+ .id_table = ath6kl_sdio_devices,
+ .probe = ath6kl_sdio_probe,
+ .remove = ath6kl_sdio_remove,
+};
+
+static int __init ath6kl_sdio_init(void)
+{
+ int ret;
+
+ ret = sdio_register_driver(&ath6kl_sdio_driver);
+ if (ret)
+ ath6kl_err("sdio driver registration failed: %d\n", ret);
+
+ return ret;
+}
+
+static void __exit ath6kl_sdio_exit(void)
+{
+ sdio_unregister_driver(&ath6kl_sdio_driver);
+}
+
+module_init(ath6kl_sdio_init);
+module_exit(ath6kl_sdio_exit);
+
+MODULE_AUTHOR("Atheros Communications, Inc.");
+MODULE_DESCRIPTION("Driver support for Atheros AR600x SDIO devices");
+MODULE_LICENSE("Dual BSD/GPL");
+
+MODULE_FIRMWARE(AR6003_REV2_OTP_FILE);
+MODULE_FIRMWARE(AR6003_REV2_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6003_REV2_PATCH_FILE);
+MODULE_FIRMWARE(AR6003_REV2_BOARD_DATA_FILE);
+MODULE_FIRMWARE(AR6003_REV2_DEFAULT_BOARD_DATA_FILE);
+MODULE_FIRMWARE(AR6003_REV3_OTP_FILE);
+MODULE_FIRMWARE(AR6003_REV3_FIRMWARE_FILE);
+MODULE_FIRMWARE(AR6003_REV3_PATCH_FILE);
+MODULE_FIRMWARE(AR6003_REV3_BOARD_DATA_FILE);
+MODULE_FIRMWARE(AR6003_REV3_DEFAULT_BOARD_DATA_FILE);
diff --git a/drivers/net/wireless/ath/ath6kl/target.h b/drivers/net/wireless/ath/ath6kl/target.h
new file mode 100644
index 000000000000..519a013c9991
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/target.h
@@ -0,0 +1,331 @@
+/*
+ * Copyright (c) 2004-2010 Atheros Communications Inc.
+ *
+ * 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.
+ */
+
+#ifndef TARGET_H
+#define TARGET_H
+
+#define AR6003_BOARD_DATA_SZ 1024
+#define AR6003_BOARD_EXT_DATA_SZ 768
+
+#define RESET_CONTROL_ADDRESS 0x00000000
+#define RESET_CONTROL_COLD_RST 0x00000100
+#define RESET_CONTROL_MBOX_RST 0x00000004
+
+#define CPU_CLOCK_STANDARD_S 0
+#define CPU_CLOCK_STANDARD 0x00000003
+#define CPU_CLOCK_ADDRESS 0x00000020
+
+#define CLOCK_CONTROL_ADDRESS 0x00000028
+#define CLOCK_CONTROL_LF_CLK32_S 2
+#define CLOCK_CONTROL_LF_CLK32 0x00000004
+
+#define SYSTEM_SLEEP_ADDRESS 0x000000c4
+#define SYSTEM_SLEEP_DISABLE_S 0
+#define SYSTEM_SLEEP_DISABLE 0x00000001
+
+#define LPO_CAL_ADDRESS 0x000000e0
+#define LPO_CAL_ENABLE_S 20
+#define LPO_CAL_ENABLE 0x00100000
+
+#define GPIO_PIN10_ADDRESS 0x00000050
+#define GPIO_PIN11_ADDRESS 0x00000054
+#define GPIO_PIN12_ADDRESS 0x00000058
+#define GPIO_PIN13_ADDRESS 0x0000005c
+
+#define HOST_INT_STATUS_ADDRESS 0x00000400
+#define HOST_INT_STATUS_ERROR_S 7
+#define HOST_INT_STATUS_ERROR 0x00000080
+
+#define HOST_INT_STATUS_CPU_S 6
+#define HOST_INT_STATUS_CPU 0x00000040
+
+#define HOST_INT_STATUS_COUNTER_S 4
+#define HOST_INT_STATUS_COUNTER 0x00000010
+
+#define CPU_INT_STATUS_ADDRESS 0x00000401
+
+#define ERROR_INT_STATUS_ADDRESS 0x00000402
+#define ERROR_INT_STATUS_WAKEUP_S 2
+#define ERROR_INT_STATUS_WAKEUP 0x00000004
+
+#define ERROR_INT_STATUS_RX_UNDERFLOW_S 1
+#define ERROR_INT_STATUS_RX_UNDERFLOW 0x00000002
+
+#define ERROR_INT_STATUS_TX_OVERFLOW_S 0
+#define ERROR_INT_STATUS_TX_OVERFLOW 0x00000001
+
+#define COUNTER_INT_STATUS_ADDRESS 0x00000403
+#define COUNTER_INT_STATUS_COUNTER_S 0
+#define COUNTER_INT_STATUS_COUNTER 0x000000ff
+
+#define RX_LOOKAHEAD_VALID_ADDRESS 0x00000405
+
+#define INT_STATUS_ENABLE_ADDRESS 0x00000418
+#define INT_STATUS_ENABLE_ERROR_S 7
+#define INT_STATUS_ENABLE_ERROR 0x00000080
+
+#define INT_STATUS_ENABLE_CPU_S 6
+#define INT_STATUS_ENABLE_CPU 0x00000040
+
+#define INT_STATUS_ENABLE_INT_S 5
+#define INT_STATUS_ENABLE_INT 0x00000020
+#define INT_STATUS_ENABLE_COUNTER_S 4
+#define INT_STATUS_ENABLE_COUNTER 0x00000010
+
+#define INT_STATUS_ENABLE_MBOX_DATA_S 0
+#define INT_STATUS_ENABLE_MBOX_DATA 0x0000000f
+
+#define CPU_INT_STATUS_ENABLE_ADDRESS 0x00000419
+#define CPU_INT_STATUS_ENABLE_BIT_S 0
+#define CPU_INT_STATUS_ENABLE_BIT 0x000000ff
+
+#define ERROR_STATUS_ENABLE_ADDRESS 0x0000041a
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW_S 1
+#define ERROR_STATUS_ENABLE_RX_UNDERFLOW 0x00000002
+
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW_S 0
+#define ERROR_STATUS_ENABLE_TX_OVERFLOW 0x00000001
+
+#define COUNTER_INT_STATUS_ENABLE_ADDRESS 0x0000041b
+#define COUNTER_INT_STATUS_ENABLE_BIT_S 0
+#define COUNTER_INT_STATUS_ENABLE_BIT 0x000000ff
+
+#define COUNT_ADDRESS 0x00000420
+
+#define COUNT_DEC_ADDRESS 0x00000440
+
+#define WINDOW_DATA_ADDRESS 0x00000474
+#define WINDOW_WRITE_ADDR_ADDRESS 0x00000478
+#define WINDOW_READ_ADDR_ADDRESS 0x0000047c
+#define CPU_DBG_SEL_ADDRESS 0x00000483
+#define CPU_DBG_ADDRESS 0x00000484
+
+#define LOCAL_SCRATCH_ADDRESS 0x000000c0
+#define ATH6KL_OPTION_SLEEP_DISABLE 0x08
+
+#define RTC_BASE_ADDRESS 0x00004000
+#define GPIO_BASE_ADDRESS 0x00014000
+#define MBOX_BASE_ADDRESS 0x00018000
+#define ANALOG_INTF_BASE_ADDRESS 0x0001c000
+
+/* real name of the register is unknown */
+#define ATH6KL_ANALOG_PLL_REGISTER (ANALOG_INTF_BASE_ADDRESS + 0x284)
+
+#define SM(f, v) (((v) << f##_S) & f)
+#define MS(f, v) (((v) & f) >> f##_S)
+
+/*
+ * xxx_HOST_INTEREST_ADDRESS is the address in Target RAM of the
+ * host_interest structure.
+ *
+ * Host Interest is shared between Host and Target in order to coordinate
+ * between the two, and is intended to remain constant (with additions only
+ * at the end).
+ */
+#define ATH6KL_HI_START_ADDR 0x00540600
+
+/*
+ * These are items that the Host may need to access
+ * via BMI or via the Diagnostic Window. The position
+ * of items in this structure must remain constant.
+ * across firmware revisions!
+ *
+ * Types for each item must be fixed size across target and host platforms.
+ * The structure is used only to calculate offset for each register with
+ * HI_ITEM() macro, no values are stored to it.
+ *
+ * More items may be added at the end.
+ */
+struct host_interest {
+ /*
+ * Pointer to application-defined area, if any.
+ * Set by Target application during startup.
+ */
+ u32 hi_app_host_interest; /* 0x00 */
+
+ /* Pointer to register dump area, valid after Target crash. */
+ u32 hi_failure_state; /* 0x04 */
+
+ /* Pointer to debug logging header */
+ u32 hi_dbglog_hdr; /* 0x08 */
+
+ u32 hi_unused1; /* 0x0c */
+
+ /*
+ * General-purpose flag bits, similar to ATH6KL_OPTION_* flags.
+ * Can be used by application rather than by OS.
+ */
+ u32 hi_option_flag; /* 0x10 */
+
+ /*
+ * Boolean that determines whether or not to
+ * display messages on the serial port.
+ */
+ u32 hi_serial_enable; /* 0x14 */
+
+ /* Start address of DataSet index, if any */
+ u32 hi_dset_list_head; /* 0x18 */
+
+ /* Override Target application start address */
+ u32 hi_app_start; /* 0x1c */
+
+ /* Clock and voltage tuning */
+ u32 hi_skip_clock_init; /* 0x20 */
+ u32 hi_core_clock_setting; /* 0x24 */
+ u32 hi_cpu_clock_setting; /* 0x28 */
+ u32 hi_system_sleep_setting; /* 0x2c */
+ u32 hi_xtal_control_setting; /* 0x30 */
+ u32 hi_pll_ctrl_setting_24ghz; /* 0x34 */
+ u32 hi_pll_ctrl_setting_5ghz; /* 0x38 */
+ u32 hi_ref_voltage_trim_setting; /* 0x3c */
+ u32 hi_clock_info; /* 0x40 */
+
+ /*
+ * Flash configuration overrides, used only
+ * when firmware is not executing from flash.
+ * (When using flash, modify the global variables
+ * with equivalent names.)
+ */
+ u32 hi_bank0_addr_value; /* 0x44 */
+ u32 hi_bank0_read_value; /* 0x48 */
+ u32 hi_bank0_write_value; /* 0x4c */
+ u32 hi_bank0_config_value; /* 0x50 */
+
+ /* Pointer to Board Data */
+ u32 hi_board_data; /* 0x54 */
+ u32 hi_board_data_initialized; /* 0x58 */
+
+ u32 hi_dset_ram_index_tbl; /* 0x5c */
+
+ u32 hi_desired_baud_rate; /* 0x60 */
+ u32 hi_dbglog_config; /* 0x64 */
+ u32 hi_end_ram_reserve_sz; /* 0x68 */
+ u32 hi_mbox_io_block_sz; /* 0x6c */
+
+ u32 hi_num_bpatch_streams; /* 0x70 -- unused */
+ u32 hi_mbox_isr_yield_limit; /* 0x74 */
+
+ u32 hi_refclk_hz; /* 0x78 */
+ u32 hi_ext_clk_detected; /* 0x7c */
+ u32 hi_dbg_uart_txpin; /* 0x80 */
+ u32 hi_dbg_uart_rxpin; /* 0x84 */
+ u32 hi_hci_uart_baud; /* 0x88 */
+ u32 hi_hci_uart_pin_assignments; /* 0x8C */
+ /*
+ * NOTE: byte [0] = tx pin, [1] = rx pin, [2] = rts pin, [3] = cts
+ * pin
+ */
+ u32 hi_hci_uart_baud_scale_val; /* 0x90 */
+ u32 hi_hci_uart_baud_step_val; /* 0x94 */
+
+ u32 hi_allocram_start; /* 0x98 */
+ u32 hi_allocram_sz; /* 0x9c */
+ u32 hi_hci_bridge_flags; /* 0xa0 */
+ u32 hi_hci_uart_support_pins; /* 0xa4 */
+ /*
+ * NOTE: byte [0] = RESET pin (bit 7 is polarity),
+ * bytes[1]..bytes[3] are for future use
+ */
+ u32 hi_hci_uart_pwr_mgmt_params; /* 0xa8 */
+ /*
+ * 0xa8 - [1]: 0 = UART FC active low, 1 = UART FC active high
+ * [31:16]: wakeup timeout in ms
+ */
+
+ /* Pointer to extended board data */
+ u32 hi_board_ext_data; /* 0xac */
+ u32 hi_board_ext_data_config; /* 0xb0 */
+
+ /*
+ * Bit [0] : valid
+ * Bit[31:16: size
+ */
+ /*
+ * hi_reset_flag is used to do some stuff when target reset.
+ * such as restore app_start after warm reset or
+ * preserve host Interest area, or preserve ROM data, literals etc.
+ */
+ u32 hi_reset_flag; /* 0xb4 */
+ /* indicate hi_reset_flag is valid */
+ u32 hi_reset_flag_valid; /* 0xb8 */
+ u32 hi_hci_uart_pwr_mgmt_params_ext; /* 0xbc */
+ /*
+ * 0xbc - [31:0]: idle timeout in ms
+ */
+ /* ACS flags */
+ u32 hi_acs_flags; /* 0xc0 */
+ u32 hi_console_flags; /* 0xc4 */
+ u32 hi_nvram_state; /* 0xc8 */
+ u32 hi_option_flag2; /* 0xcc */
+
+ /* If non-zero, override values sent to Host in WMI_READY event. */
+ u32 hi_sw_version_override; /* 0xd0 */
+ u32 hi_abi_version_override; /* 0xd4 */
+
+ /*
+ * Percentage of high priority RX traffic to total expected RX traffic -
+ * applicable only to ar6004
+ */
+ u32 hi_hp_rx_traffic_ratio; /* 0xd8 */
+
+ /* test applications flags */
+ u32 hi_test_apps_related ; /* 0xdc */
+ /* location of test script */
+ u32 hi_ota_testscript; /* 0xe0 */
+ /* location of CAL data */
+ u32 hi_cal_data; /* 0xe4 */
+ /* Number of packet log buffers */
+ u32 hi_pktlog_num_buffers; /* 0xe8 */
+
+} __packed;
+
+#define HI_ITEM(item) offsetof(struct host_interest, item)
+
+#define HI_OPTION_MAC_ADDR_METHOD_SHIFT 3
+
+#define HI_OPTION_FW_MODE_IBSS 0x0
+#define HI_OPTION_FW_MODE_BSS_STA 0x1
+#define HI_OPTION_FW_MODE_AP 0x2
+
+#define HI_OPTION_NUM_DEV_SHIFT 0x9
+
+#define HI_OPTION_FW_BRIDGE_SHIFT 0x04
+
+/* Fw Mode/SubMode Mask
+|------------------------------------------------------------------------------|
+| SUB | SUB | SUB | SUB | | | |
+| MODE[3] | MODE[2] | MODE[1] | MODE[0] | MODE[3] | MODE[2] | MODE[1] | MODE[0|
+| (2) | (2) | (2) | (2) | (2) | (2) | (2) | (2)
+|------------------------------------------------------------------------------|
+*/
+#define HI_OPTION_FW_MODE_SHIFT 0xC
+
+/* Convert a Target virtual address into a Target physical address */
+#define TARG_VTOP(vaddr) (vaddr & 0x001fffff)
+
+#define AR6003_REV2_APP_START_OVERRIDE 0x944C00
+#define AR6003_REV2_APP_LOAD_ADDRESS 0x543180
+#define AR6003_REV2_BOARD_EXT_DATA_ADDRESS 0x57E500
+#define AR6003_REV2_DATASET_PATCH_ADDRESS 0x57e884
+#define AR6003_REV2_RAM_RESERVE_SIZE 6912
+
+#define AR6003_REV3_APP_START_OVERRIDE 0x945d00
+#define AR6003_REV3_APP_LOAD_ADDRESS 0x545000
+#define AR6003_REV3_BOARD_EXT_DATA_ADDRESS 0x542330
+#define AR6003_REV3_DATASET_PATCH_ADDRESS 0x57FF74
+#define AR6003_REV3_RAM_RESERVE_SIZE 512
+
+#endif
diff --git a/drivers/net/wireless/ath/ath6kl/txrx.c b/drivers/net/wireless/ath/ath6kl/txrx.c
new file mode 100644
index 000000000000..615b46d388f6
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/txrx.c
@@ -0,0 +1,1452 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications Inc.
+ *
+ * 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 "core.h"
+#include "debug.h"
+
+static u8 ath6kl_ibss_map_epid(struct sk_buff *skb, struct net_device *dev,
+ u32 *map_no)
+{
+ struct ath6kl *ar = ath6kl_priv(dev);
+ struct ethhdr *eth_hdr;
+ u32 i, ep_map = -1;
+ u8 *datap;
+
+ *map_no = 0;
+ datap = skb->data;
+ eth_hdr = (struct ethhdr *) (datap + sizeof(struct wmi_data_hdr));
+
+ if (is_multicast_ether_addr(eth_hdr->h_dest))
+ return ENDPOINT_2;
+
+ for (i = 0; i < ar->node_num; i++) {
+ if (memcmp(eth_hdr->h_dest, ar->node_map[i].mac_addr,
+ ETH_ALEN) == 0) {
+ *map_no = i + 1;
+ ar->node_map[i].tx_pend++;
+ return ar->node_map[i].ep_id;
+ }
+
+ if ((ep_map == -1) && !ar->node_map[i].tx_pend)
+ ep_map = i;
+ }
+
+ if (ep_map == -1) {
+ ep_map = ar->node_num;
+ ar->node_num++;
+ if (ar->node_num > MAX_NODE_NUM)
+ return ENDPOINT_UNUSED;
+ }
+
+ memcpy(ar->node_map[ep_map].mac_addr, eth_hdr->h_dest, ETH_ALEN);
+
+ for (i = ENDPOINT_2; i <= ENDPOINT_5; i++) {
+ if (!ar->tx_pending[i]) {
+ ar->node_map[ep_map].ep_id = i;
+ break;
+ }
+
+ /*
+ * No free endpoint is available, start redistribution on
+ * the inuse endpoints.
+ */
+ if (i == ENDPOINT_5) {
+ ar->node_map[ep_map].ep_id = ar->next_ep_id;
+ ar->next_ep_id++;
+ if (ar->next_ep_id > ENDPOINT_5)
+ ar->next_ep_id = ENDPOINT_2;
+ }
+ }
+
+ *map_no = ep_map + 1;
+ ar->node_map[ep_map].tx_pend++;
+
+ return ar->node_map[ep_map].ep_id;
+}
+
+static bool ath6kl_powersave_ap(struct ath6kl *ar, struct sk_buff *skb,
+ bool *more_data)
+{
+ struct ethhdr *datap = (struct ethhdr *) skb->data;
+ struct ath6kl_sta *conn = NULL;
+ bool ps_queued = false, is_psq_empty = false;
+
+ if (is_multicast_ether_addr(datap->h_dest)) {
+ u8 ctr = 0;
+ bool q_mcast = false;
+
+ for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
+ if (ar->sta_list[ctr].sta_flags & STA_PS_SLEEP) {
+ q_mcast = true;
+ break;
+ }
+ }
+
+ if (q_mcast) {
+ /*
+ * If this transmit is not because of a Dtim Expiry
+ * q it.
+ */
+ if (!test_bit(DTIM_EXPIRED, &ar->flag)) {
+ bool is_mcastq_empty = false;
+
+ spin_lock_bh(&ar->mcastpsq_lock);
+ is_mcastq_empty =
+ skb_queue_empty(&ar->mcastpsq);
+ skb_queue_tail(&ar->mcastpsq, skb);
+ spin_unlock_bh(&ar->mcastpsq_lock);
+
+ /*
+ * If this is the first Mcast pkt getting
+ * queued indicate to the target to set the
+ * BitmapControl LSB of the TIM IE.
+ */
+ if (is_mcastq_empty)
+ ath6kl_wmi_set_pvb_cmd(ar->wmi,
+ MCAST_AID, 1);
+
+ ps_queued = true;
+ } else {
+ /*
+ * This transmit is because of Dtim expiry.
+ * Determine if MoreData bit has to be set.
+ */
+ spin_lock_bh(&ar->mcastpsq_lock);
+ if (!skb_queue_empty(&ar->mcastpsq))
+ *more_data = true;
+ spin_unlock_bh(&ar->mcastpsq_lock);
+ }
+ }
+ } else {
+ conn = ath6kl_find_sta(ar, datap->h_dest);
+ if (!conn) {
+ dev_kfree_skb(skb);
+
+ /* Inform the caller that the skb is consumed */
+ return true;
+ }
+
+ if (conn->sta_flags & STA_PS_SLEEP) {
+ if (!(conn->sta_flags & STA_PS_POLLED)) {
+ /* Queue the frames if the STA is sleeping */
+ spin_lock_bh(&conn->psq_lock);
+ is_psq_empty = skb_queue_empty(&conn->psq);
+ skb_queue_tail(&conn->psq, skb);
+ spin_unlock_bh(&conn->psq_lock);
+
+ /*
+ * If this is the first pkt getting queued
+ * for this STA, update the PVB for this
+ * STA.
+ */
+ if (is_psq_empty)
+ ath6kl_wmi_set_pvb_cmd(ar->wmi,
+ conn->aid, 1);
+
+ ps_queued = true;
+ } else {
+ /*
+ * This tx is because of a PsPoll.
+ * Determine if MoreData bit has to be set.
+ */
+ spin_lock_bh(&conn->psq_lock);
+ if (!skb_queue_empty(&conn->psq))
+ *more_data = true;
+ spin_unlock_bh(&conn->psq_lock);
+ }
+ }
+ }
+
+ return ps_queued;
+}
+
+/* Tx functions */
+
+int ath6kl_control_tx(void *devt, struct sk_buff *skb,
+ enum htc_endpoint_id eid)
+{
+ struct ath6kl *ar = devt;
+ int status = 0;
+ struct ath6kl_cookie *cookie = NULL;
+
+ spin_lock_bh(&ar->lock);
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
+ "%s: skb=0x%p, len=0x%x eid =%d\n", __func__,
+ skb, skb->len, eid);
+
+ if (test_bit(WMI_CTRL_EP_FULL, &ar->flag) && (eid == ar->ctrl_ep)) {
+ /*
+ * Control endpoint is full, don't allocate resources, we
+ * are just going to drop this packet.
+ */
+ cookie = NULL;
+ ath6kl_err("wmi ctrl ep full, dropping pkt : 0x%p, len:%d\n",
+ skb, skb->len);
+ } else
+ cookie = ath6kl_alloc_cookie(ar);
+
+ if (cookie == NULL) {
+ spin_unlock_bh(&ar->lock);
+ status = -ENOMEM;
+ goto fail_ctrl_tx;
+ }
+
+ ar->tx_pending[eid]++;
+
+ if (eid != ar->ctrl_ep)
+ ar->total_tx_data_pend++;
+
+ spin_unlock_bh(&ar->lock);
+
+ cookie->skb = skb;
+ cookie->map_no = 0;
+ set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len,
+ eid, ATH6KL_CONTROL_PKT_TAG);
+
+ /*
+ * This interface is asynchronous, if there is an error, cleanup
+ * will happen in the TX completion callback.
+ */
+ htc_tx(ar->htc_target, &cookie->htc_pkt);
+
+ return 0;
+
+fail_ctrl_tx:
+ dev_kfree_skb(skb);
+ return status;
+}
+
+int ath6kl_data_tx(struct sk_buff *skb, struct net_device *dev)
+{
+ struct ath6kl *ar = ath6kl_priv(dev);
+ struct ath6kl_cookie *cookie = NULL;
+ enum htc_endpoint_id eid = ENDPOINT_UNUSED;
+ u32 map_no = 0;
+ u16 htc_tag = ATH6KL_DATA_PKT_TAG;
+ u8 ac = 99 ; /* initialize to unmapped ac */
+ bool chk_adhoc_ps_mapping = false, more_data = false;
+ struct wmi_tx_meta_v2 meta_v2;
+ int ret;
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
+ "%s: skb=0x%p, data=0x%p, len=0x%x\n", __func__,
+ skb, skb->data, skb->len);
+
+ /* If target is not associated */
+ if (!test_bit(CONNECTED, &ar->flag)) {
+ dev_kfree_skb(skb);
+ return 0;
+ }
+
+ if (!test_bit(WMI_READY, &ar->flag))
+ goto fail_tx;
+
+ /* AP mode Power saving processing */
+ if (ar->nw_type == AP_NETWORK) {
+ if (ath6kl_powersave_ap(ar, skb, &more_data))
+ return 0;
+ }
+
+ if (test_bit(WMI_ENABLED, &ar->flag)) {
+ memset(&meta_v2, 0, sizeof(meta_v2));
+
+ if (skb_headroom(skb) < dev->needed_headroom) {
+ WARN_ON(1);
+ goto fail_tx;
+ }
+
+ if (ath6kl_wmi_dix_2_dot3(ar->wmi, skb)) {
+ ath6kl_err("ath6kl_wmi_dix_2_dot3 failed\n");
+ goto fail_tx;
+ }
+
+ if (ath6kl_wmi_data_hdr_add(ar->wmi, skb, DATA_MSGTYPE,
+ more_data, 0, 0, NULL)) {
+ ath6kl_err("wmi_data_hdr_add failed\n");
+ goto fail_tx;
+ }
+
+ if ((ar->nw_type == ADHOC_NETWORK) &&
+ ar->ibss_ps_enable && test_bit(CONNECTED, &ar->flag))
+ chk_adhoc_ps_mapping = true;
+ else {
+ /* get the stream mapping */
+ ret = ath6kl_wmi_implicit_create_pstream(ar->wmi, skb,
+ 0, test_bit(WMM_ENABLED, &ar->flag), &ac);
+ if (ret)
+ goto fail_tx;
+ }
+ } else
+ goto fail_tx;
+
+ spin_lock_bh(&ar->lock);
+
+ if (chk_adhoc_ps_mapping)
+ eid = ath6kl_ibss_map_epid(skb, dev, &map_no);
+ else
+ eid = ar->ac2ep_map[ac];
+
+ if (eid == 0 || eid == ENDPOINT_UNUSED) {
+ ath6kl_err("eid %d is not mapped!\n", eid);
+ spin_unlock_bh(&ar->lock);
+ goto fail_tx;
+ }
+
+ /* allocate resource for this packet */
+ cookie = ath6kl_alloc_cookie(ar);
+
+ if (!cookie) {
+ spin_unlock_bh(&ar->lock);
+ goto fail_tx;
+ }
+
+ /* update counts while the lock is held */
+ ar->tx_pending[eid]++;
+ ar->total_tx_data_pend++;
+
+ spin_unlock_bh(&ar->lock);
+
+ cookie->skb = skb;
+ cookie->map_no = map_no;
+ set_htc_pkt_info(&cookie->htc_pkt, cookie, skb->data, skb->len,
+ eid, htc_tag);
+
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, skb->data, skb->len);
+
+ /*
+ * HTC interface is asynchronous, if this fails, cleanup will
+ * happen in the ath6kl_tx_complete callback.
+ */
+ htc_tx(ar->htc_target, &cookie->htc_pkt);
+
+ return 0;
+
+fail_tx:
+ dev_kfree_skb(skb);
+
+ ar->net_stats.tx_dropped++;
+ ar->net_stats.tx_aborted_errors++;
+
+ return 0;
+}
+
+/* indicate tx activity or inactivity on a WMI stream */
+void ath6kl_indicate_tx_activity(void *devt, u8 traffic_class, bool active)
+{
+ struct ath6kl *ar = devt;
+ enum htc_endpoint_id eid;
+ int i;
+
+ eid = ar->ac2ep_map[traffic_class];
+
+ if (!test_bit(WMI_ENABLED, &ar->flag))
+ goto notify_htc;
+
+ spin_lock_bh(&ar->lock);
+
+ ar->ac_stream_active[traffic_class] = active;
+
+ if (active) {
+ /*
+ * Keep track of the active stream with the highest
+ * priority.
+ */
+ if (ar->ac_stream_pri_map[traffic_class] >
+ ar->hiac_stream_active_pri)
+ /* set the new highest active priority */
+ ar->hiac_stream_active_pri =
+ ar->ac_stream_pri_map[traffic_class];
+
+ } else {
+ /*
+ * We may have to search for the next active stream
+ * that is the highest priority.
+ */
+ if (ar->hiac_stream_active_pri ==
+ ar->ac_stream_pri_map[traffic_class]) {
+ /*
+ * The highest priority stream just went inactive
+ * reset and search for the "next" highest "active"
+ * priority stream.
+ */
+ ar->hiac_stream_active_pri = 0;
+
+ for (i = 0; i < WMM_NUM_AC; i++) {
+ if (ar->ac_stream_active[i] &&
+ (ar->ac_stream_pri_map[i] >
+ ar->hiac_stream_active_pri))
+ /*
+ * Set the new highest active
+ * priority.
+ */
+ ar->hiac_stream_active_pri =
+ ar->ac_stream_pri_map[i];
+ }
+ }
+ }
+
+ spin_unlock_bh(&ar->lock);
+
+notify_htc:
+ /* notify HTC, this may cause credit distribution changes */
+ htc_indicate_activity_change(ar->htc_target, eid, active);
+}
+
+enum htc_send_full_action ath6kl_tx_queue_full(struct htc_target *target,
+ struct htc_packet *packet)
+{
+ struct ath6kl *ar = target->dev->ar;
+ enum htc_endpoint_id endpoint = packet->endpoint;
+
+ if (endpoint == ar->ctrl_ep) {
+ /*
+ * Under normal WMI if this is getting full, then something
+ * is running rampant the host should not be exhausting the
+ * WMI queue with too many commands the only exception to
+ * this is during testing using endpointping.
+ */
+ spin_lock_bh(&ar->lock);
+ set_bit(WMI_CTRL_EP_FULL, &ar->flag);
+ spin_unlock_bh(&ar->lock);
+ ath6kl_err("wmi ctrl ep is full\n");
+ return HTC_SEND_FULL_KEEP;
+ }
+
+ if (packet->info.tx.tag == ATH6KL_CONTROL_PKT_TAG)
+ return HTC_SEND_FULL_KEEP;
+
+ if (ar->nw_type == ADHOC_NETWORK)
+ /*
+ * In adhoc mode, we cannot differentiate traffic
+ * priorities so there is no need to continue, however we
+ * should stop the network.
+ */
+ goto stop_net_queues;
+
+ /*
+ * The last MAX_HI_COOKIE_NUM "batch" of cookies are reserved for
+ * the highest active stream.
+ */
+ if (ar->ac_stream_pri_map[ar->ep2ac_map[endpoint]] <
+ ar->hiac_stream_active_pri &&
+ ar->cookie_count <= MAX_HI_COOKIE_NUM)
+ /*
+ * Give preference to the highest priority stream by
+ * dropping the packets which overflowed.
+ */
+ return HTC_SEND_FULL_DROP;
+
+stop_net_queues:
+ spin_lock_bh(&ar->lock);
+ set_bit(NETQ_STOPPED, &ar->flag);
+ spin_unlock_bh(&ar->lock);
+ netif_stop_queue(ar->net_dev);
+
+ return HTC_SEND_FULL_KEEP;
+}
+
+/* TODO this needs to be looked at */
+static void ath6kl_tx_clear_node_map(struct ath6kl *ar,
+ enum htc_endpoint_id eid, u32 map_no)
+{
+ u32 i;
+
+ if (ar->nw_type != ADHOC_NETWORK)
+ return;
+
+ if (!ar->ibss_ps_enable)
+ return;
+
+ if (eid == ar->ctrl_ep)
+ return;
+
+ if (map_no == 0)
+ return;
+
+ map_no--;
+ ar->node_map[map_no].tx_pend--;
+
+ if (ar->node_map[map_no].tx_pend)
+ return;
+
+ if (map_no != (ar->node_num - 1))
+ return;
+
+ for (i = ar->node_num; i > 0; i--) {
+ if (ar->node_map[i - 1].tx_pend)
+ break;
+
+ memset(&ar->node_map[i - 1], 0,
+ sizeof(struct ath6kl_node_mapping));
+ ar->node_num--;
+ }
+}
+
+void ath6kl_tx_complete(void *context, struct list_head *packet_queue)
+{
+ struct ath6kl *ar = context;
+ struct sk_buff_head skb_queue;
+ struct htc_packet *packet;
+ struct sk_buff *skb;
+ struct ath6kl_cookie *ath6kl_cookie;
+ u32 map_no = 0;
+ int status;
+ enum htc_endpoint_id eid;
+ bool wake_event = false;
+ bool flushing = false;
+
+ skb_queue_head_init(&skb_queue);
+
+ /* lock the driver as we update internal state */
+ spin_lock_bh(&ar->lock);
+
+ /* reap completed packets */
+ while (!list_empty(packet_queue)) {
+
+ packet = list_first_entry(packet_queue, struct htc_packet,
+ list);
+ list_del(&packet->list);
+
+ ath6kl_cookie = (struct ath6kl_cookie *)packet->pkt_cntxt;
+ if (!ath6kl_cookie)
+ goto fatal;
+
+ status = packet->status;
+ skb = ath6kl_cookie->skb;
+ eid = packet->endpoint;
+ map_no = ath6kl_cookie->map_no;
+
+ if (!skb || !skb->data)
+ goto fatal;
+
+ packet->buf = skb->data;
+
+ __skb_queue_tail(&skb_queue, skb);
+
+ if (!status && (packet->act_len != skb->len))
+ goto fatal;
+
+ ar->tx_pending[eid]--;
+
+ if (eid != ar->ctrl_ep)
+ ar->total_tx_data_pend--;
+
+ if (eid == ar->ctrl_ep) {
+ if (test_bit(WMI_CTRL_EP_FULL, &ar->flag))
+ clear_bit(WMI_CTRL_EP_FULL, &ar->flag);
+
+ if (ar->tx_pending[eid] == 0)
+ wake_event = true;
+ }
+
+ if (status) {
+ if (status == -ECANCELED)
+ /* a packet was flushed */
+ flushing = true;
+
+ ar->net_stats.tx_errors++;
+
+ if (status != -ENOSPC)
+ ath6kl_err("tx error, status: 0x%x\n", status);
+ ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
+ "%s: skb=0x%p data=0x%p len=0x%x eid=%d %s\n",
+ __func__, skb, packet->buf, packet->act_len,
+ eid, "error!");
+ } else {
+ ath6kl_dbg(ATH6KL_DBG_WLAN_TX,
+ "%s: skb=0x%p data=0x%p len=0x%x eid=%d %s\n",
+ __func__, skb, packet->buf, packet->act_len,
+ eid, "OK");
+
+ flushing = false;
+ ar->net_stats.tx_packets++;
+ ar->net_stats.tx_bytes += skb->len;
+ }
+
+ ath6kl_tx_clear_node_map(ar, eid, map_no);
+
+ ath6kl_free_cookie(ar, ath6kl_cookie);
+
+ if (test_bit(NETQ_STOPPED, &ar->flag))
+ clear_bit(NETQ_STOPPED, &ar->flag);
+ }
+
+ spin_unlock_bh(&ar->lock);
+
+ __skb_queue_purge(&skb_queue);
+
+ if (test_bit(CONNECTED, &ar->flag)) {
+ if (!flushing)
+ netif_wake_queue(ar->net_dev);
+ }
+
+ if (wake_event)
+ wake_up(&ar->event_wq);
+
+ return;
+
+fatal:
+ WARN_ON(1);
+ spin_unlock_bh(&ar->lock);
+ return;
+}
+
+void ath6kl_tx_data_cleanup(struct ath6kl *ar)
+{
+ int i;
+
+ /* flush all the data (non-control) streams */
+ for (i = 0; i < WMM_NUM_AC; i++)
+ htc_flush_txep(ar->htc_target, ar->ac2ep_map[i],
+ ATH6KL_DATA_PKT_TAG);
+}
+
+/* Rx functions */
+
+static void ath6kl_deliver_frames_to_nw_stack(struct net_device *dev,
+ struct sk_buff *skb)
+{
+ if (!skb)
+ return;
+
+ skb->dev = dev;
+
+ if (!(skb->dev->flags & IFF_UP)) {
+ dev_kfree_skb(skb);
+ return;
+ }
+
+ skb->protocol = eth_type_trans(skb, skb->dev);
+
+ netif_rx_ni(skb);
+}
+
+static void ath6kl_alloc_netbufs(struct sk_buff_head *q, u16 num)
+{
+ struct sk_buff *skb;
+
+ while (num) {
+ skb = ath6kl_buf_alloc(ATH6KL_BUFFER_SIZE);
+ if (!skb) {
+ ath6kl_err("netbuf allocation failed\n");
+ return;
+ }
+ skb_queue_tail(q, skb);
+ num--;
+ }
+}
+
+static struct sk_buff *aggr_get_free_skb(struct aggr_info *p_aggr)
+{
+ struct sk_buff *skb = NULL;
+
+ if (skb_queue_len(&p_aggr->free_q) < (AGGR_NUM_OF_FREE_NETBUFS >> 2))
+ ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS);
+
+ skb = skb_dequeue(&p_aggr->free_q);
+
+ return skb;
+}
+
+void ath6kl_rx_refill(struct htc_target *target, enum htc_endpoint_id endpoint)
+{
+ struct ath6kl *ar = target->dev->ar;
+ struct sk_buff *skb;
+ int rx_buf;
+ int n_buf_refill;
+ struct htc_packet *packet;
+ struct list_head queue;
+
+ n_buf_refill = ATH6KL_MAX_RX_BUFFERS -
+ htc_get_rxbuf_num(ar->htc_target, endpoint);
+
+ if (n_buf_refill <= 0)
+ return;
+
+ INIT_LIST_HEAD(&queue);
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_RX,
+ "%s: providing htc with %d buffers at eid=%d\n",
+ __func__, n_buf_refill, endpoint);
+
+ for (rx_buf = 0; rx_buf < n_buf_refill; rx_buf++) {
+ skb = ath6kl_buf_alloc(ATH6KL_BUFFER_SIZE);
+ if (!skb)
+ break;
+
+ packet = (struct htc_packet *) skb->head;
+ set_htc_rxpkt_info(packet, skb, skb->data,
+ ATH6KL_BUFFER_SIZE, endpoint);
+ list_add_tail(&packet->list, &queue);
+ }
+
+ if (!list_empty(&queue))
+ htc_add_rxbuf_multiple(ar->htc_target, &queue);
+}
+
+void ath6kl_refill_amsdu_rxbufs(struct ath6kl *ar, int count)
+{
+ struct htc_packet *packet;
+ struct sk_buff *skb;
+
+ while (count) {
+ skb = ath6kl_buf_alloc(ATH6KL_AMSDU_BUFFER_SIZE);
+ if (!skb)
+ return;
+
+ packet = (struct htc_packet *) skb->head;
+ set_htc_rxpkt_info(packet, skb, skb->data,
+ ATH6KL_AMSDU_BUFFER_SIZE, 0);
+ spin_lock_bh(&ar->lock);
+ list_add_tail(&packet->list, &ar->amsdu_rx_buffer_queue);
+ spin_unlock_bh(&ar->lock);
+ count--;
+ }
+}
+
+/*
+ * Callback to allocate a receive buffer for a pending packet. We use a
+ * pre-allocated list of buffers of maximum AMSDU size (4K).
+ */
+struct htc_packet *ath6kl_alloc_amsdu_rxbuf(struct htc_target *target,
+ enum htc_endpoint_id endpoint,
+ int len)
+{
+ struct ath6kl *ar = target->dev->ar;
+ struct htc_packet *packet = NULL;
+ struct list_head *pkt_pos;
+ int refill_cnt = 0, depth = 0;
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: eid=%d, len:%d\n",
+ __func__, endpoint, len);
+
+ if ((len <= ATH6KL_BUFFER_SIZE) ||
+ (len > ATH6KL_AMSDU_BUFFER_SIZE))
+ return NULL;
+
+ spin_lock_bh(&ar->lock);
+
+ if (list_empty(&ar->amsdu_rx_buffer_queue)) {
+ spin_unlock_bh(&ar->lock);
+ refill_cnt = ATH6KL_MAX_AMSDU_RX_BUFFERS;
+ goto refill_buf;
+ }
+
+ packet = list_first_entry(&ar->amsdu_rx_buffer_queue,
+ struct htc_packet, list);
+ list_del(&packet->list);
+ list_for_each(pkt_pos, &ar->amsdu_rx_buffer_queue)
+ depth++;
+
+ refill_cnt = ATH6KL_MAX_AMSDU_RX_BUFFERS - depth;
+ spin_unlock_bh(&ar->lock);
+
+ /* set actual endpoint ID */
+ packet->endpoint = endpoint;
+
+refill_buf:
+ if (refill_cnt >= ATH6KL_AMSDU_REFILL_THRESHOLD)
+ ath6kl_refill_amsdu_rxbufs(ar, refill_cnt);
+
+ return packet;
+}
+
+static void aggr_slice_amsdu(struct aggr_info *p_aggr,
+ struct rxtid *rxtid, struct sk_buff *skb)
+{
+ struct sk_buff *new_skb;
+ struct ethhdr *hdr;
+ u16 frame_8023_len, payload_8023_len, mac_hdr_len, amsdu_len;
+ u8 *framep;
+
+ mac_hdr_len = sizeof(struct ethhdr);
+ framep = skb->data + mac_hdr_len;
+ amsdu_len = skb->len - mac_hdr_len;
+
+ while (amsdu_len > mac_hdr_len) {
+ hdr = (struct ethhdr *) framep;
+ payload_8023_len = ntohs(hdr->h_proto);
+
+ if (payload_8023_len < MIN_MSDU_SUBFRAME_PAYLOAD_LEN ||
+ payload_8023_len > MAX_MSDU_SUBFRAME_PAYLOAD_LEN) {
+ ath6kl_err("802.3 AMSDU frame bound check failed. len %d\n",
+ payload_8023_len);
+ break;
+ }
+
+ frame_8023_len = payload_8023_len + mac_hdr_len;
+ new_skb = aggr_get_free_skb(p_aggr);
+ if (!new_skb) {
+ ath6kl_err("no buffer available\n");
+ break;
+ }
+
+ memcpy(new_skb->data, framep, frame_8023_len);
+ skb_put(new_skb, frame_8023_len);
+ if (ath6kl_wmi_dot3_2_dix(new_skb)) {
+ ath6kl_err("dot3_2_dix error\n");
+ dev_kfree_skb(new_skb);
+ break;
+ }
+
+ skb_queue_tail(&rxtid->q, new_skb);
+
+ /* Is this the last subframe within this aggregate ? */
+ if ((amsdu_len - frame_8023_len) == 0)
+ break;
+
+ /* Add the length of A-MSDU subframe padding bytes -
+ * Round to nearest word.
+ */
+ frame_8023_len = ALIGN(frame_8023_len + 3, 3);
+
+ framep += frame_8023_len;
+ amsdu_len -= frame_8023_len;
+ }
+
+ dev_kfree_skb(skb);
+}
+
+static void aggr_deque_frms(struct aggr_info *p_aggr, u8 tid,
+ u16 seq_no, u8 order)
+{
+ struct sk_buff *skb;
+ struct rxtid *rxtid;
+ struct skb_hold_q *node;
+ u16 idx, idx_end, seq_end;
+ struct rxtid_stats *stats;
+
+ if (!p_aggr)
+ return;
+
+ rxtid = &p_aggr->rx_tid[tid];
+ stats = &p_aggr->stat[tid];
+
+ idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
+
+ /*
+ * idx_end is typically the last possible frame in the window,
+ * but changes to 'the' seq_no, when BAR comes. If seq_no
+ * is non-zero, we will go up to that and stop.
+ * Note: last seq no in current window will occupy the same
+ * index position as index that is just previous to start.
+ * An imp point : if win_sz is 7, for seq_no space of 4095,
+ * then, there would be holes when sequence wrap around occurs.
+ * Target should judiciously choose the win_sz, based on
+ * this condition. For 4095, (TID_WINDOW_SZ = 2 x win_sz
+ * 2, 4, 8, 16 win_sz works fine).
+ * We must deque from "idx" to "idx_end", including both.
+ */
+ seq_end = seq_no ? seq_no : rxtid->seq_next;
+ idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz);
+
+ spin_lock_bh(&rxtid->lock);
+
+ do {
+ node = &rxtid->hold_q[idx];
+ if ((order == 1) && (!node->skb))
+ break;
+
+ if (node->skb) {
+ if (node->is_amsdu)
+ aggr_slice_amsdu(p_aggr, rxtid, node->skb);
+ else
+ skb_queue_tail(&rxtid->q, node->skb);
+ node->skb = NULL;
+ } else
+ stats->num_hole++;
+
+ rxtid->seq_next = ATH6KL_NEXT_SEQ_NO(rxtid->seq_next);
+ idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
+ } while (idx != idx_end);
+
+ spin_unlock_bh(&rxtid->lock);
+
+ stats->num_delivered += skb_queue_len(&rxtid->q);
+
+ while ((skb = skb_dequeue(&rxtid->q)))
+ ath6kl_deliver_frames_to_nw_stack(p_aggr->dev, skb);
+}
+
+static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
+ u16 seq_no,
+ bool is_amsdu, struct sk_buff *frame)
+{
+ struct rxtid *rxtid;
+ struct rxtid_stats *stats;
+ struct sk_buff *skb;
+ struct skb_hold_q *node;
+ u16 idx, st, cur, end;
+ bool is_queued = false;
+ u16 extended_end;
+
+ rxtid = &agg_info->rx_tid[tid];
+ stats = &agg_info->stat[tid];
+
+ stats->num_into_aggr++;
+
+ if (!rxtid->aggr) {
+ if (is_amsdu) {
+ aggr_slice_amsdu(agg_info, rxtid, frame);
+ is_queued = true;
+ stats->num_amsdu++;
+ while ((skb = skb_dequeue(&rxtid->q)))
+ ath6kl_deliver_frames_to_nw_stack(agg_info->dev,
+ skb);
+ }
+ return is_queued;
+ }
+
+ /* Check the incoming sequence no, if it's in the window */
+ st = rxtid->seq_next;
+ cur = seq_no;
+ end = (st + rxtid->hold_q_sz-1) & ATH6KL_MAX_SEQ_NO;
+
+ if (((st < end) && (cur < st || cur > end)) ||
+ ((st > end) && (cur > end) && (cur < st))) {
+ extended_end = (end + rxtid->hold_q_sz - 1) &
+ ATH6KL_MAX_SEQ_NO;
+
+ if (((end < extended_end) &&
+ (cur < end || cur > extended_end)) ||
+ ((end > extended_end) && (cur > extended_end) &&
+ (cur < end))) {
+ aggr_deque_frms(agg_info, tid, 0, 0);
+ if (cur >= rxtid->hold_q_sz - 1)
+ rxtid->seq_next = cur - (rxtid->hold_q_sz - 1);
+ else
+ rxtid->seq_next = ATH6KL_MAX_SEQ_NO -
+ (rxtid->hold_q_sz - 2 - cur);
+ } else {
+ /*
+ * Dequeue only those frames that are outside the
+ * new shifted window.
+ */
+ if (cur >= rxtid->hold_q_sz - 1)
+ st = cur - (rxtid->hold_q_sz - 1);
+ else
+ st = ATH6KL_MAX_SEQ_NO -
+ (rxtid->hold_q_sz - 2 - cur);
+
+ aggr_deque_frms(agg_info, tid, st, 0);
+ }
+
+ stats->num_oow++;
+ }
+
+ idx = AGGR_WIN_IDX(seq_no, rxtid->hold_q_sz);
+
+ node = &rxtid->hold_q[idx];
+
+ spin_lock_bh(&rxtid->lock);
+
+ /*
+ * Is the cur frame duplicate or something beyond our window(hold_q
+ * -> which is 2x, already)?
+ *
+ * 1. Duplicate is easy - drop incoming frame.
+ * 2. Not falling in current sliding window.
+ * 2a. is the frame_seq_no preceding current tid_seq_no?
+ * -> drop the frame. perhaps sender did not get our ACK.
+ * this is taken care of above.
+ * 2b. is the frame_seq_no beyond window(st, TID_WINDOW_SZ);
+ * -> Taken care of it above, by moving window forward.
+ */
+ dev_kfree_skb(node->skb);
+ stats->num_dups++;
+
+ node->skb = frame;
+ is_queued = true;
+ node->is_amsdu = is_amsdu;
+ node->seq_no = seq_no;
+
+ if (node->is_amsdu)
+ stats->num_amsdu++;
+ else
+ stats->num_mpdu++;
+
+ spin_unlock_bh(&rxtid->lock);
+
+ aggr_deque_frms(agg_info, tid, 0, 1);
+
+ if (agg_info->timer_scheduled)
+ rxtid->progress = true;
+ else
+ for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) {
+ if (rxtid->hold_q[idx].skb) {
+ /*
+ * There is a frame in the queue and no
+ * timer so start a timer to ensure that
+ * the frame doesn't remain stuck
+ * forever.
+ */
+ agg_info->timer_scheduled = true;
+ mod_timer(&agg_info->timer,
+ (jiffies +
+ HZ * (AGGR_RX_TIMEOUT) / 1000));
+ rxtid->progress = false;
+ rxtid->timer_mon = true;
+ break;
+ }
+ }
+
+ return is_queued;
+}
+
+void ath6kl_rx(struct htc_target *target, struct htc_packet *packet)
+{
+ struct ath6kl *ar = target->dev->ar;
+ struct sk_buff *skb = packet->pkt_cntxt;
+ struct wmi_rx_meta_v2 *meta;
+ struct wmi_data_hdr *dhdr;
+ int min_hdr_len;
+ u8 meta_type, dot11_hdr = 0;
+ int status = packet->status;
+ enum htc_endpoint_id ept = packet->endpoint;
+ bool is_amsdu, prev_ps, ps_state = false;
+ struct ath6kl_sta *conn = NULL;
+ struct sk_buff *skb1 = NULL;
+ struct ethhdr *datap = NULL;
+ u16 seq_no, offset;
+ u8 tid;
+
+ ath6kl_dbg(ATH6KL_DBG_WLAN_RX,
+ "%s: ar=0x%p eid=%d, skb=0x%p, data=0x%p, len=0x%x status:%d",
+ __func__, ar, ept, skb, packet->buf,
+ packet->act_len, status);
+
+ if (status || !(skb->data + HTC_HDR_LENGTH)) {
+ ar->net_stats.rx_errors++;
+ dev_kfree_skb(skb);
+ return;
+ }
+
+ /*
+ * Take lock to protect buffer counts and adaptive power throughput
+ * state.
+ */
+ spin_lock_bh(&ar->lock);
+
+ ar->net_stats.rx_packets++;
+ ar->net_stats.rx_bytes += packet->act_len;
+
+ skb_put(skb, packet->act_len + HTC_HDR_LENGTH);
+ skb_pull(skb, HTC_HDR_LENGTH);
+
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, __func__, skb->data, skb->len);
+
+ spin_unlock_bh(&ar->lock);
+
+ skb->dev = ar->net_dev;
+
+ if (!test_bit(WMI_ENABLED, &ar->flag)) {
+ if (EPPING_ALIGNMENT_PAD > 0)
+ skb_pull(skb, EPPING_ALIGNMENT_PAD);
+ ath6kl_deliver_frames_to_nw_stack(ar->net_dev, skb);
+ return;
+ }
+
+ if (ept == ar->ctrl_ep) {
+ ath6kl_wmi_control_rx(ar->wmi, skb);
+ return;
+ }
+
+ min_hdr_len = sizeof(struct ethhdr);
+ min_hdr_len += sizeof(struct wmi_data_hdr) +
+ sizeof(struct ath6kl_llc_snap_hdr);
+
+ dhdr = (struct wmi_data_hdr *) skb->data;
+
+ /*
+ * In the case of AP mode we may receive NULL data frames
+ * that do not have LLC hdr. They are 16 bytes in size.
+ * Allow these frames in the AP mode.
+ */
+ if (ar->nw_type != AP_NETWORK &&
+ ((packet->act_len < min_hdr_len) ||
+ (packet->act_len > WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH))) {
+ ath6kl_info("frame len is too short or too long\n");
+ ar->net_stats.rx_errors++;
+ ar->net_stats.rx_length_errors++;
+ dev_kfree_skb(skb);
+ return;
+ }
+
+ /* Get the Power save state of the STA */
+ if (ar->nw_type == AP_NETWORK) {
+ meta_type = wmi_data_hdr_get_meta(dhdr);
+
+ ps_state = !!((dhdr->info >> WMI_DATA_HDR_PS_SHIFT) &
+ WMI_DATA_HDR_PS_MASK);
+
+ offset = sizeof(struct wmi_data_hdr);
+
+ switch (meta_type) {
+ case 0:
+ break;
+ case WMI_META_VERSION_1:
+ offset += sizeof(struct wmi_rx_meta_v1);
+ break;
+ case WMI_META_VERSION_2:
+ offset += sizeof(struct wmi_rx_meta_v2);
+ break;
+ default:
+ break;
+ }
+
+ datap = (struct ethhdr *) (skb->data + offset);
+ conn = ath6kl_find_sta(ar, datap->h_source);
+
+ if (!conn) {
+ dev_kfree_skb(skb);
+ return;
+ }
+
+ /*
+ * If there is a change in PS state of the STA,
+ * take appropriate steps:
+ *
+ * 1. If Sleep-->Awake, flush the psq for the STA
+ * Clear the PVB for the STA.
+ * 2. If Awake-->Sleep, Starting queueing frames
+ * the STA.
+ */
+ prev_ps = !!(conn->sta_flags & STA_PS_SLEEP);
+
+ if (ps_state)
+ conn->sta_flags |= STA_PS_SLEEP;
+ else
+ conn->sta_flags &= ~STA_PS_SLEEP;
+
+ if (prev_ps ^ !!(conn->sta_flags & STA_PS_SLEEP)) {
+ if (!(conn->sta_flags & STA_PS_SLEEP)) {
+ struct sk_buff *skbuff = NULL;
+
+ spin_lock_bh(&conn->psq_lock);
+ while ((skbuff = skb_dequeue(&conn->psq))
+ != NULL) {
+ spin_unlock_bh(&conn->psq_lock);
+ ath6kl_data_tx(skbuff, ar->net_dev);
+ spin_lock_bh(&conn->psq_lock);
+ }
+ spin_unlock_bh(&conn->psq_lock);
+ /* Clear the PVB for this STA */
+ ath6kl_wmi_set_pvb_cmd(ar->wmi, conn->aid, 0);
+ }
+ }
+
+ /* drop NULL data frames here */
+ if ((packet->act_len < min_hdr_len) ||
+ (packet->act_len >
+ WMI_MAX_AMSDU_RX_DATA_FRAME_LENGTH)) {
+ dev_kfree_skb(skb);
+ return;
+ }
+ }
+
+ is_amsdu = wmi_data_hdr_is_amsdu(dhdr) ? true : false;
+ tid = wmi_data_hdr_get_up(dhdr);
+ seq_no = wmi_data_hdr_get_seqno(dhdr);
+ meta_type = wmi_data_hdr_get_meta(dhdr);
+ dot11_hdr = wmi_data_hdr_get_dot11(dhdr);
+
+ ath6kl_wmi_data_hdr_remove(ar->wmi, skb);
+
+ switch (meta_type) {
+ case WMI_META_VERSION_1:
+ skb_pull(skb, sizeof(struct wmi_rx_meta_v1));
+ break;
+ case WMI_META_VERSION_2:
+ meta = (struct wmi_rx_meta_v2 *) skb->data;
+ if (meta->csum_flags & 0x1) {
+ skb->ip_summed = CHECKSUM_COMPLETE;
+ skb->csum = (__force __wsum) meta->csum;
+ }
+ skb_pull(skb, sizeof(struct wmi_rx_meta_v2));
+ break;
+ default:
+ break;
+ }
+
+ if (dot11_hdr)
+ status = ath6kl_wmi_dot11_hdr_remove(ar->wmi, skb);
+ else if (!is_amsdu)
+ status = ath6kl_wmi_dot3_2_dix(skb);
+
+ if (status) {
+ /*
+ * Drop frames that could not be processed (lack of
+ * memory, etc.)
+ */
+ dev_kfree_skb(skb);
+ return;
+ }
+
+ if (!(ar->net_dev->flags & IFF_UP)) {
+ dev_kfree_skb(skb);
+ return;
+ }
+
+ if (ar->nw_type == AP_NETWORK) {
+ datap = (struct ethhdr *) skb->data;
+ if (is_multicast_ether_addr(datap->h_dest))
+ /*
+ * Bcast/Mcast frames should be sent to the
+ * OS stack as well as on the air.
+ */
+ skb1 = skb_copy(skb, GFP_ATOMIC);
+ else {
+ /*
+ * Search for a connected STA with dstMac
+ * as the Mac address. If found send the
+ * frame to it on the air else send the
+ * frame up the stack.
+ */
+ struct ath6kl_sta *conn = NULL;
+ conn = ath6kl_find_sta(ar, datap->h_dest);
+
+ if (conn && ar->intra_bss) {
+ skb1 = skb;
+ skb = NULL;
+ } else if (conn && !ar->intra_bss) {
+ dev_kfree_skb(skb);
+ skb = NULL;
+ }
+ }
+ if (skb1)
+ ath6kl_data_tx(skb1, ar->net_dev);
+ }
+
+ if (!aggr_process_recv_frm(ar->aggr_cntxt, tid, seq_no,
+ is_amsdu, skb))
+ ath6kl_deliver_frames_to_nw_stack(ar->net_dev, skb);
+}
+
+static void aggr_timeout(unsigned long arg)
+{
+ u8 i, j;
+ struct aggr_info *p_aggr = (struct aggr_info *) arg;
+ struct rxtid *rxtid;
+ struct rxtid_stats *stats;
+
+ for (i = 0; i < NUM_OF_TIDS; i++) {
+ rxtid = &p_aggr->rx_tid[i];
+ stats = &p_aggr->stat[i];
+
+ if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress)
+ continue;
+
+ stats->num_timeouts++;
+ ath6kl_err("aggr timeout (st %d end %d)\n",
+ rxtid->seq_next,
+ ((rxtid->seq_next + rxtid->hold_q_sz-1) &
+ ATH6KL_MAX_SEQ_NO));
+ aggr_deque_frms(p_aggr, i, 0, 0);
+ }
+
+ p_aggr->timer_scheduled = false;
+
+ for (i = 0; i < NUM_OF_TIDS; i++) {
+ rxtid = &p_aggr->rx_tid[i];
+
+ if (rxtid->aggr && rxtid->hold_q) {
+ for (j = 0; j < rxtid->hold_q_sz; j++) {
+ if (rxtid->hold_q[j].skb) {
+ p_aggr->timer_scheduled = true;
+ rxtid->timer_mon = true;
+ rxtid->progress = false;
+ break;
+ }
+ }
+
+ if (j >= rxtid->hold_q_sz)
+ rxtid->timer_mon = false;
+ }
+ }
+
+ if (p_aggr->timer_scheduled)
+ mod_timer(&p_aggr->timer,
+ jiffies + msecs_to_jiffies(AGGR_RX_TIMEOUT));
+}
+
+static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid)
+{
+ struct rxtid *rxtid;
+ struct rxtid_stats *stats;
+
+ if (!p_aggr || tid >= NUM_OF_TIDS)
+ return;
+
+ rxtid = &p_aggr->rx_tid[tid];
+ stats = &p_aggr->stat[tid];
+
+ if (rxtid->aggr)
+ aggr_deque_frms(p_aggr, tid, 0, 0);
+
+ rxtid->aggr = false;
+ rxtid->progress = false;
+ rxtid->timer_mon = false;
+ rxtid->win_sz = 0;
+ rxtid->seq_next = 0;
+ rxtid->hold_q_sz = 0;
+
+ kfree(rxtid->hold_q);
+ rxtid->hold_q = NULL;
+
+ memset(stats, 0, sizeof(struct rxtid_stats));
+}
+
+void aggr_recv_addba_req_evt(struct ath6kl *ar, u8 tid, u16 seq_no, u8 win_sz)
+{
+ struct aggr_info *p_aggr = ar->aggr_cntxt;
+ struct rxtid *rxtid;
+ struct rxtid_stats *stats;
+ u16 hold_q_size;
+
+ if (!p_aggr)
+ return;
+
+ rxtid = &p_aggr->rx_tid[tid];
+ stats = &p_aggr->stat[tid];
+
+ if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX)
+ ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: win_sz %d, tid %d\n",
+ __func__, win_sz, tid);
+
+ if (rxtid->aggr)
+ aggr_delete_tid_state(p_aggr, tid);
+
+ rxtid->seq_next = seq_no;
+ hold_q_size = TID_WINDOW_SZ(win_sz) * sizeof(struct skb_hold_q);
+ rxtid->hold_q = kzalloc(hold_q_size, GFP_KERNEL);
+ if (!rxtid->hold_q)
+ return;
+
+ rxtid->win_sz = win_sz;
+ rxtid->hold_q_sz = TID_WINDOW_SZ(win_sz);
+ if (!skb_queue_empty(&rxtid->q))
+ return;
+
+ rxtid->aggr = true;
+}
+
+struct aggr_info *aggr_init(struct net_device *dev)
+{
+ struct aggr_info *p_aggr = NULL;
+ struct rxtid *rxtid;
+ u8 i;
+
+ p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL);
+ if (!p_aggr) {
+ ath6kl_err("failed to alloc memory for aggr_node\n");
+ return NULL;
+ }
+
+ p_aggr->aggr_sz = AGGR_SZ_DEFAULT;
+ p_aggr->dev = dev;
+ init_timer(&p_aggr->timer);
+ p_aggr->timer.function = aggr_timeout;
+ p_aggr->timer.data = (unsigned long) p_aggr;
+
+ p_aggr->timer_scheduled = false;
+ skb_queue_head_init(&p_aggr->free_q);
+
+ ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS);
+
+ for (i = 0; i < NUM_OF_TIDS; i++) {
+ rxtid = &p_aggr->rx_tid[i];
+ rxtid->aggr = false;
+ rxtid->progress = false;
+ rxtid->timer_mon = false;
+ skb_queue_head_init(&rxtid->q);
+ spin_lock_init(&rxtid->lock);
+ }
+
+ return p_aggr;
+}
+
+void aggr_recv_delba_req_evt(struct ath6kl *ar, u8 tid)
+{
+ struct aggr_info *p_aggr = ar->aggr_cntxt;
+ struct rxtid *rxtid;
+
+ if (!p_aggr)
+ return;
+
+ rxtid = &p_aggr->rx_tid[tid];
+
+ if (rxtid->aggr)
+ aggr_delete_tid_state(p_aggr, tid);
+}
+
+void aggr_reset_state(struct aggr_info *aggr_info)
+{
+ u8 tid;
+
+ for (tid = 0; tid < NUM_OF_TIDS; tid++)
+ aggr_delete_tid_state(aggr_info, tid);
+}
+
+/* clean up our amsdu buffer list */
+void ath6kl_cleanup_amsdu_rxbufs(struct ath6kl *ar)
+{
+ struct htc_packet *packet, *tmp_pkt;
+
+ spin_lock_bh(&ar->lock);
+ if (list_empty(&ar->amsdu_rx_buffer_queue)) {
+ spin_unlock_bh(&ar->lock);
+ return;
+ }
+
+ list_for_each_entry_safe(packet, tmp_pkt, &ar->amsdu_rx_buffer_queue,
+ list) {
+ list_del(&packet->list);
+ spin_unlock_bh(&ar->lock);
+ dev_kfree_skb(packet->pkt_cntxt);
+ spin_lock_bh(&ar->lock);
+ }
+
+ spin_unlock_bh(&ar->lock);
+}
+
+void aggr_module_destroy(struct aggr_info *aggr_info)
+{
+ struct rxtid *rxtid;
+ u8 i, k;
+
+ if (!aggr_info)
+ return;
+
+ if (aggr_info->timer_scheduled) {
+ del_timer(&aggr_info->timer);
+ aggr_info->timer_scheduled = false;
+ }
+
+ for (i = 0; i < NUM_OF_TIDS; i++) {
+ rxtid = &aggr_info->rx_tid[i];
+ if (rxtid->hold_q) {
+ for (k = 0; k < rxtid->hold_q_sz; k++)
+ dev_kfree_skb(rxtid->hold_q[k].skb);
+ kfree(rxtid->hold_q);
+ }
+
+ skb_queue_purge(&rxtid->q);
+ }
+
+ skb_queue_purge(&aggr_info->free_q);
+ kfree(aggr_info);
+}
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.c b/drivers/net/wireless/ath/ath6kl/wmi.c
new file mode 100644
index 000000000000..a52d7d201fbd
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/wmi.c
@@ -0,0 +1,2762 @@
+/*
+ * Copyright (c) 2004-2011 Atheros Communications Inc.
+ *
+ * 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 <linux/ip.h>
+#include "core.h"
+#include "debug.h"
+
+static int ath6kl_wmi_sync_point(struct wmi *wmi);
+
+static const s32 wmi_rate_tbl[][2] = {
+ /* {W/O SGI, with SGI} */
+ {1000, 1000},
+ {2000, 2000},
+ {5500, 5500},
+ {11000, 11000},
+ {6000, 6000},
+ {9000, 9000},
+ {12000, 12000},
+ {18000, 18000},
+ {24000, 24000},
+ {36000, 36000},
+ {48000, 48000},
+ {54000, 54000},
+ {6500, 7200},
+ {13000, 14400},
+ {19500, 21700},
+ {26000, 28900},
+ {39000, 43300},
+ {52000, 57800},
+ {58500, 65000},
+ {65000, 72200},
+ {13500, 15000},
+ {27000, 30000},
+ {40500, 45000},
+ {54000, 60000},
+ {81000, 90000},
+ {108000, 120000},
+ {121500, 135000},
+ {135000, 150000},
+ {0, 0}
+};
+
+/* 802.1d to AC mapping. Refer pg 57 of WMM-test-plan-v1.2 */
+static const u8 up_to_ac[] = {
+ WMM_AC_BE,
+ WMM_AC_BK,
+ WMM_AC_BK,
+ WMM_AC_BE,
+ WMM_AC_VI,
+ WMM_AC_VI,
+ WMM_AC_VO,
+ WMM_AC_VO,
+};
+
+void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id ep_id)
+{
+ if (WARN_ON(ep_id == ENDPOINT_UNUSED || ep_id >= ENDPOINT_MAX))
+ return;
+
+ wmi->ep_id = ep_id;
+}
+
+enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi)
+{
+ return wmi->ep_id;
+}
+
+/* Performs DIX to 802.3 encapsulation for transmit packets.
+ * Assumes the entire DIX header is contigous and that there is
+ * enough room in the buffer for a 802.3 mac header and LLC+SNAP headers.
+ */
+int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb)
+{
+ struct ath6kl_llc_snap_hdr *llc_hdr;
+ struct ethhdr *eth_hdr;
+ size_t new_len;
+ __be16 type;
+ u8 *datap;
+ u16 size;
+
+ if (WARN_ON(skb == NULL))
+ return -EINVAL;
+
+ size = sizeof(struct ath6kl_llc_snap_hdr) + sizeof(struct wmi_data_hdr);
+ if (skb_headroom(skb) < size)
+ return -ENOMEM;
+
+ eth_hdr = (struct ethhdr *) skb->data;
+ type = eth_hdr->h_proto;
+
+ if (!is_ethertype(be16_to_cpu(type))) {
+ ath6kl_dbg(ATH6KL_DBG_WMI,
+ "%s: pkt is already in 802.3 format\n", __func__);
+ return 0;
+ }
+
+ new_len = skb->len - sizeof(*eth_hdr) + sizeof(*llc_hdr);
+
+ skb_push(skb, sizeof(struct ath6kl_llc_snap_hdr));
+ datap = skb->data;
+
+ eth_hdr->h_proto = cpu_to_be16(new_len);
+
+ memcpy(datap, eth_hdr, sizeof(*eth_hdr));
+
+ llc_hdr = (struct ath6kl_llc_snap_hdr *)(datap + sizeof(*eth_hdr));
+ llc_hdr->dsap = 0xAA;
+ llc_hdr->ssap = 0xAA;
+ llc_hdr->cntl = 0x03;
+ llc_hdr->org_code[0] = 0x0;
+ llc_hdr->org_code[1] = 0x0;
+ llc_hdr->org_code[2] = 0x0;
+ llc_hdr->eth_type = type;
+
+ return 0;
+}
+
+static int ath6kl_wmi_meta_add(struct wmi *wmi, struct sk_buff *skb,
+ u8 *version, void *tx_meta_info)
+{
+ struct wmi_tx_meta_v1 *v1;
+ struct wmi_tx_meta_v2 *v2;
+
+ if (WARN_ON(skb == NULL || version == NULL))
+ return -EINVAL;
+
+ switch (*version) {
+ case WMI_META_VERSION_1:
+ skb_push(skb, WMI_MAX_TX_META_SZ);
+ v1 = (struct wmi_tx_meta_v1 *) skb->data;
+ v1->pkt_id = 0;
+ v1->rate_plcy_id = 0;
+ *version = WMI_META_VERSION_1;
+ break;
+ case WMI_META_VERSION_2:
+ skb_push(skb, WMI_MAX_TX_META_SZ);
+ v2 = (struct wmi_tx_meta_v2 *) skb->data;
+ memcpy(v2, (struct wmi_tx_meta_v2 *) tx_meta_info,
+ sizeof(struct wmi_tx_meta_v2));
+ break;
+ }
+
+ return 0;
+}
+
+int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
+ u8 msg_type, bool more_data,
+ enum wmi_data_hdr_data_type data_type,
+ u8 meta_ver, void *tx_meta_info)
+{
+ struct wmi_data_hdr *data_hdr;
+ int ret;
+
+ if (WARN_ON(skb == NULL))
+ return -EINVAL;
+
+ ret = ath6kl_wmi_meta_add(wmi, skb, &meta_ver, tx_meta_info);
+ if (ret)
+ return ret;
+
+ skb_push(skb, sizeof(struct wmi_data_hdr));
+
+ data_hdr = (struct wmi_data_hdr *)skb->data;
+ memset(data_hdr, 0, sizeof(struct wmi_data_hdr));
+
+ data_hdr->info = msg_type << WMI_DATA_HDR_MSG_TYPE_SHIFT;
+ data_hdr->info |= data_type << WMI_DATA_HDR_DATA_TYPE_SHIFT;
+
+ if (more_data)
+ data_hdr->info |=
+ WMI_DATA_HDR_MORE_MASK << WMI_DATA_HDR_MORE_SHIFT;
+
+ data_hdr->info2 = cpu_to_le16(meta_ver << WMI_DATA_HDR_META_SHIFT);
+ data_hdr->info3 = 0;
+
+ return 0;
+}
+
+static u8 ath6kl_wmi_determine_user_priority(u8 *pkt, u32 layer2_pri)
+{
+ struct iphdr *ip_hdr = (struct iphdr *) pkt;
+ u8 ip_pri;
+
+ /*
+ * Determine IPTOS priority
+ *
+ * IP-TOS - 8bits
+ * : DSCP(6-bits) ECN(2-bits)
+ * : DSCP - P2 P1 P0 X X X
+ * where (P2 P1 P0) form 802.1D
+ */
+ ip_pri = ip_hdr->tos >> 5;
+ ip_pri &= 0x7;
+
+ if ((layer2_pri & 0x7) > ip_pri)
+ return (u8) layer2_pri & 0x7;
+ else
+ return ip_pri;
+}
+
+int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, struct sk_buff *skb,
+ u32 layer2_priority, bool wmm_enabled,
+ u8 *ac)
+{
+ struct wmi_data_hdr *data_hdr;
+ struct ath6kl_llc_snap_hdr *llc_hdr;
+ struct wmi_create_pstream_cmd cmd;
+ u32 meta_size, hdr_size;
+ u16 ip_type = IP_ETHERTYPE;
+ u8 stream_exist, usr_pri;
+ u8 traffic_class = WMM_AC_BE;
+ u8 *datap;
+
+ if (WARN_ON(skb == NULL))
+ return -EINVAL;
+
+ datap = skb->data;
+ data_hdr = (struct wmi_data_hdr *) datap;
+
+ meta_size = ((le16_to_cpu(data_hdr->info2) >> WMI_DATA_HDR_META_SHIFT) &
+ WMI_DATA_HDR_META_MASK) ? WMI_MAX_TX_META_SZ : 0;
+
+ if (!wmm_enabled) {
+ /* If WMM is disabled all traffic goes as BE traffic */
+ usr_pri = 0;
+ } else {
+ hdr_size = sizeof(struct ethhdr);
+
+ llc_hdr = (struct ath6kl_llc_snap_hdr *)(datap +
+ sizeof(struct
+ wmi_data_hdr) +
+ meta_size + hdr_size);
+
+ if (llc_hdr->eth_type == htons(ip_type)) {
+ /*
+ * Extract the endpoint info from the TOS field
+ * in the IP header.
+ */
+ usr_pri =
+ ath6kl_wmi_determine_user_priority(((u8 *) llc_hdr) +
+ sizeof(struct ath6kl_llc_snap_hdr),
+ layer2_priority);
+ } else
+ usr_pri = layer2_priority & 0x7;
+ }
+
+ /* workaround for WMM S5 */
+ if ((wmi->traffic_class == WMM_AC_VI) &&
+ ((usr_pri == 5) || (usr_pri == 4)))
+ usr_pri = 1;
+
+ /* Convert user priority to traffic class */
+ traffic_class = up_to_ac[usr_pri & 0x7];
+
+ wmi_data_hdr_set_up(data_hdr, usr_pri);
+
+ spin_lock_bh(&wmi->lock);
+ stream_exist = wmi->fat_pipe_exist;
+ spin_unlock_bh(&wmi->lock);
+
+ if (!(stream_exist & (1 << traffic_class))) {
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.traffic_class = traffic_class;
+ cmd.user_pri = usr_pri;
+ cmd.inactivity_int =
+ cpu_to_le32(WMI_IMPLICIT_PSTREAM_INACTIVITY_INT);
+ /* Implicit streams are created with TSID 0xFF */
+ cmd.tsid = WMI_IMPLICIT_PSTREAM;
+ ath6kl_wmi_create_pstream_cmd(wmi, &cmd);
+ }
+
+ *ac = traffic_class;
+
+ return 0;
+}
+
+int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb)
+{
+ struct ieee80211_hdr_3addr *pwh, wh;
+ struct ath6kl_llc_snap_hdr *llc_hdr;
+ struct ethhdr eth_hdr;
+ u32 hdr_size;
+ u8 *datap;
+ __le16 sub_type;
+
+ if (WARN_ON(skb == NULL))
+ return -EINVAL;
+
+ datap = skb->data;
+ pwh = (struct ieee80211_hdr_3addr *) datap;
+
+ sub_type = pwh->frame_control & cpu_to_le16(IEEE80211_FCTL_STYPE);
+
+ memcpy((u8 *) &wh, datap, sizeof(struct ieee80211_hdr_3addr));
+
+ /* Strip off the 802.11 header */
+ if (sub_type == cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
+ hdr_size = roundup(sizeof(struct ieee80211_qos_hdr),
+ sizeof(u32));
+ skb_pull(skb, hdr_size);
+ } else if (sub_type == cpu_to_le16(IEEE80211_STYPE_DATA))
+ skb_pull(skb, sizeof(struct ieee80211_hdr_3addr));
+
+ datap = skb->data;
+ llc_hdr = (struct ath6kl_llc_snap_hdr *)(datap);
+
+ eth_hdr.h_proto = llc_hdr->eth_type;
+ memset(eth_hdr.h_dest, 0, sizeof(eth_hdr.h_dest));
+ memset(eth_hdr.h_source, 0, sizeof(eth_hdr.h_source));
+
+ switch ((le16_to_cpu(wh.frame_control)) &
+ (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
+ case 0:
+ memcpy(eth_hdr.h_dest, wh.addr1, ETH_ALEN);
+ memcpy(eth_hdr.h_source, wh.addr2, ETH_ALEN);
+ break;
+ case IEEE80211_FCTL_TODS:
+ memcpy(eth_hdr.h_dest, wh.addr3, ETH_ALEN);
+ memcpy(eth_hdr.h_source, wh.addr2, ETH_ALEN);
+ break;
+ case IEEE80211_FCTL_FROMDS:
+ memcpy(eth_hdr.h_dest, wh.addr1, ETH_ALEN);
+ memcpy(eth_hdr.h_source, wh.addr3, ETH_ALEN);
+ break;
+ case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
+ break;
+ }
+
+ skb_pull(skb, sizeof(struct ath6kl_llc_snap_hdr));
+ skb_push(skb, sizeof(eth_hdr));
+
+ datap = skb->data;
+
+ memcpy(datap, &eth_hdr, sizeof(eth_hdr));
+
+ return 0;
+}
+
+/*
+ * Performs 802.3 to DIX encapsulation for received packets.
+ * Assumes the entire 802.3 header is contigous.
+ */
+int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb)
+{
+ struct ath6kl_llc_snap_hdr *llc_hdr;
+ struct ethhdr eth_hdr;
+ u8 *datap;
+
+ if (WARN_ON(skb == NULL))
+ return -EINVAL;
+
+ datap = skb->data;
+
+ memcpy(&eth_hdr, datap, sizeof(eth_hdr));
+
+ llc_hdr = (struct ath6kl_llc_snap_hdr *) (datap + sizeof(eth_hdr));
+ eth_hdr.h_proto = llc_hdr->eth_type;
+
+ skb_pull(skb, sizeof(struct ath6kl_llc_snap_hdr));
+ datap = skb->data;
+
+ memcpy(datap, &eth_hdr, sizeof(eth_hdr));
+
+ return 0;
+}
+
+int ath6kl_wmi_data_hdr_remove(struct wmi *wmi, struct sk_buff *skb)
+{
+ if (WARN_ON(skb == NULL))
+ return -EINVAL;
+
+ skb_pull(skb, sizeof(struct wmi_data_hdr));
+
+ return 0;
+}
+
+void ath6kl_wmi_iterate_nodes(struct wmi *wmi,
+ void (*f) (void *arg, struct bss *),
+ void *arg)
+{
+ wlan_iterate_nodes(&wmi->scan_table, f, arg);
+}
+
+static void ath6kl_wmi_convert_bssinfo_hdr2_to_hdr(struct sk_buff *skb,
+ u8 *datap)
+{
+ struct wmi_bss_info_hdr2 bih2;
+ struct wmi_bss_info_hdr *bih;
+
+ memcpy(&bih2, datap, sizeof(struct wmi_bss_info_hdr2));
+
+ skb_push(skb, 4);
+ bih = (struct wmi_bss_info_hdr *) skb->data;
+
+ bih->ch = bih2.ch;
+ bih->frame_type = bih2.frame_type;
+ bih->snr = bih2.snr;
+ bih->rssi = a_cpu_to_sle16(bih2.snr - 95);
+ bih->ie_mask = cpu_to_le32(le16_to_cpu(bih2.ie_mask));
+ memcpy(bih->bssid, bih2.bssid, ETH_ALEN);
+}
+
+static int ath6kl_wmi_tx_complete_event_rx(u8 *datap, int len)
+{
+ struct tx_complete_msg_v1 *msg_v1;
+ struct wmi_tx_complete_event *evt;
+ int index;
+ u16 size;
+
+ evt = (struct wmi_tx_complete_event *) datap;
+
+ ath6kl_dbg(ATH6KL_DBG_WMI, "comp: %d %d %d\n",
+ evt->num_msg, evt->msg_len, evt->msg_type);
+
+ if (!AR_DBG_LVL_CHECK(ATH6KL_DBG_WMI))
+ return 0;
+
+ for (index = 0; index < evt->num_msg; index++) {
+ size = sizeof(struct wmi_tx_complete_event) +
+ (index * sizeof(struct tx_complete_msg_v1));
+ msg_v1 = (struct tx_complete_msg_v1 *)(datap + size);
+
+ ath6kl_dbg(ATH6KL_DBG_WMI, "msg: %d %d %d %d\n",
+ msg_v1->status, msg_v1->pkt_id,
+ msg_v1->rate_idx, msg_v1->ack_failures);
+ }
+
+ return 0;
+}
+
+static inline struct sk_buff *ath6kl_wmi_get_new_buf(u32 size)
+{
+ struct sk_buff *skb;
+
+ skb = ath6kl_buf_alloc(size);
+ if (!skb)
+ return NULL;
+
+ skb_put(skb, size);
+ if (size)
+ memset(skb->data, 0, size);
+
+ return skb;
+}
+
+/* Send a "simple" wmi command -- one with no arguments */
+static int ath6kl_wmi_simple_cmd(struct wmi *wmi, enum wmi_cmd_id cmd_id)
+{
+ struct sk_buff *skb;
+ int ret;
+
+ skb = ath6kl_wmi_get_new_buf(0);
+ if (!skb)
+ return -ENOMEM;
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, cmd_id, NO_SYNC_WMIFLAG);
+
+ return ret;
+}
+
+static int ath6kl_wmi_ready_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ struct wmi_ready_event_2 *ev = (struct wmi_ready_event_2 *) datap;
+
+ if (len < sizeof(struct wmi_ready_event_2))
+ return -EINVAL;
+
+ wmi->ready = true;
+ ath6kl_ready_event(wmi->parent_dev, ev->mac_addr,
+ le32_to_cpu(ev->sw_version),
+ le32_to_cpu(ev->abi_version));
+
+ return 0;
+}
+
+static int ath6kl_wmi_connect_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ struct wmi_connect_event *ev;
+ u8 *pie, *peie;
+
+ if (len < sizeof(struct wmi_connect_event))
+ return -EINVAL;
+
+ ev = (struct wmi_connect_event *) datap;
+
+ ath6kl_dbg(ATH6KL_DBG_WMI, "%s: freq %d bssid %pM\n",
+ __func__, ev->ch, ev->bssid);
+
+ memcpy(wmi->bssid, ev->bssid, ETH_ALEN);
+
+ /* Start of assoc rsp IEs */
+ pie = ev->assoc_info + ev->beacon_ie_len +
+ ev->assoc_req_len + (sizeof(u16) * 3); /* capinfo, status, aid */
+
+ /* End of assoc rsp IEs */
+ peie = ev->assoc_info + ev->beacon_ie_len + ev->assoc_req_len +
+ ev->assoc_resp_len;
+
+ while (pie < peie) {
+ switch (*pie) {
+ case WLAN_EID_VENDOR_SPECIFIC:
+ if (pie[1] > 3 && pie[2] == 0x00 && pie[3] == 0x50 &&
+ pie[4] == 0xf2 && pie[5] == WMM_OUI_TYPE) {
+ /* WMM OUT (00:50:F2) */
+ if (pie[1] > 5
+ && pie[6] == WMM_PARAM_OUI_SUBTYPE)
+ wmi->is_wmm_enabled = true;
+ }
+ break;
+ }
+
+ if (wmi->is_wmm_enabled)
+ break;
+
+ pie += pie[1] + 2;
+ }
+
+ ath6kl_connect_event(wmi->parent_dev, le16_to_cpu(ev->ch), ev->bssid,
+ le16_to_cpu(ev->listen_intvl),
+ le16_to_cpu(ev->beacon_intvl),
+ le32_to_cpu(ev->nw_type),
+ ev->beacon_ie_len, ev->assoc_req_len,
+ ev->assoc_resp_len, ev->assoc_info);
+
+ return 0;
+}
+
+static int ath6kl_wmi_disconnect_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ struct wmi_disconnect_event *ev;
+ wmi->traffic_class = 100;
+
+ if (len < sizeof(struct wmi_disconnect_event))
+ return -EINVAL;
+
+ ev = (struct wmi_disconnect_event *) datap;
+ memset(wmi->bssid, 0, sizeof(wmi->bssid));
+
+ wmi->is_wmm_enabled = false;
+ wmi->pair_crypto_type = NONE_CRYPT;
+ wmi->grp_crypto_type = NONE_CRYPT;
+
+ ath6kl_disconnect_event(wmi->parent_dev, ev->disconn_reason,
+ ev->bssid, ev->assoc_resp_len, ev->assoc_info,
+ le16_to_cpu(ev->proto_reason_status));
+
+ return 0;
+}
+
+static int ath6kl_wmi_peer_node_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ struct wmi_peer_node_event *ev;
+
+ if (len < sizeof(struct wmi_peer_node_event))
+ return -EINVAL;
+
+ ev = (struct wmi_peer_node_event *) datap;
+
+ if (ev->event_code == PEER_NODE_JOIN_EVENT)
+ ath6kl_dbg(ATH6KL_DBG_WMI, "joined node with mac addr: %pM\n",
+ ev->peer_mac_addr);
+ else if (ev->event_code == PEER_NODE_LEAVE_EVENT)
+ ath6kl_dbg(ATH6KL_DBG_WMI, "left node with mac addr: %pM\n",
+ ev->peer_mac_addr);
+
+ return 0;
+}
+
+static int ath6kl_wmi_tkip_micerr_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ struct wmi_tkip_micerr_event *ev;
+
+ if (len < sizeof(struct wmi_tkip_micerr_event))
+ return -EINVAL;
+
+ ev = (struct wmi_tkip_micerr_event *) datap;
+
+ ath6kl_tkip_micerr_event(wmi->parent_dev, ev->key_id, ev->is_mcast);
+
+ return 0;
+}
+
+static int ath6kl_wlan_parse_beacon(u8 *buf, int frame_len,
+ struct ath6kl_common_ie *cie)
+{
+ u8 *frm, *efrm;
+ u8 elemid_ssid = false;
+
+ frm = buf;
+ efrm = (u8 *) (frm + frame_len);
+
+ /*
+ * beacon/probe response frame format
+ * [8] time stamp
+ * [2] beacon interval
+ * [2] capability information
+ * [tlv] ssid
+ * [tlv] supported rates
+ * [tlv] country information
+ * [tlv] parameter set (FH/DS)
+ * [tlv] erp information
+ * [tlv] extended supported rates
+ * [tlv] WMM
+ * [tlv] WPA or RSN
+ * [tlv] Atheros Advanced Capabilities
+ */
+ if ((efrm - frm) < 12)
+ return -EINVAL;
+
+ memset(cie, 0, sizeof(*cie));
+
+ cie->ie_tstamp = frm;
+ frm += 8;
+ cie->ie_beaconInt = *(u16 *) frm;
+ frm += 2;
+ cie->ie_capInfo = *(u16 *) frm;
+ frm += 2;
+ cie->ie_chan = 0;
+
+ while (frm < efrm) {
+ switch (*frm) {
+ case WLAN_EID_SSID:
+ if (!elemid_ssid) {
+ cie->ie_ssid = frm;
+ elemid_ssid = true;
+ }
+ break;
+ case WLAN_EID_SUPP_RATES:
+ cie->ie_rates = frm;
+ break;
+ case WLAN_EID_COUNTRY:
+ cie->ie_country = frm;
+ break;
+ case WLAN_EID_FH_PARAMS:
+ break;
+ case WLAN_EID_DS_PARAMS:
+ cie->ie_chan = frm[2];
+ break;
+ case WLAN_EID_TIM:
+ cie->ie_tim = frm;
+ break;
+ case WLAN_EID_IBSS_PARAMS:
+ break;
+ case WLAN_EID_EXT_SUPP_RATES:
+ cie->ie_xrates = frm;
+ break;
+ case WLAN_EID_ERP_INFO:
+ if (frm[1] != 1)
+ return -EINVAL;
+
+ cie->ie_erp = frm[2];
+ break;
+ case WLAN_EID_RSN:
+ cie->ie_rsn = frm;
+ break;
+ case WLAN_EID_HT_CAPABILITY:
+ cie->ie_htcap = frm;
+ break;
+ case WLAN_EID_HT_INFORMATION:
+ cie->ie_htop = frm;
+ break;
+ case WLAN_EID_VENDOR_SPECIFIC:
+ if (frm[1] > 3 && frm[2] == 0x00 && frm[3] == 0x50 &&
+ frm[4] == 0xf2) {
+ /* OUT Type (00:50:F2) */
+
+ if (frm[5] == WPA_OUI_TYPE) {
+ /* WPA OUT */
+ cie->ie_wpa = frm;
+ } else if (frm[5] == WMM_OUI_TYPE) {
+ /* WMM OUT */
+ cie->ie_wmm = frm;
+ } else if (frm[5] == WSC_OUT_TYPE) {
+ /* WSC OUT */
+ cie->ie_wsc = frm;
+ }
+
+ } else if (frm[1] > 3 && frm[2] == 0x00
+ && frm[3] == 0x03 && frm[4] == 0x7f
+ && frm[5] == ATH_OUI_TYPE) {
+ /* Atheros OUI (00:03:7f) */
+ cie->ie_ath = frm;
+ }
+ break;
+ default:
+ break;
+ }
+ frm += frm[1] + 2;
+ }
+
+ if ((cie->ie_rates == NULL)
+ || (cie->ie_rates[1] > ATH6KL_RATE_MAXSIZE))
+ return -EINVAL;
+
+ if ((cie->ie_ssid == NULL)
+ || (cie->ie_ssid[1] > IEEE80211_MAX_SSID_LEN))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int ath6kl_wmi_bssinfo_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ struct bss *bss = NULL;
+ struct wmi_bss_info_hdr *bih;
+ u8 cached_ssid_len = 0;
+ u8 cached_ssid[IEEE80211_MAX_SSID_LEN] = { 0 };
+ u8 beacon_ssid_len = 0;
+ u8 *buf, *ie_ssid;
+ u8 *ni_buf;
+ int buf_len;
+
+ int ret;
+
+ if (len <= sizeof(struct wmi_bss_info_hdr))
+ return -EINVAL;
+
+ bih = (struct wmi_bss_info_hdr *) datap;
+ bss = wlan_find_node(&wmi->scan_table, bih->bssid);
+
+ if (a_sle16_to_cpu(bih->rssi) > 0) {
+ if (bss == NULL)
+ return 0;
+ else
+ bih->rssi = a_cpu_to_sle16(bss->ni_rssi);
+ }
+
+ buf = datap + sizeof(struct wmi_bss_info_hdr);
+ len -= sizeof(struct wmi_bss_info_hdr);
+
+ ath6kl_dbg(ATH6KL_DBG_WMI,
+ "bss info evt - ch %u, rssi %02x, bssid \"%pM\"\n",
+ bih->ch, a_sle16_to_cpu(bih->rssi), bih->bssid);
+
+ if (bss != NULL) {
+ /*
+ * Free up the node. We are about to allocate a new node.
+ * In case of hidden AP, beacon will not have ssid,
+ * but a directed probe response will have it,
+ * so cache the probe-resp-ssid if already present.
+ */
+ if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE)) {
+ ie_ssid = bss->ni_cie.ie_ssid;
+ if (ie_ssid && (ie_ssid[1] <= IEEE80211_MAX_SSID_LEN) &&
+ (ie_ssid[2] != 0)) {
+ cached_ssid_len = ie_ssid[1];
+ memcpy(cached_ssid, ie_ssid + 2,
+ cached_ssid_len);
+ }
+ }
+
+ /*
+ * Use the current average rssi of associated AP base on
+ * assumption
+ * 1. Most os with GUI will update RSSI by
+ * ath6kl_wmi_get_stats_cmd() periodically.
+ * 2. ath6kl_wmi_get_stats_cmd(..) will be called when calling
+ * ath6kl_wmi_startscan_cmd(...)
+ * The average value of RSSI give end-user better feeling for
+ * instance value of scan result. It also sync up RSSI info
+ * in GUI between scan result and RSSI signal icon.
+ */
+ if (memcmp(wmi->bssid, bih->bssid, ETH_ALEN) == 0) {
+ bih->rssi = a_cpu_to_sle16(bss->ni_rssi);
+ bih->snr = bss->ni_snr;
+ }
+
+ wlan_node_reclaim(&wmi->scan_table, bss);
+ }
+
+ /*
+ * beacon/probe response frame format
+ * [8] time stamp
+ * [2] beacon interval
+ * [2] capability information
+ * [tlv] ssid
+ */
+ beacon_ssid_len = buf[SSID_IE_LEN_INDEX];
+
+ /*
+ * If ssid is cached for this hidden AP, then change
+ * buffer len accordingly.
+ */
+ if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE) &&
+ (cached_ssid_len != 0) &&
+ (beacon_ssid_len == 0 || (cached_ssid_len > beacon_ssid_len &&
+ buf[SSID_IE_LEN_INDEX + 1] == 0))) {
+
+ len += (cached_ssid_len - beacon_ssid_len);
+ }
+
+ bss = wlan_node_alloc(len);
+ if (!bss)
+ return -ENOMEM;
+
+ bss->ni_snr = bih->snr;
+ bss->ni_rssi = a_sle16_to_cpu(bih->rssi);
+
+ if (WARN_ON(!bss->ni_buf))
+ return -EINVAL;
+
+ /*
+ * In case of hidden AP, beacon will not have ssid,
+ * but a directed probe response will have it,
+ * so place the cached-ssid(probe-resp) in the bss info.
+ */
+ if (wmi->is_probe_ssid && (bih->frame_type == BEACON_FTYPE) &&
+ (cached_ssid_len != 0) &&
+ (beacon_ssid_len == 0 || (beacon_ssid_len &&
+ buf[SSID_IE_LEN_INDEX + 1] == 0))) {
+ ni_buf = bss->ni_buf;
+ buf_len = len;
+
+ /*
+ * Copy the first 14 bytes:
+ * time-stamp(8), beacon-interval(2),
+ * cap-info(2), ssid-id(1), ssid-len(1).
+ */
+ memcpy(ni_buf, buf, SSID_IE_LEN_INDEX + 1);
+
+ ni_buf[SSID_IE_LEN_INDEX] = cached_ssid_len;
+ ni_buf += (SSID_IE_LEN_INDEX + 1);
+
+ buf += (SSID_IE_LEN_INDEX + 1);
+ buf_len -= (SSID_IE_LEN_INDEX + 1);
+
+ memcpy(ni_buf, cached_ssid, cached_ssid_len);
+ ni_buf += cached_ssid_len;
+
+ buf += beacon_ssid_len;
+ buf_len -= beacon_ssid_len;
+
+ if (cached_ssid_len > beacon_ssid_len)
+ buf_len -= (cached_ssid_len - beacon_ssid_len);
+
+ memcpy(ni_buf, buf, buf_len);
+ } else
+ memcpy(bss->ni_buf, buf, len);
+
+ bss->ni_framelen = len;
+
+ ret = ath6kl_wlan_parse_beacon(bss->ni_buf, len, &bss->ni_cie);
+ if (ret) {
+ wlan_node_free(bss);
+ return -EINVAL;
+ }
+
+ /*
+ * Update the frequency in ie_chan, overwriting of channel number
+ * which is done in ath6kl_wlan_parse_beacon
+ */
+ bss->ni_cie.ie_chan = le16_to_cpu(bih->ch);
+ wlan_setup_node(&wmi->scan_table, bss, bih->bssid);
+
+ return 0;
+}
+
+static int ath6kl_wmi_opt_frame_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ struct bss *bss;
+ struct wmi_opt_rx_info_hdr *bih;
+ u8 *buf;
+
+ if (len <= sizeof(struct wmi_opt_rx_info_hdr))
+ return -EINVAL;
+
+ bih = (struct wmi_opt_rx_info_hdr *) datap;
+ buf = datap + sizeof(struct wmi_opt_rx_info_hdr);
+ len -= sizeof(struct wmi_opt_rx_info_hdr);
+
+ ath6kl_dbg(ATH6KL_DBG_WMI, "opt frame event %2.2x:%2.2x\n",
+ bih->bssid[4], bih->bssid[5]);
+
+ bss = wlan_find_node(&wmi->scan_table, bih->bssid);
+ if (bss != NULL) {
+ /* Free up the node. We are about to allocate a new node. */
+ wlan_node_reclaim(&wmi->scan_table, bss);
+ }
+
+ bss = wlan_node_alloc(len);
+ if (!bss)
+ return -ENOMEM;
+
+ bss->ni_snr = bih->snr;
+ bss->ni_cie.ie_chan = le16_to_cpu(bih->ch);
+
+ if (WARN_ON(!bss->ni_buf))
+ return -EINVAL;
+
+ memcpy(bss->ni_buf, buf, len);
+ wlan_setup_node(&wmi->scan_table, bss, bih->bssid);
+
+ return 0;
+}
+
+/* Inactivity timeout of a fatpipe(pstream) at the target */
+static int ath6kl_wmi_pstream_timeout_event_rx(struct wmi *wmi, u8 *datap,
+ int len)
+{
+ struct wmi_pstream_timeout_event *ev;
+
+ if (len < sizeof(struct wmi_pstream_timeout_event))
+ return -EINVAL;
+
+ ev = (struct wmi_pstream_timeout_event *) datap;
+
+ /*
+ * When the pstream (fat pipe == AC) timesout, it means there were
+ * no thinStreams within this pstream & it got implicitly created
+ * due to data flow on this AC. We start the inactivity timer only
+ * for implicitly created pstream. Just reset the host state.
+ */
+ spin_lock_bh(&wmi->lock);
+ wmi->stream_exist_for_ac[ev->traffic_class] = 0;
+ wmi->fat_pipe_exist &= ~(1 << ev->traffic_class);
+ spin_unlock_bh(&wmi->lock);
+
+ /* Indicate inactivity to driver layer for this fatpipe (pstream) */
+ ath6kl_indicate_tx_activity(wmi->parent_dev, ev->traffic_class, false);
+
+ return 0;
+}
+
+static int ath6kl_wmi_bitrate_reply_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ struct wmi_bit_rate_reply *reply;
+ s32 rate;
+ u32 sgi, index;
+
+ if (len < sizeof(struct wmi_bit_rate_reply))
+ return -EINVAL;
+
+ reply = (struct wmi_bit_rate_reply *) datap;
+
+ ath6kl_dbg(ATH6KL_DBG_WMI, "rateindex %d\n", reply->rate_index);
+
+ if (reply->rate_index == (s8) RATE_AUTO) {
+ rate = RATE_AUTO;
+ } else {
+ index = reply->rate_index & 0x7f;
+ sgi = (reply->rate_index & 0x80) ? 1 : 0;
+ rate = wmi_rate_tbl[index][sgi];
+ }
+
+ ath6kl_wakeup_event(wmi->parent_dev);
+
+ return 0;
+}
+
+static int ath6kl_wmi_ratemask_reply_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ if (len < sizeof(struct wmi_fix_rates_reply))
+ return -EINVAL;
+
+ ath6kl_wakeup_event(wmi->parent_dev);
+
+ return 0;
+}
+
+static int ath6kl_wmi_ch_list_reply_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ if (len < sizeof(struct wmi_channel_list_reply))
+ return -EINVAL;
+
+ ath6kl_wakeup_event(wmi->parent_dev);
+
+ return 0;
+}
+
+static int ath6kl_wmi_tx_pwr_reply_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ struct wmi_tx_pwr_reply *reply;
+
+ if (len < sizeof(struct wmi_tx_pwr_reply))
+ return -EINVAL;
+
+ reply = (struct wmi_tx_pwr_reply *) datap;
+ ath6kl_txpwr_rx_evt(wmi->parent_dev, reply->dbM);
+
+ return 0;
+}
+
+static int ath6kl_wmi_keepalive_reply_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ if (len < sizeof(struct wmi_get_keepalive_cmd))
+ return -EINVAL;
+
+ ath6kl_wakeup_event(wmi->parent_dev);
+
+ return 0;
+}
+
+static int ath6kl_wmi_scan_complete_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ struct wmi_scan_complete_event *ev;
+
+ ev = (struct wmi_scan_complete_event *) datap;
+
+ if (a_sle32_to_cpu(ev->status) == 0)
+ wlan_refresh_inactive_nodes(&wmi->scan_table);
+
+ ath6kl_scan_complete_evt(wmi->parent_dev, a_sle32_to_cpu(ev->status));
+ wmi->is_probe_ssid = false;
+
+ return 0;
+}
+
+/*
+ * Target is reporting a programming error. This is for
+ * developer aid only. Target only checks a few common violations
+ * and it is responsibility of host to do all error checking.
+ * Behavior of target after wmi error event is undefined.
+ * A reset is recommended.
+ */
+static int ath6kl_wmi_error_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ const char *type = "unknown error";
+ struct wmi_cmd_error_event *ev;
+ ev = (struct wmi_cmd_error_event *) datap;
+
+ switch (ev->err_code) {
+ case INVALID_PARAM:
+ type = "invalid parameter";
+ break;
+ case ILLEGAL_STATE:
+ type = "invalid state";
+ break;
+ case INTERNAL_ERROR:
+ type = "internal error";
+ break;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_WMI, "programming error, cmd=%d %s\n",
+ ev->cmd_id, type);
+
+ return 0;
+}
+
+static int ath6kl_wmi_stats_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ ath6kl_tgt_stats_event(wmi->parent_dev, datap, len);
+
+ return 0;
+}
+
+static u8 ath6kl_wmi_get_upper_threshold(s16 rssi,
+ struct sq_threshold_params *sq_thresh,
+ u32 size)
+{
+ u32 index;
+ u8 threshold = (u8) sq_thresh->upper_threshold[size - 1];
+
+ /* The list is already in sorted order. Get the next lower value */
+ for (index = 0; index < size; index++) {
+ if (rssi < sq_thresh->upper_threshold[index]) {
+ threshold = (u8) sq_thresh->upper_threshold[index];
+ break;
+ }
+ }
+
+ return threshold;
+}
+
+static u8 ath6kl_wmi_get_lower_threshold(s16 rssi,
+ struct sq_threshold_params *sq_thresh,
+ u32 size)
+{
+ u32 index;
+ u8 threshold = (u8) sq_thresh->lower_threshold[size - 1];
+
+ /* The list is already in sorted order. Get the next lower value */
+ for (index = 0; index < size; index++) {
+ if (rssi > sq_thresh->lower_threshold[index]) {
+ threshold = (u8) sq_thresh->lower_threshold[index];
+ break;
+ }
+ }
+
+ return threshold;
+}
+
+static int ath6kl_wmi_send_rssi_threshold_params(struct wmi *wmi,
+ struct wmi_rssi_threshold_params_cmd *rssi_cmd)
+{
+ struct sk_buff *skb;
+ struct wmi_rssi_threshold_params_cmd *cmd;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_rssi_threshold_params_cmd *) skb->data;
+ memcpy(cmd, rssi_cmd, sizeof(struct wmi_rssi_threshold_params_cmd));
+
+ return ath6kl_wmi_cmd_send(wmi, skb, WMI_RSSI_THRESHOLD_PARAMS_CMDID,
+ NO_SYNC_WMIFLAG);
+}
+
+static int ath6kl_wmi_rssi_threshold_event_rx(struct wmi *wmi, u8 *datap,
+ int len)
+{
+ struct wmi_rssi_threshold_event *reply;
+ struct wmi_rssi_threshold_params_cmd cmd;
+ struct sq_threshold_params *sq_thresh;
+ enum wmi_rssi_threshold_val new_threshold;
+ u8 upper_rssi_threshold, lower_rssi_threshold;
+ s16 rssi;
+ int ret;
+
+ if (len < sizeof(struct wmi_rssi_threshold_event))
+ return -EINVAL;
+
+ reply = (struct wmi_rssi_threshold_event *) datap;
+ new_threshold = (enum wmi_rssi_threshold_val) reply->range;
+ rssi = a_sle16_to_cpu(reply->rssi);
+
+ sq_thresh = &wmi->sq_threshld[SIGNAL_QUALITY_METRICS_RSSI];
+
+ /*
+ * Identify the threshold breached and communicate that to the app.
+ * After that install a new set of thresholds based on the signal
+ * quality reported by the target
+ */
+ if (new_threshold) {
+ /* Upper threshold breached */
+ if (rssi < sq_thresh->upper_threshold[0]) {
+ ath6kl_dbg(ATH6KL_DBG_WMI,
+ "spurious upper rssi threshold event: %d\n",
+ rssi);
+ } else if ((rssi < sq_thresh->upper_threshold[1]) &&
+ (rssi >= sq_thresh->upper_threshold[0])) {
+ new_threshold = WMI_RSSI_THRESHOLD1_ABOVE;
+ } else if ((rssi < sq_thresh->upper_threshold[2]) &&
+ (rssi >= sq_thresh->upper_threshold[1])) {
+ new_threshold = WMI_RSSI_THRESHOLD2_ABOVE;
+ } else if ((rssi < sq_thresh->upper_threshold[3]) &&
+ (rssi >= sq_thresh->upper_threshold[2])) {
+ new_threshold = WMI_RSSI_THRESHOLD3_ABOVE;
+ } else if ((rssi < sq_thresh->upper_threshold[4]) &&
+ (rssi >= sq_thresh->upper_threshold[3])) {
+ new_threshold = WMI_RSSI_THRESHOLD4_ABOVE;
+ } else if ((rssi < sq_thresh->upper_threshold[5]) &&
+ (rssi >= sq_thresh->upper_threshold[4])) {
+ new_threshold = WMI_RSSI_THRESHOLD5_ABOVE;
+ } else if (rssi >= sq_thresh->upper_threshold[5]) {
+ new_threshold = WMI_RSSI_THRESHOLD6_ABOVE;
+ }
+ } else {
+ /* Lower threshold breached */
+ if (rssi > sq_thresh->lower_threshold[0]) {
+ ath6kl_dbg(ATH6KL_DBG_WMI,
+ "spurious lower rssi threshold event: %d %d\n",
+ rssi, sq_thresh->lower_threshold[0]);
+ } else if ((rssi > sq_thresh->lower_threshold[1]) &&
+ (rssi <= sq_thresh->lower_threshold[0])) {
+ new_threshold = WMI_RSSI_THRESHOLD6_BELOW;
+ } else if ((rssi > sq_thresh->lower_threshold[2]) &&
+ (rssi <= sq_thresh->lower_threshold[1])) {
+ new_threshold = WMI_RSSI_THRESHOLD5_BELOW;
+ } else if ((rssi > sq_thresh->lower_threshold[3]) &&
+ (rssi <= sq_thresh->lower_threshold[2])) {
+ new_threshold = WMI_RSSI_THRESHOLD4_BELOW;
+ } else if ((rssi > sq_thresh->lower_threshold[4]) &&
+ (rssi <= sq_thresh->lower_threshold[3])) {
+ new_threshold = WMI_RSSI_THRESHOLD3_BELOW;
+ } else if ((rssi > sq_thresh->lower_threshold[5]) &&
+ (rssi <= sq_thresh->lower_threshold[4])) {
+ new_threshold = WMI_RSSI_THRESHOLD2_BELOW;
+ } else if (rssi <= sq_thresh->lower_threshold[5]) {
+ new_threshold = WMI_RSSI_THRESHOLD1_BELOW;
+ }
+ }
+
+ /* Calculate and install the next set of thresholds */
+ lower_rssi_threshold = ath6kl_wmi_get_lower_threshold(rssi, sq_thresh,
+ sq_thresh->lower_threshold_valid_count);
+ upper_rssi_threshold = ath6kl_wmi_get_upper_threshold(rssi, sq_thresh,
+ sq_thresh->upper_threshold_valid_count);
+
+ /* Issue a wmi command to install the thresholds */
+ cmd.thresh_above1_val = a_cpu_to_sle16(upper_rssi_threshold);
+ cmd.thresh_below1_val = a_cpu_to_sle16(lower_rssi_threshold);
+ cmd.weight = sq_thresh->weight;
+ cmd.poll_time = cpu_to_le32(sq_thresh->polling_interval);
+
+ ret = ath6kl_wmi_send_rssi_threshold_params(wmi, &cmd);
+ if (ret) {
+ ath6kl_err("unable to configure rssi thresholds\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int ath6kl_wmi_cac_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ struct wmi_cac_event *reply;
+ struct ieee80211_tspec_ie *ts;
+ u16 active_tsids, tsinfo;
+ u8 tsid, index;
+ u8 ts_id;
+
+ if (len < sizeof(struct wmi_cac_event))
+ return -EINVAL;
+
+ reply = (struct wmi_cac_event *) datap;
+
+ if ((reply->cac_indication == CAC_INDICATION_ADMISSION_RESP) &&
+ (reply->status_code != IEEE80211_TSPEC_STATUS_ADMISS_ACCEPTED)) {
+
+ ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion);
+ tsinfo = le16_to_cpu(ts->tsinfo);
+ tsid = (tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) &
+ IEEE80211_WMM_IE_TSPEC_TID_MASK;
+
+ ath6kl_wmi_delete_pstream_cmd(wmi, reply->ac, tsid);
+ } else if (reply->cac_indication == CAC_INDICATION_NO_RESP) {
+ /*
+ * Following assumes that there is only one outstanding
+ * ADDTS request when this event is received
+ */
+ spin_lock_bh(&wmi->lock);
+ active_tsids = wmi->stream_exist_for_ac[reply->ac];
+ spin_unlock_bh(&wmi->lock);
+
+ for (index = 0; index < sizeof(active_tsids) * 8; index++) {
+ if ((active_tsids >> index) & 1)
+ break;
+ }
+ if (index < (sizeof(active_tsids) * 8))
+ ath6kl_wmi_delete_pstream_cmd(wmi, reply->ac, index);
+ }
+
+ /*
+ * Clear active tsids and Add missing handling
+ * for delete qos stream from AP
+ */
+ else if (reply->cac_indication == CAC_INDICATION_DELETE) {
+
+ ts = (struct ieee80211_tspec_ie *) &(reply->tspec_suggestion);
+ tsinfo = le16_to_cpu(ts->tsinfo);
+ ts_id = ((tsinfo >> IEEE80211_WMM_IE_TSPEC_TID_SHIFT) &
+ IEEE80211_WMM_IE_TSPEC_TID_MASK);
+
+ spin_lock_bh(&wmi->lock);
+ wmi->stream_exist_for_ac[reply->ac] &= ~(1 << ts_id);
+ active_tsids = wmi->stream_exist_for_ac[reply->ac];
+ spin_unlock_bh(&wmi->lock);
+
+ /* Indicate stream inactivity to driver layer only if all tsids
+ * within this AC are deleted.
+ */
+ if (!active_tsids) {
+ ath6kl_indicate_tx_activity(wmi->parent_dev, reply->ac,
+ false);
+ wmi->fat_pipe_exist &= ~(1 << reply->ac);
+ }
+ }
+
+ return 0;
+}
+
+static int ath6kl_wmi_send_snr_threshold_params(struct wmi *wmi,
+ struct wmi_snr_threshold_params_cmd *snr_cmd)
+{
+ struct sk_buff *skb;
+ struct wmi_snr_threshold_params_cmd *cmd;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_snr_threshold_params_cmd *) skb->data;
+ memcpy(cmd, snr_cmd, sizeof(struct wmi_snr_threshold_params_cmd));
+
+ return ath6kl_wmi_cmd_send(wmi, skb, WMI_SNR_THRESHOLD_PARAMS_CMDID,
+ NO_SYNC_WMIFLAG);
+}
+
+static int ath6kl_wmi_snr_threshold_event_rx(struct wmi *wmi, u8 *datap,
+ int len)
+{
+ struct wmi_snr_threshold_event *reply;
+ struct sq_threshold_params *sq_thresh;
+ struct wmi_snr_threshold_params_cmd cmd;
+ enum wmi_snr_threshold_val new_threshold;
+ u8 upper_snr_threshold, lower_snr_threshold;
+ s16 snr;
+ int ret;
+
+ if (len < sizeof(struct wmi_snr_threshold_event))
+ return -EINVAL;
+
+ reply = (struct wmi_snr_threshold_event *) datap;
+
+ new_threshold = (enum wmi_snr_threshold_val) reply->range;
+ snr = reply->snr;
+
+ sq_thresh = &wmi->sq_threshld[SIGNAL_QUALITY_METRICS_SNR];
+
+ /*
+ * Identify the threshold breached and communicate that to the app.
+ * After that install a new set of thresholds based on the signal
+ * quality reported by the target.
+ */
+ if (new_threshold) {
+ /* Upper threshold breached */
+ if (snr < sq_thresh->upper_threshold[0]) {
+ ath6kl_dbg(ATH6KL_DBG_WMI,
+ "spurious upper snr threshold event: %d\n",
+ snr);
+ } else if ((snr < sq_thresh->upper_threshold[1]) &&
+ (snr >= sq_thresh->upper_threshold[0])) {
+ new_threshold = WMI_SNR_THRESHOLD1_ABOVE;
+ } else if ((snr < sq_thresh->upper_threshold[2]) &&
+ (snr >= sq_thresh->upper_threshold[1])) {
+ new_threshold = WMI_SNR_THRESHOLD2_ABOVE;
+ } else if ((snr < sq_thresh->upper_threshold[3]) &&
+ (snr >= sq_thresh->upper_threshold[2])) {
+ new_threshold = WMI_SNR_THRESHOLD3_ABOVE;
+ } else if (snr >= sq_thresh->upper_threshold[3]) {
+ new_threshold = WMI_SNR_THRESHOLD4_ABOVE;
+ }
+ } else {
+ /* Lower threshold breached */
+ if (snr > sq_thresh->lower_threshold[0]) {
+ ath6kl_dbg(ATH6KL_DBG_WMI,
+ "spurious lower snr threshold event: %d\n",
+ sq_thresh->lower_threshold[0]);
+ } else if ((snr > sq_thresh->lower_threshold[1]) &&
+ (snr <= sq_thresh->lower_threshold[0])) {
+ new_threshold = WMI_SNR_THRESHOLD4_BELOW;
+ } else if ((snr > sq_thresh->lower_threshold[2]) &&
+ (snr <= sq_thresh->lower_threshold[1])) {
+ new_threshold = WMI_SNR_THRESHOLD3_BELOW;
+ } else if ((snr > sq_thresh->lower_threshold[3]) &&
+ (snr <= sq_thresh->lower_threshold[2])) {
+ new_threshold = WMI_SNR_THRESHOLD2_BELOW;
+ } else if (snr <= sq_thresh->lower_threshold[3]) {
+ new_threshold = WMI_SNR_THRESHOLD1_BELOW;
+ }
+ }
+
+ /* Calculate and install the next set of thresholds */
+ lower_snr_threshold = ath6kl_wmi_get_lower_threshold(snr, sq_thresh,
+ sq_thresh->lower_threshold_valid_count);
+ upper_snr_threshold = ath6kl_wmi_get_upper_threshold(snr, sq_thresh,
+ sq_thresh->upper_threshold_valid_count);
+
+ /* Issue a wmi command to install the thresholds */
+ cmd.thresh_above1_val = upper_snr_threshold;
+ cmd.thresh_below1_val = lower_snr_threshold;
+ cmd.weight = sq_thresh->weight;
+ cmd.poll_time = cpu_to_le32(sq_thresh->polling_interval);
+
+ ath6kl_dbg(ATH6KL_DBG_WMI,
+ "snr: %d, threshold: %d, lower: %d, upper: %d\n",
+ snr, new_threshold,
+ lower_snr_threshold, upper_snr_threshold);
+
+ ret = ath6kl_wmi_send_snr_threshold_params(wmi, &cmd);
+ if (ret) {
+ ath6kl_err("unable to configure snr threshold\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int ath6kl_wmi_aplist_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ u16 ap_info_entry_size;
+ struct wmi_aplist_event *ev = (struct wmi_aplist_event *) datap;
+ struct wmi_ap_info_v1 *ap_info_v1;
+ u8 index;
+
+ if (len < sizeof(struct wmi_aplist_event) ||
+ ev->ap_list_ver != APLIST_VER1)
+ return -EINVAL;
+
+ ap_info_entry_size = sizeof(struct wmi_ap_info_v1);
+ ap_info_v1 = (struct wmi_ap_info_v1 *) ev->ap_list;
+
+ ath6kl_dbg(ATH6KL_DBG_WMI,
+ "number of APs in aplist event: %d\n", ev->num_ap);
+
+ if (len < (int) (sizeof(struct wmi_aplist_event) +
+ (ev->num_ap - 1) * ap_info_entry_size))
+ return -EINVAL;
+
+ /* AP list version 1 contents */
+ for (index = 0; index < ev->num_ap; index++) {
+ ath6kl_dbg(ATH6KL_DBG_WMI, "AP#%d BSSID %pM Channel %d\n",
+ index, ap_info_v1->bssid, ap_info_v1->channel);
+ ap_info_v1++;
+ }
+
+ return 0;
+}
+
+int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb,
+ enum wmi_cmd_id cmd_id, enum wmi_sync_flag sync_flag)
+{
+ struct wmi_cmd_hdr *cmd_hdr;
+ enum htc_endpoint_id ep_id = wmi->ep_id;
+ int ret;
+
+ if (WARN_ON(skb == NULL))
+ return -EINVAL;
+
+ if (sync_flag >= END_WMIFLAG) {
+ dev_kfree_skb(skb);
+ return -EINVAL;
+ }
+
+ if ((sync_flag == SYNC_BEFORE_WMIFLAG) ||
+ (sync_flag == SYNC_BOTH_WMIFLAG)) {
+ /*
+ * Make sure all data currently queued is transmitted before
+ * the cmd execution. Establish a new sync point.
+ */
+ ath6kl_wmi_sync_point(wmi);
+ }
+
+ skb_push(skb, sizeof(struct wmi_cmd_hdr));
+
+ cmd_hdr = (struct wmi_cmd_hdr *) skb->data;
+ cmd_hdr->cmd_id = cpu_to_le16(cmd_id);
+ cmd_hdr->info1 = 0; /* added for virtual interface */
+
+ /* Only for OPT_TX_CMD, use BE endpoint. */
+ if (cmd_id == WMI_OPT_TX_FRAME_CMDID) {
+ ret = ath6kl_wmi_data_hdr_add(wmi, skb, OPT_MSGTYPE,
+ false, false, 0, NULL);
+ if (ret) {
+ dev_kfree_skb(skb);
+ return ret;
+ }
+ ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev, WMM_AC_BE);
+ }
+
+ ath6kl_control_tx(wmi->parent_dev, skb, ep_id);
+
+ if ((sync_flag == SYNC_AFTER_WMIFLAG) ||
+ (sync_flag == SYNC_BOTH_WMIFLAG)) {
+ /*
+ * Make sure all new data queued waits for the command to
+ * execute. Establish a new sync point.
+ */
+ ath6kl_wmi_sync_point(wmi);
+ }
+
+ return 0;
+}
+
+int ath6kl_wmi_connect_cmd(struct wmi *wmi, enum network_type nw_type,
+ enum dot11_auth_mode dot11_auth_mode,
+ enum auth_mode auth_mode,
+ enum crypto_type pairwise_crypto,
+ u8 pairwise_crypto_len,
+ enum crypto_type group_crypto,
+ u8 group_crypto_len, int ssid_len, u8 *ssid,
+ u8 *bssid, u16 channel, u32 ctrl_flags)
+{
+ struct sk_buff *skb;
+ struct wmi_connect_cmd *cc;
+ int ret;
+
+ wmi->traffic_class = 100;
+
+ if ((pairwise_crypto == NONE_CRYPT) && (group_crypto != NONE_CRYPT))
+ return -EINVAL;
+
+ if ((pairwise_crypto != NONE_CRYPT) && (group_crypto == NONE_CRYPT))
+ return -EINVAL;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_connect_cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cc = (struct wmi_connect_cmd *) skb->data;
+
+ if (ssid_len)
+ memcpy(cc->ssid, ssid, ssid_len);
+
+ cc->ssid_len = ssid_len;
+ cc->nw_type = nw_type;
+ cc->dot11_auth_mode = dot11_auth_mode;
+ cc->auth_mode = auth_mode;
+ cc->prwise_crypto_type = pairwise_crypto;
+ cc->prwise_crypto_len = pairwise_crypto_len;
+ cc->grp_crypto_type = group_crypto;
+ cc->grp_crypto_len = group_crypto_len;
+ cc->ch = cpu_to_le16(channel);
+ cc->ctrl_flags = cpu_to_le32(ctrl_flags);
+
+ if (bssid != NULL)
+ memcpy(cc->bssid, bssid, ETH_ALEN);
+
+ wmi->pair_crypto_type = pairwise_crypto;
+ wmi->grp_crypto_type = group_crypto;
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_CONNECT_CMDID, NO_SYNC_WMIFLAG);
+
+ return ret;
+}
+
+int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 *bssid, u16 channel)
+{
+ struct sk_buff *skb;
+ struct wmi_reconnect_cmd *cc;
+ int ret;
+
+ wmi->traffic_class = 100;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_reconnect_cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cc = (struct wmi_reconnect_cmd *) skb->data;
+ cc->channel = cpu_to_le16(channel);
+
+ if (bssid != NULL)
+ memcpy(cc->bssid, bssid, ETH_ALEN);
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_RECONNECT_CMDID,
+ NO_SYNC_WMIFLAG);
+
+ return ret;
+}
+
+int ath6kl_wmi_disconnect_cmd(struct wmi *wmi)
+{
+ int ret;
+
+ wmi->traffic_class = 100;
+
+ /* Disconnect command does not need to do a SYNC before. */
+ ret = ath6kl_wmi_simple_cmd(wmi, WMI_DISCONNECT_CMDID);
+
+ return ret;
+}
+
+int ath6kl_wmi_startscan_cmd(struct wmi *wmi, enum wmi_scan_type scan_type,
+ u32 force_fgscan, u32 is_legacy,
+ u32 home_dwell_time, u32 force_scan_interval,
+ s8 num_chan, u16 *ch_list)
+{
+ struct sk_buff *skb;
+ struct wmi_start_scan_cmd *sc;
+ s8 size;
+ int ret;
+
+ size = sizeof(struct wmi_start_scan_cmd);
+
+ if ((scan_type != WMI_LONG_SCAN) && (scan_type != WMI_SHORT_SCAN))
+ return -EINVAL;
+
+ if (num_chan > WMI_MAX_CHANNELS)
+ return -EINVAL;
+
+ if (num_chan)
+ size += sizeof(u16) * (num_chan - 1);
+
+ skb = ath6kl_wmi_get_new_buf(size);
+ if (!skb)
+ return -ENOMEM;
+
+ sc = (struct wmi_start_scan_cmd *) skb->data;
+ sc->scan_type = scan_type;
+ sc->force_fg_scan = cpu_to_le32(force_fgscan);
+ sc->is_legacy = cpu_to_le32(is_legacy);
+ sc->home_dwell_time = cpu_to_le32(home_dwell_time);
+ sc->force_scan_intvl = cpu_to_le32(force_scan_interval);
+ sc->num_ch = num_chan;
+
+ if (num_chan)
+ memcpy(sc->ch_list, ch_list, num_chan * sizeof(u16));
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_START_SCAN_CMDID,
+ NO_SYNC_WMIFLAG);
+
+ return ret;
+}
+
+int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u16 fg_start_sec,
+ u16 fg_end_sec, u16 bg_sec,
+ u16 minact_chdw_msec, u16 maxact_chdw_msec,
+ u16 pas_chdw_msec, u8 short_scan_ratio,
+ u8 scan_ctrl_flag, u32 max_dfsch_act_time,
+ u16 maxact_scan_per_ssid)
+{
+ struct sk_buff *skb;
+ struct wmi_scan_params_cmd *sc;
+ int ret;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*sc));
+ if (!skb)
+ return -ENOMEM;
+
+ sc = (struct wmi_scan_params_cmd *) skb->data;
+ sc->fg_start_period = cpu_to_le16(fg_start_sec);
+ sc->fg_end_period = cpu_to_le16(fg_end_sec);
+ sc->bg_period = cpu_to_le16(bg_sec);
+ sc->minact_chdwell_time = cpu_to_le16(minact_chdw_msec);
+ sc->maxact_chdwell_time = cpu_to_le16(maxact_chdw_msec);
+ sc->pas_chdwell_time = cpu_to_le16(pas_chdw_msec);
+ sc->short_scan_ratio = short_scan_ratio;
+ sc->scan_ctrl_flags = scan_ctrl_flag;
+ sc->max_dfsch_act_time = cpu_to_le32(max_dfsch_act_time);
+ sc->maxact_scan_per_ssid = cpu_to_le16(maxact_scan_per_ssid);
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_SCAN_PARAMS_CMDID,
+ NO_SYNC_WMIFLAG);
+ return ret;
+}
+
+int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 filter, u32 ie_mask)
+{
+ struct sk_buff *skb;
+ struct wmi_bss_filter_cmd *cmd;
+ int ret;
+
+ if (filter >= LAST_BSS_FILTER)
+ return -EINVAL;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_bss_filter_cmd *) skb->data;
+ cmd->bss_filter = filter;
+ cmd->ie_mask = cpu_to_le32(ie_mask);
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_BSS_FILTER_CMDID,
+ NO_SYNC_WMIFLAG);
+ return ret;
+}
+
+int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 index, u8 flag,
+ u8 ssid_len, u8 *ssid)
+{
+ struct sk_buff *skb;
+ struct wmi_probed_ssid_cmd *cmd;
+ int ret;
+
+ if (index > MAX_PROBED_SSID_INDEX)
+ return -EINVAL;
+
+ if (ssid_len > sizeof(cmd->ssid))
+ return -EINVAL;
+
+ if ((flag & (DISABLE_SSID_FLAG | ANY_SSID_FLAG)) && (ssid_len > 0))
+ return -EINVAL;
+
+ if ((flag & SPECIFIC_SSID_FLAG) && !ssid_len)
+ return -EINVAL;
+
+ if (flag & SPECIFIC_SSID_FLAG)
+ wmi->is_probe_ssid = true;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_probed_ssid_cmd *) skb->data;
+ cmd->entry_index = index;
+ cmd->flag = flag;
+ cmd->ssid_len = ssid_len;
+ memcpy(cmd->ssid, ssid, ssid_len);
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_PROBED_SSID_CMDID,
+ NO_SYNC_WMIFLAG);
+ return ret;
+}
+
+int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u16 listen_interval,
+ u16 listen_beacons)
+{
+ struct sk_buff *skb;
+ struct wmi_listen_int_cmd *cmd;
+ int ret;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_listen_int_cmd *) skb->data;
+ cmd->listen_intvl = cpu_to_le16(listen_interval);
+ cmd->num_beacons = cpu_to_le16(listen_beacons);
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_LISTEN_INT_CMDID,
+ NO_SYNC_WMIFLAG);
+ return ret;
+}
+
+int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 pwr_mode)
+{
+ struct sk_buff *skb;
+ struct wmi_power_mode_cmd *cmd;
+ int ret;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_power_mode_cmd *) skb->data;
+ cmd->pwr_mode = pwr_mode;
+ wmi->pwr_mode = pwr_mode;
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_POWER_MODE_CMDID,
+ NO_SYNC_WMIFLAG);
+ return ret;
+}
+
+int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u16 idle_period,
+ u16 ps_poll_num, u16 dtim_policy,
+ u16 tx_wakeup_policy, u16 num_tx_to_wakeup,
+ u16 ps_fail_event_policy)
+{
+ struct sk_buff *skb;
+ struct wmi_power_params_cmd *pm;
+ int ret;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*pm));
+ if (!skb)
+ return -ENOMEM;
+
+ pm = (struct wmi_power_params_cmd *)skb->data;
+ pm->idle_period = cpu_to_le16(idle_period);
+ pm->pspoll_number = cpu_to_le16(ps_poll_num);
+ pm->dtim_policy = cpu_to_le16(dtim_policy);
+ pm->tx_wakeup_policy = cpu_to_le16(tx_wakeup_policy);
+ pm->num_tx_to_wakeup = cpu_to_le16(num_tx_to_wakeup);
+ pm->ps_fail_event_policy = cpu_to_le16(ps_fail_event_policy);
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_POWER_PARAMS_CMDID,
+ NO_SYNC_WMIFLAG);
+ return ret;
+}
+
+int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 timeout)
+{
+ struct sk_buff *skb;
+ struct wmi_disc_timeout_cmd *cmd;
+ int ret;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_disc_timeout_cmd *) skb->data;
+ cmd->discon_timeout = timeout;
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_DISC_TIMEOUT_CMDID,
+ NO_SYNC_WMIFLAG);
+ return ret;
+}
+
+int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index,
+ enum crypto_type key_type,
+ u8 key_usage, u8 key_len,
+ u8 *key_rsc, u8 *key_material,
+ u8 key_op_ctrl, u8 *mac_addr,
+ enum wmi_sync_flag sync_flag)
+{
+ struct sk_buff *skb;
+ struct wmi_add_cipher_key_cmd *cmd;
+ int ret;
+
+ if ((key_index > WMI_MAX_KEY_INDEX) || (key_len > WMI_MAX_KEY_LEN) ||
+ (key_material == NULL))
+ return -EINVAL;
+
+ if ((WEP_CRYPT != key_type) && (NULL == key_rsc))
+ return -EINVAL;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_add_cipher_key_cmd *) skb->data;
+ cmd->key_index = key_index;
+ cmd->key_type = key_type;
+ cmd->key_usage = key_usage;
+ cmd->key_len = key_len;
+ memcpy(cmd->key, key_material, key_len);
+
+ if (key_rsc != NULL)
+ memcpy(cmd->key_rsc, key_rsc, sizeof(cmd->key_rsc));
+
+ cmd->key_op_ctrl = key_op_ctrl;
+
+ if (mac_addr)
+ memcpy(cmd->key_mac_addr, mac_addr, ETH_ALEN);
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_ADD_CIPHER_KEY_CMDID,
+ sync_flag);
+
+ return ret;
+}
+
+int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 *krk)
+{
+ struct sk_buff *skb;
+ struct wmi_add_krk_cmd *cmd;
+ int ret;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_add_krk_cmd *) skb->data;
+ memcpy(cmd->krk, krk, WMI_KRK_LEN);
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_ADD_KRK_CMDID, NO_SYNC_WMIFLAG);
+
+ return ret;
+}
+
+int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 key_index)
+{
+ struct sk_buff *skb;
+ struct wmi_delete_cipher_key_cmd *cmd;
+ int ret;
+
+ if (key_index > WMI_MAX_KEY_INDEX)
+ return -EINVAL;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_delete_cipher_key_cmd *) skb->data;
+ cmd->key_index = key_index;
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_DELETE_CIPHER_KEY_CMDID,
+ NO_SYNC_WMIFLAG);
+
+ return ret;
+}
+
+int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, const u8 *bssid,
+ const u8 *pmkid, bool set)
+{
+ struct sk_buff *skb;
+ struct wmi_setpmkid_cmd *cmd;
+ int ret;
+
+ if (bssid == NULL)
+ return -EINVAL;
+
+ if (set && pmkid == NULL)
+ return -EINVAL;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_setpmkid_cmd *) skb->data;
+ memcpy(cmd->bssid, bssid, ETH_ALEN);
+ if (set) {
+ memcpy(cmd->pmkid, pmkid, sizeof(cmd->pmkid));
+ cmd->enable = PMKID_ENABLE;
+ } else {
+ memset(cmd->pmkid, 0, sizeof(cmd->pmkid));
+ cmd->enable = PMKID_DISABLE;
+ }
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_PMKID_CMDID,
+ NO_SYNC_WMIFLAG);
+
+ return ret;
+}
+
+static int ath6kl_wmi_data_sync_send(struct wmi *wmi, struct sk_buff *skb,
+ enum htc_endpoint_id ep_id)
+{
+ struct wmi_data_hdr *data_hdr;
+ int ret;
+
+ if (WARN_ON(skb == NULL || ep_id == wmi->ep_id))
+ return -EINVAL;
+
+ skb_push(skb, sizeof(struct wmi_data_hdr));
+
+ data_hdr = (struct wmi_data_hdr *) skb->data;
+ data_hdr->info = SYNC_MSGTYPE << WMI_DATA_HDR_MSG_TYPE_SHIFT;
+ data_hdr->info3 = 0;
+
+ ret = ath6kl_control_tx(wmi->parent_dev, skb, ep_id);
+
+ return ret;
+}
+
+static int ath6kl_wmi_sync_point(struct wmi *wmi)
+{
+ struct sk_buff *skb;
+ struct wmi_sync_cmd *cmd;
+ struct wmi_data_sync_bufs data_sync_bufs[WMM_NUM_AC];
+ enum htc_endpoint_id ep_id;
+ u8 index, num_pri_streams = 0;
+ int ret = 0;
+
+ memset(data_sync_bufs, 0, sizeof(data_sync_bufs));
+
+ spin_lock_bh(&wmi->lock);
+
+ for (index = 0; index < WMM_NUM_AC; index++) {
+ if (wmi->fat_pipe_exist & (1 << index)) {
+ num_pri_streams++;
+ data_sync_bufs[num_pri_streams - 1].traffic_class =
+ index;
+ }
+ }
+
+ spin_unlock_bh(&wmi->lock);
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb) {
+ ret = -ENOMEM;
+ goto free_skb;
+ }
+
+ cmd = (struct wmi_sync_cmd *) skb->data;
+
+ /*
+ * In the SYNC cmd sent on the control Ep, send a bitmap
+ * of the data eps on which the Data Sync will be sent
+ */
+ cmd->data_sync_map = wmi->fat_pipe_exist;
+
+ for (index = 0; index < num_pri_streams; index++) {
+ data_sync_bufs[index].skb = ath6kl_buf_alloc(0);
+ if (data_sync_bufs[index].skb == NULL) {
+ ret = -ENOMEM;
+ break;
+ }
+ }
+
+ /*
+ * If buffer allocation for any of the dataSync fails,
+ * then do not send the Synchronize cmd on the control ep
+ */
+ if (ret)
+ goto free_skb;
+
+ /*
+ * Send sync cmd followed by sync data messages on all
+ * endpoints being used
+ */
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SYNCHRONIZE_CMDID,
+ NO_SYNC_WMIFLAG);
+
+ if (ret)
+ goto free_skb;
+
+ /* cmd buffer sent, we no longer own it */
+ skb = NULL;
+
+ for (index = 0; index < num_pri_streams; index++) {
+
+ if (WARN_ON(!data_sync_bufs[index].skb))
+ break;
+
+ ep_id = ath6kl_ac2_endpoint_id(wmi->parent_dev,
+ data_sync_bufs[index].
+ traffic_class);
+ ret =
+ ath6kl_wmi_data_sync_send(wmi, data_sync_bufs[index].skb,
+ ep_id);
+
+ if (ret)
+ break;
+
+ data_sync_bufs[index].skb = NULL;
+ }
+
+free_skb:
+ /* free up any resources left over (possibly due to an error) */
+ if (skb)
+ dev_kfree_skb(skb);
+
+ for (index = 0; index < num_pri_streams; index++) {
+ if (data_sync_bufs[index].skb != NULL) {
+ dev_kfree_skb((struct sk_buff *)data_sync_bufs[index].
+ skb);
+ }
+ }
+
+ return ret;
+}
+
+int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi,
+ struct wmi_create_pstream_cmd *params)
+{
+ struct sk_buff *skb;
+ struct wmi_create_pstream_cmd *cmd;
+ u8 fatpipe_exist_for_ac = 0;
+ s32 min_phy = 0;
+ s32 nominal_phy = 0;
+ int ret;
+
+ if (!((params->user_pri < 8) &&
+ (params->user_pri <= 0x7) &&
+ (up_to_ac[params->user_pri & 0x7] == params->traffic_class) &&
+ (params->traffic_direc == UPLINK_TRAFFIC ||
+ params->traffic_direc == DNLINK_TRAFFIC ||
+ params->traffic_direc == BIDIR_TRAFFIC) &&
+ (params->traffic_type == TRAFFIC_TYPE_APERIODIC ||
+ params->traffic_type == TRAFFIC_TYPE_PERIODIC) &&
+ (params->voice_psc_cap == DISABLE_FOR_THIS_AC ||
+ params->voice_psc_cap == ENABLE_FOR_THIS_AC ||
+ params->voice_psc_cap == ENABLE_FOR_ALL_AC) &&
+ (params->tsid == WMI_IMPLICIT_PSTREAM ||
+ params->tsid <= WMI_MAX_THINSTREAM))) {
+ return -EINVAL;
+ }
+
+ /*
+ * Check nominal PHY rate is >= minimalPHY,
+ * so that DUT can allow TSRS IE
+ */
+
+ /* Get the physical rate (units of bps) */
+ min_phy = ((le32_to_cpu(params->min_phy_rate) / 1000) / 1000);
+
+ /* Check minimal phy < nominal phy rate */
+ if (params->nominal_phy >= min_phy) {
+ /* unit of 500 kbps */
+ nominal_phy = (params->nominal_phy * 1000) / 500;
+ ath6kl_dbg(ATH6KL_DBG_WMI,
+ "TSRS IE enabled::MinPhy %x->NominalPhy ===> %x\n",
+ min_phy, nominal_phy);
+
+ params->nominal_phy = nominal_phy;
+ } else {
+ params->nominal_phy = 0;
+ }
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ ath6kl_dbg(ATH6KL_DBG_WMI,
+ "sending create_pstream_cmd: ac=%d tsid:%d\n",
+ params->traffic_class, params->tsid);
+
+ cmd = (struct wmi_create_pstream_cmd *) skb->data;
+ memcpy(cmd, params, sizeof(*cmd));
+
+ /* This is an implicitly created Fat pipe */
+ if ((u32) params->tsid == (u32) WMI_IMPLICIT_PSTREAM) {
+ spin_lock_bh(&wmi->lock);
+ fatpipe_exist_for_ac = (wmi->fat_pipe_exist &
+ (1 << params->traffic_class));
+ wmi->fat_pipe_exist |= (1 << params->traffic_class);
+ spin_unlock_bh(&wmi->lock);
+ } else {
+ /* explicitly created thin stream within a fat pipe */
+ spin_lock_bh(&wmi->lock);
+ fatpipe_exist_for_ac = (wmi->fat_pipe_exist &
+ (1 << params->traffic_class));
+ wmi->stream_exist_for_ac[params->traffic_class] |=
+ (1 << params->tsid);
+ /*
+ * If a thinstream becomes active, the fat pipe automatically
+ * becomes active
+ */
+ wmi->fat_pipe_exist |= (1 << params->traffic_class);
+ spin_unlock_bh(&wmi->lock);
+ }
+
+ /*
+ * Indicate activty change to driver layer only if this is the
+ * first TSID to get created in this AC explicitly or an implicit
+ * fat pipe is getting created.
+ */
+ if (!fatpipe_exist_for_ac)
+ ath6kl_indicate_tx_activity(wmi->parent_dev,
+ params->traffic_class, true);
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_CREATE_PSTREAM_CMDID,
+ NO_SYNC_WMIFLAG);
+ return ret;
+}
+
+int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 traffic_class, u8 tsid)
+{
+ struct sk_buff *skb;
+ struct wmi_delete_pstream_cmd *cmd;
+ u16 active_tsids = 0;
+ int ret;
+
+ if (traffic_class > 3) {
+ ath6kl_err("invalid traffic class: %d\n", traffic_class);
+ return -EINVAL;
+ }
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_delete_pstream_cmd *) skb->data;
+ cmd->traffic_class = traffic_class;
+ cmd->tsid = tsid;
+
+ spin_lock_bh(&wmi->lock);
+ active_tsids = wmi->stream_exist_for_ac[traffic_class];
+ spin_unlock_bh(&wmi->lock);
+
+ if (!(active_tsids & (1 << tsid))) {
+ dev_kfree_skb(skb);
+ ath6kl_dbg(ATH6KL_DBG_WMI,
+ "TSID %d doesn't exist for traffic class: %d\n",
+ tsid, traffic_class);
+ return -ENODATA;
+ }
+
+ ath6kl_dbg(ATH6KL_DBG_WMI,
+ "sending delete_pstream_cmd: traffic class: %d tsid=%d\n",
+ traffic_class, tsid);
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_DELETE_PSTREAM_CMDID,
+ SYNC_BEFORE_WMIFLAG);
+
+ spin_lock_bh(&wmi->lock);
+ wmi->stream_exist_for_ac[traffic_class] &= ~(1 << tsid);
+ active_tsids = wmi->stream_exist_for_ac[traffic_class];
+ spin_unlock_bh(&wmi->lock);
+
+ /*
+ * Indicate stream inactivity to driver layer only if all tsids
+ * within this AC are deleted.
+ */
+ if (!active_tsids) {
+ ath6kl_indicate_tx_activity(wmi->parent_dev,
+ traffic_class, false);
+ wmi->fat_pipe_exist &= ~(1 << traffic_class);
+ }
+
+ return ret;
+}
+
+int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd)
+{
+ struct sk_buff *skb;
+ struct wmi_set_ip_cmd *cmd;
+ int ret;
+
+ /* Multicast address are not valid */
+ if ((*((u8 *) &ip_cmd->ips[0]) >= 0xE0) ||
+ (*((u8 *) &ip_cmd->ips[1]) >= 0xE0))
+ return -EINVAL;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_ip_cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_set_ip_cmd *) skb->data;
+ memcpy(cmd, ip_cmd, sizeof(struct wmi_set_ip_cmd));
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_IP_CMDID, NO_SYNC_WMIFLAG);
+ return ret;
+}
+
+static int ath6kl_wmi_get_wow_list_event_rx(struct wmi *wmi, u8 * datap,
+ int len)
+{
+ if (len < sizeof(struct wmi_get_wow_list_reply))
+ return -EINVAL;
+
+ return 0;
+}
+
+static int ath6kl_wmi_cmd_send_xtnd(struct wmi *wmi, struct sk_buff *skb,
+ enum wmix_command_id cmd_id,
+ enum wmi_sync_flag sync_flag)
+{
+ struct wmix_cmd_hdr *cmd_hdr;
+ int ret;
+
+ skb_push(skb, sizeof(struct wmix_cmd_hdr));
+
+ cmd_hdr = (struct wmix_cmd_hdr *) skb->data;
+ cmd_hdr->cmd_id = cpu_to_le32(cmd_id);
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_EXTENSION_CMDID, sync_flag);
+
+ return ret;
+}
+
+int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source)
+{
+ struct sk_buff *skb;
+ struct wmix_hb_challenge_resp_cmd *cmd;
+ int ret;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmix_hb_challenge_resp_cmd *) skb->data;
+ cmd->cookie = cpu_to_le32(cookie);
+ cmd->source = cpu_to_le32(source);
+
+ ret = ath6kl_wmi_cmd_send_xtnd(wmi, skb, WMIX_HB_CHALLENGE_RESP_CMDID,
+ NO_SYNC_WMIFLAG);
+ return ret;
+}
+
+int ath6kl_wmi_get_stats_cmd(struct wmi *wmi)
+{
+ return ath6kl_wmi_simple_cmd(wmi, WMI_GET_STATISTICS_CMDID);
+}
+
+int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 dbM)
+{
+ struct sk_buff *skb;
+ struct wmi_set_tx_pwr_cmd *cmd;
+ int ret;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_tx_pwr_cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_set_tx_pwr_cmd *) skb->data;
+ cmd->dbM = dbM;
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_TX_PWR_CMDID,
+ NO_SYNC_WMIFLAG);
+
+ return ret;
+}
+
+int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi)
+{
+ return ath6kl_wmi_simple_cmd(wmi, WMI_GET_TX_PWR_CMDID);
+}
+
+void ath6kl_wmi_get_current_bssid(struct wmi *wmi, u8 *bssid)
+{
+ if (bssid)
+ memcpy(bssid, wmi->bssid, ETH_ALEN);
+}
+
+int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status, u8 preamble_policy)
+{
+ struct sk_buff *skb;
+ struct wmi_set_lpreamble_cmd *cmd;
+ int ret;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_lpreamble_cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_set_lpreamble_cmd *) skb->data;
+ cmd->status = status;
+ cmd->preamble_policy = preamble_policy;
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_LPREAMBLE_CMDID,
+ NO_SYNC_WMIFLAG);
+ return ret;
+}
+
+int ath6kl_wmi_set_rts_cmd(struct wmi *wmi, u16 threshold)
+{
+ struct sk_buff *skb;
+ struct wmi_set_rts_cmd *cmd;
+ int ret;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_rts_cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_set_rts_cmd *) skb->data;
+ cmd->threshold = cpu_to_le16(threshold);
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_RTS_CMDID, NO_SYNC_WMIFLAG);
+ return ret;
+}
+
+int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, enum wmi_txop_cfg cfg)
+{
+ struct sk_buff *skb;
+ struct wmi_set_wmm_txop_cmd *cmd;
+ int ret;
+
+ if (!((cfg == WMI_TXOP_DISABLED) || (cfg == WMI_TXOP_ENABLED)))
+ return -EINVAL;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_set_wmm_txop_cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_set_wmm_txop_cmd *) skb->data;
+ cmd->txop_enable = cfg;
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_WMM_TXOP_CMDID,
+ NO_SYNC_WMIFLAG);
+ return ret;
+}
+
+int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl)
+{
+ struct sk_buff *skb;
+ struct wmi_set_keepalive_cmd *cmd;
+ int ret;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_set_keepalive_cmd *) skb->data;
+ cmd->keep_alive_intvl = keep_alive_intvl;
+ wmi->keep_alive_intvl = keep_alive_intvl;
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_SET_KEEPALIVE_CMDID,
+ NO_SYNC_WMIFLAG);
+ return ret;
+}
+
+s32 ath6kl_wmi_get_rate(s8 rate_index)
+{
+ if (rate_index == RATE_AUTO)
+ return 0;
+
+ return wmi_rate_tbl[(u32) rate_index][0];
+}
+
+void ath6kl_wmi_node_return(struct wmi *wmi, struct bss *bss)
+{
+ if (bss)
+ wlan_node_return(&wmi->scan_table, bss);
+}
+
+struct bss *ath6kl_wmi_find_ssid_node(struct wmi *wmi, u8 * ssid,
+ u32 ssid_len, bool is_wpa2,
+ bool match_ssid)
+{
+ struct bss *node = NULL;
+
+ node = wlan_find_ssid_node(&wmi->scan_table, ssid,
+ ssid_len, is_wpa2, match_ssid);
+ return node;
+}
+
+struct bss *ath6kl_wmi_find_node(struct wmi *wmi, const u8 * mac_addr)
+{
+ struct bss *ni = NULL;
+
+ ni = wlan_find_node(&wmi->scan_table, mac_addr);
+
+ return ni;
+}
+
+void ath6kl_wmi_node_free(struct wmi *wmi, const u8 * mac_addr)
+{
+ struct bss *ni = NULL;
+
+ ni = wlan_find_node(&wmi->scan_table, mac_addr);
+ if (ni != NULL)
+ wlan_node_reclaim(&wmi->scan_table, ni);
+
+ return;
+}
+
+static int ath6kl_wmi_get_pmkid_list_event_rx(struct wmi *wmi, u8 *datap,
+ u32 len)
+{
+ struct wmi_pmkid_list_reply *reply;
+ u32 expected_len;
+
+ if (len < sizeof(struct wmi_pmkid_list_reply))
+ return -EINVAL;
+
+ reply = (struct wmi_pmkid_list_reply *)datap;
+ expected_len = sizeof(reply->num_pmkid) +
+ le32_to_cpu(reply->num_pmkid) * WMI_PMKID_LEN;
+
+ if (len < expected_len)
+ return -EINVAL;
+
+ return 0;
+}
+
+static int ath6kl_wmi_addba_req_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ struct wmi_addba_req_event *cmd = (struct wmi_addba_req_event *) datap;
+
+ aggr_recv_addba_req_evt(wmi->parent_dev, cmd->tid,
+ le16_to_cpu(cmd->st_seq_no), cmd->win_sz);
+
+ return 0;
+}
+
+static int ath6kl_wmi_delba_req_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ struct wmi_delba_event *cmd = (struct wmi_delba_event *) datap;
+
+ aggr_recv_delba_req_evt(wmi->parent_dev, cmd->tid);
+
+ return 0;
+}
+
+/* AP mode functions */
+static int ath6kl_wmi_pspoll_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ struct wmi_pspoll_event *ev;
+
+ if (len < sizeof(struct wmi_pspoll_event))
+ return -EINVAL;
+
+ ev = (struct wmi_pspoll_event *) datap;
+
+ ath6kl_pspoll_event(wmi->parent_dev, le16_to_cpu(ev->aid));
+
+ return 0;
+}
+
+static int ath6kl_wmi_dtimexpiry_event_rx(struct wmi *wmi, u8 *datap, int len)
+{
+ ath6kl_dtimexpiry_event(wmi->parent_dev);
+
+ return 0;
+}
+
+int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u16 aid, bool flag)
+{
+ struct sk_buff *skb;
+ struct wmi_ap_set_pvb_cmd *cmd;
+ int ret;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(struct wmi_ap_set_pvb_cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_ap_set_pvb_cmd *) skb->data;
+ cmd->aid = cpu_to_le16(aid);
+ cmd->flag = cpu_to_le32(flag);
+
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_AP_SET_PVB_CMDID,
+ NO_SYNC_WMIFLAG);
+
+ return 0;
+}
+
+int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 rx_meta_ver,
+ bool rx_dot11_hdr, bool defrag_on_host)
+{
+ struct sk_buff *skb;
+ struct wmi_rx_frame_format_cmd *cmd;
+ int ret;
+
+ skb = ath6kl_wmi_get_new_buf(sizeof(*cmd));
+ if (!skb)
+ return -ENOMEM;
+
+ cmd = (struct wmi_rx_frame_format_cmd *) skb->data;
+ cmd->dot11_hdr = rx_dot11_hdr ? 1 : 0;
+ cmd->defrag_on_host = defrag_on_host ? 1 : 0;
+ cmd->meta_ver = rx_meta_ver;
+
+ /* Delete the local aggr state, on host */
+ ret = ath6kl_wmi_cmd_send(wmi, skb, WMI_RX_FRAME_FORMAT_CMDID,
+ NO_SYNC_WMIFLAG);
+
+ return ret;
+}
+
+static int ath6kl_wmi_control_rx_xtnd(struct wmi *wmi, struct sk_buff *skb)
+{
+ struct wmix_cmd_hdr *cmd;
+ u32 len;
+ u16 id;
+ u8 *datap;
+ int ret = 0;
+
+ if (skb->len < sizeof(struct wmix_cmd_hdr)) {
+ ath6kl_err("bad packet 1\n");
+ wmi->stat.cmd_len_err++;
+ return -EINVAL;
+ }
+
+ cmd = (struct wmix_cmd_hdr *) skb->data;
+ id = le32_to_cpu(cmd->cmd_id);
+
+ skb_pull(skb, sizeof(struct wmix_cmd_hdr));
+
+ datap = skb->data;
+ len = skb->len;
+
+ switch (id) {
+ case WMIX_HB_CHALLENGE_RESP_EVENTID:
+ break;
+ case WMIX_DBGLOG_EVENTID:
+ break;
+ default:
+ ath6kl_err("unknown cmd id 0x%x\n", id);
+ wmi->stat.cmd_id_err++;
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+/* Control Path */
+int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb)
+{
+ struct wmi_cmd_hdr *cmd;
+ u32 len;
+ u16 id;
+ u8 *datap;
+ int ret = 0;
+
+ if (WARN_ON(skb == NULL))
+ return -EINVAL;
+
+ if (skb->len < sizeof(struct wmi_cmd_hdr)) {
+ ath6kl_err("bad packet 1\n");
+ dev_kfree_skb(skb);
+ wmi->stat.cmd_len_err++;
+ return -EINVAL;
+ }
+
+ cmd = (struct wmi_cmd_hdr *) skb->data;
+ id = le16_to_cpu(cmd->cmd_id);
+
+ skb_pull(skb, sizeof(struct wmi_cmd_hdr));
+
+ datap = skb->data;
+ len = skb->len;
+
+ ath6kl_dbg(ATH6KL_DBG_WMI, "%s: wmi id: %d\n", __func__, id);
+ ath6kl_dbg_dump(ATH6KL_DBG_RAW_BYTES, "msg payload ", datap, len);
+
+ switch (id) {
+ case WMI_GET_BITRATE_CMDID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_BITRATE_CMDID\n");
+ ret = ath6kl_wmi_bitrate_reply_rx(wmi, datap, len);
+ break;
+ case WMI_GET_CHANNEL_LIST_CMDID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_CHANNEL_LIST_CMDID\n");
+ ret = ath6kl_wmi_ch_list_reply_rx(wmi, datap, len);
+ break;
+ case WMI_GET_TX_PWR_CMDID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_TX_PWR_CMDID\n");
+ ret = ath6kl_wmi_tx_pwr_reply_rx(wmi, datap, len);
+ break;
+ case WMI_READY_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_READY_EVENTID\n");
+ ret = ath6kl_wmi_ready_event_rx(wmi, datap, len);
+ break;
+ case WMI_CONNECT_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CONNECT_EVENTID\n");
+ ret = ath6kl_wmi_connect_event_rx(wmi, datap, len);
+ break;
+ case WMI_DISCONNECT_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DISCONNECT_EVENTID\n");
+ ret = ath6kl_wmi_disconnect_event_rx(wmi, datap, len);
+ break;
+ case WMI_PEER_NODE_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PEER_NODE_EVENTID\n");
+ ret = ath6kl_wmi_peer_node_event_rx(wmi, datap, len);
+ break;
+ case WMI_TKIP_MICERR_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TKIP_MICERR_EVENTID\n");
+ ret = ath6kl_wmi_tkip_micerr_event_rx(wmi, datap, len);
+ break;
+ case WMI_BSSINFO_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_BSSINFO_EVENTID\n");
+ ath6kl_wmi_convert_bssinfo_hdr2_to_hdr(skb, datap);
+ ret = ath6kl_wmi_bssinfo_event_rx(wmi, skb->data, skb->len);
+ break;
+ case WMI_REGDOMAIN_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REGDOMAIN_EVENTID\n");
+ break;
+ case WMI_PSTREAM_TIMEOUT_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSTREAM_TIMEOUT_EVENTID\n");
+ ret = ath6kl_wmi_pstream_timeout_event_rx(wmi, datap, len);
+ break;
+ case WMI_NEIGHBOR_REPORT_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_NEIGHBOR_REPORT_EVENTID\n");
+ break;
+ case WMI_SCAN_COMPLETE_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SCAN_COMPLETE_EVENTID\n");
+ ret = ath6kl_wmi_scan_complete_rx(wmi, datap, len);
+ break;
+ case WMI_CMDERROR_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CMDERROR_EVENTID\n");
+ ret = ath6kl_wmi_error_event_rx(wmi, datap, len);
+ break;
+ case WMI_REPORT_STATISTICS_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_STATISTICS_EVENTID\n");
+ ret = ath6kl_wmi_stats_event_rx(wmi, datap, len);
+ break;
+ case WMI_RSSI_THRESHOLD_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_RSSI_THRESHOLD_EVENTID\n");
+ ret = ath6kl_wmi_rssi_threshold_event_rx(wmi, datap, len);
+ break;
+ case WMI_ERROR_REPORT_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ERROR_REPORT_EVENTID\n");
+ break;
+ case WMI_OPT_RX_FRAME_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_OPT_RX_FRAME_EVENTID\n");
+ ret = ath6kl_wmi_opt_frame_event_rx(wmi, datap, len);
+ break;
+ case WMI_REPORT_ROAM_TBL_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_TBL_EVENTID\n");
+ break;
+ case WMI_EXTENSION_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_EXTENSION_EVENTID\n");
+ ret = ath6kl_wmi_control_rx_xtnd(wmi, skb);
+ break;
+ case WMI_CAC_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CAC_EVENTID\n");
+ ret = ath6kl_wmi_cac_event_rx(wmi, datap, len);
+ break;
+ case WMI_CHANNEL_CHANGE_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_CHANNEL_CHANGE_EVENTID\n");
+ break;
+ case WMI_REPORT_ROAM_DATA_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_REPORT_ROAM_DATA_EVENTID\n");
+ break;
+ case WMI_GET_FIXRATES_CMDID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_FIXRATES_CMDID\n");
+ ret = ath6kl_wmi_ratemask_reply_rx(wmi, datap, len);
+ break;
+ case WMI_TX_RETRY_ERR_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_RETRY_ERR_EVENTID\n");
+ break;
+ case WMI_SNR_THRESHOLD_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SNR_THRESHOLD_EVENTID\n");
+ ret = ath6kl_wmi_snr_threshold_event_rx(wmi, datap, len);
+ break;
+ case WMI_LQ_THRESHOLD_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_LQ_THRESHOLD_EVENTID\n");
+ break;
+ case WMI_APLIST_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_APLIST_EVENTID\n");
+ ret = ath6kl_wmi_aplist_event_rx(wmi, datap, len);
+ break;
+ case WMI_GET_KEEPALIVE_CMDID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_KEEPALIVE_CMDID\n");
+ ret = ath6kl_wmi_keepalive_reply_rx(wmi, datap, len);
+ break;
+ case WMI_GET_WOW_LIST_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_WOW_LIST_EVENTID\n");
+ ret = ath6kl_wmi_get_wow_list_event_rx(wmi, datap, len);
+ break;
+ case WMI_GET_PMKID_LIST_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_GET_PMKID_LIST_EVENTID\n");
+ ret = ath6kl_wmi_get_pmkid_list_event_rx(wmi, datap, len);
+ break;
+ case WMI_PSPOLL_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_PSPOLL_EVENTID\n");
+ ret = ath6kl_wmi_pspoll_event_rx(wmi, datap, len);
+ break;
+ case WMI_DTIMEXPIRY_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DTIMEXPIRY_EVENTID\n");
+ ret = ath6kl_wmi_dtimexpiry_event_rx(wmi, datap, len);
+ break;
+ case WMI_SET_PARAMS_REPLY_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_SET_PARAMS_REPLY_EVENTID\n");
+ break;
+ case WMI_ADDBA_REQ_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_REQ_EVENTID\n");
+ ret = ath6kl_wmi_addba_req_event_rx(wmi, datap, len);
+ break;
+ case WMI_ADDBA_RESP_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_ADDBA_RESP_EVENTID\n");
+ break;
+ case WMI_DELBA_REQ_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_DELBA_REQ_EVENTID\n");
+ ret = ath6kl_wmi_delba_req_event_rx(wmi, datap, len);
+ break;
+ case WMI_REPORT_BTCOEX_CONFIG_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI,
+ "WMI_REPORT_BTCOEX_CONFIG_EVENTID\n");
+ break;
+ case WMI_REPORT_BTCOEX_STATS_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI,
+ "WMI_REPORT_BTCOEX_STATS_EVENTID\n");
+ break;
+ case WMI_TX_COMPLETE_EVENTID:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "WMI_TX_COMPLETE_EVENTID\n");
+ ret = ath6kl_wmi_tx_complete_event_rx(datap, len);
+ break;
+ default:
+ ath6kl_dbg(ATH6KL_DBG_WMI, "unknown cmd id 0x%x\n", id);
+ wmi->stat.cmd_id_err++;
+ ret = -EINVAL;
+ break;
+ }
+
+ dev_kfree_skb(skb);
+
+ return ret;
+}
+
+static void ath6kl_wmi_qos_state_init(struct wmi *wmi)
+{
+ if (!wmi)
+ return;
+
+ spin_lock_bh(&wmi->lock);
+
+ wmi->fat_pipe_exist = 0;
+ memset(wmi->stream_exist_for_ac, 0, sizeof(wmi->stream_exist_for_ac));
+
+ spin_unlock_bh(&wmi->lock);
+}
+
+void *ath6kl_wmi_init(void *dev)
+{
+ struct wmi *wmi;
+
+ wmi = kzalloc(sizeof(struct wmi), GFP_KERNEL);
+ if (!wmi)
+ return NULL;
+
+ spin_lock_init(&wmi->lock);
+
+ wmi->parent_dev = dev;
+
+ wlan_node_table_init(wmi, &wmi->scan_table);
+ ath6kl_wmi_qos_state_init(wmi);
+
+ wmi->pwr_mode = REC_POWER;
+ wmi->phy_mode = WMI_11G_MODE;
+
+ wmi->pair_crypto_type = NONE_CRYPT;
+ wmi->grp_crypto_type = NONE_CRYPT;
+
+ wmi->ht_allowed[A_BAND_24GHZ] = 1;
+ wmi->ht_allowed[A_BAND_5GHZ] = 1;
+
+ return wmi;
+}
+
+void ath6kl_wmi_shutdown(struct wmi *wmi)
+{
+ if (!wmi)
+ return;
+
+ wlan_node_table_cleanup(&wmi->scan_table);
+ kfree(wmi);
+}
diff --git a/drivers/net/wireless/ath/ath6kl/wmi.h b/drivers/net/wireless/ath/ath6kl/wmi.h
new file mode 100644
index 000000000000..bbaa7049f4a8
--- /dev/null
+++ b/drivers/net/wireless/ath/ath6kl/wmi.h
@@ -0,0 +1,2024 @@
+/*
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
+ *
+ * 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.
+ */
+
+/*
+ * This file contains the definitions of the WMI protocol specified in the
+ * Wireless Module Interface (WMI). It includes definitions of all the
+ * commands and events. Commands are messages from the host to the WM.
+ * Events and Replies are messages from the WM to the host.
+ */
+
+#ifndef WMI_H
+#define WMI_H
+
+#include <linux/ieee80211.h>
+
+#include "htc.h"
+
+#define HTC_PROTOCOL_VERSION 0x0002
+#define WMI_PROTOCOL_VERSION 0x0002
+#define WMI_CONTROL_MSG_MAX_LEN 256
+#define is_ethertype(type_or_len) ((type_or_len) >= 0x0600)
+
+#define IP_ETHERTYPE 0x0800
+
+#define WMI_IMPLICIT_PSTREAM 0xFF
+#define WMI_MAX_THINSTREAM 15
+
+#define SSID_IE_LEN_INDEX 13
+
+/* Host side link management data structures */
+#define SIG_QUALITY_THRESH_LVLS 6
+#define SIG_QUALITY_UPPER_THRESH_LVLS SIG_QUALITY_THRESH_LVLS
+#define SIG_QUALITY_LOWER_THRESH_LVLS SIG_QUALITY_THRESH_LVLS
+
+#define A_BAND_24GHZ 0
+#define A_BAND_5GHZ 1
+#define A_NUM_BANDS 2
+
+/* in ms */
+#define WMI_IMPLICIT_PSTREAM_INACTIVITY_INT 5000
+
+/*
+ * There are no signed versions of __le16 and __le32, so for a temporary
+ * solution come up with our own version. The idea is from fs/ntfs/types.h.
+ *
+ * Use a_ prefix so that it doesn't conflict if we get proper support to
+ * linux/types.h.
+ */
+typedef __s16 __bitwise a_sle16;
+typedef __s32 __bitwise a_sle32;
+
+static inline a_sle32 a_cpu_to_sle32(s32 val)
+{
+ return (__force a_sle32) cpu_to_le32(val);
+}
+
+static inline s32 a_sle32_to_cpu(a_sle32 val)
+{
+ return le32_to_cpu((__force __le32) val);
+}
+
+static inline a_sle16 a_cpu_to_sle16(s16 val)
+{
+ return (__force a_sle16) cpu_to_le16(val);
+}
+
+static inline s16 a_sle16_to_cpu(a_sle16 val)
+{
+ return le16_to_cpu((__force __le16) val);
+}
+
+struct sq_threshold_params {
+ s16 upper_threshold[SIG_QUALITY_UPPER_THRESH_LVLS];
+ s16 lower_threshold[SIG_QUALITY_LOWER_THRESH_LVLS];
+ u32 upper_threshold_valid_count;
+ u32 lower_threshold_valid_count;
+ u32 polling_interval;
+ u8 weight;
+ u8 last_rssi;
+ u8 last_rssi_poll_event;
+};
+
+struct wmi_stats {
+ u32 cmd_len_err;
+ u32 cmd_id_err;
+};
+
+struct wmi_data_sync_bufs {
+ u8 traffic_class;
+ struct sk_buff *skb;
+};
+
+/* WMM stream classes */
+#define WMM_NUM_AC 4
+#define WMM_AC_BE 0 /* best effort */
+#define WMM_AC_BK 1 /* background */
+#define WMM_AC_VI 2 /* video */
+#define WMM_AC_VO 3 /* voice */
+
+struct wmi {
+ bool ready;
+ u16 stream_exist_for_ac[WMM_NUM_AC];
+ u8 fat_pipe_exist;
+ void *parent_dev;
+ struct wmi_stats stat;
+ struct ath6kl_node_table scan_table;
+ u8 bssid[ETH_ALEN];
+ u8 pwr_mode;
+ u8 phy_mode;
+ u8 keep_alive_intvl;
+ spinlock_t lock;
+ enum htc_endpoint_id ep_id;
+ struct sq_threshold_params
+ sq_threshld[SIGNAL_QUALITY_METRICS_NUM_MAX];
+ enum crypto_type pair_crypto_type;
+ enum crypto_type grp_crypto_type;
+ bool is_wmm_enabled;
+ u8 ht_allowed[A_NUM_BANDS];
+ u8 traffic_class;
+ bool is_probe_ssid;
+};
+
+struct host_app_area {
+ u32 wmi_protocol_ver;
+};
+
+enum wmi_msg_type {
+ DATA_MSGTYPE = 0x0,
+ CNTL_MSGTYPE,
+ SYNC_MSGTYPE,
+ OPT_MSGTYPE,
+};
+
+/*
+ * Macros for operating on WMI_DATA_HDR (info) field
+ */
+
+#define WMI_DATA_HDR_MSG_TYPE_MASK 0x03
+#define WMI_DATA_HDR_MSG_TYPE_SHIFT 0
+#define WMI_DATA_HDR_UP_MASK 0x07
+#define WMI_DATA_HDR_UP_SHIFT 2
+
+/* In AP mode, the same bit (b5) is used to indicate Power save state in
+ * the Rx dir and More data bit state in the tx direction.
+ */
+#define WMI_DATA_HDR_PS_MASK 0x1
+#define WMI_DATA_HDR_PS_SHIFT 5
+
+#define WMI_DATA_HDR_MORE_MASK 0x1
+#define WMI_DATA_HDR_MORE_SHIFT 5
+
+enum wmi_data_hdr_data_type {
+ WMI_DATA_HDR_DATA_TYPE_802_3 = 0,
+ WMI_DATA_HDR_DATA_TYPE_802_11,
+
+ /* used to be used for the PAL */
+ WMI_DATA_HDR_DATA_TYPE_ACL,
+};
+
+#define WMI_DATA_HDR_DATA_TYPE_MASK 0x3
+#define WMI_DATA_HDR_DATA_TYPE_SHIFT 6
+
+/* Macros for operating on WMI_DATA_HDR (info2) field */
+#define WMI_DATA_HDR_SEQNO_MASK 0xFFF
+#define WMI_DATA_HDR_SEQNO_SHIFT 0
+
+#define WMI_DATA_HDR_AMSDU_MASK 0x1
+#define WMI_DATA_HDR_AMSDU_SHIFT 12
+
+#define WMI_DATA_HDR_META_MASK 0x7
+#define WMI_DATA_HDR_META_SHIFT 13
+
+struct wmi_data_hdr {
+ s8 rssi;
+
+ /*
+ * usage of 'info' field(8-bit):
+ *
+ * b1:b0 - WMI_MSG_TYPE
+ * b4:b3:b2 - UP(tid)
+ * b5 - Used in AP mode.
+ * More-data in tx dir, PS in rx.
+ * b7:b6 - Dot3 header(0),
+ * Dot11 Header(1),
+ * ACL data(2)
+ */
+ u8 info;
+
+ /*
+ * usage of 'info2' field(16-bit):
+ *
+ * b11:b0 - seq_no
+ * b12 - A-MSDU?
+ * b15:b13 - META_DATA_VERSION 0 - 7
+ */
+ __le16 info2;
+ __le16 info3;
+} __packed;
+
+static inline u8 wmi_data_hdr_get_up(struct wmi_data_hdr *dhdr)
+{
+ return (dhdr->info >> WMI_DATA_HDR_UP_SHIFT) & WMI_DATA_HDR_UP_MASK;
+}
+
+static inline void wmi_data_hdr_set_up(struct wmi_data_hdr *dhdr,
+ u8 usr_pri)
+{
+ dhdr->info &= ~(WMI_DATA_HDR_UP_MASK << WMI_DATA_HDR_UP_SHIFT);
+ dhdr->info |= usr_pri << WMI_DATA_HDR_UP_SHIFT;
+}
+
+static inline u8 wmi_data_hdr_get_dot11(struct wmi_data_hdr *dhdr)
+{
+ u8 data_type;
+
+ data_type = (dhdr->info >> WMI_DATA_HDR_DATA_TYPE_SHIFT) &
+ WMI_DATA_HDR_DATA_TYPE_MASK;
+ return (data_type == WMI_DATA_HDR_DATA_TYPE_802_11);
+}
+
+static inline u16 wmi_data_hdr_get_seqno(struct wmi_data_hdr *dhdr)
+{
+ return (le16_to_cpu(dhdr->info2) >> WMI_DATA_HDR_SEQNO_SHIFT) &
+ WMI_DATA_HDR_SEQNO_MASK;
+}
+
+static inline u8 wmi_data_hdr_is_amsdu(struct wmi_data_hdr *dhdr)
+{
+ return (le16_to_cpu(dhdr->info2) >> WMI_DATA_HDR_AMSDU_SHIFT) &
+ WMI_DATA_HDR_AMSDU_MASK;
+}
+
+static inline u8 wmi_data_hdr_get_meta(struct wmi_data_hdr *dhdr)
+{
+ return (le16_to_cpu(dhdr->info2) >> WMI_DATA_HDR_META_SHIFT) &
+ WMI_DATA_HDR_META_MASK;
+}
+
+/* Tx meta version definitions */
+#define WMI_MAX_TX_META_SZ 12
+#define WMI_META_VERSION_1 0x01
+#define WMI_META_VERSION_2 0x02
+
+struct wmi_tx_meta_v1 {
+ /* packet ID to identify the tx request */
+ u8 pkt_id;
+
+ /* rate policy to be used for the tx of this frame */
+ u8 rate_plcy_id;
+} __packed;
+
+struct wmi_tx_meta_v2 {
+ /*
+ * Offset from start of the WMI header for csum calculation to
+ * begin.
+ */
+ u8 csum_start;
+
+ /* offset from start of WMI header where final csum goes */
+ u8 csum_dest;
+
+ /* no of bytes over which csum is calculated */
+ u8 csum_flags;
+} __packed;
+
+struct wmi_rx_meta_v1 {
+ u8 status;
+
+ /* rate index mapped to rate at which this packet was received. */
+ u8 rix;
+
+ /* rssi of packet */
+ u8 rssi;
+
+ /* rf channel during packet reception */
+ u8 channel;
+
+ __le16 flags;
+} __packed;
+
+struct wmi_rx_meta_v2 {
+ __le16 csum;
+
+ /* bit 0 set -partial csum valid bit 1 set -test mode */
+ u8 csum_flags;
+} __packed;
+
+/* Control Path */
+struct wmi_cmd_hdr {
+ __le16 cmd_id;
+
+ /* info1 - 16 bits
+ * b03:b00 - id
+ * b15:b04 - unused */
+ __le16 info1;
+
+ /* for alignment */
+ __le16 reserved;
+} __packed;
+
+/* List of WMI commands */
+enum wmi_cmd_id {
+ WMI_CONNECT_CMDID = 0x0001,
+ WMI_RECONNECT_CMDID,
+ WMI_DISCONNECT_CMDID,
+ WMI_SYNCHRONIZE_CMDID,
+ WMI_CREATE_PSTREAM_CMDID,
+ WMI_DELETE_PSTREAM_CMDID,
+ WMI_START_SCAN_CMDID,
+ WMI_SET_SCAN_PARAMS_CMDID,
+ WMI_SET_BSS_FILTER_CMDID,
+ WMI_SET_PROBED_SSID_CMDID, /* 10 */
+ WMI_SET_LISTEN_INT_CMDID,
+ WMI_SET_BMISS_TIME_CMDID,
+ WMI_SET_DISC_TIMEOUT_CMDID,
+ WMI_GET_CHANNEL_LIST_CMDID,
+ WMI_SET_BEACON_INT_CMDID,
+ WMI_GET_STATISTICS_CMDID,
+ WMI_SET_CHANNEL_PARAMS_CMDID,
+ WMI_SET_POWER_MODE_CMDID,
+ WMI_SET_IBSS_PM_CAPS_CMDID,
+ WMI_SET_POWER_PARAMS_CMDID, /* 20 */
+ WMI_SET_POWERSAVE_TIMERS_POLICY_CMDID,
+ WMI_ADD_CIPHER_KEY_CMDID,
+ WMI_DELETE_CIPHER_KEY_CMDID,
+ WMI_ADD_KRK_CMDID,
+ WMI_DELETE_KRK_CMDID,
+ WMI_SET_PMKID_CMDID,
+ WMI_SET_TX_PWR_CMDID,
+ WMI_GET_TX_PWR_CMDID,
+ WMI_SET_ASSOC_INFO_CMDID,
+ WMI_ADD_BAD_AP_CMDID, /* 30 */
+ WMI_DELETE_BAD_AP_CMDID,
+ WMI_SET_TKIP_COUNTERMEASURES_CMDID,
+ WMI_RSSI_THRESHOLD_PARAMS_CMDID,
+ WMI_TARGET_ERROR_REPORT_BITMASK_CMDID,
+ WMI_SET_ACCESS_PARAMS_CMDID,
+ WMI_SET_RETRY_LIMITS_CMDID,
+ WMI_SET_OPT_MODE_CMDID,
+ WMI_OPT_TX_FRAME_CMDID,
+ WMI_SET_VOICE_PKT_SIZE_CMDID,
+ WMI_SET_MAX_SP_LEN_CMDID, /* 40 */
+ WMI_SET_ROAM_CTRL_CMDID,
+ WMI_GET_ROAM_TBL_CMDID,
+ WMI_GET_ROAM_DATA_CMDID,
+ WMI_ENABLE_RM_CMDID,
+ WMI_SET_MAX_OFFHOME_DURATION_CMDID,
+ WMI_EXTENSION_CMDID, /* Non-wireless extensions */
+ WMI_SNR_THRESHOLD_PARAMS_CMDID,
+ WMI_LQ_THRESHOLD_PARAMS_CMDID,
+ WMI_SET_LPREAMBLE_CMDID,
+ WMI_SET_RTS_CMDID, /* 50 */
+ WMI_CLR_RSSI_SNR_CMDID,
+ WMI_SET_FIXRATES_CMDID,
+ WMI_GET_FIXRATES_CMDID,
+ WMI_SET_AUTH_MODE_CMDID,
+ WMI_SET_REASSOC_MODE_CMDID,
+ WMI_SET_WMM_CMDID,
+ WMI_SET_WMM_TXOP_CMDID,
+ WMI_TEST_CMDID,
+
+ /* COEX AR6002 only */
+ WMI_SET_BT_STATUS_CMDID,
+ WMI_SET_BT_PARAMS_CMDID, /* 60 */
+
+ WMI_SET_KEEPALIVE_CMDID,
+ WMI_GET_KEEPALIVE_CMDID,
+ WMI_SET_APPIE_CMDID,
+ WMI_GET_APPIE_CMDID,
+ WMI_SET_WSC_STATUS_CMDID,
+
+ /* Wake on Wireless */
+ WMI_SET_HOST_SLEEP_MODE_CMDID,
+ WMI_SET_WOW_MODE_CMDID,
+ WMI_GET_WOW_LIST_CMDID,
+ WMI_ADD_WOW_PATTERN_CMDID,
+ WMI_DEL_WOW_PATTERN_CMDID, /* 70 */
+
+ WMI_SET_FRAMERATES_CMDID,
+ WMI_SET_AP_PS_CMDID,
+ WMI_SET_QOS_SUPP_CMDID,
+
+ /* WMI_THIN_RESERVED_... mark the start and end
+ * values for WMI_THIN_RESERVED command IDs. These
+ * command IDs can be found in wmi_thin.h */
+ WMI_THIN_RESERVED_START = 0x8000,
+ WMI_THIN_RESERVED_END = 0x8fff,
+
+ /* Developer commands starts at 0xF000 */
+ WMI_SET_BITRATE_CMDID = 0xF000,
+ WMI_GET_BITRATE_CMDID,
+ WMI_SET_WHALPARAM_CMDID,
+ WMI_SET_MAC_ADDRESS_CMDID,
+ WMI_SET_AKMP_PARAMS_CMDID,
+ WMI_SET_PMKID_LIST_CMDID,
+ WMI_GET_PMKID_LIST_CMDID,
+ WMI_ABORT_SCAN_CMDID,
+ WMI_SET_TARGET_EVENT_REPORT_CMDID,
+
+ /* Unused */
+ WMI_UNUSED1,
+ WMI_UNUSED2,
+
+ /* AP mode commands */
+ WMI_AP_HIDDEN_SSID_CMDID,
+ WMI_AP_SET_NUM_STA_CMDID,
+ WMI_AP_ACL_POLICY_CMDID,
+ WMI_AP_ACL_MAC_LIST_CMDID,
+ WMI_AP_CONFIG_COMMIT_CMDID,
+ WMI_AP_SET_MLME_CMDID,
+ WMI_AP_SET_PVB_CMDID,
+ WMI_AP_CONN_INACT_CMDID,
+ WMI_AP_PROT_SCAN_TIME_CMDID,
+ WMI_AP_SET_COUNTRY_CMDID,
+ WMI_AP_SET_DTIM_CMDID,
+ WMI_AP_MODE_STAT_CMDID,
+
+ WMI_SET_IP_CMDID,
+ WMI_SET_PARAMS_CMDID,
+ WMI_SET_MCAST_FILTER_CMDID,
+ WMI_DEL_MCAST_FILTER_CMDID,
+
+ WMI_ALLOW_AGGR_CMDID,
+ WMI_ADDBA_REQ_CMDID,
+ WMI_DELBA_REQ_CMDID,
+ WMI_SET_HT_CAP_CMDID,
+ WMI_SET_HT_OP_CMDID,
+ WMI_SET_TX_SELECT_RATES_CMDID,
+ WMI_SET_TX_SGI_PARAM_CMDID,
+ WMI_SET_RATE_POLICY_CMDID,
+
+ WMI_HCI_CMD_CMDID,
+ WMI_RX_FRAME_FORMAT_CMDID,
+ WMI_SET_THIN_MODE_CMDID,
+ WMI_SET_BT_WLAN_CONN_PRECEDENCE_CMDID,
+
+ WMI_AP_SET_11BG_RATESET_CMDID,
+ WMI_SET_PMK_CMDID,
+ WMI_MCAST_FILTER_CMDID,
+
+ /* COEX CMDID AR6003 */
+ WMI_SET_BTCOEX_FE_ANT_CMDID,
+ WMI_SET_BTCOEX_COLOCATED_BT_DEV_CMDID,
+ WMI_SET_BTCOEX_SCO_CONFIG_CMDID,
+ WMI_SET_BTCOEX_A2DP_CONFIG_CMDID,
+ WMI_SET_BTCOEX_ACLCOEX_CONFIG_CMDID,
+ WMI_SET_BTCOEX_BTINQUIRY_PAGE_CONFIG_CMDID,
+ WMI_SET_BTCOEX_DEBUG_CMDID,
+ WMI_SET_BTCOEX_BT_OPERATING_STATUS_CMDID,
+ WMI_GET_BTCOEX_STATS_CMDID,
+ WMI_GET_BTCOEX_CONFIG_CMDID,
+
+ WMI_SET_DFS_ENABLE_CMDID, /* F034 */
+ WMI_SET_DFS_MINRSSITHRESH_CMDID,
+ WMI_SET_DFS_MAXPULSEDUR_CMDID,
+ WMI_DFS_RADAR_DETECTED_CMDID,
+
+ /* P2P commands */
+ WMI_P2P_SET_CONFIG_CMDID, /* F038 */
+ WMI_WPS_SET_CONFIG_CMDID,
+ WMI_SET_REQ_DEV_ATTR_CMDID,
+ WMI_P2P_FIND_CMDID,
+ WMI_P2P_STOP_FIND_CMDID,
+ WMI_P2P_GO_NEG_START_CMDID,
+ WMI_P2P_LISTEN_CMDID,
+
+ WMI_CONFIG_TX_MAC_RULES_CMDID, /* F040 */
+ WMI_SET_PROMISCUOUS_MODE_CMDID,
+ WMI_RX_FRAME_FILTER_CMDID,
+ WMI_SET_CHANNEL_CMDID,
+
+ /* WAC commands */
+ WMI_ENABLE_WAC_CMDID,
+ WMI_WAC_SCAN_REPLY_CMDID,
+ WMI_WAC_CTRL_REQ_CMDID,
+ WMI_SET_DIV_PARAMS_CMDID,
+
+ WMI_GET_PMK_CMDID,
+ WMI_SET_PASSPHRASE_CMDID,
+ WMI_SEND_ASSOC_RES_CMDID,
+ WMI_SET_ASSOC_REQ_RELAY_CMDID,
+ WMI_GET_RFKILL_MODE_CMDID,
+
+ /* ACS command, consists of sub-commands */
+ WMI_ACS_CTRL_CMDID,
+
+ /* Ultra low power store / recall commands */
+ WMI_STORERECALL_CONFIGURE_CMDID,
+ WMI_STORERECALL_RECALL_CMDID,
+ WMI_STORERECALL_HOST_READY_CMDID,
+ WMI_FORCE_TARGET_ASSERT_CMDID,
+ WMI_SET_EXCESS_TX_RETRY_THRES_CMDID,
+};
+
+/* WMI_CONNECT_CMDID */
+enum network_type {
+ INFRA_NETWORK = 0x01,
+ ADHOC_NETWORK = 0x02,
+ ADHOC_CREATOR = 0x04,
+ AP_NETWORK = 0x10,
+};
+
+enum dot11_auth_mode {
+ OPEN_AUTH = 0x01,
+ SHARED_AUTH = 0x02,
+
+ /* different from IEEE_AUTH_MODE definitions */
+ LEAP_AUTH = 0x04,
+};
+
+enum {
+ AUTH_IDLE,
+ AUTH_OPEN_IN_PROGRESS,
+};
+
+enum auth_mode {
+ NONE_AUTH = 0x01,
+ WPA_AUTH = 0x02,
+ WPA2_AUTH = 0x04,
+ WPA_PSK_AUTH = 0x08,
+ WPA2_PSK_AUTH = 0x10,
+ WPA_AUTH_CCKM = 0x20,
+ WPA2_AUTH_CCKM = 0x40,
+};
+
+#define WMI_MIN_CRYPTO_TYPE NONE_CRYPT
+#define WMI_MAX_CRYPTO_TYPE (AES_CRYPT + 1)
+
+#define WMI_MIN_KEY_INDEX 0
+#define WMI_MAX_KEY_INDEX 3
+
+#define WMI_MAX_KEY_LEN 32
+
+/*
+ * NB: these values are ordered carefully; there are lots of
+ * of implications in any reordering. In particular beware
+ * that 4 is not used to avoid conflicting with IEEE80211_F_PRIVACY.
+ */
+#define ATH6KL_CIPHER_WEP 0
+#define ATH6KL_CIPHER_TKIP 1
+#define ATH6KL_CIPHER_AES_OCB 2
+#define ATH6KL_CIPHER_AES_CCM 3
+#define ATH6KL_CIPHER_CKIP 5
+#define ATH6KL_CIPHER_CCKM_KRK 6
+#define ATH6KL_CIPHER_NONE 7 /* pseudo value */
+
+/*
+ * 802.11 rate set.
+ */
+#define ATH6KL_RATE_MAXSIZE 15 /* max rates we'll handle */
+
+#define ATH_OUI_TYPE 0x01
+#define WPA_OUI_TYPE 0x01
+#define WMM_PARAM_OUI_SUBTYPE 0x01
+#define WMM_OUI_TYPE 0x02
+#define WSC_OUT_TYPE 0x04
+
+enum wmi_connect_ctrl_flags_bits {
+ CONNECT_ASSOC_POLICY_USER = 0x0001,
+ CONNECT_SEND_REASSOC = 0x0002,
+ CONNECT_IGNORE_WPAx_GROUP_CIPHER = 0x0004,
+ CONNECT_PROFILE_MATCH_DONE = 0x0008,
+ CONNECT_IGNORE_AAC_BEACON = 0x0010,
+ CONNECT_CSA_FOLLOW_BSS = 0x0020,
+ CONNECT_DO_WPA_OFFLOAD = 0x0040,
+ CONNECT_DO_NOT_DEAUTH = 0x0080,
+};
+
+struct wmi_connect_cmd {
+ u8 nw_type;
+ u8 dot11_auth_mode;
+ u8 auth_mode;
+ u8 prwise_crypto_type;
+ u8 prwise_crypto_len;
+ u8 grp_crypto_type;
+ u8 grp_crypto_len;
+ u8 ssid_len;
+ u8 ssid[IEEE80211_MAX_SSID_LEN];
+ __le16 ch;
+ u8 bssid[ETH_ALEN];
+ __le32 ctrl_flags;
+} __packed;
+
+/* WMI_RECONNECT_CMDID */
+struct wmi_reconnect_cmd {
+ /* channel hint */
+ __le16 channel;
+
+ /* mandatory if set */
+ u8 bssid[ETH_ALEN];
+} __packed;
+
+/* WMI_ADD_CIPHER_KEY_CMDID */
+enum key_usage {
+ PAIRWISE_USAGE = 0x00,
+ GROUP_USAGE = 0x01,
+
+ /* default Tx Key - static WEP only */
+ TX_USAGE = 0x02,
+};
+
+/*
+ * Bit Flag
+ * Bit 0 - Initialise TSC - default is Initialize
+ */
+#define KEY_OP_INIT_TSC 0x01
+#define KEY_OP_INIT_RSC 0x02
+
+/* default initialise the TSC & RSC */
+#define KEY_OP_INIT_VAL 0x03
+#define KEY_OP_VALID_MASK 0x03
+
+struct wmi_add_cipher_key_cmd {
+ u8 key_index;
+ u8 key_type;
+
+ /* enum key_usage */
+ u8 key_usage;
+
+ u8 key_len;
+
+ /* key replay sequence counter */
+ u8 key_rsc[8];
+
+ u8 key[WLAN_MAX_KEY_LEN];
+
+ /* additional key control info */
+ u8 key_op_ctrl;
+
+ u8 key_mac_addr[ETH_ALEN];
+} __packed;
+
+/* WMI_DELETE_CIPHER_KEY_CMDID */
+struct wmi_delete_cipher_key_cmd {
+ u8 key_index;
+} __packed;
+
+#define WMI_KRK_LEN 16
+
+/* WMI_ADD_KRK_CMDID */
+struct wmi_add_krk_cmd {
+ u8 krk[WMI_KRK_LEN];
+} __packed;
+
+/* WMI_SETPMKID_CMDID */
+
+#define WMI_PMKID_LEN 16
+
+enum pmkid_enable_flg {
+ PMKID_DISABLE = 0,
+ PMKID_ENABLE = 1,
+};
+
+struct wmi_setpmkid_cmd {
+ u8 bssid[ETH_ALEN];
+
+ /* enum pmkid_enable_flg */
+ u8 enable;
+
+ u8 pmkid[WMI_PMKID_LEN];
+} __packed;
+
+/* WMI_START_SCAN_CMD */
+enum wmi_scan_type {
+ WMI_LONG_SCAN = 0,
+ WMI_SHORT_SCAN = 1,
+};
+
+struct wmi_start_scan_cmd {
+ __le32 force_fg_scan;
+
+ /* for legacy cisco AP compatibility */
+ __le32 is_legacy;
+
+ /* max duration in the home channel(msec) */
+ __le32 home_dwell_time;
+
+ /* time interval between scans (msec) */
+ __le32 force_scan_intvl;
+
+ /* enum wmi_scan_type */
+ u8 scan_type;
+
+ /* how many channels follow */
+ u8 num_ch;
+
+ /* channels in Mhz */
+ __le16 ch_list[1];
+} __packed;
+
+/* WMI_SET_SCAN_PARAMS_CMDID */
+#define WMI_SHORTSCANRATIO_DEFAULT 3
+
+/*
+ * Warning: scan control flag value of 0xFF is used to disable
+ * all flags in WMI_SCAN_PARAMS_CMD. Do not add any more
+ * flags here
+ */
+enum wmi_scan_ctrl_flags_bits {
+
+ /* set if can scan in the connect cmd */
+ CONNECT_SCAN_CTRL_FLAGS = 0x01,
+
+ /* set if scan for the SSID it is already connected to */
+ SCAN_CONNECTED_CTRL_FLAGS = 0x02,
+
+ /* set if enable active scan */
+ ACTIVE_SCAN_CTRL_FLAGS = 0x04,
+
+ /* set if enable roam scan when bmiss and lowrssi */
+ ROAM_SCAN_CTRL_FLAGS = 0x08,
+
+ /* set if follows customer BSSINFO reporting rule */
+ REPORT_BSSINFO_CTRL_FLAGS = 0x10,
+
+ /* if disabled, target doesn't scan after a disconnect event */
+ ENABLE_AUTO_CTRL_FLAGS = 0x20,
+
+ /*
+ * Scan complete event with canceled status will be generated when
+ * a scan is prempted before it gets completed.
+ */
+ ENABLE_SCAN_ABORT_EVENT = 0x40
+};
+
+#define DEFAULT_SCAN_CTRL_FLAGS \
+ (CONNECT_SCAN_CTRL_FLAGS | \
+ SCAN_CONNECTED_CTRL_FLAGS | \
+ ACTIVE_SCAN_CTRL_FLAGS | \
+ ROAM_SCAN_CTRL_FLAGS | \
+ ENABLE_AUTO_CTRL_FLAGS)
+
+struct wmi_scan_params_cmd {
+ /* sec */
+ __le16 fg_start_period;
+
+ /* sec */
+ __le16 fg_end_period;
+
+ /* sec */
+ __le16 bg_period;
+
+ /* msec */
+ __le16 maxact_chdwell_time;
+
+ /* msec */
+ __le16 pas_chdwell_time;
+
+ /* how many shorts scan for one long */
+ u8 short_scan_ratio;
+
+ u8 scan_ctrl_flags;
+
+ /* msec */
+ __le16 minact_chdwell_time;
+
+ /* max active scans per ssid */
+ __le16 maxact_scan_per_ssid;
+
+ /* msecs */
+ __le32 max_dfsch_act_time;
+} __packed;
+
+/* WMI_SET_BSS_FILTER_CMDID */
+enum wmi_bss_filter {
+ /* no beacons forwarded */
+ NONE_BSS_FILTER = 0x0,
+
+ /* all beacons forwarded */
+ ALL_BSS_FILTER,
+
+ /* only beacons matching profile */
+ PROFILE_FILTER,
+
+ /* all but beacons matching profile */
+ ALL_BUT_PROFILE_FILTER,
+
+ /* only beacons matching current BSS */
+ CURRENT_BSS_FILTER,
+
+ /* all but beacons matching BSS */
+ ALL_BUT_BSS_FILTER,
+
+ /* beacons matching probed ssid */
+ PROBED_SSID_FILTER,
+
+ /* marker only */
+ LAST_BSS_FILTER,
+};
+
+struct wmi_bss_filter_cmd {
+ /* see, enum wmi_bss_filter */
+ u8 bss_filter;
+
+ /* for alignment */
+ u8 reserved1;
+
+ /* for alignment */
+ __le16 reserved2;
+
+ __le32 ie_mask;
+} __packed;
+
+/* WMI_SET_PROBED_SSID_CMDID */
+#define MAX_PROBED_SSID_INDEX 9
+
+enum wmi_ssid_flag {
+ /* disables entry */
+ DISABLE_SSID_FLAG = 0,
+
+ /* probes specified ssid */
+ SPECIFIC_SSID_FLAG = 0x01,
+
+ /* probes for any ssid */
+ ANY_SSID_FLAG = 0x02,
+};
+
+struct wmi_probed_ssid_cmd {
+ /* 0 to MAX_PROBED_SSID_INDEX */
+ u8 entry_index;
+
+ /* see, enum wmi_ssid_flg */
+ u8 flag;
+
+ u8 ssid_len;
+ u8 ssid[IEEE80211_MAX_SSID_LEN];
+} __packed;
+
+/*
+ * WMI_SET_LISTEN_INT_CMDID
+ * The Listen interval is between 15 and 3000 TUs
+ */
+struct wmi_listen_int_cmd {
+ __le16 listen_intvl;
+ __le16 num_beacons;
+} __packed;
+
+/* WMI_SET_POWER_MODE_CMDID */
+enum wmi_power_mode {
+ REC_POWER = 0x01,
+ MAX_PERF_POWER,
+};
+
+struct wmi_power_mode_cmd {
+ /* see, enum wmi_power_mode */
+ u8 pwr_mode;
+} __packed;
+
+/*
+ * Policy to determnine whether power save failure event should be sent to
+ * host during scanning
+ */
+enum power_save_fail_event_policy {
+ SEND_POWER_SAVE_FAIL_EVENT_ALWAYS = 1,
+ IGNORE_POWER_SAVE_FAIL_EVENT_DURING_SCAN = 2,
+};
+
+struct wmi_power_params_cmd {
+ /* msec */
+ __le16 idle_period;
+
+ __le16 pspoll_number;
+ __le16 dtim_policy;
+ __le16 tx_wakeup_policy;
+ __le16 num_tx_to_wakeup;
+ __le16 ps_fail_event_policy;
+} __packed;
+
+/* WMI_SET_DISC_TIMEOUT_CMDID */
+struct wmi_disc_timeout_cmd {
+ /* seconds */
+ u8 discon_timeout;
+} __packed;
+
+enum dir_type {
+ UPLINK_TRAFFIC = 0,
+ DNLINK_TRAFFIC = 1,
+ BIDIR_TRAFFIC = 2,
+};
+
+enum voiceps_cap_type {
+ DISABLE_FOR_THIS_AC = 0,
+ ENABLE_FOR_THIS_AC = 1,
+ ENABLE_FOR_ALL_AC = 2,
+};
+
+enum traffic_type {
+ TRAFFIC_TYPE_APERIODIC = 0,
+ TRAFFIC_TYPE_PERIODIC = 1,
+};
+
+/* WMI_SYNCHRONIZE_CMDID */
+struct wmi_sync_cmd {
+ u8 data_sync_map;
+} __packed;
+
+/* WMI_CREATE_PSTREAM_CMDID */
+struct wmi_create_pstream_cmd {
+ /* msec */
+ __le32 min_service_int;
+
+ /* msec */
+ __le32 max_service_int;
+
+ /* msec */
+ __le32 inactivity_int;
+
+ /* msec */
+ __le32 suspension_int;
+
+ __le32 service_start_time;
+
+ /* in bps */
+ __le32 min_data_rate;
+
+ /* in bps */
+ __le32 mean_data_rate;
+
+ /* in bps */
+ __le32 peak_data_rate;
+
+ __le32 max_burst_size;
+ __le32 delay_bound;
+
+ /* in bps */
+ __le32 min_phy_rate;
+
+ __le32 sba;
+ __le32 medium_time;
+
+ /* in octects */
+ __le16 nominal_msdu;
+
+ /* in octects */
+ __le16 max_msdu;
+
+ u8 traffic_class;
+
+ /* see, enum dir_type */
+ u8 traffic_direc;
+
+ u8 rx_queue_num;
+
+ /* see, enum traffic_type */
+ u8 traffic_type;
+
+ /* see, enum voiceps_cap_type */
+ u8 voice_psc_cap;
+ u8 tsid;
+
+ /* 802.1D user priority */
+ u8 user_pri;
+
+ /* nominal phy rate */
+ u8 nominal_phy;
+} __packed;
+
+/* WMI_DELETE_PSTREAM_CMDID */
+struct wmi_delete_pstream_cmd {
+ u8 tx_queue_num;
+ u8 rx_queue_num;
+ u8 traffic_direc;
+ u8 traffic_class;
+ u8 tsid;
+} __packed;
+
+/* WMI_SET_CHANNEL_PARAMS_CMDID */
+enum wmi_phy_mode {
+ WMI_11A_MODE = 0x1,
+ WMI_11G_MODE = 0x2,
+ WMI_11AG_MODE = 0x3,
+ WMI_11B_MODE = 0x4,
+ WMI_11GONLY_MODE = 0x5,
+};
+
+#define WMI_MAX_CHANNELS 32
+
+/*
+ * WMI_RSSI_THRESHOLD_PARAMS_CMDID
+ * Setting the polltime to 0 would disable polling. Threshold values are
+ * in the ascending order, and should agree to:
+ * (lowThreshold_lowerVal < lowThreshold_upperVal < highThreshold_lowerVal
+ * < highThreshold_upperVal)
+ */
+
+struct wmi_rssi_threshold_params_cmd {
+ /* polling time as a factor of LI */
+ __le32 poll_time;
+
+ /* lowest of upper */
+ a_sle16 thresh_above1_val;
+
+ a_sle16 thresh_above2_val;
+ a_sle16 thresh_above3_val;
+ a_sle16 thresh_above4_val;
+ a_sle16 thresh_above5_val;
+
+ /* highest of upper */
+ a_sle16 thresh_above6_val;
+
+ /* lowest of bellow */
+ a_sle16 thresh_below1_val;
+
+ a_sle16 thresh_below2_val;
+ a_sle16 thresh_below3_val;
+ a_sle16 thresh_below4_val;
+ a_sle16 thresh_below5_val;
+
+ /* highest of bellow */
+ a_sle16 thresh_below6_val;
+
+ /* "alpha" */
+ u8 weight;
+
+ u8 reserved[3];
+} __packed;
+
+/*
+ * WMI_SNR_THRESHOLD_PARAMS_CMDID
+ * Setting the polltime to 0 would disable polling.
+ */
+
+struct wmi_snr_threshold_params_cmd {
+ /* polling time as a factor of LI */
+ __le32 poll_time;
+
+ /* "alpha" */
+ u8 weight;
+
+ /* lowest of uppper */
+ u8 thresh_above1_val;
+
+ u8 thresh_above2_val;
+ u8 thresh_above3_val;
+
+ /* highest of upper */
+ u8 thresh_above4_val;
+
+ /* lowest of bellow */
+ u8 thresh_below1_val;
+
+ u8 thresh_below2_val;
+ u8 thresh_below3_val;
+
+ /* highest of bellow */
+ u8 thresh_below4_val;
+
+ u8 reserved[3];
+} __packed;
+
+enum wmi_preamble_policy {
+ WMI_IGNORE_BARKER_IN_ERP = 0,
+ WMI_DONOT_IGNORE_BARKER_IN_ERP
+};
+
+struct wmi_set_lpreamble_cmd {
+ u8 status;
+ u8 preamble_policy;
+} __packed;
+
+struct wmi_set_rts_cmd {
+ __le16 threshold;
+} __packed;
+
+/* WMI_SET_TX_PWR_CMDID */
+struct wmi_set_tx_pwr_cmd {
+ /* in dbM units */
+ u8 dbM;
+} __packed;
+
+struct wmi_tx_pwr_reply {
+ /* in dbM units */
+ u8 dbM;
+} __packed;
+
+struct wmi_report_sleep_state_event {
+ __le32 sleep_state;
+};
+
+enum wmi_report_sleep_status {
+ WMI_REPORT_SLEEP_STATUS_IS_DEEP_SLEEP = 0,
+ WMI_REPORT_SLEEP_STATUS_IS_AWAKE
+};
+enum target_event_report_config {
+ /* default */
+ DISCONN_EVT_IN_RECONN = 0,
+
+ NO_DISCONN_EVT_IN_RECONN
+};
+
+/* Command Replies */
+
+/* WMI_GET_CHANNEL_LIST_CMDID reply */
+struct wmi_channel_list_reply {
+ u8 reserved;
+
+ /* number of channels in reply */
+ u8 num_ch;
+
+ /* channel in Mhz */
+ __le16 ch_list[1];
+} __packed;
+
+/* List of Events (target to host) */
+enum wmi_event_id {
+ WMI_READY_EVENTID = 0x1001,
+ WMI_CONNECT_EVENTID,
+ WMI_DISCONNECT_EVENTID,
+ WMI_BSSINFO_EVENTID,
+ WMI_CMDERROR_EVENTID,
+ WMI_REGDOMAIN_EVENTID,
+ WMI_PSTREAM_TIMEOUT_EVENTID,
+ WMI_NEIGHBOR_REPORT_EVENTID,
+ WMI_TKIP_MICERR_EVENTID,
+ WMI_SCAN_COMPLETE_EVENTID, /* 0x100a */
+ WMI_REPORT_STATISTICS_EVENTID,
+ WMI_RSSI_THRESHOLD_EVENTID,
+ WMI_ERROR_REPORT_EVENTID,
+ WMI_OPT_RX_FRAME_EVENTID,
+ WMI_REPORT_ROAM_TBL_EVENTID,
+ WMI_EXTENSION_EVENTID,
+ WMI_CAC_EVENTID,
+ WMI_SNR_THRESHOLD_EVENTID,
+ WMI_LQ_THRESHOLD_EVENTID,
+ WMI_TX_RETRY_ERR_EVENTID, /* 0x1014 */
+ WMI_REPORT_ROAM_DATA_EVENTID,
+ WMI_TEST_EVENTID,
+ WMI_APLIST_EVENTID,
+ WMI_GET_WOW_LIST_EVENTID,
+ WMI_GET_PMKID_LIST_EVENTID,
+ WMI_CHANNEL_CHANGE_EVENTID,
+ WMI_PEER_NODE_EVENTID,
+ WMI_PSPOLL_EVENTID,
+ WMI_DTIMEXPIRY_EVENTID,
+ WMI_WLAN_VERSION_EVENTID,
+ WMI_SET_PARAMS_REPLY_EVENTID,
+ WMI_ADDBA_REQ_EVENTID, /*0x1020 */
+ WMI_ADDBA_RESP_EVENTID,
+ WMI_DELBA_REQ_EVENTID,
+ WMI_TX_COMPLETE_EVENTID,
+ WMI_HCI_EVENT_EVENTID,
+ WMI_ACL_DATA_EVENTID,
+ WMI_REPORT_SLEEP_STATE_EVENTID,
+ WMI_REPORT_BTCOEX_STATS_EVENTID,
+ WMI_REPORT_BTCOEX_CONFIG_EVENTID,
+ WMI_GET_PMK_EVENTID,
+
+ /* DFS Events */
+ WMI_DFS_HOST_ATTACH_EVENTID,
+ WMI_DFS_HOST_INIT_EVENTID,
+ WMI_DFS_RESET_DELAYLINES_EVENTID,
+ WMI_DFS_RESET_RADARQ_EVENTID,
+ WMI_DFS_RESET_AR_EVENTID,
+ WMI_DFS_RESET_ARQ_EVENTID,
+ WMI_DFS_SET_DUR_MULTIPLIER_EVENTID,
+ WMI_DFS_SET_BANGRADAR_EVENTID,
+ WMI_DFS_SET_DEBUGLEVEL_EVENTID,
+ WMI_DFS_PHYERR_EVENTID,
+
+ /* CCX Evants */
+ WMI_CCX_RM_STATUS_EVENTID,
+
+ /* P2P Events */
+ WMI_P2P_GO_NEG_RESULT_EVENTID,
+
+ WMI_WAC_SCAN_DONE_EVENTID,
+ WMI_WAC_REPORT_BSS_EVENTID,
+ WMI_WAC_START_WPS_EVENTID,
+ WMI_WAC_CTRL_REQ_REPLY_EVENTID,
+
+ /* RFKILL Events */
+ WMI_RFKILL_STATE_CHANGE_EVENTID,
+ WMI_RFKILL_GET_MODE_CMD_EVENTID,
+ WMI_THIN_RESERVED_START_EVENTID = 0x8000,
+
+ /*
+ * Events in this range are reserved for thinmode
+ * See wmi_thin.h for actual definitions
+ */
+ WMI_THIN_RESERVED_END_EVENTID = 0x8fff,
+
+ WMI_SET_CHANNEL_EVENTID,
+ WMI_ASSOC_REQ_EVENTID,
+
+ /* Generic ACS event */
+ WMI_ACS_EVENTID,
+ WMI_REPORT_WMM_PARAMS_EVENTID
+};
+
+struct wmi_ready_event_2 {
+ __le32 sw_version;
+ __le32 abi_version;
+ u8 mac_addr[ETH_ALEN];
+ u8 phy_cap;
+} __packed;
+
+/* Connect Event */
+struct wmi_connect_event {
+ __le16 ch;
+ u8 bssid[ETH_ALEN];
+ __le16 listen_intvl;
+ __le16 beacon_intvl;
+ __le32 nw_type;
+ u8 beacon_ie_len;
+ u8 assoc_req_len;
+ u8 assoc_resp_len;
+ u8 assoc_info[1];
+} __packed;
+
+/* Disconnect Event */
+enum wmi_disconnect_reason {
+ NO_NETWORK_AVAIL = 0x01,
+
+ /* bmiss */
+ LOST_LINK = 0x02,
+
+ DISCONNECT_CMD = 0x03,
+ BSS_DISCONNECTED = 0x04,
+ AUTH_FAILED = 0x05,
+ ASSOC_FAILED = 0x06,
+ NO_RESOURCES_AVAIL = 0x07,
+ CSERV_DISCONNECT = 0x08,
+ INVALID_PROFILE = 0x0a,
+ DOT11H_CHANNEL_SWITCH = 0x0b,
+ PROFILE_MISMATCH = 0x0c,
+ CONNECTION_EVICTED = 0x0d,
+ IBSS_MERGE = 0xe,
+};
+
+struct wmi_disconnect_event {
+ /* reason code, see 802.11 spec. */
+ __le16 proto_reason_status;
+
+ /* set if known */
+ u8 bssid[ETH_ALEN];
+
+ /* see WMI_DISCONNECT_REASON */
+ u8 disconn_reason;
+
+ u8 assoc_resp_len;
+ u8 assoc_info[1];
+} __packed;
+
+/*
+ * BSS Info Event.
+ * Mechanism used to inform host of the presence and characteristic of
+ * wireless networks present. Consists of bss info header followed by
+ * the beacon or probe-response frame body. The 802.11 header is no included.
+ */
+enum wmi_bi_ftype {
+ BEACON_FTYPE = 0x1,
+ PROBERESP_FTYPE,
+ ACTION_MGMT_FTYPE,
+ PROBEREQ_FTYPE,
+};
+
+struct wmi_bss_info_hdr {
+ __le16 ch;
+
+ /* see, enum wmi_bi_ftype */
+ u8 frame_type;
+
+ u8 snr;
+ a_sle16 rssi;
+ u8 bssid[ETH_ALEN];
+ __le32 ie_mask;
+} __packed;
+
+/*
+ * BSS INFO HDR version 2.0
+ * With 6 bytes HTC header and 6 bytes of WMI header
+ * WMI_BSS_INFO_HDR cannot be accommodated in the removed 802.11 management
+ * header space.
+ * - Reduce the ie_mask to 2 bytes as only two bit flags are used
+ * - Remove rssi and compute it on the host. rssi = snr - 95
+ */
+struct wmi_bss_info_hdr2 {
+ __le16 ch;
+
+ /* see, enum wmi_bi_ftype */
+ u8 frame_type;
+
+ u8 snr;
+ u8 bssid[ETH_ALEN];
+ __le16 ie_mask;
+} __packed;
+
+/* Command Error Event */
+enum wmi_error_code {
+ INVALID_PARAM = 0x01,
+ ILLEGAL_STATE = 0x02,
+ INTERNAL_ERROR = 0x03,
+};
+
+struct wmi_cmd_error_event {
+ __le16 cmd_id;
+ u8 err_code;
+} __packed;
+
+struct wmi_pstream_timeout_event {
+ u8 tx_queue_num;
+ u8 rx_queue_num;
+ u8 traffic_direc;
+ u8 traffic_class;
+} __packed;
+
+/*
+ * The WMI_NEIGHBOR_REPORT Event is generated by the target to inform
+ * the host of BSS's it has found that matches the current profile.
+ * It can be used by the host to cache PMKs and/to initiate pre-authentication
+ * if the BSS supports it. The first bssid is always the current associated
+ * BSS.
+ * The bssid and bssFlags information repeats according to the number
+ * or APs reported.
+ */
+enum wmi_bss_flags {
+ WMI_DEFAULT_BSS_FLAGS = 0x00,
+ WMI_PREAUTH_CAPABLE_BSS = 0x01,
+ WMI_PMKID_VALID_BSS = 0x02,
+};
+
+/* TKIP MIC Error Event */
+struct wmi_tkip_micerr_event {
+ u8 key_id;
+ u8 is_mcast;
+} __packed;
+
+/* WMI_SCAN_COMPLETE_EVENTID */
+struct wmi_scan_complete_event {
+ a_sle32 status;
+} __packed;
+
+#define MAX_OPT_DATA_LEN 1400
+
+/*
+ * Special frame receive Event.
+ * Mechanism used to inform host of the receiption of the special frames.
+ * Consists of special frame info header followed by special frame body.
+ * The 802.11 header is not included.
+ */
+struct wmi_opt_rx_info_hdr {
+ __le16 ch;
+ u8 frame_type;
+ s8 snr;
+ u8 src_addr[ETH_ALEN];
+ u8 bssid[ETH_ALEN];
+} __packed;
+
+/* Reporting statistic */
+struct tx_stats {
+ __le32 pkt;
+ __le32 byte;
+ __le32 ucast_pkt;
+ __le32 ucast_byte;
+ __le32 mcast_pkt;
+ __le32 mcast_byte;
+ __le32 bcast_pkt;
+ __le32 bcast_byte;
+ __le32 rts_success_cnt;
+ __le32 pkt_per_ac[4];
+ __le32 err_per_ac[4];
+
+ __le32 err;
+ __le32 fail_cnt;
+ __le32 retry_cnt;
+ __le32 mult_retry_cnt;
+ __le32 rts_fail_cnt;
+ a_sle32 ucast_rate;
+} __packed;
+
+struct rx_stats {
+ __le32 pkt;
+ __le32 byte;
+ __le32 ucast_pkt;
+ __le32 ucast_byte;
+ __le32 mcast_pkt;
+ __le32 mcast_byte;
+ __le32 bcast_pkt;
+ __le32 bcast_byte;
+ __le32 frgment_pkt;
+
+ __le32 err;
+ __le32 crc_err;
+ __le32 key_cache_miss;
+ __le32 decrypt_err;
+ __le32 dupl_frame;
+ a_sle32 ucast_rate;
+} __packed;
+
+struct tkip_ccmp_stats {
+ __le32 tkip_local_mic_fail;
+ __le32 tkip_cnter_measures_invoked;
+ __le32 tkip_replays;
+ __le32 tkip_fmt_err;
+ __le32 ccmp_fmt_err;
+ __le32 ccmp_replays;
+} __packed;
+
+struct pm_stats {
+ __le32 pwr_save_failure_cnt;
+ __le16 stop_tx_failure_cnt;
+ __le16 atim_tx_failure_cnt;
+ __le16 atim_rx_failure_cnt;
+ __le16 bcn_rx_failure_cnt;
+} __packed;
+
+struct cserv_stats {
+ __le32 cs_bmiss_cnt;
+ __le32 cs_low_rssi_cnt;
+ __le16 cs_connect_cnt;
+ __le16 cs_discon_cnt;
+ a_sle16 cs_ave_beacon_rssi;
+ __le16 cs_roam_count;
+ a_sle16 cs_rssi;
+ u8 cs_snr;
+ u8 cs_ave_beacon_snr;
+ u8 cs_last_roam_msec;
+} __packed;
+
+struct wlan_net_stats {
+ struct tx_stats tx;
+ struct rx_stats rx;
+ struct tkip_ccmp_stats tkip_ccmp_stats;
+} __packed;
+
+struct arp_stats {
+ __le32 arp_received;
+ __le32 arp_matched;
+ __le32 arp_replied;
+} __packed;
+
+struct wlan_wow_stats {
+ __le32 wow_pkt_dropped;
+ __le16 wow_evt_discarded;
+ u8 wow_host_pkt_wakeups;
+ u8 wow_host_evt_wakeups;
+} __packed;
+
+struct wmi_target_stats {
+ __le32 lq_val;
+ a_sle32 noise_floor_calib;
+ struct pm_stats pm_stats;
+ struct wlan_net_stats stats;
+ struct wlan_wow_stats wow_stats;
+ struct arp_stats arp_stats;
+ struct cserv_stats cserv_stats;
+} __packed;
+
+/*
+ * WMI_RSSI_THRESHOLD_EVENTID.
+ * Indicate the RSSI events to host. Events are indicated when we breach a
+ * thresold value.
+ */
+enum wmi_rssi_threshold_val {
+ WMI_RSSI_THRESHOLD1_ABOVE = 0,
+ WMI_RSSI_THRESHOLD2_ABOVE,
+ WMI_RSSI_THRESHOLD3_ABOVE,
+ WMI_RSSI_THRESHOLD4_ABOVE,
+ WMI_RSSI_THRESHOLD5_ABOVE,
+ WMI_RSSI_THRESHOLD6_ABOVE,
+ WMI_RSSI_THRESHOLD1_BELOW,
+ WMI_RSSI_THRESHOLD2_BELOW,
+ WMI_RSSI_THRESHOLD3_BELOW,
+ WMI_RSSI_THRESHOLD4_BELOW,
+ WMI_RSSI_THRESHOLD5_BELOW,
+ WMI_RSSI_THRESHOLD6_BELOW
+};
+
+struct wmi_rssi_threshold_event {
+ a_sle16 rssi;
+ u8 range;
+} __packed;
+
+enum wmi_snr_threshold_val {
+ WMI_SNR_THRESHOLD1_ABOVE = 1,
+ WMI_SNR_THRESHOLD1_BELOW,
+ WMI_SNR_THRESHOLD2_ABOVE,
+ WMI_SNR_THRESHOLD2_BELOW,
+ WMI_SNR_THRESHOLD3_ABOVE,
+ WMI_SNR_THRESHOLD3_BELOW,
+ WMI_SNR_THRESHOLD4_ABOVE,
+ WMI_SNR_THRESHOLD4_BELOW
+};
+
+struct wmi_snr_threshold_event {
+ /* see, enum wmi_snr_threshold_val */
+ u8 range;
+
+ u8 snr;
+} __packed;
+
+/* WMI_REPORT_ROAM_TBL_EVENTID */
+#define MAX_ROAM_TBL_CAND 5
+
+struct wmi_bss_roam_info {
+ a_sle32 roam_util;
+ u8 bssid[ETH_ALEN];
+ s8 rssi;
+ s8 rssidt;
+ s8 last_rssi;
+ s8 util;
+ s8 bias;
+
+ /* for alignment */
+ u8 reserved;
+} __packed;
+
+/* WMI_CAC_EVENTID */
+enum cac_indication {
+ CAC_INDICATION_ADMISSION = 0x00,
+ CAC_INDICATION_ADMISSION_RESP = 0x01,
+ CAC_INDICATION_DELETE = 0x02,
+ CAC_INDICATION_NO_RESP = 0x03,
+};
+
+#define WMM_TSPEC_IE_LEN 63
+
+struct wmi_cac_event {
+ u8 ac;
+ u8 cac_indication;
+ u8 status_code;
+ u8 tspec_suggestion[WMM_TSPEC_IE_LEN];
+} __packed;
+
+/* WMI_APLIST_EVENTID */
+
+enum aplist_ver {
+ APLIST_VER1 = 1,
+};
+
+struct wmi_ap_info_v1 {
+ u8 bssid[ETH_ALEN];
+ __le16 channel;
+} __packed;
+
+union wmi_ap_info {
+ struct wmi_ap_info_v1 ap_info_v1;
+} __packed;
+
+struct wmi_aplist_event {
+ u8 ap_list_ver;
+ u8 num_ap;
+ union wmi_ap_info ap_list[1];
+} __packed;
+
+/* Developer Commands */
+
+/*
+ * WMI_SET_BITRATE_CMDID
+ *
+ * Get bit rate cmd uses same definition as set bit rate cmd
+ */
+enum wmi_bit_rate {
+ RATE_AUTO = -1,
+ RATE_1Mb = 0,
+ RATE_2Mb = 1,
+ RATE_5_5Mb = 2,
+ RATE_11Mb = 3,
+ RATE_6Mb = 4,
+ RATE_9Mb = 5,
+ RATE_12Mb = 6,
+ RATE_18Mb = 7,
+ RATE_24Mb = 8,
+ RATE_36Mb = 9,
+ RATE_48Mb = 10,
+ RATE_54Mb = 11,
+ RATE_MCS_0_20 = 12,
+ RATE_MCS_1_20 = 13,
+ RATE_MCS_2_20 = 14,
+ RATE_MCS_3_20 = 15,
+ RATE_MCS_4_20 = 16,
+ RATE_MCS_5_20 = 17,
+ RATE_MCS_6_20 = 18,
+ RATE_MCS_7_20 = 19,
+ RATE_MCS_0_40 = 20,
+ RATE_MCS_1_40 = 21,
+ RATE_MCS_2_40 = 22,
+ RATE_MCS_3_40 = 23,
+ RATE_MCS_4_40 = 24,
+ RATE_MCS_5_40 = 25,
+ RATE_MCS_6_40 = 26,
+ RATE_MCS_7_40 = 27,
+};
+
+struct wmi_bit_rate_reply {
+ /* see, enum wmi_bit_rate */
+ s8 rate_index;
+} __packed;
+
+/*
+ * WMI_SET_FIXRATES_CMDID
+ *
+ * Get fix rates cmd uses same definition as set fix rates cmd
+ */
+struct wmi_fix_rates_reply {
+ /* see wmi_bit_rate */
+ __le32 fix_rate_mask;
+} __packed;
+
+enum roam_data_type {
+ /* get the roam time data */
+ ROAM_DATA_TIME = 1,
+};
+
+struct wmi_target_roam_time {
+ __le32 disassoc_time;
+ __le32 no_txrx_time;
+ __le32 assoc_time;
+ __le32 allow_txrx_time;
+ u8 disassoc_bssid[ETH_ALEN];
+ s8 disassoc_bss_rssi;
+ u8 assoc_bssid[ETH_ALEN];
+ s8 assoc_bss_rssi;
+} __packed;
+
+enum wmi_txop_cfg {
+ WMI_TXOP_DISABLED = 0,
+ WMI_TXOP_ENABLED
+};
+
+struct wmi_set_wmm_txop_cmd {
+ u8 txop_enable;
+} __packed;
+
+struct wmi_set_keepalive_cmd {
+ u8 keep_alive_intvl;
+} __packed;
+
+struct wmi_get_keepalive_cmd {
+ __le32 configured;
+ u8 keep_alive_intvl;
+} __packed;
+
+/* Notify the WSC registration status to the target */
+#define WSC_REG_ACTIVE 1
+#define WSC_REG_INACTIVE 0
+
+#define WOW_MAX_FILTER_LISTS 1
+#define WOW_MAX_FILTERS_PER_LIST 4
+#define WOW_PATTERN_SIZE 64
+#define WOW_MASK_SIZE 64
+
+#define MAC_MAX_FILTERS_PER_LIST 4
+
+struct wow_filter {
+ u8 wow_valid_filter;
+ u8 wow_filter_id;
+ u8 wow_filter_size;
+ u8 wow_filter_offset;
+ u8 wow_filter_mask[WOW_MASK_SIZE];
+ u8 wow_filter_pattern[WOW_PATTERN_SIZE];
+} __packed;
+
+#define MAX_IP_ADDRS 2
+
+struct wmi_set_ip_cmd {
+ /* IP in network byte order */
+ __le32 ips[MAX_IP_ADDRS];
+} __packed;
+
+/* WMI_GET_WOW_LIST_CMD reply */
+struct wmi_get_wow_list_reply {
+ /* number of patterns in reply */
+ u8 num_filters;
+
+ /* this is filter # x of total num_filters */
+ u8 this_filter_num;
+
+ u8 wow_mode;
+ u8 host_mode;
+ struct wow_filter wow_filters[1];
+} __packed;
+
+/* WMI_SET_AKMP_PARAMS_CMD */
+
+struct wmi_pmkid {
+ u8 pmkid[WMI_PMKID_LEN];
+} __packed;
+
+/* WMI_GET_PMKID_LIST_CMD Reply */
+struct wmi_pmkid_list_reply {
+ __le32 num_pmkid;
+ u8 bssid_list[ETH_ALEN][1];
+ struct wmi_pmkid pmkid_list[1];
+} __packed;
+
+/* WMI_ADDBA_REQ_EVENTID */
+struct wmi_addba_req_event {
+ u8 tid;
+ u8 win_sz;
+ __le16 st_seq_no;
+
+ /* f/w response for ADDBA Req; OK (0) or failure (!=0) */
+ u8 status;
+} __packed;
+
+/* WMI_ADDBA_RESP_EVENTID */
+struct wmi_addba_resp_event {
+ u8 tid;
+
+ /* OK (0), failure (!=0) */
+ u8 status;
+
+ /* three values: not supported(0), 3839, 8k */
+ __le16 amsdu_sz;
+} __packed;
+
+/* WMI_DELBA_EVENTID
+ * f/w received a DELBA for peer and processed it.
+ * Host is notified of this
+ */
+struct wmi_delba_event {
+ u8 tid;
+ u8 is_peer_initiator;
+ __le16 reason_code;
+} __packed;
+
+#define PEER_NODE_JOIN_EVENT 0x00
+#define PEER_NODE_LEAVE_EVENT 0x01
+#define PEER_FIRST_NODE_JOIN_EVENT 0x10
+#define PEER_LAST_NODE_LEAVE_EVENT 0x11
+
+struct wmi_peer_node_event {
+ u8 event_code;
+ u8 peer_mac_addr[ETH_ALEN];
+} __packed;
+
+/* Transmit complete event data structure(s) */
+
+/* version 1 of tx complete msg */
+struct tx_complete_msg_v1 {
+#define TX_COMPLETE_STATUS_SUCCESS 0
+#define TX_COMPLETE_STATUS_RETRIES 1
+#define TX_COMPLETE_STATUS_NOLINK 2
+#define TX_COMPLETE_STATUS_TIMEOUT 3
+#define TX_COMPLETE_STATUS_OTHER 4
+
+ u8 status;
+
+ /* packet ID to identify parent packet */
+ u8 pkt_id;
+
+ /* rate index on successful transmission */
+ u8 rate_idx;
+
+ /* number of ACK failures in tx attempt */
+ u8 ack_failures;
+} __packed;
+
+struct wmi_tx_complete_event {
+ /* no of tx comp msgs following this struct */
+ u8 num_msg;
+
+ /* length in bytes for each individual msg following this struct */
+ u8 msg_len;
+
+ /* version of tx complete msg data following this struct */
+ u8 msg_type;
+
+ /* individual messages follow this header */
+ u8 reserved;
+} __packed;
+
+/*
+ * ------- AP Mode definitions --------------
+ */
+
+/*
+ * !!! Warning !!!
+ * -Changing the following values needs compilation of both driver and firmware
+ */
+#define AP_MAX_NUM_STA 8
+
+/* Spl. AID used to set DTIM flag in the beacons */
+#define MCAST_AID 0xFF
+
+#define DEF_AP_COUNTRY_CODE "US "
+
+/* Used with WMI_AP_SET_NUM_STA_CMDID */
+
+struct wmi_ap_set_pvb_cmd {
+ __le32 flag;
+ __le16 aid;
+} __packed;
+
+struct wmi_rx_frame_format_cmd {
+ /* version of meta data for rx packets <0 = default> (0-7 = valid) */
+ u8 meta_ver;
+
+ /*
+ * 1 == leave .11 header intact,
+ * 0 == replace .11 header with .3 <default>
+ */
+ u8 dot11_hdr;
+
+ /*
+ * 1 == defragmentation is performed by host,
+ * 0 == performed by target <default>
+ */
+ u8 defrag_on_host;
+
+ /* for alignment */
+ u8 reserved[1];
+} __packed;
+
+/* AP mode events */
+
+/* WMI_PS_POLL_EVENT */
+struct wmi_pspoll_event {
+ __le16 aid;
+} __packed;
+
+struct wmi_per_sta_stat {
+ __le32 tx_bytes;
+ __le32 tx_pkts;
+ __le32 tx_error;
+ __le32 tx_discard;
+ __le32 rx_bytes;
+ __le32 rx_pkts;
+ __le32 rx_error;
+ __le32 rx_discard;
+ __le32 aid;
+} __packed;
+
+struct wmi_ap_mode_stat {
+ __le32 action;
+ struct wmi_per_sta_stat sta[AP_MAX_NUM_STA + 1];
+} __packed;
+
+/* End of AP mode definitions */
+
+/* Extended WMI (WMIX)
+ *
+ * Extended WMIX commands are encapsulated in a WMI message with
+ * cmd=WMI_EXTENSION_CMD.
+ *
+ * Extended WMI commands are those that are needed during wireless
+ * operation, but which are not really wireless commands. This allows,
+ * for instance, platform-specific commands. Extended WMI commands are
+ * embedded in a WMI command message with WMI_COMMAND_ID=WMI_EXTENSION_CMDID.
+ * Extended WMI events are similarly embedded in a WMI event message with
+ * WMI_EVENT_ID=WMI_EXTENSION_EVENTID.
+ */
+struct wmix_cmd_hdr {
+ __le32 cmd_id;
+} __packed;
+
+enum wmix_command_id {
+ WMIX_DSETOPEN_REPLY_CMDID = 0x2001,
+ WMIX_DSETDATA_REPLY_CMDID,
+ WMIX_GPIO_OUTPUT_SET_CMDID,
+ WMIX_GPIO_INPUT_GET_CMDID,
+ WMIX_GPIO_REGISTER_SET_CMDID,
+ WMIX_GPIO_REGISTER_GET_CMDID,
+ WMIX_GPIO_INTR_ACK_CMDID,
+ WMIX_HB_CHALLENGE_RESP_CMDID,
+ WMIX_DBGLOG_CFG_MODULE_CMDID,
+ WMIX_PROF_CFG_CMDID, /* 0x200a */
+ WMIX_PROF_ADDR_SET_CMDID,
+ WMIX_PROF_START_CMDID,
+ WMIX_PROF_STOP_CMDID,
+ WMIX_PROF_COUNT_GET_CMDID,
+};
+
+enum wmix_event_id {
+ WMIX_DSETOPENREQ_EVENTID = 0x3001,
+ WMIX_DSETCLOSE_EVENTID,
+ WMIX_DSETDATAREQ_EVENTID,
+ WMIX_GPIO_INTR_EVENTID,
+ WMIX_GPIO_DATA_EVENTID,
+ WMIX_GPIO_ACK_EVENTID,
+ WMIX_HB_CHALLENGE_RESP_EVENTID,
+ WMIX_DBGLOG_EVENTID,
+ WMIX_PROF_COUNT_EVENTID,
+};
+
+/*
+ * ------Error Detection support-------
+ */
+
+/*
+ * WMIX_HB_CHALLENGE_RESP_CMDID
+ * Heartbeat Challenge Response command
+ */
+struct wmix_hb_challenge_resp_cmd {
+ __le32 cookie;
+ __le32 source;
+} __packed;
+
+/* End of Extended WMI (WMIX) */
+
+enum wmi_sync_flag {
+ NO_SYNC_WMIFLAG = 0,
+
+ /* transmit all queued data before cmd */
+ SYNC_BEFORE_WMIFLAG,
+
+ /* any new data waits until cmd execs */
+ SYNC_AFTER_WMIFLAG,
+
+ SYNC_BOTH_WMIFLAG,
+
+ /* end marker */
+ END_WMIFLAG
+};
+
+enum htc_endpoint_id ath6kl_wmi_get_control_ep(struct wmi *wmi);
+void ath6kl_wmi_set_control_ep(struct wmi *wmi, enum htc_endpoint_id ep_id);
+int ath6kl_wmi_dix_2_dot3(struct wmi *wmi, struct sk_buff *skb);
+int ath6kl_wmi_data_hdr_add(struct wmi *wmi, struct sk_buff *skb,
+ u8 msg_type, bool more_data,
+ enum wmi_data_hdr_data_type data_type,
+ u8 meta_ver, void *tx_meta_info);
+
+int ath6kl_wmi_dot11_hdr_remove(struct wmi *wmi, struct sk_buff *skb);
+int ath6kl_wmi_dot3_2_dix(struct sk_buff *skb);
+int ath6kl_wmi_data_hdr_remove(struct wmi *wmi, struct sk_buff *skb);
+int ath6kl_wmi_implicit_create_pstream(struct wmi *wmi, struct sk_buff *skb,
+ u32 layer2_priority, bool wmm_enabled,
+ u8 *ac);
+
+int ath6kl_wmi_control_rx(struct wmi *wmi, struct sk_buff *skb);
+void ath6kl_wmi_iterate_nodes(struct wmi *wmi,
+ void (*f) (void *arg, struct bss *),
+ void *arg);
+struct bss *ath6kl_wmi_find_node(struct wmi *wmi, const u8 *mac_addr);
+void ath6kl_wmi_node_free(struct wmi *wmi, const u8 *mac_addr);
+
+int ath6kl_wmi_cmd_send(struct wmi *wmi, struct sk_buff *skb,
+ enum wmi_cmd_id cmd_id, enum wmi_sync_flag sync_flag);
+
+int ath6kl_wmi_connect_cmd(struct wmi *wmi, enum network_type nw_type,
+ enum dot11_auth_mode dot11_auth_mode,
+ enum auth_mode auth_mode,
+ enum crypto_type pairwise_crypto,
+ u8 pairwise_crypto_len,
+ enum crypto_type group_crypto,
+ u8 group_crypto_len, int ssid_len, u8 *ssid,
+ u8 *bssid, u16 channel, u32 ctrl_flags);
+
+int ath6kl_wmi_reconnect_cmd(struct wmi *wmi, u8 *bssid, u16 channel);
+int ath6kl_wmi_disconnect_cmd(struct wmi *wmi);
+int ath6kl_wmi_startscan_cmd(struct wmi *wmi, enum wmi_scan_type scan_type,
+ u32 force_fgscan, u32 is_legacy,
+ u32 home_dwell_time, u32 force_scan_interval,
+ s8 num_chan, u16 *ch_list);
+int ath6kl_wmi_scanparams_cmd(struct wmi *wmi, u16 fg_start_sec,
+ u16 fg_end_sec, u16 bg_sec,
+ u16 minact_chdw_msec, u16 maxact_chdw_msec,
+ u16 pas_chdw_msec, u8 short_scan_ratio,
+ u8 scan_ctrl_flag, u32 max_dfsch_act_time,
+ u16 maxact_scan_per_ssid);
+int ath6kl_wmi_bssfilter_cmd(struct wmi *wmi, u8 filter, u32 ie_mask);
+int ath6kl_wmi_probedssid_cmd(struct wmi *wmi, u8 index, u8 flag,
+ u8 ssid_len, u8 *ssid);
+int ath6kl_wmi_listeninterval_cmd(struct wmi *wmi, u16 listen_interval,
+ u16 listen_beacons);
+int ath6kl_wmi_powermode_cmd(struct wmi *wmi, u8 pwr_mode);
+int ath6kl_wmi_pmparams_cmd(struct wmi *wmi, u16 idle_period,
+ u16 ps_poll_num, u16 dtim_policy,
+ u16 tx_wakup_policy, u16 num_tx_to_wakeup,
+ u16 ps_fail_event_policy);
+int ath6kl_wmi_disctimeout_cmd(struct wmi *wmi, u8 timeout);
+int ath6kl_wmi_create_pstream_cmd(struct wmi *wmi,
+ struct wmi_create_pstream_cmd *pstream);
+int ath6kl_wmi_delete_pstream_cmd(struct wmi *wmi, u8 traffic_class, u8 tsid);
+
+int ath6kl_wmi_set_rts_cmd(struct wmi *wmi, u16 threshold);
+int ath6kl_wmi_set_lpreamble_cmd(struct wmi *wmi, u8 status,
+ u8 preamble_policy);
+
+int ath6kl_wmi_get_challenge_resp_cmd(struct wmi *wmi, u32 cookie, u32 source);
+
+int ath6kl_wmi_get_stats_cmd(struct wmi *wmi);
+int ath6kl_wmi_addkey_cmd(struct wmi *wmi, u8 key_index,
+ enum crypto_type key_type,
+ u8 key_usage, u8 key_len,
+ u8 *key_rsc, u8 *key_material,
+ u8 key_op_ctrl, u8 *mac_addr,
+ enum wmi_sync_flag sync_flag);
+int ath6kl_wmi_add_krk_cmd(struct wmi *wmi, u8 *krk);
+int ath6kl_wmi_deletekey_cmd(struct wmi *wmi, u8 key_index);
+int ath6kl_wmi_setpmkid_cmd(struct wmi *wmi, const u8 *bssid,
+ const u8 *pmkid, bool set);
+int ath6kl_wmi_set_tx_pwr_cmd(struct wmi *wmi, u8 dbM);
+int ath6kl_wmi_get_tx_pwr_cmd(struct wmi *wmi);
+void ath6kl_wmi_get_current_bssid(struct wmi *wmi, u8 *bssid);
+
+int ath6kl_wmi_set_wmm_txop(struct wmi *wmi, enum wmi_txop_cfg cfg);
+int ath6kl_wmi_set_keepalive_cmd(struct wmi *wmi, u8 keep_alive_intvl);
+
+s32 ath6kl_wmi_get_rate(s8 rate_index);
+
+int ath6kl_wmi_set_ip_cmd(struct wmi *wmi, struct wmi_set_ip_cmd *ip_cmd);
+
+struct bss *ath6kl_wmi_find_ssid_node(struct wmi *wmi, u8 *ssid,
+ u32 ssid_len, bool is_wpa2,
+ bool match_ssid);
+
+void ath6kl_wmi_node_return(struct wmi *wmi, struct bss *bss);
+
+/* AP mode */
+int ath6kl_wmi_set_pvb_cmd(struct wmi *wmi, u16 aid, bool flag);
+
+int ath6kl_wmi_set_rx_frame_format_cmd(struct wmi *wmi, u8 rx_meta_version,
+ bool rx_dot11_hdr, bool defrag_on_host);
+
+void *ath6kl_wmi_init(void *devt);
+void ath6kl_wmi_shutdown(struct wmi *wmi);
+
+#endif /* WMI_H */
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 0fa466a91bf4..565ab525db33 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -91,3 +91,5 @@ config PCI_IOAPIC
config PCI_LABEL
def_bool y if (DMI || ACPI)
select NLS
+
+source "drivers/pci/pcie/Kconfig"
diff --git a/drivers/usb/gadget/arcotg_udc.c b/drivers/usb/gadget/arcotg_udc.c
index 55fc066e636d..1cc50da4c9c2 100755
--- a/drivers/usb/gadget/arcotg_udc.c
+++ b/drivers/usb/gadget/arcotg_udc.c
@@ -102,6 +102,7 @@ static int udc_suspend(struct fsl_udc *udc);
static int fsl_udc_suspend(struct platform_device *pdev, pm_message_t state);
static int fsl_udc_resume(struct platform_device *pdev);
static void fsl_ep_fifo_flush(struct usb_ep *_ep);
+static void gadget_wait_line_to_se0(void);
#ifdef CONFIG_USB_OTG
/* Get platform resource from OTG driver */
@@ -294,6 +295,23 @@ static void nuke(struct fsl_ep *ep, int status)
/*------------------------------------------------------------------
Internal Hardware related function
------------------------------------------------------------------*/
+static void dr_discharge_dp(struct fsl_usb2_platform_data *pdata)
+{
+ /* enable pulldown dp */
+ if (pdata->gadget_discharge_dp)
+ pdata->gadget_discharge_dp(true);
+ /*
+ * Some boards are very slow change line state from J to SE0 for DP,
+ * So, we need to discharge DP, otherwise there is a wakeup interrupt
+ * after we enable the wakeup function.
+ */
+ gadget_wait_line_to_se0();
+
+ /* Disable pulldown dp */
+ if (pdata->gadget_discharge_dp)
+ pdata->gadget_discharge_dp(false);
+}
+
static inline void
dr_wake_up_enable(struct fsl_udc *udc, bool enable)
{
@@ -381,6 +399,8 @@ static int dr_controller_setup(struct fsl_udc *udc)
if (pdata->es)
tmp |= USB_MODE_ES;
fsl_writel(tmp, &dr_regs->usbmode);
+ /* wait dp to 0v */
+ dr_discharge_dp(pdata);
fsl_platform_set_device_mode(pdata);
@@ -2026,6 +2046,7 @@ static void suspend_irq(struct fsl_udc *udc)
udc->resume_state = udc->usb_state;
udc->usb_state = USB_STATE_SUSPENDED;
+
/* report suspend to the driver, serial.c does not support this */
if (udc->driver->suspend)
udc->driver->suspend(&udc->gadget);
@@ -2147,12 +2168,9 @@ static void fsl_gadget_disconnect_event(struct work_struct *work)
u32 tmp;
pdata = udc->pdata;
- /*
- * Some boards are very slow change line state from J to SE0 for DP,
- * So, we need to discharge DP, otherwise there is a wakeup interrupt
- * after we enable the wakeup function.
- */
- gadget_wait_line_to_se0();
+
+ /* wait dp to 0v */
+ dr_discharge_dp(pdata);
/*
* Wait class drivers finish, an well-behaviour class driver should
@@ -2211,7 +2229,6 @@ bool try_wake_up_udc(struct fsl_udc *udc)
fsl_writel(tmp | USB_CMD_RUN_STOP, &dr_regs->usbcmd);
printk(KERN_DEBUG "%s: udc out low power mode\n", __func__);
} else {
- printk(KERN_INFO "USB device disconnected\n");
fsl_writel(tmp & ~USB_CMD_RUN_STOP, &dr_regs->usbcmd);
/* here we need disable B_SESSION_IRQ, after
* schedule_work finished, it need to be enabled again.
diff --git a/drivers/usb/host/ehci-arc.c b/drivers/usb/host/ehci-arc.c
index d34e7deb8b24..99ba497f5f5a 100755
--- a/drivers/usb/host/ehci-arc.c
+++ b/drivers/usb/host/ehci-arc.c
@@ -1,6 +1,6 @@
/*
* Copyright (c) 2005 MontaVista Software
- * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
*
* 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
@@ -521,9 +521,6 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
struct ehci_hcd *ehci = hcd_to_ehci(hcd);
int retval;
- /* overwrite the default wakeup strategy */
- device_set_wakeup_enable(&hcd->self.root_hub->dev, false);
-
/* EHCI registers start at offset 0x100 */
ehci->caps = hcd->regs + 0x100;
ehci->regs = hcd->regs + 0x100 +
@@ -553,6 +550,19 @@ static int ehci_fsl_setup(struct usb_hcd *hcd)
return retval;
}
+/* called after hcd send port_reset cmd */
+static int ehci_fsl_reset_device(struct usb_hcd *hcd, struct usb_device *udev)
+{
+ struct fsl_usb2_platform_data *pdata;
+
+ pdata = hcd->self.controller->platform_data;
+
+ if (pdata->hsic_device_connected)
+ pdata->hsic_device_connected();
+
+ return 0;
+}
+
static const struct hc_driver ehci_fsl_hc_driver = {
.description = hcd_name,
.product_desc = "Freescale On-Chip EHCI Host Controller",
@@ -596,6 +606,7 @@ static const struct hc_driver ehci_fsl_hc_driver = {
.port_handed_over = ehci_port_handed_over,
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
+ .reset_device = ehci_fsl_reset_device,
};
static int ehci_fsl_drv_probe(struct platform_device *pdev)
diff --git a/drivers/video/mxc/ldb.c b/drivers/video/mxc/ldb.c
index bb34f239215f..6172c0fa0775 100644
--- a/drivers/video/mxc/ldb.c
+++ b/drivers/video/mxc/ldb.c
@@ -532,7 +532,7 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp,
}
/* clock setting */
- if (cpu_is_mx6q() &&
+ if ((cpu_is_mx6q() || cpu_is_mx6dl()) &&
((ldb->mode == LDB_SEP0) || (ldb->mode == LDB_SEP1)))
ldb_clk[6] += lvds_channel;
else
@@ -582,7 +582,7 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp,
}
setting_idx = 1;
- if (cpu_is_mx6q()) {
+ if (cpu_is_mx6q() || cpu_is_mx6dl()) {
setting->dev_id = plat_data->sec_ipu_id;
setting->disp_id = plat_data->sec_disp_id;
} else {
@@ -628,7 +628,7 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp,
writel(reg, ldb->control_reg);
/* clock setting */
- if (cpu_is_mx6q())
+ if (cpu_is_mx6q() || cpu_is_mx6dl())
ldb_clk[6] += lvds_channel;
else
ldb_clk[6] += setting->disp_id;
@@ -653,7 +653,7 @@ static int ldb_disp_init(struct mxc_dispdrv_handle *disp,
ldb->setting[setting_idx].ch_mask = ch_mask;
ldb->setting[setting_idx].ch_val = ch_val;
- if (cpu_is_mx6q()) {
+ if (cpu_is_mx6q() || cpu_is_mx6dl()) {
if ((ldb->mode == LDB_SEP0) || (ldb->mode == LDB_SEP1)) {
reg = readl(ldb->control_reg);
reg &= ~(LDB_CH0_MODE_MASK | LDB_CH1_MODE_MASK);
diff --git a/drivers/video/mxc/mipi_dsi.c b/drivers/video/mxc/mipi_dsi.c
index c236ee7434ec..fa00ce177608 100644
--- a/drivers/video/mxc/mipi_dsi.c
+++ b/drivers/video/mxc/mipi_dsi.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -454,6 +454,10 @@ static int mipi_dsi_power_on(struct mxc_dispdrv_handle *disp)
if (!mipi_dsi->dsi_power_on) {
clk_enable(mipi_dsi->dphy_clk);
mipi_dsi_enable_controller(mipi_dsi, false);
+ mipi_dsi_set_mode(mipi_dsi, false);
+ /* host send pclk/hsync/vsync for two frames before sleep-out */
+ msleep((1000/mipi_dsi->mode->refresh + 1) << 1);
+ mipi_dsi_set_mode(mipi_dsi, true);
err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_EXIT_SLEEP_MODE,
NULL, 0);
if (err) {
@@ -880,7 +884,6 @@ static struct mxc_dispdrv_driver mipi_dsi_drv = {
.name = DISPDRV_MIPI,
.init = mipi_dsi_disp_init,
.deinit = mipi_dsi_disp_deinit,
- .enable = mipi_dsi_power_on,
.disable = mipi_dsi_power_off,
};
diff --git a/drivers/video/mxc/mxc_edid.c b/drivers/video/mxc/mxc_edid.c
index 2fa655d345c5..e8a2b9761b65 100644
--- a/drivers/video/mxc/mxc_edid.c
+++ b/drivers/video/mxc/mxc_edid.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2009-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -313,6 +313,42 @@ int mxc_edid_parse_ext_blk(unsigned char *edid,
break;
}
case 0x1: /*Audio data block*/
+ {
+ u8 audio_format, max_ch, byte1, byte2, byte3;
+
+ i = 0;
+ cfg->max_channels = 0;
+ cfg->sample_rates = 0;
+ cfg->sample_sizes = 0;
+
+ while (i < blklen) {
+ byte1 = edid[index + 1];
+ byte2 = edid[index + 2];
+ byte3 = edid[index + 3];
+ index += 3;
+ i += 3;
+
+ audio_format = byte1 >> 3;
+ max_ch = (byte1 & 0x07) + 1;
+
+ DPRINTK("Audio Format Descriptor : %2d\n", audio_format);
+ DPRINTK("Max Number of Channels : %2d\n", max_ch);
+ DPRINTK("Sample Rates : %02x\n", byte2);
+
+ /* ALSA can't specify specific compressed
+ * formats, so only care about PCM for now. */
+ if (audio_format == AUDIO_CODING_TYPE_LPCM) {
+ if (max_ch > cfg->max_channels)
+ cfg->max_channels = max_ch;
+
+ cfg->sample_rates |= byte2;
+ cfg->sample_sizes |= byte3 & 0x7;
+ DPRINTK("Sample Sizes : %02x\n",
+ byte3 & 0x7);
+ }
+ }
+ break;
+ }
case 0x4: /*Speaker allocation block*/
case 0x7: /*User extended block*/
default:
diff --git a/drivers/video/mxc/mxc_ipuv3_fb.c b/drivers/video/mxc/mxc_ipuv3_fb.c
index 0f4f15ede3da..eaa3032fc2e9 100644
--- a/drivers/video/mxc/mxc_ipuv3_fb.c
+++ b/drivers/video/mxc/mxc_ipuv3_fb.c
@@ -451,6 +451,15 @@ static int mxcfb_set_par(struct fb_info *fbi)
ipu_enable_channel(mxc_fbi->ipu, mxc_fbi->ipu_ch);
+ if (mxc_fbi->dispdrv && mxc_fbi->dispdrv->drv->enable) {
+ retval = mxc_fbi->dispdrv->drv->enable(mxc_fbi->dispdrv);
+ if (retval < 0) {
+ dev_err(fbi->device, "enable error, dispdrv:%s.\n",
+ mxc_fbi->dispdrv->drv->name);
+ return -EINVAL;
+ }
+ }
+
return retval;
}
diff --git a/drivers/video/mxc/mxcfb_hx8369_wvga.c b/drivers/video/mxc/mxcfb_hx8369_wvga.c
index d8771fd3c1a3..ed6ffbc37530 100644
--- a/drivers/video/mxc/mxcfb_hx8369_wvga.c
+++ b/drivers/video/mxc/mxcfb_hx8369_wvga.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -317,7 +317,10 @@ int mipid_hx8369_lcd_setup(struct mipi_dsi_info *mipi_dsi)
buf[0] = MIPI_DCS_EXIT_SLEEP_MODE;
mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM,
buf, 0);
-
+ /* To allow time for the supply voltages
+ * and clock circuits to stabilize.
+ */
+ msleep(5);
buf[0] = MIPI_DCS_SET_DISPLAY_ON;
mipi_dsi_pkt_write(mipi_dsi, MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM,
buf, 0);
diff --git a/drivers/video/mxc_hdmi.c b/drivers/video/mxc_hdmi.c
index 6572c1b8e41e..0462f09a8fee 100644
--- a/drivers/video/mxc_hdmi.c
+++ b/drivers/video/mxc_hdmi.c
@@ -180,6 +180,8 @@ struct mxc_hdmi {
struct i2c_client *hdmi_i2c;
+static bool hdmi_inited;
+
extern const struct fb_videomode mxc_cea_mode[64];
#ifdef DEBUG
@@ -1362,6 +1364,9 @@ static int mxc_hdmi_read_edid(struct mxc_hdmi *hdmi)
if (ret < 0)
return HDMI_EDID_FAIL;
+ /* Save edid cfg for audio driver */
+ hdmi_set_edid_cfg(&hdmi->edid_cfg);
+
if (!memcmp(edid_old, hdmi->edid, HDMI_EDID_LEN)) {
dev_info(&hdmi->pdev->dev, "same edid\n");
return HDMI_EDID_SAME;
@@ -1693,6 +1698,19 @@ static void mxc_hdmi_cable_connected(struct mxc_hdmi *hdmi)
dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
}
+static int mxc_hdmi_power_on(struct mxc_dispdrv_handle *disp)
+{
+ struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
+ mxc_hdmi_phy_init(hdmi);
+ return 0;
+}
+
+static void mxc_hdmi_power_off(struct mxc_dispdrv_handle *disp)
+{
+ struct mxc_hdmi *hdmi = mxc_dispdrv_getdata(disp);
+ mxc_hdmi_phy_disable(hdmi);
+}
+
static void mxc_hdmi_cable_disconnected(struct mxc_hdmi *hdmi)
{
dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
@@ -2084,6 +2102,13 @@ static int mxc_hdmi_disp_init(struct mxc_dispdrv_handle *disp,
dev_dbg(&hdmi->pdev->dev, "%s\n", __func__);
+ /* Check hdmi disp init once */
+ if (hdmi_inited) {
+ dev_err(&hdmi->pdev->dev,
+ "Error only one HDMI output support now!\n");
+ return -1;
+ }
+
if (!plat || irq < 0)
return -ENODEV;
@@ -2208,6 +2233,8 @@ static int mxc_hdmi_disp_init(struct mxc_dispdrv_handle *disp,
dev_dbg(&hdmi->pdev->dev, "%s exit\n", __func__);
+ hdmi_inited = true;
+
return ret;
efbclient:
@@ -2250,6 +2277,8 @@ static void mxc_hdmi_disp_deinit(struct mxc_dispdrv_handle *disp)
platform_device_unregister(hdmi->pdev);
+ hdmi_inited = false;
+
kfree(hdmi);
}
@@ -2257,6 +2286,8 @@ static struct mxc_dispdrv_driver mxc_hdmi_drv = {
.name = DISPDRV_HDMI,
.init = mxc_hdmi_disp_init,
.deinit = mxc_hdmi_disp_deinit,
+ .enable = mxc_hdmi_power_on,
+ .disable = mxc_hdmi_power_off,
};
static int __devinit mxc_hdmi_probe(struct platform_device *pdev)
@@ -2285,6 +2316,8 @@ static int __devinit mxc_hdmi_probe(struct platform_device *pdev)
goto ecore;
}
+ hdmi_inited = false;
+
hdmi->disp_mxc_hdmi = mxc_dispdrv_register(&mxc_hdmi_drv);
if (IS_ERR(hdmi->disp_mxc_hdmi)) {
dev_err(&pdev->dev, "Failed to register dispdrv - 0x%x\n",
diff --git a/include/linux/fsl_devices.h b/include/linux/fsl_devices.h
index 395ddc7f0f96..e96cca48cbf8 100644
--- a/include/linux/fsl_devices.h
+++ b/include/linux/fsl_devices.h
@@ -123,6 +123,8 @@ struct fsl_usb2_platform_data {
enum usb_wakeup_event (*is_wakeup_event)(struct fsl_usb2_platform_data *);
void (*wakeup_handler)(struct fsl_usb2_platform_data *);
void (*hsic_post_ops)(void);
+ void (*hsic_device_connected)(void);
+ void (*gadget_discharge_dp) (bool);
struct fsl_usb2_wakeup_platform_data *wakeup_pdata;
struct platform_device *pdev;
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index bf56b6f78270..233ca3b60ecf 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -1445,6 +1445,43 @@ enum ieee80211_sa_query_action {
#define WLAN_PMKID_LEN 16
+/*
+ * WMM/802.11e Tspec Element
+ */
+#define IEEE80211_WMM_IE_TSPEC_TID_MASK 0x0F
+#define IEEE80211_WMM_IE_TSPEC_TID_SHIFT 1
+
+enum ieee80211_tspec_status_code {
+ IEEE80211_TSPEC_STATUS_ADMISS_ACCEPTED = 0,
+ IEEE80211_TSPEC_STATUS_ADDTS_INVAL_PARAMS = 0x1,
+};
+
+struct ieee80211_tspec_ie {
+ u8 element_id;
+ u8 len;
+ u8 oui[3];
+ u8 oui_type;
+ u8 oui_subtype;
+ u8 version;
+ __le16 tsinfo;
+ u8 tsinfo_resvd;
+ __le16 nominal_msdu;
+ __le16 max_msdu;
+ __le32 min_service_int;
+ __le32 max_service_int;
+ __le32 inactivity_int;
+ __le32 suspension_int;
+ __le32 service_start_time;
+ __le32 min_data_rate;
+ __le32 mean_data_rate;
+ __le32 peak_data_rate;
+ __le32 max_burst_size;
+ __le32 delay_bound;
+ __le32 min_phy_rate;
+ __le16 sba;
+ __le16 medium_time;
+} __packed;
+
/**
* ieee80211_get_qos_ctl - get pointer to qos control bytes
* @hdr: the frame
diff --git a/include/linux/mfd/mxc-hdmi-core.h b/include/linux/mfd/mxc-hdmi-core.h
index 8c6ce456ddad..b607feec147a 100644
--- a/include/linux/mfd/mxc-hdmi-core.h
+++ b/include/linux/mfd/mxc-hdmi-core.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -19,6 +19,8 @@
#ifndef __LINUX_MXC_HDMI_CORE_H_
#define __LINUX_MXC_HDMI_CORE_H_
+#include <mach/mxc_edid.h>
+
#define IRQ_DISABLE_SUCCEED 0
#define IRQ_DISABLE_FAIL 1
@@ -38,6 +40,9 @@ void hdmi_set_sample_rate(unsigned int rate);
void hdmi_init_clk_regenerator(void);
void hdmi_clk_regenerator_update_pixel_clock(void);
+void hdmi_set_edid_cfg(struct mxc_edid_cfg *cfg);
+void hdmi_get_edid_cfg(struct mxc_edid_cfg *cfg);
+
extern int mxc_hdmi_ipu_id;
extern int mxc_hdmi_disp_id;
diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h
index 686434404651..b8ed8398240b 100644
--- a/include/linux/mmc/card.h
+++ b/include/linux/mmc/card.h
@@ -401,7 +401,7 @@ struct mmc_driver {
struct device_driver drv;
int (*probe)(struct mmc_card *);
void (*remove)(struct mmc_card *);
- int (*suspend)(struct mmc_card *, pm_message_t);
+ int (*suspend)(struct mmc_card *);
int (*resume)(struct mmc_card *);
};
diff --git a/include/linux/mtd/gpmi-nand.h b/include/linux/mtd/gpmi-nand.h
index 69b6dbf46b5e..6659446591ec 100644
--- a/include/linux/mtd/gpmi-nand.h
+++ b/include/linux/mtd/gpmi-nand.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -51,6 +51,7 @@
* @partitions: An optional pointer to an array of partition
* descriptions.
* @partition_count: The number of elements in the partitions array.
+ * @enable_bbt: Enable the BBT or not.
*/
struct gpmi_nand_platform_data {
/* SoC hardware information. */
@@ -64,5 +65,6 @@ struct gpmi_nand_platform_data {
/* Medium information. */
struct mtd_partition *partitions;
unsigned partition_count;
+ unsigned int enable_bbt:1;
};
#endif
diff --git a/include/linux/mxc_v4l2.h b/include/linux/mxc_v4l2.h
index e83e5923c2a4..dd106ff31265 100644
--- a/include/linux/mxc_v4l2.h
+++ b/include/linux/mxc_v4l2.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -29,7 +29,8 @@
#define V4L2_CID_MXC_ROT (V4L2_CID_PRIVATE_BASE + 0)
#define V4L2_CID_MXC_FLASH (V4L2_CID_PRIVATE_BASE + 1)
#define V4L2_CID_MXC_VF_ROT (V4L2_CID_PRIVATE_BASE + 2)
-#define V4L2_CID_MXC_MOTION (V4L2_CID_PRIVATE_BASE + 3)
+#define V4L2_CID_MXC_MOTION (V4L2_CID_PRIVATE_BASE + 3)
+#define V4L2_CID_MXC_SWITCH_CAM (V4L2_CID_PRIVATE_BASE + 6)
#define V4L2_MXC_ROTATE_NONE 0
#define V4L2_MXC_ROTATE_VERT_FLIP 1
diff --git a/arch/arm/mach-mxs/include/mach/dma.h b/include/linux/mxs-dma.h
index 203d7c4a3e11..9186f908d207 100644
--- a/arch/arm/mach-mxs/include/mach/dma.h
+++ b/include/linux/mxs-dma.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/include/linux/pxp_dma.h b/include/linux/pxp_dma.h
index 8ae29b4ede8b..bf63bf3570e5 100644
--- a/include/linux/pxp_dma.h
+++ b/include/linux/pxp_dma.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -109,6 +109,7 @@ struct rect {
struct pxp_layer_param {
unsigned short width;
unsigned short height;
+ unsigned short stride; /* aka pitch */
unsigned int pixel_fmt;
/* layers combining parameters
diff --git a/sound/soc/codecs/cs42888.c b/sound/soc/codecs/cs42888.c
index f2480cc1490f..bc88a719df6f 100644
--- a/sound/soc/codecs/cs42888.c
+++ b/sound/soc/codecs/cs42888.c
@@ -1,6 +1,6 @@
/*
* cs42888.c -- CS42888 ALSA SoC Audio Driver
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
* The code contained herein is licensed under the GNU General Public
@@ -807,7 +807,7 @@ static int cs42888_probe(struct snd_soc_codec *codec)
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
return ret;
}
- if (cpu_is_mx6q()) {
+ if (cpu_is_mx6q() || cpu_is_mx6dl()) {
for (i = 0; i < ARRAY_SIZE(cs42888->supplies); i++)
cs42888->supplies[i].supply = cs42888_supply_names[i];
diff --git a/sound/soc/codecs/mxc_hdmi.c b/sound/soc/codecs/mxc_hdmi.c
index c6a6bcbdbfd9..70c9b8c9bfe0 100644
--- a/sound/soc/codecs/mxc_hdmi.c
+++ b/sound/soc/codecs/mxc_hdmi.c
@@ -1,7 +1,7 @@
/*
* MXC HDMI ALSA Soc Codec Driver
*
- * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
*/
/*
@@ -42,6 +42,7 @@
#include <mach/hardware.h>
#include <linux/mfd/mxc-hdmi-core.h>
+#include <mach/mxc_edid.h>
#include <mach/mxc_hdmi.h>
#include "../imx/imx-hdmi.h"
@@ -53,6 +54,16 @@ struct mxc_hdmi_priv {
struct clk *iahb_clk;
};
+static struct mxc_edid_cfg edid_cfg;
+
+static unsigned int playback_rates[HDMI_MAX_RATES];
+static unsigned int playback_sample_size[HDMI_MAX_SAMPLE_SIZE];
+static unsigned int playback_channels[HDMI_MAX_CHANNEL_CONSTRAINTS];
+
+static struct snd_pcm_hw_constraint_list playback_constraint_rates;
+static struct snd_pcm_hw_constraint_list playback_constraint_bits;
+static struct snd_pcm_hw_constraint_list playback_constraint_channels;
+
#ifdef DEBUG
static void dumpregs(void)
{
@@ -100,19 +111,126 @@ static void hdmi_set_audio_infoframe(void)
hdmi_writeb(0x00, HDMI_FC_AUDICONF2);
}
-static unsigned int hdmi_playback_rates[] = { 32000, 44100, 48000, 88200, 96000 };
-
-static struct snd_pcm_hw_constraint_list playback_rate_constraints = {
- .count = ARRAY_SIZE(hdmi_playback_rates),
- .list = hdmi_playback_rates,
- .mask = 0,
+static int cea_audio_rates[HDMI_MAX_RATES] = {
+ 32000,
+ 44100,
+ 48000,
+ 88200,
+ 96000,
+ 176400,
+ 192000,
};
+static void mxc_hdmi_get_playback_rates(void)
+{
+ int i, count = 0;
+ u8 rates;
+
+ /* always assume basic audio support */
+ rates = edid_cfg.sample_rates | 0x7;
+
+ for (i = 0 ; i < HDMI_MAX_RATES ; i++)
+ if ((rates & (1 << i)) != 0)
+ playback_rates[count++] = cea_audio_rates[i];
+
+ playback_constraint_rates.list = playback_rates;
+ playback_constraint_rates.count = count;
+
+#ifdef DEBUG
+ for (i = 0 ; i < playback_constraint_rates.count ; i++)
+ pr_debug("%s: constraint = %d Hz\n", __func__,
+ playback_rates[i]);
+#endif
+}
+
+static void mxc_hdmi_get_playback_sample_size(void)
+{
+ int i = 0;
+
+ /* always assume basic audio support */
+ playback_sample_size[i++] = 16;
+
+ if (edid_cfg.sample_sizes & 0x2)
+ playback_sample_size[i++] = 20;
+
+ if (edid_cfg.sample_sizes & 0x4)
+ playback_sample_size[i++] = 24;
+
+ playback_constraint_bits.list = playback_sample_size;
+ playback_constraint_bits.count = i;
+
+#ifdef DEBUG
+ for (i = 0 ; i < playback_constraint_bits.count ; i++)
+ pr_debug("%s: constraint = %d bits\n", __func__,
+ playback_sample_size[i]);
+#endif
+}
+
+static void mxc_hdmi_get_playback_channels(void)
+{
+ int channels = 2, i = 0;
+
+ /* always assume basic audio support */
+ playback_channels[i++] = channels;
+ channels += 2;
+
+ while ((i < HDMI_MAX_CHANNEL_CONSTRAINTS) &&
+ (channels <= edid_cfg.max_channels)) {
+ playback_channels[i++] = channels;
+ channels += 2;
+ }
+
+ playback_constraint_channels.list = playback_channels;
+ playback_constraint_channels.count = i;
+
+#ifdef DEBUG
+ for (i = 0 ; i < playback_constraint_channels.count ; i++)
+ pr_debug("%s: constraint = %d channels\n", __func__,
+ playback_channels[i]);
+#endif
+}
+
+static int mxc_hdmi_update_constraints(struct mxc_hdmi_priv *priv,
+ struct snd_pcm_substream *substream)
+{
+ struct snd_pcm_runtime *runtime = substream->runtime;
+ int ret;
+
+ hdmi_get_edid_cfg(&edid_cfg);
+
+ mxc_hdmi_get_playback_rates();
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_RATE,
+ &playback_constraint_rates);
+ if (ret < 0)
+ return ret;
+
+ mxc_hdmi_get_playback_sample_size();
+ ret = snd_pcm_hw_constraint_list(substream->runtime, 0,
+ SNDRV_PCM_HW_PARAM_SAMPLE_BITS,
+ &playback_constraint_bits);
+ if (ret < 0)
+ return ret;
+
+ mxc_hdmi_get_playback_channels();
+ ret = snd_pcm_hw_constraint_list(runtime, 0,
+ SNDRV_PCM_HW_PARAM_CHANNELS,
+ &playback_constraint_channels);
+ if (ret < 0)
+ return ret;
+
+ ret = snd_pcm_hw_constraint_integer(substream->runtime,
+ SNDRV_PCM_HW_PARAM_PERIODS);
+ if (ret < 0)
+ return ret;
+
+ return 0;
+}
+
static int mxc_hdmi_codec_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
struct mxc_hdmi_priv *hdmi_priv = snd_soc_dai_get_drvdata(dai);
- struct snd_pcm_runtime *runtime = substream->runtime;
int ret;
clk_enable(hdmi_priv->isfr_clk);
@@ -122,14 +240,7 @@ static int mxc_hdmi_codec_startup(struct snd_pcm_substream *substream,
(int)clk_get_rate(hdmi_priv->isfr_clk),
(int)clk_get_rate(hdmi_priv->iahb_clk));
- ret = snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_RATE,
- &playback_rate_constraints);
- if (ret < 0)
- return ret;
-
- ret = snd_pcm_hw_constraint_integer(runtime,
- SNDRV_PCM_HW_PARAM_PERIODS);
+ ret = mxc_hdmi_update_constraints(hdmi_priv, substream);
if (ret < 0)
return ret;
diff --git a/sound/soc/imx/Makefile b/sound/soc/imx/Makefile
index 7ba4e8ad7bd6..07153b90d13e 100644
--- a/sound/soc/imx/Makefile
+++ b/sound/soc/imx/Makefile
@@ -24,5 +24,6 @@ obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
+obj-$(CONFIG_SND_SOC_IMX_CS42888) += snd-soc-imx-cs42888.o
obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
obj-$(CONFIG_SND_SOC_IMX_HDMI) += snd-soc-imx-hdmi.o
diff --git a/sound/soc/imx/imx-cs42888.c b/sound/soc/imx/imx-cs42888.c
index 4e97ec246792..26745d35b936 100644
--- a/sound/soc/imx/imx-cs42888.c
+++ b/sound/soc/imx/imx-cs42888.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright (C) 2010-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -117,7 +117,7 @@ static int imx_3stack_surround_hw_params(struct snd_pcm_substream *substream,
pr_info("Rate not support.\n");
return -EINVAL;;
}
- } else if (cpu_is_mx6q()) {
+ } else if (cpu_is_mx6q() || cpu_is_mx6dl()) {
switch (rate) {
case 32000:
lrclk_ratio = 5;
@@ -163,7 +163,7 @@ static int imx_3stack_surround_hw_params(struct snd_pcm_substream *substream,
if (cpu_is_mx53()) {
snd_soc_dai_set_sysclk(cpu_dai, ESAI_CLK_EXTAL,
mclk_freq, SND_SOC_CLOCK_OUT);
- } else if (cpu_is_mx6q()) {
+ } else if (cpu_is_mx6q() || cpu_is_mx6dl()) {
snd_soc_dai_set_sysclk(cpu_dai, ESAI_CLK_EXTAL_DIV,
mclk_freq, SND_SOC_CLOCK_OUT);
}
@@ -171,14 +171,14 @@ static int imx_3stack_surround_hw_params(struct snd_pcm_substream *substream,
snd_soc_dai_set_clkdiv(cpu_dai, ESAI_TX_DIV_PSR, 1);
if (cpu_is_mx53())
snd_soc_dai_set_clkdiv(cpu_dai, ESAI_TX_DIV_PM, 0);
- else if (cpu_is_mx6q())
+ else if (cpu_is_mx6q() || cpu_is_mx6dl())
snd_soc_dai_set_clkdiv(cpu_dai, ESAI_TX_DIV_PM, 2);
snd_soc_dai_set_clkdiv(cpu_dai, ESAI_TX_DIV_FP, lrclk_ratio);
snd_soc_dai_set_clkdiv(cpu_dai, ESAI_RX_DIV_PSR, 1);
if (cpu_is_mx53())
snd_soc_dai_set_clkdiv(cpu_dai, ESAI_RX_DIV_PM, 0);
- else if (cpu_is_mx6q())
+ else if (cpu_is_mx6q() || cpu_is_mx6dl())
snd_soc_dai_set_clkdiv(cpu_dai, ESAI_RX_DIV_PM, 2);
snd_soc_dai_set_clkdiv(cpu_dai, ESAI_RX_DIV_FP, lrclk_ratio);
diff --git a/sound/soc/imx/imx-hdmi-dma.c b/sound/soc/imx/imx-hdmi-dma.c
index 9ce99efccc1b..d0c4d52e9c56 100644
--- a/sound/soc/imx/imx-hdmi-dma.c
+++ b/sound/soc/imx/imx-hdmi-dma.c
@@ -649,14 +649,6 @@ static struct snd_pcm_hardware snd_imx_hardware = {
.fifo_size = 0,
};
-static unsigned int hw_channels[] = {2, 4, 6, 8};
-
-static struct snd_pcm_hw_constraint_list hw_constraint_channels = {
- .count = ARRAY_SIZE(hw_channels),
- .list = hw_channels,
- .mask = 0,
-};
-
static void hdmi_dma_irq_enable(struct imx_hdmi_dma_runtime_data *rtd)
{
unsigned long flags;
@@ -712,12 +704,6 @@ static int hdmi_dma_open(struct snd_pcm_substream *substream)
if (ret < 0)
return ret;
- ret = snd_pcm_hw_constraint_list(runtime, 0,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- &hw_constraint_channels);
- if (ret < 0)
- return ret;
-
snd_soc_set_runtime_hwparams(substream, &snd_imx_hardware);
hdmi_dma_irq_enable(hdmi_dma_priv);
diff --git a/sound/soc/imx/imx-hdmi.h b/sound/soc/imx/imx-hdmi.h
index 52c58dd516d5..11737579af31 100644
--- a/sound/soc/imx/imx-hdmi.h
+++ b/sound/soc/imx/imx-hdmi.h
@@ -1,7 +1,7 @@
/*
* MXC HDMI ALSA Soc Codec Driver
*
- * Copyright (C) 2011 Freescale Semiconductor, Inc.
+ * Copyright (C) 2011-2012 Freescale Semiconductor, Inc.
*/
/*
@@ -31,11 +31,17 @@ struct imx_hdmi {
struct platform_device *soc_platform_pdev;
};
+#define HDMI_MAX_RATES 7
+#define HDMI_MAX_SAMPLE_SIZE 3
+#define HDMI_MAX_CHANNEL_CONSTRAINTS 4
+
#define MXC_HDMI_RATES_PLAYBACK (SNDRV_PCM_RATE_32000 | \
SNDRV_PCM_RATE_44100 | \
SNDRV_PCM_RATE_48000 | \
SNDRV_PCM_RATE_88200 | \
- SNDRV_PCM_RATE_96000)
+ SNDRV_PCM_RATE_96000 | \
+ SNDRV_PCM_RATE_176400 | \
+ SNDRV_PCM_RATE_192000)
#define MXC_HDMI_FORMATS_PLAYBACK (SNDRV_PCM_FMTBIT_S16_LE | \
SNDRV_PCM_FMTBIT_S24_LE)