summaryrefslogtreecommitdiff
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig23
-rw-r--r--arch/arm/Makefile8
-rw-r--r--arch/arm/configs/imx27ads_defconfig1020
-rw-r--r--arch/arm/configs/imx31_3stack_defconfig1750
-rw-r--r--arch/arm/configs/imx31ads_defconfig1707
-rw-r--r--arch/arm/configs/imx35_3stack_defconfig1724
-rw-r--r--arch/arm/configs/imx35evb_defconfig976
-rw-r--r--arch/arm/configs/imx37_3stack_defconfig1761
-rw-r--r--arch/arm/configs/imx51_3stack_defconfig1794
-rw-r--r--arch/arm/include/asm/cacheflush.h8
-rw-r--r--arch/arm/include/asm/hardware/cache-l2x0.h2
-rw-r--r--arch/arm/include/asm/mach/keypad.h28
-rw-r--r--arch/arm/mach-mx27/Kconfig43
-rw-r--r--arch/arm/mach-mx27/Makefile18
-rw-r--r--arch/arm/mach-mx27/Makefile.boot3
-rw-r--r--arch/arm/mach-mx27/board-mx27ads.h385
-rw-r--r--arch/arm/mach-mx27/clock.c1530
-rw-r--r--arch/arm/mach-mx27/cpu.c33
-rw-r--r--arch/arm/mach-mx27/crm_regs.h284
-rw-r--r--arch/arm/mach-mx27/devices.c698
-rw-r--r--arch/arm/mach-mx27/dma.c553
-rw-r--r--arch/arm/mach-mx27/dptc.c49
-rw-r--r--arch/arm/mach-mx27/gpio_mux.c308
-rw-r--r--arch/arm/mach-mx27/gpio_mux.h78
-rw-r--r--arch/arm/mach-mx27/mm.c62
-rw-r--r--arch/arm/mach-mx27/mx27_pins.h207
-rw-r--r--arch/arm/mach-mx27/mx27ads.c822
-rw-r--r--arch/arm/mach-mx27/mx27ads_gpio.c1226
-rw-r--r--arch/arm/mach-mx27/mxc_pm.c459
-rw-r--r--arch/arm/mach-mx27/pm.c102
-rw-r--r--arch/arm/mach-mx27/serial.c275
-rw-r--r--arch/arm/mach-mx27/serial.h170
-rw-r--r--arch/arm/mach-mx27/system.c60
-rw-r--r--arch/arm/mach-mx27/time.c240
-rw-r--r--arch/arm/mach-mx27/usb.h116
-rw-r--r--arch/arm/mach-mx27/usb_dr.c126
-rw-r--r--arch/arm/mach-mx27/usb_h1.c53
-rw-r--r--arch/arm/mach-mx27/usb_h2.c53
-rw-r--r--arch/arm/mach-mx3/Kconfig91
-rw-r--r--arch/arm/mach-mx3/Makefile16
-rw-r--r--arch/arm/mach-mx3/board-mx31ads.h326
-rw-r--r--arch/arm/mach-mx3/board-mx3_3stack.h150
-rw-r--r--arch/arm/mach-mx3/clock.c402
-rw-r--r--arch/arm/mach-mx3/cpu.c78
-rw-r--r--arch/arm/mach-mx3/crm_regs.h6
-rw-r--r--arch/arm/mach-mx3/devices.c909
-rw-r--r--arch/arm/mach-mx3/dma.c745
-rw-r--r--arch/arm/mach-mx3/dptc.c103
-rw-r--r--arch/arm/mach-mx3/dvfs_v2.c537
-rw-r--r--arch/arm/mach-mx3/iomux.c267
-rw-r--r--arch/arm/mach-mx3/iomux.h185
-rw-r--r--arch/arm/mach-mx3/mm.c54
-rw-r--r--arch/arm/mach-mx3/mx31_pins.h429
-rw-r--r--arch/arm/mach-mx3/mx31ads.c961
-rw-r--r--arch/arm/mach-mx3/mx31ads_gpio.c1561
-rw-r--r--arch/arm/mach-mx3/mx3_3stack.c1085
-rw-r--r--arch/arm/mach-mx3/mx3_3stack_gpio.c1298
-rw-r--r--arch/arm/mach-mx3/mxc_pm.c439
-rw-r--r--arch/arm/mach-mx3/pm.c113
-rw-r--r--arch/arm/mach-mx3/sdma_script_code.h581
-rw-r--r--arch/arm/mach-mx3/sdma_script_code_pass2.h434
-rw-r--r--arch/arm/mach-mx3/serial.c267
-rw-r--r--arch/arm/mach-mx3/serial.h158
-rw-r--r--arch/arm/mach-mx3/system.c103
-rw-r--r--arch/arm/mach-mx3/usb.h116
-rw-r--r--arch/arm/mach-mx3/usb_dr.c125
-rw-r--r--arch/arm/mach-mx3/usb_h1.c53
-rw-r--r--arch/arm/mach-mx3/usb_h2.c88
-rw-r--r--arch/arm/mach-mx35/Kconfig106
-rw-r--r--arch/arm/mach-mx35/Makefile20
-rw-r--r--arch/arm/mach-mx35/Makefile.boot9
-rw-r--r--arch/arm/mach-mx35/board-mx35_3stack.h199
-rw-r--r--arch/arm/mach-mx35/board-mx35evb.h144
-rw-r--r--arch/arm/mach-mx35/clock.c1849
-rw-r--r--arch/arm/mach-mx35/cpu.c82
-rw-r--r--arch/arm/mach-mx35/crm_regs.h423
-rw-r--r--arch/arm/mach-mx35/devices.c729
-rw-r--r--arch/arm/mach-mx35/dma.c753
-rw-r--r--arch/arm/mach-mx35/dvfs.c598
-rw-r--r--arch/arm/mach-mx35/iomux.c217
-rw-r--r--arch/arm/mach-mx35/iomux.h292
-rw-r--r--arch/arm/mach-mx35/mm.c77
-rw-r--r--arch/arm/mach-mx35/mx35_3stack.c1168
-rw-r--r--arch/arm/mach-mx35/mx35_3stack_cpld.c160
-rw-r--r--arch/arm/mach-mx35/mx35_3stack_gpio.c1353
-rw-r--r--arch/arm/mach-mx35/mx35_3stack_irq.c371
-rw-r--r--arch/arm/mach-mx35/mx35_pins.h333
-rw-r--r--arch/arm/mach-mx35/mx35evb.c396
-rw-r--r--arch/arm/mach-mx35/mx35evb_cpld.c82
-rw-r--r--arch/arm/mach-mx35/mx35evb_gpio.c276
-rw-r--r--arch/arm/mach-mx35/pm.c79
-rw-r--r--arch/arm/mach-mx35/sdma_script_code.h254
-rw-r--r--arch/arm/mach-mx35/sdma_script_code_v2.h234
-rw-r--r--arch/arm/mach-mx35/serial.c180
-rw-r--r--arch/arm/mach-mx35/serial.h132
-rw-r--r--arch/arm/mach-mx35/system.c126
-rw-r--r--arch/arm/mach-mx35/usb.h104
-rw-r--r--arch/arm/mach-mx35/usb_dr.c109
-rw-r--r--arch/arm/mach-mx35/usb_h2.c62
-rw-r--r--arch/arm/mach-mx37/Kconfig89
-rw-r--r--arch/arm/mach-mx37/Makefile19
-rw-r--r--arch/arm/mach-mx37/Makefile.boot3
-rw-r--r--arch/arm/mach-mx37/board-mx37_3stack.h117
-rw-r--r--arch/arm/mach-mx37/clock.c2992
-rw-r--r--arch/arm/mach-mx37/cpu.c71
-rw-r--r--arch/arm/mach-mx37/crm_regs.h611
-rw-r--r--arch/arm/mach-mx37/devices.c908
-rw-r--r--arch/arm/mach-mx37/dma.c666
-rw-r--r--arch/arm/mach-mx37/dptc.c69
-rw-r--r--arch/arm/mach-mx37/iomux.c205
-rw-r--r--arch/arm/mach-mx37/iomux.h226
-rw-r--r--arch/arm/mach-mx37/lpmodes.c408
-rw-r--r--arch/arm/mach-mx37/mm.c82
-rw-r--r--arch/arm/mach-mx37/mx37_3stack.c907
-rw-r--r--arch/arm/mach-mx37/mx37_3stack_cpld.c231
-rw-r--r--arch/arm/mach-mx37/mx37_3stack_gpio.c1016
-rw-r--r--arch/arm/mach-mx37/mx37_3stack_pmic_wm8350.c394
-rw-r--r--arch/arm/mach-mx37/mx37_pins.h256
-rw-r--r--arch/arm/mach-mx37/pm.c72
-rw-r--r--arch/arm/mach-mx37/sdma_script_code.h203
-rw-r--r--arch/arm/mach-mx37/serial.c169
-rw-r--r--arch/arm/mach-mx37/serial.h127
-rw-r--r--arch/arm/mach-mx37/system.c192
-rw-r--r--arch/arm/mach-mx37/usb.h112
-rw-r--r--arch/arm/mach-mx37/usb_dr.c120
-rw-r--r--arch/arm/mach-mx51/Kconfig85
-rw-r--r--arch/arm/mach-mx51/Makefile19
-rw-r--r--arch/arm/mach-mx51/Makefile.boot3
-rw-r--r--arch/arm/mach-mx51/board-mx51_3stack.h128
-rw-r--r--arch/arm/mach-mx51/clock.c3048
-rw-r--r--arch/arm/mach-mx51/cpu.c60
-rw-r--r--arch/arm/mach-mx51/crm_regs.h673
-rw-r--r--arch/arm/mach-mx51/devices.c913
-rw-r--r--arch/arm/mach-mx51/dma.c666
-rw-r--r--arch/arm/mach-mx51/iomux.c249
-rw-r--r--arch/arm/mach-mx51/iomux.h236
-rw-r--r--arch/arm/mach-mx51/lpmodes.c204
-rw-r--r--arch/arm/mach-mx51/mm.c84
-rw-r--r--arch/arm/mach-mx51/mx51_3stack.c1054
-rw-r--r--arch/arm/mach-mx51/mx51_3stack_gpio.c1706
-rw-r--r--arch/arm/mach-mx51/mx51_pins.h361
-rw-r--r--arch/arm/mach-mx51/pm.c147
-rw-r--r--arch/arm/mach-mx51/sdma_script_code.h170
-rw-r--r--arch/arm/mach-mx51/serial.c169
-rw-r--r--arch/arm/mach-mx51/serial.h127
-rw-r--r--arch/arm/mach-mx51/suspend.S145
-rw-r--r--arch/arm/mach-mx51/system.c186
-rw-r--r--arch/arm/mach-mx51/usb.h114
-rw-r--r--arch/arm/mach-mx51/usb_dr.c143
-rw-r--r--arch/arm/mach-mx51/usb_h1.c54
-rw-r--r--arch/arm/mach-mx51/wfi.S427
-rw-r--r--arch/arm/mm/Kconfig6
-rw-r--r--arch/arm/mm/cache-l2x0.c82
-rw-r--r--arch/arm/oprofile/Makefile1
-rw-r--r--arch/arm/oprofile/evtmon_regs.h84
-rw-r--r--arch/arm/oprofile/op_model_arm11.c477
-rw-r--r--arch/arm/oprofile/op_model_arm11_core.c44
-rw-r--r--arch/arm/oprofile/op_model_arm11_core.h13
-rw-r--r--arch/arm/oprofile/op_model_arm11_evtmon.c188
-rw-r--r--arch/arm/oprofile/op_model_v6.c19
-rw-r--r--arch/arm/plat-mxc/Kconfig140
-rw-r--r--arch/arm/plat-mxc/Makefile52
-rw-r--r--arch/arm/plat-mxc/clock.c134
-rw-r--r--arch/arm/plat-mxc/cpu_common.c85
-rw-r--r--arch/arm/plat-mxc/cpufreq.c595
-rw-r--r--arch/arm/plat-mxc/dma_mx2.c1315
-rw-r--r--arch/arm/plat-mxc/dptc.c612
-rw-r--r--arch/arm/plat-mxc/dvfs_core.c576
-rw-r--r--arch/arm/plat-mxc/entry-pm.S315
-rw-r--r--arch/arm/plat-mxc/gpio.c981
-rw-r--r--arch/arm/plat-mxc/include/mach/arc_otg.h329
-rw-r--r--arch/arm/plat-mxc/include/mach/audio_controls.h220
-rw-r--r--arch/arm/plat-mxc/include/mach/clock.h15
-rw-r--r--arch/arm/plat-mxc/include/mach/common.h6
-rw-r--r--arch/arm/plat-mxc/include/mach/dma.h251
-rw-r--r--arch/arm/plat-mxc/include/mach/dptc.h186
-rw-r--r--arch/arm/plat-mxc/include/mach/dvfs_dptc_struct.h169
-rw-r--r--arch/arm/plat-mxc/include/mach/entry-macro.S35
-rw-r--r--arch/arm/plat-mxc/include/mach/fsl_usb.h79
-rw-r--r--arch/arm/plat-mxc/include/mach/fsl_usb_gadget.h40
-rw-r--r--arch/arm/plat-mxc/include/mach/gpio.h185
-rw-r--r--arch/arm/plat-mxc/include/mach/hardware.h154
-rw-r--r--arch/arm/plat-mxc/include/mach/hw_events.h65
-rw-r--r--arch/arm/plat-mxc/include/mach/imx_adc.h275
-rw-r--r--arch/arm/plat-mxc/include/mach/io.h45
-rw-r--r--arch/arm/plat-mxc/include/mach/ipu.h1162
-rw-r--r--arch/arm/plat-mxc/include/mach/irqs.h17
-rw-r--r--arch/arm/plat-mxc/include/mach/memory.h54
-rw-r--r--arch/arm/plat-mxc/include/mach/mmc.h35
-rw-r--r--arch/arm/plat-mxc/include/mach/mtd-xip.h52
-rw-r--r--arch/arm/plat-mxc/include/mach/mx21.h303
-rw-r--r--arch/arm/plat-mxc/include/mach/mx27.h102
-rw-r--r--arch/arm/plat-mxc/include/mach/mx2_dma.h261
-rw-r--r--arch/arm/plat-mxc/include/mach/mx31.h235
-rw-r--r--arch/arm/plat-mxc/include/mach/mx35.h455
-rw-r--r--arch/arm/plat-mxc/include/mach/mx37.h509
-rw-r--r--arch/arm/plat-mxc/include/mach/mx51.h520
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc.h356
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_asrc.h198
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_dptc.h111
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_gpc.h74
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_mlb.h51
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_pf.h125
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_pm.h252
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_scc.h45
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_scc2_driver.h973
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_scc_driver.h1031
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_timer.h9
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_uart.h275
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_v4l2.h42
-rw-r--r--arch/arm/plat-mxc/include/mach/mxc_vpu.h92
-rw-r--r--arch/arm/plat-mxc/include/mach/mxcfb.h75
-rw-r--r--arch/arm/plat-mxc/include/mach/pcmcia.h218
-rw-r--r--arch/arm/plat-mxc/include/mach/pmic_adc.h455
-rw-r--r--arch/arm/plat-mxc/include/mach/pmic_audio.h2315
-rw-r--r--arch/arm/plat-mxc/include/mach/pmic_battery.h419
-rw-r--r--arch/arm/plat-mxc/include/mach/pmic_convity.h873
-rw-r--r--arch/arm/plat-mxc/include/mach/pmic_external.h1135
-rw-r--r--arch/arm/plat-mxc/include/mach/pmic_light.h1082
-rw-r--r--arch/arm/plat-mxc/include/mach/pmic_power.h1358
-rw-r--r--arch/arm/plat-mxc/include/mach/pmic_rtc.h153
-rw-r--r--arch/arm/plat-mxc/include/mach/pmic_status.h82
-rw-r--r--arch/arm/plat-mxc/include/mach/sdma.h505
-rw-r--r--arch/arm/plat-mxc/include/mach/spba.h66
-rw-r--r--arch/arm/plat-mxc/include/mach/system.h23
-rw-r--r--arch/arm/plat-mxc/include/mach/uncompress.h2
-rw-r--r--arch/arm/plat-mxc/io.c41
-rw-r--r--arch/arm/plat-mxc/irq.c164
-rw-r--r--arch/arm/plat-mxc/isp1301xc.c290
-rw-r--r--arch/arm/plat-mxc/isp1504xc.c279
-rw-r--r--arch/arm/plat-mxc/leds.c111
-rw-r--r--arch/arm/plat-mxc/mc13783_xc.c299
-rw-r--r--arch/arm/plat-mxc/sdma/Makefile18
-rw-r--r--arch/arm/plat-mxc/sdma/dma_sdma.c684
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/Makefile5
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/include/epm.h187
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/include/iapi.h49
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/include/iapiDefaults.h128
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/include/iapiHigh.h136
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/include/iapiLow.h78
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/include/iapiLowDsp.h50
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/include/iapiLowMcu.h60
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/include/iapiMiddle.h52
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/include/iapiMiddleMcu.h41
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/include/iapiOS.h96
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/include/sdmaStruct.h425
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/src/Makefile18
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/src/iapiDefaults.c110
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/src/iapiHigh.c2798
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/src/iapiLow.c150
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/src/iapiLowDsp.c79
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/src/iapiLowMcu.c516
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/src/iapiMiddle.c623
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/src/iapiMiddleMcu.c52
-rw-r--r--arch/arm/plat-mxc/sdma/iapi/src/iapiOS.c64
-rw-r--r--arch/arm/plat-mxc/sdma/sdma.c1397
-rw-r--r--arch/arm/plat-mxc/sdma/sdma_malloc.c388
-rw-r--r--arch/arm/plat-mxc/serialxc.c64
-rw-r--r--arch/arm/plat-mxc/snoop.c133
-rw-r--r--arch/arm/plat-mxc/spba.c133
-rw-r--r--arch/arm/plat-mxc/tzic.c179
-rw-r--r--arch/arm/plat-mxc/usb_common.c772
-rw-r--r--arch/arm/plat-mxc/utmixc.c120
-rw-r--r--arch/arm/plat-mxc/wdog.c67
264 files changed, 96585 insertions, 931 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 247be5934b8d..45e154332d8b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -421,11 +421,12 @@ config ARCH_MV78XX0
config ARCH_MXC
bool "Freescale MXC/iMX-based"
+ select ARCH_MTD_XIP
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
- select ARCH_MTD_XIP
- select GENERIC_GPIO
- select ARCH_REQUIRE_GPIOLIB
+# select GENERIC_GPIO
+# select ARCH_REQUIRE_GPIOLIB
+ select ZONE_DMA
help
Support for Freescale MXC/iMX-based family of processors
@@ -899,7 +900,7 @@ config LEDS
ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
ARCH_AT91 || ARCH_DAVINCI || \
- ARCH_KS8695 || MACH_RD88F5182
+ ARCH_KS8695 || MACH_RD88F5182 || ARCH_MXC
help
If you say Y here, the LEDs on your machine will be used
to provide useful information about your current system status.
@@ -1060,7 +1061,7 @@ endmenu
menu "CPU Power Management"
-if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)
+if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA || ARCH_MXC)
source "drivers/cpufreq/Kconfig"
@@ -1100,6 +1101,12 @@ config CPU_FREQ_PXA
default y
select CPU_FREQ_DEFAULT_GOV_USERSPACE
+config CPU_FREQ_IMX
+ tristate "CPUfreq driver for i.MX CPUs"
+ depends on ARCH_MXC && CPU_FREQ && REGULATOR
+ help
+ This enables the CPUfreq driver for i.MX CPUs.
+
endif
source "drivers/cpuidle/Kconfig"
@@ -1247,6 +1254,8 @@ source "drivers/char/Kconfig"
source "drivers/i2c/Kconfig"
+source "drivers/i2c-slave/Kconfig"
+
source "drivers/spi/Kconfig"
source "drivers/gpio/Kconfig"
@@ -1299,6 +1308,10 @@ source "drivers/regulator/Kconfig"
source "drivers/uio/Kconfig"
+if ARCH_MXC
+source "drivers/mxc/Kconfig"
+endif
+
endmenu
source "fs/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index bd6e28115ebb..2d56f7fa8007 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -47,7 +47,7 @@ comma = ,
# Note that GCC does not numerically define an architecture version
# macro, but instead defines a whole series of macros which makes
# testing for a specific architecture or later rather impossible.
-arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7-a,-march=armv5t -Wa$(comma)-march=armv7-a)
+arch-$(CONFIG_CPU_32v7) :=-D__LINUX_ARM_ARCH__=7 $(call cc-option,-march=armv7a,-march=armv5t -Wa$(comma)-march=armv7a)
arch-$(CONFIG_CPU_32v6) :=-D__LINUX_ARM_ARCH__=6 $(call cc-option,-march=armv6,-march=armv5t -Wa$(comma)-march=armv6)
# Only override the compiler option if ARMv6. The ARMv6K extensions are
# always available in ARMv7
@@ -139,6 +139,12 @@ endif
plat-$(CONFIG_ARCH_MXC) := mxc
machine-$(CONFIG_ARCH_MX2) := mx2
machine-$(CONFIG_ARCH_MX3) := mx3
+ machine-$(CONFIG_ARCH_MX35) := mx35
+ machine-$(CONFIG_ARCH_MX37) := mx37
+ machine-$(CONFIG_ARCH_MX51) := mx51
+ machine-$(CONFIG_ARCH_MX27) := mx27
+ machine-$(CONFIG_ARCH_MX25) := mx25
+ machine-$(CONFIG_ARCH_MX21) := mx21
machine-$(CONFIG_ARCH_ORION5X) := orion5x
plat-$(CONFIG_PLAT_ORION) := orion
machine-$(CONFIG_ARCH_MSM) := msm
diff --git a/arch/arm/configs/imx27ads_defconfig b/arch/arm/configs/imx27ads_defconfig
index bcd95b8dd2df..153dd43b97c6 100644
--- a/arch/arm/configs/imx27ads_defconfig
+++ b/arch/arm/configs/imx27ads_defconfig
@@ -1,11 +1,11 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.26-rc6
-# Fri Jun 20 16:29:34 2008
+# Linux kernel version: 2.6.26
+# Tue Sep 16 10:19:20 2008
#
CONFIG_ARM=y
CONFIG_SYS_SUPPORTS_APM_EMULATION=y
-CONFIG_GENERIC_GPIO=y
+# CONFIG_GENERIC_GPIO is not set
CONFIG_GENERIC_TIME=y
CONFIG_GENERIC_CLOCKEVENTS=y
CONFIG_MMU=y
@@ -36,14 +36,15 @@ CONFIG_LOCK_KERNEL=y
CONFIG_INIT_ENV_ARG_LIMIT=32
CONFIG_LOCALVERSION=""
CONFIG_LOCALVERSION_AUTO=y
-# CONFIG_SWAP is not set
+CONFIG_SWAP=y
CONFIG_SYSVIPC=y
CONFIG_SYSVIPC_SYSCTL=y
-CONFIG_POSIX_MQUEUE=y
+# CONFIG_POSIX_MQUEUE is not set
# CONFIG_BSD_PROCESS_ACCT is not set
# CONFIG_TASKSTATS is not set
# CONFIG_AUDIT is not set
-# CONFIG_IKCONFIG is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=14
# CONFIG_CGROUPS is not set
# CONFIG_GROUP_SCHED is not set
@@ -52,14 +53,14 @@ CONFIG_SYSFS_DEPRECATED_V2=y
# CONFIG_RELAY is not set
# CONFIG_NAMESPACES is not set
# CONFIG_BLK_DEV_INITRD is not set
-# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SYSCTL=y
CONFIG_EMBEDDED=y
CONFIG_UID16=y
CONFIG_SYSCTL_SYSCALL=y
CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_KALLSYMS=y
-CONFIG_KALLSYMS_EXTRA_PASS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
CONFIG_HOTPLUG=y
CONFIG_PRINTK=y
CONFIG_BUG=y
@@ -74,11 +75,13 @@ CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
CONFIG_VM_EVENT_COUNTERS=y
-CONFIG_SLAB=y
-# CONFIG_SLUB is not set
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
# CONFIG_SLOB is not set
-# CONFIG_PROFILING is not set
+CONFIG_PROFILING=y
# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
CONFIG_HAVE_OPROFILE=y
# CONFIG_KPROBES is not set
CONFIG_HAVE_KPROBES=y
@@ -92,10 +95,10 @@ CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
-# CONFIG_MODULE_FORCE_UNLOAD is not set
-# CONFIG_MODVERSIONS is not set
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
# CONFIG_MODULE_SRCVERSION_ALL is not set
-# CONFIG_KMOD is not set
+CONFIG_KMOD=y
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
@@ -106,14 +109,14 @@ CONFIG_BLOCK=y
# IO Schedulers
#
CONFIG_IOSCHED_NOOP=y
-# CONFIG_IOSCHED_AS is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
# CONFIG_DEFAULT_AS is not set
# CONFIG_DEFAULT_DEADLINE is not set
-# CONFIG_DEFAULT_CFQ is not set
-CONFIG_DEFAULT_NOOP=y
-CONFIG_DEFAULT_IOSCHED="noop"
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_CLASSIC_RCU=y
#
@@ -166,25 +169,40 @@ CONFIG_ARCH_MXC=y
#
# Freescale MXC Implementations
#
-CONFIG_ARCH_MX2=y
+# CONFIG_ARCH_MX37 is not set
+# CONFIG_ARCH_MX35 is not set
+# CONFIG_ARCH_MX51 is not set
# CONFIG_ARCH_MX3 is not set
+CONFIG_ARCH_MX27=y
+# CONFIG_ARCH_MX21 is not set
#
-# MX2 family CPU support
+# MX27 Options
#
-CONFIG_MACH_MX27=y
+CONFIG_MX27_OPTIONS=y
+CONFIG_MACH_MX27ADS=y
+CONFIG_ARCH_MXC_HAS_NFC_V1=y
#
-# MX2 Platforms
-#
-CONFIG_MACH_MX27ADS=y
-# CONFIG_MACH_PCM038 is not set
+# Device options
+#
+CONFIG_I2C_MXC_SELECT1=y
+# CONFIG_I2C_MXC_SELECT2 is not set
+CONFIG_MXC_EMMA=y
+CONFIG_DMA_ZONE_SIZE=24
+CONFIG_ISP1301_MXC=y
+CONFIG_MXC_USB_SU6=y
+# CONFIG_MXC_USB_SB3 is not set
+# CONFIG_MXC_USB_DU6 is not set
+# CONFIG_MXC_USB_DB4 is not set
#
# Processor Type
#
CONFIG_CPU_32=y
CONFIG_CPU_ARM926T=y
+# CONFIG_CPU_V6 is not set
+# CONFIG_CPU_V7 is not set
CONFIG_CPU_32v5=y
CONFIG_CPU_ABRT_EV5TJ=y
CONFIG_CPU_PABRT_NOIFAR=y
@@ -237,6 +255,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4096
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
CONFIG_ALIGNMENT_TRAP=y
#
@@ -244,11 +263,16 @@ CONFIG_ALIGNMENT_TRAP=y
#
CONFIG_ZBOOT_ROM_TEXT=0x0
CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_CMDLINE=""
+CONFIG_CMDLINE="noinitrd console=ttymxc0 root=/dev/mtdblock2 rw ip=off"
# CONFIG_XIP_KERNEL is not set
# CONFIG_KEXEC is not set
#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
# Floating point emulation
#
@@ -267,7 +291,12 @@ CONFIG_BINFMT_ELF=y
#
# Power management options
#
-# CONFIG_PM is not set
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
CONFIG_ARCH_SUSPEND_POSSIBLE=y
#
@@ -281,14 +310,19 @@ CONFIG_NET=y
CONFIG_PACKET=y
CONFIG_PACKET_MMAP=y
CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
# CONFIG_NET_KEY is not set
CONFIG_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 is not set
-# CONFIG_IP_PNP_BOOTP is not set
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
# CONFIG_IP_PNP_RARP is not set
# CONFIG_NET_IPIP is not set
# CONFIG_NET_IPGRE is not set
@@ -300,11 +334,12 @@ CONFIG_IP_PNP=y
# CONFIG_INET_IPCOMP is not set
# CONFIG_INET_XFRM_TUNNEL is not set
# CONFIG_INET_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
-# CONFIG_INET_XFRM_MODE_TUNNEL is not set
-# CONFIG_INET_XFRM_MODE_BEET is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
# CONFIG_INET_LRO is not set
-# CONFIG_INET_DIAG is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
# CONFIG_TCP_CONG_ADVANCED is not set
CONFIG_TCP_CONG_CUBIC=y
CONFIG_DEFAULT_TCP_CONG="cubic"
@@ -334,7 +369,46 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# CONFIG_NET_PKTGEN is not set
# CONFIG_HAMRADIO is not set
# CONFIG_CAN is not set
-# CONFIG_IRDA is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+# CONFIG_KINGSUN_DONGLE is not set
+# CONFIG_KSDAZZLE_DONGLE is not set
+# CONFIG_KS959_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_MCS_FIR is not set
+# CONFIG_MXC_FIR is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
@@ -342,9 +416,13 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
# Wireless
#
# CONFIG_CFG80211 is not set
-# CONFIG_WIRELESS_EXT is not set
+CONFIG_WIRELESS_EXT=y
# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+# CONFIG_IEEE80211_CRYPT_WEP is not set
+# CONFIG_IEEE80211_CRYPT_CCMP is not set
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -358,14 +436,18 @@ CONFIG_DEFAULT_TCP_CONG="cubic"
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
# CONFIG_SYS_HYPERVISOR is not set
-# CONFIG_CONNECTOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
CONFIG_MTD=y
# CONFIG_MTD_DEBUG is not set
# CONFIG_MTD_CONCAT is not set
CONFIG_MTD_PARTITIONS=y
-# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
CONFIG_MTD_CMDLINE_PARTS=y
# CONFIG_MTD_AFS_PARTS is not set
# CONFIG_MTD_AR7_PARTS is not set
@@ -405,11 +487,11 @@ CONFIG_MTD_CFI_I1=y
# CONFIG_MTD_CFI_I4 is not set
# CONFIG_MTD_CFI_I8 is not set
# CONFIG_MTD_OTP is not set
-CONFIG_MTD_CFI_INTELEXT=y
-# CONFIG_MTD_CFI_AMDSTD is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
# CONFIG_MTD_CFI_STAA is not set
CONFIG_MTD_CFI_UTIL=y
-# CONFIG_MTD_RAM is not set
+CONFIG_MTD_RAM=y
# CONFIG_MTD_ROM is not set
# CONFIG_MTD_ABSENT is not set
# CONFIG_MTD_XIP is not set
@@ -418,16 +500,16 @@ CONFIG_MTD_CFI_UTIL=y
# Mapping drivers for chip access
#
# CONFIG_MTD_COMPLEX_MAPPINGS is not set
-CONFIG_MTD_PHYSMAP=y
-CONFIG_MTD_PHYSMAP_START=0x00000000
-CONFIG_MTD_PHYSMAP_LEN=0x0
-CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PHYSMAP is not set
# CONFIG_MTD_ARM_INTEGRATOR is not set
# CONFIG_MTD_PLATRAM is not set
+CONFIG_MTD_MXC=y
#
# Self-contained MTD device drivers
#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
# CONFIG_MTD_SLRAM is not set
# CONFIG_MTD_PHRAM is not set
# CONFIG_MTD_MTDRAM is not set
@@ -439,22 +521,47 @@ CONFIG_MTD_PHYSMAP_BANKWIDTH=2
# CONFIG_MTD_DOC2000 is not set
# CONFIG_MTD_DOC2001 is not set
# CONFIG_MTD_DOC2001PLUS is not set
-# CONFIG_MTD_NAND is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS 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_MXC=y
+# CONFIG_MTD_NAND_MXC_SWECC is not set
+# CONFIG_MTD_NAND_MXC_FORCE_CE is not set
+# CONFIG_MTD_NAND_MXC_ECC_CORRECTION_OPTION2 is not set
+# CONFIG_MXC_NAND_LOW_LEVEL_ERASE is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
# CONFIG_MTD_ONENAND is not set
#
# UBI - Unsorted block images
#
# CONFIG_MTD_UBI is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
# CONFIG_PARPORT is not set
CONFIG_BLK_DEV=y
# CONFIG_BLK_DEV_COW_COMMON is not set
-# CONFIG_BLK_DEV_LOOP is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
# CONFIG_BLK_DEV_NBD is not set
-# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
-# CONFIG_MISC_DEVICES is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -462,10 +569,49 @@ CONFIG_HAVE_IDE=y
# SCSI device support
#
# CONFIG_RAID_ATTRS is not set
-# CONFIG_SCSI is not set
-# CONFIG_SCSI_DMA is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
# CONFIG_SCSI_NETLINK is not set
-# CONFIG_ATA is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+CONFIG_ATA=m
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_PMP is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_MV is not set
+# CONFIG_PATA_PLATFORM is not set
+CONFIG_PATA_FSL=m
# CONFIG_MD is not set
CONFIG_NETDEVICES=y
# CONFIG_NETDEVICES_MULTIQUEUE is not set
@@ -477,16 +623,20 @@ CONFIG_NETDEVICES=y
# CONFIG_VETH is not set
# CONFIG_PHYLIB is not set
CONFIG_NET_ETHERNET=y
-# CONFIG_MII is not set
+CONFIG_MII=y
# CONFIG_AX88796 is not set
# CONFIG_SMC91X is not set
# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
# CONFIG_IBM_NEW_EMAC_ZMII is not set
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
# CONFIG_B44 is not set
-# CONFIG_FEC_OLD is not set
+CONFIG_CS89x0=y
+# CONFIG_FEC is not set
# CONFIG_NETDEV_1000 is not set
# CONFIG_NETDEV_10000 is not set
@@ -496,6 +646,15 @@ CONFIG_NET_ETHERNET=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
# CONFIG_WAN is not set
# CONFIG_PPP is not set
# CONFIG_SLIP is not set
@@ -522,20 +681,30 @@ CONFIG_INPUT_EVDEV=y
#
# Input Device Drivers
#
-# CONFIG_INPUT_KEYBOARD is not set
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_MXC=y
# CONFIG_INPUT_MOUSE is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
# CONFIG_TOUCHSCREEN_FUJITSU is not set
# CONFIG_TOUCHSCREEN_GUNZE is not set
# CONFIG_TOUCHSCREEN_ELO is not set
# CONFIG_TOUCHSCREEN_MTOUCH is not set
# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_TOUCHSCREEN_MXC=y
# CONFIG_TOUCHSCREEN_PENMOUNT is not set
# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
# CONFIG_INPUT_MISC is not set
#
@@ -547,46 +716,128 @@ CONFIG_INPUT_TOUCHSCREEN=y
#
# Character devices
#
-# CONFIG_VT is not set
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
CONFIG_DEVKMEM=y
# CONFIG_SERIAL_NONSTANDARD is not set
#
# Serial drivers
#
-# CONFIG_SERIAL_8250 is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=1
+CONFIG_SERIAL_8250_RUNTIME_UARTS=1
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
#
# Non-8250 serial port support
#
-# CONFIG_SERIAL_IMX is not set
+CONFIG_SERIAL_MXC=y
+CONFIG_SERIAL_MXC_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_UNIX98_PTYS=y
-# CONFIG_LEGACY_PTYS is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
-# CONFIG_HW_RANDOM is not set
+CONFIG_HW_RANDOM=y
# CONFIG_NVRAM is not set
# CONFIG_R3964 is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
-# CONFIG_I2C is not set
-# CONFIG_SPI is not set
-CONFIG_HAVE_GPIO_LIB=y
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_MXC=y
+# CONFIG_I2C_MXC_HS is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_I2C_SLAVE is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_MXC=y
+# CONFIG_SPI_MXC_TEST_LOOPBACK is not set
+CONFIG_SPI_MXC_SELECT1=y
+CONFIG_SPI_MXC_SELECT2=y
+# CONFIG_SPI_MXC_SELECT3 is not set
#
-# GPIO Support
+# SPI Protocol Masters
#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_W1=m
+CONFIG_W1_CON=y
#
-# I2C GPIO expanders:
+# 1-wire Bus Masters
#
+# CONFIG_W1_MASTER_DS2490 is not set
+# CONFIG_W1_MASTER_DS2482 is not set
+CONFIG_W1_MASTER_MXC=m
+# CONFIG_W1_MASTER_DS1WM is not set
#
-# SPI GPIO expanders:
+# 1-wire Slaves
#
-# CONFIG_W1 is not set
+# CONFIG_W1_SLAVE_THERM is not set
+# CONFIG_W1_SLAVE_SMEM is not set
+# CONFIG_W1_SLAVE_DS2751 is not set
+CONFIG_W1_SLAVE_DS2433=m
+# CONFIG_W1_SLAVE_DS2433_CRC is not set
+# CONFIG_W1_SLAVE_DS2760 is not set
# CONFIG_POWER_SUPPLY is not set
# CONFIG_HWMON is not set
-# CONFIG_WATCHDOG is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_MXC_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
#
# Sonics Silicon Backplane
@@ -599,7 +850,6 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_MFD_SM501 is not set
# CONFIG_MFD_ASIC3 is not set
-# CONFIG_HTC_EGPIO is not set
# CONFIG_HTC_PASIC3 is not set
#
@@ -609,22 +859,123 @@ CONFIG_SSB_POSSIBLE=y
#
# Multimedia core support
#
-# CONFIG_VIDEO_DEV is not set
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
# CONFIG_DVB_CORE is not set
-# CONFIG_VIDEO_MEDIA is not set
+CONFIG_VIDEO_MEDIA=y
#
# Multimedia drivers
#
-# CONFIG_DAB is not set
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_MXC_CAMERA=y
+
+#
+# MXC Camera/V4L2 PRP Features support
+#
+CONFIG_VIDEO_MXC_EMMA_CAMERA=y
+# CONFIG_VIDEO_MXC_CSI_DMA is not set
+# CONFIG_MXC_CAMERA_MC521DA is not set
+CONFIG_MXC_CAMERA_MICRON111=y
+# CONFIG_MXC_CAMERA_OV2640 is not set
+# CONFIG_MXC_TVIN_ADV7180 is not set
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_EMMA_OUTPUT=y
+CONFIG_VIDEO_MXC_OUTPUT_FBSYNC=y
+CONFIG_VIDEO_MXC_OPL=y
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_USB_VIDEO_CLASS is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+# CONFIG_USB_W9968CF is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_SOC_CAMERA is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_SI470X is not set
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
#
# Graphics support
#
# CONFIG_VGASTATE is not set
# CONFIG_VIDEO_OUTPUT_CONTROL is not set
-# CONFIG_FB is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_MXC=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+# CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
+CONFIG_FB_MXC_TVOUT=y
+# CONFIG_FB_MXC_TVOUT_CH7024 is not set
+# CONFIG_FB_MXC_ASYNC_PANEL is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_MXC=y
+CONFIG_BACKLIGHT_MXC_LCDC=y
+CONFIG_BACKLIGHT_MXC_PMIC=y
#
# Display device support
@@ -632,21 +983,419 @@ CONFIG_SSB_POSSIBLE=y
# CONFIG_DISPLAY_SUPPORT is not set
#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
# Sound
#
-# CONFIG_SOUND is not set
-# CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
-# CONFIG_MMC is not set
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+# CONFIG_SND_MXC_SPDIF is not set
+CONFIG_SND_MXC_PMIC=y
+# CONFIG_HEADSET_DETECT_ENABLE is not set
+
+#
+# SPI devices
+#
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+# CONFIG_SND_MXC_SOC is not set
+# CONFIG_SND_MXC_SOC_IRAM is not set
+# CONFIG_SND_SOC_IMX_3STACK_WM8350 is not set
+# CONFIG_SND_SOC_IMX_3STACK_AK4647 is not set
+# CONFIG_SND_SOC_IMX_3STACK_WM8580 is not set
+# CONFIG_SND_SOC_IMX_3STACK_WM8903 is not set
+
+#
+# ALSA SoC audio for Freescale SOCs
+#
+
+#
+# SoC Audio for the Texas Instruments OMAP
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ARC=y
+CONFIG_USB_EHCI_ARC_H1=y
+# CONFIG_USB_EHCI_ARC_H2 is not set
+CONFIG_USB_EHCI_ARC_OTG=y
+# CONFIG_USB_STATIC_IRAM is not set
+# CONFIG_USB_EHCI_FSL_MC13783 is not set
+CONFIG_USB_EHCI_FSL_1301=y
+# CONFIG_USB_EHCI_FSL_1504 is not set
+# CONFIG_USB_EHCI_FSL_UTMI is not set
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+CONFIG_USB_MON=y
+
+#
+# Belcarra USBLAN Networking for USB
+#
+# CONFIG_USB_USBLAN is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+CONFIG_USB_GADGET_ARC=y
+CONFIG_USB_ARC=m
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+# CONFIG_USB_GADGET_DUALSPEED is not set
+CONFIG_USB_GADGET_ARC_OTG=y
+# CONFIG_USB_GADGET_FSL_MC13783 is not set
+CONFIG_USB_GADGET_FSL_1301=y
+# CONFIG_USB_GADGET_FSL_1504 is not set
+# CONFIG_USB_GADGET_FSL_UTMI is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SPI is not set
+CONFIG_MMC_MXC=y
+# CONFIG_MMC_IMX_ESDHCI is not set
+# CONFIG_MMC_IMX_ESDHCI_PIO_MODE is not set
# CONFIG_NEW_LEDS is not set
CONFIG_RTC_LIB=y
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_MXC=y
+# CONFIG_RTC_DRV_MXC_V2 is not set
# CONFIG_UIO is not set
#
+# MXC support drivers
+#
+
+#
+# MXC SSI support
+#
+CONFIG_MXC_SSI=y
+
+#
+# MXC Digital Audio Multiplexer support
+#
+CONFIG_MXC_DAM=y
+
+#
+# MXC PMIC support
+#
+CONFIG_MXC_PMIC=y
+CONFIG_MXC_PMIC_MC13783=y
+# CONFIG_MXC_PMIC_MC13892 is not set
+# CONFIG_MXC_PMIC_MC9SDZ60 is not set
+CONFIG_MXC_PMIC_CHARDEV=y
+
+#
+# MXC PMIC Client Drivers
+#
+CONFIG_MXC_MC13783_ADC=y
+CONFIG_MXC_MC13783_AUDIO=y
+CONFIG_MXC_MC13783_RTC=y
+CONFIG_MXC_MC13783_LIGHT=y
+CONFIG_MXC_MC13783_BATTERY=y
+CONFIG_MXC_MC13783_CONNECTIVITY=y
+CONFIG_MXC_MC13783_POWER=y
+
+#
+# Advanced Power Management devices
+#
+# CONFIG_MX27_DPTC is not set
+
+#
+# MXC Security Drivers
+#
+CONFIG_MXC_SECURITY_SCC=y
+# CONFIG_SCC_DEBUG is not set
+
+#
+# SAHARA2 Security Hardware Support
+#
+CONFIG_MXC_SAHARA=y
+CONFIG_MXC_SAHARA_USER_MODE=y
+# CONFIG_MXC_SAHARA_POLL_MODE is not set
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+
+#
+# MXC HARDWARE EVENT
+#
+CONFIG_MXC_HWEVENT=y
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+CONFIG_MXC_VPU=y
+# CONFIG_MXC_VPU_DEBUG is not set
+
+#
+# MXC Asynchronous Sample Rate Converter support
+#
+
+#
+# MXC Bluetooth support
+#
+
+#
+# Broadcom GPS ioctrl support
+#
+
+#
+# MXC Media Local Bus Driver
+#
+
+#
# File systems
#
-# CONFIG_EXT2_FS is not set
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
# CONFIG_EXT3_FS is not set
# CONFIG_EXT4DEV_FS is not set
# CONFIG_REISERFS_FS is not set
@@ -654,11 +1403,12 @@ CONFIG_RTC_LIB=y
# CONFIG_FS_POSIX_ACL is not set
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
-# CONFIG_DNOTIFY is not set
-# CONFIG_INOTIFY is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
# CONFIG_QUOTA is not set
# CONFIG_AUTOFS_FS is not set
-# CONFIG_AUTOFS4_FS is not set
+CONFIG_AUTOFS4_FS=m
# CONFIG_FUSE_FS is not set
#
@@ -670,8 +1420,11 @@ CONFIG_RTC_LIB=y
#
# DOS/FAT/NT Filesystems
#
-# CONFIG_MSDOS_FS is not set
-# CONFIG_VFAT_FS is not set
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
# CONFIG_NTFS_FS is not set
#
@@ -706,7 +1459,7 @@ CONFIG_JFFS2_ZLIB=y
# CONFIG_JFFS2_LZO is not set
CONFIG_JFFS2_RTIME=y
# CONFIG_JFFS2_RUBIN is not set
-# CONFIG_CRAMFS is not set
+CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
# CONFIG_HPFS_FS is not set
@@ -741,10 +1494,10 @@ CONFIG_SUNRPC=y
CONFIG_MSDOS_PARTITION=y
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
-CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_CODEPAGE_437=y
# CONFIG_NLS_CODEPAGE_737 is not set
# CONFIG_NLS_CODEPAGE_775 is not set
-CONFIG_NLS_CODEPAGE_850=m
+# CONFIG_NLS_CODEPAGE_850 is not set
# CONFIG_NLS_CODEPAGE_852 is not set
# CONFIG_NLS_CODEPAGE_855 is not set
# CONFIG_NLS_CODEPAGE_857 is not set
@@ -764,7 +1517,7 @@ CONFIG_NLS_CODEPAGE_850=m
# CONFIG_NLS_ISO8859_8 is not set
# CONFIG_NLS_CODEPAGE_1250 is not set
# CONFIG_NLS_CODEPAGE_1251 is not set
-# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ASCII=m
CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_2 is not set
# CONFIG_NLS_ISO8859_3 is not set
@@ -775,10 +1528,10 @@ CONFIG_NLS_ISO8859_1=y
# CONFIG_NLS_ISO8859_9 is not set
# CONFIG_NLS_ISO8859_13 is not set
# CONFIG_NLS_ISO8859_14 is not set
-CONFIG_NLS_ISO8859_15=m
+# CONFIG_NLS_ISO8859_15 is not set
# CONFIG_NLS_KOI8_R is not set
# CONFIG_NLS_KOI8_U is not set
-# CONFIG_NLS_UTF8 is not set
+CONFIG_NLS_UTF8=m
# CONFIG_DLM is not set
#
@@ -793,6 +1546,8 @@ CONFIG_FRAME_WARN=1024
# CONFIG_DEBUG_FS is not set
# CONFIG_HEADERS_CHECK is not set
# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
# CONFIG_DEBUG_BUGVERBOSE is not set
CONFIG_FRAME_POINTER=y
# CONFIG_SAMPLES is not set
@@ -804,7 +1559,80 @@ CONFIG_FRAME_POINTER=y
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
-# CONFIG_CRYPTO is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
#
# Library routines
@@ -812,7 +1640,7 @@ CONFIG_FRAME_POINTER=y
CONFIG_BITREVERSE=y
# CONFIG_GENERIC_FIND_FIRST_BIT is not set
# CONFIG_GENERIC_FIND_NEXT_BIT is not set
-# CONFIG_CRC_CCITT is not set
+CONFIG_CRC_CCITT=m
# CONFIG_CRC16 is not set
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
diff --git a/arch/arm/configs/imx31_3stack_defconfig b/arch/arm/configs/imx31_3stack_defconfig
new file mode 100644
index 000000000000..0ca806b2ea33
--- /dev/null
+++ b/arch/arm/configs/imx31_3stack_defconfig
@@ -0,0 +1,1750 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.26
+# Tue Sep 16 10:19:21 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_OPROFILE_ARMV6=y
+CONFIG_OPROFILE_ARM11_CORE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+CONFIG_ARCH_MXC=y
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX37 is not set
+# CONFIG_ARCH_MX35 is not set
+# CONFIG_ARCH_MX51 is not set
+CONFIG_ARCH_MX3=y
+# CONFIG_ARCH_MX27 is not set
+# CONFIG_ARCH_MX21 is not set
+CONFIG_ARCH_MXC_HAS_NFC_V1=y
+CONFIG_I2C_MXC_SELECT1=y
+# CONFIG_I2C_MXC_SELECT2 is not set
+
+#
+# MX3 Options
+#
+CONFIG_MX3_OPTIONS=y
+# CONFIG_MACH_MX31ADS is not set
+CONFIG_MACH_MX31_3DS=y
+# CONFIG_MX3_DOZE_DURING_IDLE is not set
+CONFIG_MXC_SDMA_API=y
+
+#
+# SDMA options
+#
+# CONFIG_SDMA_IRAM is not set
+CONFIG_ARCH_MXC_HAS_NFC_V2=y
+
+#
+# Device options
+#
+# CONFIG_I2C_MXC_SELECT3 is not set
+CONFIG_ARCH_HAS_EVTMON=y
+CONFIG_DMA_ZONE_SIZE=24
+CONFIG_ISP1504_MXC=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_ARM926T is not set
+CONFIG_CPU_V6=y
+# CONFIG_CPU_32v6K is not set
+# CONFIG_CPU_V7 is not set
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_CACHE_L2X0=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+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_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_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
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+# CONFIG_NET_SCH_CBQ is not set
+# CONFIG_NET_SCH_HTB is not set
+# CONFIG_NET_SCH_HFSC is not set
+# CONFIG_NET_SCH_PRIO is not set
+# CONFIG_NET_SCH_RED is not set
+# CONFIG_NET_SCH_SFQ is not set
+# CONFIG_NET_SCH_TEQL is not set
+# CONFIG_NET_SCH_TBF is not set
+# CONFIG_NET_SCH_GRED is not set
+# CONFIG_NET_SCH_DSMARK is not set
+# CONFIG_NET_SCH_NETEM is not set
+
+#
+# Classification
+#
+# CONFIG_NET_CLS_BASIC is not set
+# CONFIG_NET_CLS_TCINDEX is not set
+# CONFIG_NET_CLS_ROUTE4 is not set
+# CONFIG_NET_CLS_FW is not set
+# CONFIG_NET_CLS_U32 is not set
+# CONFIG_NET_CLS_RSVP is not set
+# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_CLS_FLOW is not set
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_SCH_FIFO=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+# CONFIG_IEEE80211_CRYPT_WEP is not set
+# CONFIG_IEEE80211_CRYPT_CCMP is not set
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+# CONFIG_MTD_MXC is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS 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_MXC=y
+CONFIG_MTD_NAND_MXC_V2=y
+# CONFIG_MTD_NAND_MXC_SWECC is not set
+# CONFIG_MTD_NAND_MXC_FORCE_CE is not set
+# CONFIG_MTD_NAND_MXC_ECC_CORRECTION_OPTION2 is not set
+# CONFIG_MXC_NAND_LOW_LEVEL_ERASE is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+
+#
+# Voltage and Current regulators
+#
+CONFIG_REGULATOR_API=y
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+CONFIG_REGULATOR_MC13783=y
+# CONFIG_REGULATOR_WM8350 is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+CONFIG_ATA=m
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_PMP is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_MV is not set
+# CONFIG_PATA_PLATFORM is not set
+CONFIG_PATA_FSL=m
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+CONFIG_USB_USBNET=m
+# CONFIG_USB_NET_AX8817X is not set
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_GL620A is not set
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_POLLDEV=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_MXC=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_TOUCHSCREEN_MXC=y
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_FM_SI4702=m
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_MXC=y
+CONFIG_SERIAL_MXC_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_MXC=y
+# CONFIG_I2C_MXC_HS is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_I2C_SLAVE is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_MXC=y
+# CONFIG_SPI_MXC_TEST_LOOPBACK is not set
+CONFIG_SPI_MXC_SELECT1=y
+CONFIG_SPI_MXC_SELECT2=y
+# CONFIG_SPI_MXC_SELECT3 is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 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_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 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_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+CONFIG_MXC_MMA7450=m
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_MXC_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_PASIC3 is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# Encoders/decoders and other helper chips
+#
+
+#
+# Audio decoders
+#
+# CONFIG_VIDEO_TVAUDIO is not set
+# CONFIG_VIDEO_TDA7432 is not set
+# CONFIG_VIDEO_TDA9840 is not set
+# CONFIG_VIDEO_TDA9875 is not set
+# CONFIG_VIDEO_TEA6415C is not set
+# CONFIG_VIDEO_TEA6420 is not set
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS5345 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_M52790 is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_VP27SMPX is not set
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_BT819 is not set
+# CONFIG_VIDEO_BT856 is not set
+# CONFIG_VIDEO_BT866 is not set
+# CONFIG_VIDEO_KS0127 is not set
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_TCM825X is not set
+# CONFIG_VIDEO_SAA7110 is not set
+# CONFIG_VIDEO_SAA7111 is not set
+# CONFIG_VIDEO_SAA7114 is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_SAA7191 is not set
+# CONFIG_VIDEO_TVP5150 is not set
+# CONFIG_VIDEO_VPX3220 is not set
+
+#
+# Video and audio decoders
+#
+# CONFIG_VIDEO_CX25840 is not set
+
+#
+# MPEG video encoders
+#
+# CONFIG_VIDEO_CX2341X is not set
+
+#
+# Video encoders
+#
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_SAA7185 is not set
+# CONFIG_VIDEO_ADV7170 is not set
+# CONFIG_VIDEO_ADV7175 is not set
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_MXC_CAMERA=m
+
+#
+# MXC Camera/V4L2 PRP Features support
+#
+CONFIG_VIDEO_MXC_IPU_CAMERA=y
+# CONFIG_MXC_CAMERA_MC521DA is not set
+# CONFIG_MXC_CAMERA_MICRON111 is not set
+CONFIG_MXC_CAMERA_OV2640=m
+# CONFIG_MXC_TVIN_ADV7180 is not set
+CONFIG_MXC_IPU_PRP_VF_SDC=m
+CONFIG_MXC_IPU_PRP_ENC=m
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set
+# CONFIG_VIDEO_MXC_OPL is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_USB_VIDEO_CLASS is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+# CONFIG_USB_W9968CF is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_MXC=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL=y
+# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_TVOUT is not set
+CONFIG_FB_MXC_TVOUT_CH7024=y
+# CONFIG_FB_MXC_ASYNC_PANEL is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_MXC=y
+CONFIG_BACKLIGHT_MXC_IPU=y
+CONFIG_BACKLIGHT_MXC_PMIC=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+# CONFIG_SND_MXC_SPDIF is not set
+CONFIG_SND_MXC_PMIC=y
+# CONFIG_SND_MXC_PLAYBACK_MIXING is not set
+# CONFIG_HEADSET_DETECT_ENABLE is not set
+
+#
+# SPI devices
+#
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+# CONFIG_SND_MXC_SOC is not set
+# CONFIG_SND_MXC_SOC_IRAM is not set
+# CONFIG_SND_SOC_IMX_3STACK_WM8350 is not set
+# CONFIG_SND_SOC_IMX_3STACK_AK4647 is not set
+# CONFIG_SND_SOC_IMX_3STACK_WM8580 is not set
+# CONFIG_SND_SOC_IMX_3STACK_WM8903 is not set
+
+#
+# ALSA SoC audio for Freescale SOCs
+#
+
+#
+# SoC Audio for the Texas Instruments OMAP
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ARC=y
+# CONFIG_USB_EHCI_ARC_H1 is not set
+CONFIG_USB_EHCI_ARC_H2=y
+CONFIG_USB_EHCI_ARC_OTG=y
+# CONFIG_USB_STATIC_IRAM is not set
+# CONFIG_USB_EHCI_FSL_MC13783 is not set
+# CONFIG_USB_EHCI_FSL_1301 is not set
+CONFIG_USB_EHCI_FSL_1504=y
+# CONFIG_USB_EHCI_FSL_UTMI is not set
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+CONFIG_USB_MON=y
+
+#
+# Belcarra USBLAN Networking for USB
+#
+# CONFIG_USB_USBLAN is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+CONFIG_USB_GADGET_ARC=y
+CONFIG_USB_ARC=m
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_GADGET_ARC_OTG=y
+# CONFIG_USB_GADGET_FSL_MC13783 is not set
+# CONFIG_USB_GADGET_FSL_1301 is not set
+CONFIG_USB_GADGET_FSL_1504=y
+# CONFIG_USB_GADGET_FSL_UTMI is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+CONFIG_SDIO_UNIFI_FS=m
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SPI is not set
+CONFIG_MMC_MXC=m
+# CONFIG_MMC_IMX_ESDHCI is not set
+# CONFIG_MMC_IMX_ESDHCI_PIO_MODE is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_MXC=y
+# CONFIG_RTC_DRV_MXC_V2 is not set
+# CONFIG_UIO is not set
+
+#
+# MXC support drivers
+#
+CONFIG_MXC_IPU=y
+CONFIG_MXC_IPU_V1=y
+CONFIG_MXC_IPU_PF=y
+
+#
+# MXC SSI support
+#
+CONFIG_MXC_SSI=y
+
+#
+# MXC Digital Audio Multiplexer support
+#
+CONFIG_MXC_DAM=y
+
+#
+# MXC PMIC support
+#
+CONFIG_MXC_PMIC=y
+CONFIG_MXC_PMIC_MC13783=y
+# CONFIG_MXC_PMIC_MC13892 is not set
+# CONFIG_MXC_PMIC_MC9SDZ60 is not set
+CONFIG_MXC_PMIC_CHARDEV=y
+
+#
+# MXC PMIC Client Drivers
+#
+CONFIG_MXC_MC13783_ADC=y
+CONFIG_MXC_MC13783_AUDIO=y
+CONFIG_MXC_MC13783_RTC=y
+CONFIG_MXC_MC13783_LIGHT=y
+CONFIG_MXC_MC13783_BATTERY=y
+CONFIG_MXC_MC13783_CONNECTIVITY=y
+CONFIG_MXC_MC13783_POWER=y
+
+#
+# Advanced Power Management devices
+#
+
+#
+# MXC Security Drivers
+#
+CONFIG_MXC_SECURITY_SCC=y
+# CONFIG_SCC_DEBUG is not set
+CONFIG_MXC_SECURITY_RNG=y
+# CONFIG_MXC_RNG_TEST_DRIVER is not set
+# CONFIG_MXC_RNG_DEBUG is not set
+CONFIG_MXC_SECURITY_CORE=y
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+CONFIG_MXC_HMP4E=y
+# CONFIG_MXC_HMP4E_DEBUG is not set
+
+#
+# MXC HARDWARE EVENT
+#
+CONFIG_MXC_HWEVENT=y
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+# CONFIG_MXC_VPU is not set
+
+#
+# MXC Asynchronous Sample Rate Converter support
+#
+
+#
+# MXC Bluetooth support
+#
+CONFIG_MXC_BLUETOOTH=m
+
+#
+# Broadcom GPS ioctrl support
+#
+CONFIG_GPS_IOCTRL=m
+
+#
+# MXC Media Local Bus Driver
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/imx31ads_defconfig b/arch/arm/configs/imx31ads_defconfig
new file mode 100644
index 000000000000..02834ddedebc
--- /dev/null
+++ b/arch/arm/configs/imx31ads_defconfig
@@ -0,0 +1,1707 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.26
+# Tue Sep 16 10:19:21 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_OPROFILE_ARMV6=y
+CONFIG_OPROFILE_ARM11_CORE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+CONFIG_ARCH_MXC=y
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX37 is not set
+# CONFIG_ARCH_MX35 is not set
+# CONFIG_ARCH_MX51 is not set
+CONFIG_ARCH_MX3=y
+# CONFIG_ARCH_MX27 is not set
+# CONFIG_ARCH_MX21 is not set
+CONFIG_ARCH_MXC_HAS_NFC_V1=y
+CONFIG_I2C_MXC_SELECT1=y
+# CONFIG_I2C_MXC_SELECT2 is not set
+
+#
+# MX3 Options
+#
+CONFIG_MX3_OPTIONS=y
+CONFIG_MACH_MX31ADS=y
+# CONFIG_MACH_MX31_3DS is not set
+# CONFIG_MX3_DOZE_DURING_IDLE is not set
+CONFIG_MXC_SDMA_API=y
+
+#
+# SDMA options
+#
+# CONFIG_SDMA_IRAM is not set
+CONFIG_ARCH_MXC_HAS_NFC_V2=y
+
+#
+# Device options
+#
+# CONFIG_I2C_MXC_SELECT3 is not set
+CONFIG_ARCH_HAS_EVTMON=y
+CONFIG_DMA_ZONE_SIZE=24
+CONFIG_ISP1504_MXC=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_ARM926T is not set
+CONFIG_CPU_V6=y
+# CONFIG_CPU_32v6K is not set
+# CONFIG_CPU_V7 is not set
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_CACHE_L2X0=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+# CONFIG_PCMCIA_IOCTL is not set
+
+#
+# PC-card bridges
+#
+CONFIG_PCMCIA_MX31ADS=m
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_CMDLINE="noinitrd console=ttymxc0 root=/dev/mtdblock2 rw ip=off"
+# CONFIG_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_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
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+CONFIG_IRDA=m
+
+#
+# IrDA protocols
+#
+CONFIG_IRLAN=m
+CONFIG_IRCOMM=m
+# CONFIG_IRDA_ULTRA is not set
+
+#
+# IrDA options
+#
+CONFIG_IRDA_CACHE_LAST_LSAP=y
+CONFIG_IRDA_FAST_RR=y
+# CONFIG_IRDA_DEBUG is not set
+
+#
+# Infrared-port device drivers
+#
+
+#
+# SIR device drivers
+#
+CONFIG_IRTTY_SIR=m
+
+#
+# Dongle support
+#
+# CONFIG_DONGLE is not set
+# CONFIG_KINGSUN_DONGLE is not set
+# CONFIG_KSDAZZLE_DONGLE is not set
+# CONFIG_KS959_DONGLE is not set
+
+#
+# FIR device drivers
+#
+# CONFIG_USB_IRDA is not set
+# CONFIG_SIGMATEL_FIR is not set
+# CONFIG_MCS_FIR is not set
+CONFIG_MXC_FIR=m
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+# CONFIG_IEEE80211_CRYPT_WEP is not set
+# CONFIG_IEEE80211_CRYPT_CCMP is not set
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+CONFIG_MTD_REDBOOT_PARTS=y
+CONFIG_MTD_REDBOOT_DIRECTORY_BLOCK=-1
+# CONFIG_MTD_REDBOOT_PARTS_UNALLOCATED is not set
+# CONFIG_MTD_REDBOOT_PARTS_READONLY is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+CONFIG_MTD_CFI_ADV_OPTIONS=y
+CONFIG_MTD_CFI_NOSWAP=y
+# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
+# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
+CONFIG_MTD_CFI_GEOMETRY=y
+# CONFIG_MTD_MAP_BANK_WIDTH_1 is not set
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+# CONFIG_MTD_CFI_I2 is not set
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_OTP is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_RAM=y
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+CONFIG_MTD_MXC=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS 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_MXC=y
+CONFIG_MTD_NAND_MXC_V2=y
+# CONFIG_MTD_NAND_MXC_SWECC is not set
+# CONFIG_MTD_NAND_MXC_FORCE_CE is not set
+# CONFIG_MTD_NAND_MXC_ECC_CORRECTION_OPTION2 is not set
+# CONFIG_MXC_NAND_LOW_LEVEL_ERASE is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+
+#
+# Voltage and Current regulators
+#
+CONFIG_REGULATOR_API=y
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+CONFIG_REGULATOR_MC13783=y
+# CONFIG_REGULATOR_WM8350 is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=16
+CONFIG_BLK_DEV_RAM_SIZE=16384
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+CONFIG_ATA=m
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_PMP is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_MV is not set
+# CONFIG_PATA_PCMCIA is not set
+# CONFIG_PATA_PLATFORM is not set
+CONFIG_PATA_FSL=m
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+CONFIG_CS89x0=y
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=m
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_MXC=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_TOUCHSCREEN_MXC=y
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_SERIAL_8250_CS is not set
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+CONFIG_SERIAL_8250_EXTENDED=y
+# CONFIG_SERIAL_8250_MANY_PORTS is not set
+# CONFIG_SERIAL_8250_SHARE_IRQ is not set
+# CONFIG_SERIAL_8250_DETECT_IRQ is not set
+# CONFIG_SERIAL_8250_RSA is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_MXC=y
+CONFIG_SERIAL_MXC_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_IPWIRELESS is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_MXC=y
+# CONFIG_I2C_MXC_HS is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_I2C_SLAVE is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_MXC=y
+# CONFIG_SPI_MXC_TEST_LOOPBACK is not set
+# CONFIG_SPI_MXC_SELECT1 is not set
+CONFIG_SPI_MXC_SELECT2=y
+# CONFIG_SPI_MXC_SELECT3 is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_W1=y
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2490 is not set
+# CONFIG_W1_MASTER_DS2482 is not set
+CONFIG_W1_MASTER_MXC=y
+# CONFIG_W1_MASTER_DS1WM is not set
+
+#
+# 1-wire Slaves
+#
+# CONFIG_W1_SLAVE_THERM is not set
+# CONFIG_W1_SLAVE_SMEM is not set
+# CONFIG_W1_SLAVE_DS2751 is not set
+CONFIG_W1_SLAVE_DS2433=y
+# CONFIG_W1_SLAVE_DS2433_CRC is not set
+# CONFIG_W1_SLAVE_DS2760 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_MXC_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_PASIC3 is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_MXC_CAMERA=y
+
+#
+# MXC Camera/V4L2 PRP Features support
+#
+CONFIG_VIDEO_MXC_IPU_CAMERA=y
+# CONFIG_MXC_CAMERA_MC521DA is not set
+CONFIG_MXC_CAMERA_MICRON111=y
+# CONFIG_MXC_CAMERA_OV2640 is not set
+# CONFIG_MXC_TVIN_ADV7180 is not set
+CONFIG_MXC_IPU_PRP_VF_SDC=y
+CONFIG_MXC_IPU_PRP_ENC=y
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set
+# CONFIG_VIDEO_MXC_OPL is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_USB_VIDEO_CLASS is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+# CONFIG_USB_W9968CF is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_SOC_CAMERA is not set
+CONFIG_RADIO_ADAPTERS=y
+# CONFIG_USB_DSBR is not set
+# CONFIG_USB_SI470X is not set
+CONFIG_DAB=y
+# CONFIG_USB_DABUSB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_MXC=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+# CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
+CONFIG_FB_MXC_TVOUT=y
+# CONFIG_FB_MXC_TVOUT_CH7024 is not set
+# CONFIG_FB_MXC_ASYNC_PANEL is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_MXC=y
+CONFIG_BACKLIGHT_MXC_IPU=y
+CONFIG_BACKLIGHT_MXC_PMIC=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+# CONFIG_FONTS is not set
+CONFIG_FONT_8x8=y
+CONFIG_FONT_8x16=y
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+# CONFIG_SND_MXC_SPDIF is not set
+CONFIG_SND_MXC_PMIC=y
+# CONFIG_SND_MXC_PLAYBACK_MIXING is not set
+# CONFIG_HEADSET_DETECT_ENABLE is not set
+
+#
+# SPI devices
+#
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# PCMCIA devices
+#
+# CONFIG_SND_VXPOCKET is not set
+# CONFIG_SND_PDAUDIOCF is not set
+
+#
+# System on Chip audio support
+#
+# CONFIG_SND_SOC is not set
+# CONFIG_SND_MXC_SOC is not set
+# CONFIG_SND_MXC_SOC_IRAM is not set
+# CONFIG_SND_SOC_IMX_3STACK_WM8350 is not set
+# CONFIG_SND_SOC_IMX_3STACK_AK4647 is not set
+# CONFIG_SND_SOC_IMX_3STACK_WM8580 is not set
+# CONFIG_SND_SOC_IMX_3STACK_WM8903 is not set
+
+#
+# ALSA SoC audio for Freescale SOCs
+#
+
+#
+# SoC Audio for the Texas Instruments OMAP
+#
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ARC=y
+CONFIG_USB_EHCI_ARC_H1=y
+CONFIG_USB_EHCI_ARC_H2=y
+CONFIG_USB_EHCI_ARC_OTG=y
+# CONFIG_USB_STATIC_IRAM is not set
+# CONFIG_USB_EHCI_FSL_MC13783 is not set
+# CONFIG_USB_EHCI_FSL_1301 is not set
+CONFIG_USB_EHCI_FSL_1504=y
+# CONFIG_USB_EHCI_FSL_UTMI is not set
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+CONFIG_USB_MON=y
+
+#
+# Belcarra USBLAN Networking for USB
+#
+# CONFIG_USB_USBLAN is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+CONFIG_USB_GADGET_ARC=y
+CONFIG_USB_ARC=m
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_GADGET_ARC_OTG=y
+# CONFIG_USB_GADGET_FSL_MC13783 is not set
+# CONFIG_USB_GADGET_FSL_1301 is not set
+CONFIG_USB_GADGET_FSL_1504=y
+# CONFIG_USB_GADGET_FSL_UTMI is not set
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SPI is not set
+CONFIG_MMC_MXC=y
+# CONFIG_MMC_IMX_ESDHCI is not set
+# CONFIG_MMC_IMX_ESDHCI_PIO_MODE is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_MXC=y
+# CONFIG_RTC_DRV_MXC_V2 is not set
+# CONFIG_UIO is not set
+
+#
+# MXC support drivers
+#
+CONFIG_MXC_IPU=y
+CONFIG_MXC_IPU_V1=y
+CONFIG_MXC_IPU_PF=y
+
+#
+# MXC SSI support
+#
+CONFIG_MXC_SSI=y
+
+#
+# MXC Digital Audio Multiplexer support
+#
+CONFIG_MXC_DAM=y
+
+#
+# MXC PMIC support
+#
+CONFIG_MXC_PMIC=y
+CONFIG_MXC_PMIC_MC13783=y
+# CONFIG_MXC_PMIC_MC13892 is not set
+# CONFIG_MXC_PMIC_MC9SDZ60 is not set
+CONFIG_MXC_PMIC_CHARDEV=y
+
+#
+# MXC PMIC Client Drivers
+#
+CONFIG_MXC_MC13783_ADC=y
+CONFIG_MXC_MC13783_AUDIO=y
+CONFIG_MXC_MC13783_RTC=y
+CONFIG_MXC_MC13783_LIGHT=y
+CONFIG_MXC_MC13783_BATTERY=y
+CONFIG_MXC_MC13783_CONNECTIVITY=y
+CONFIG_MXC_MC13783_POWER=y
+
+#
+# Advanced Power Management devices
+#
+
+#
+# MXC Security Drivers
+#
+CONFIG_MXC_SECURITY_SCC=y
+# CONFIG_SCC_DEBUG is not set
+CONFIG_MXC_SECURITY_RNG=y
+# CONFIG_MXC_RNG_TEST_DRIVER is not set
+# CONFIG_MXC_RNG_DEBUG is not set
+CONFIG_MXC_SECURITY_CORE=y
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+CONFIG_MXC_HMP4E=y
+# CONFIG_MXC_HMP4E_DEBUG is not set
+
+#
+# MXC HARDWARE EVENT
+#
+CONFIG_MXC_HWEVENT=y
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+CONFIG_MXC_VPU=y
+# CONFIG_MXC_VPU_DEBUG is not set
+
+#
+# MXC Asynchronous Sample Rate Converter support
+#
+
+#
+# MXC Bluetooth support
+#
+
+#
+# Broadcom GPS ioctrl support
+#
+
+#
+# MXC Media Local Bus Driver
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/imx35_3stack_defconfig b/arch/arm/configs/imx35_3stack_defconfig
new file mode 100644
index 000000000000..7b293e169e4c
--- /dev/null
+++ b/arch/arm/configs/imx35_3stack_defconfig
@@ -0,0 +1,1724 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.26
+# Thu Jan 15 17:18:26 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_OPROFILE_ARMV6=y
+CONFIG_OPROFILE_ARM11_CORE=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+CONFIG_PROFILING=y
+# CONFIG_MARKERS is not set
+CONFIG_OPROFILE=y
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+CONFIG_ARCH_MXC=y
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX37 is not set
+CONFIG_ARCH_MX35=y
+# CONFIG_ARCH_MX51 is not set
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MX27 is not set
+# CONFIG_ARCH_MX25 is not set
+# CONFIG_ARCH_MX21 is not set
+CONFIG_I2C_MXC_SELECT1=y
+# CONFIG_I2C_MXC_SELECT2 is not set
+CONFIG_MXC_SDMA_API=y
+CONFIG_ARCH_MXC_HAS_NFC_V2=y
+CONFIG_ARCH_MXC_HAS_NFC_V2_1=y
+# CONFIG_I2C_MXC_SELECT3 is not set
+# CONFIG_SDMA_IRAM is not set
+
+#
+# MX35 Options
+#
+CONFIG_MX35_OPTIONS=y
+CONFIG_MACH_MX35_3DS=y
+# CONFIG_MACH_MX35EVB is not set
+# CONFIG_MX35_DOZE_DURING_IDLE is not set
+
+#
+# SDMA options
+#
+
+#
+# Device options
+#
+CONFIG_MXC_PSEUDO_IRQS=y
+CONFIG_ARCH_HAS_EVTMON=y
+CONFIG_DMA_ZONE_SIZE=24
+CONFIG_UTMI_MXC=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_ARM926T is not set
+CONFIG_CPU_V6=y
+# CONFIG_CPU_32v6K is not set
+# CONFIG_CPU_V7 is not set
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_CACHE_L2X0=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+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_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# CPU Frequency scaling
+#
+# CONFIG_CPU_FREQ is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_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
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+# CONFIG_NET_SCH_CBQ is not set
+# CONFIG_NET_SCH_HTB is not set
+# CONFIG_NET_SCH_HFSC is not set
+# CONFIG_NET_SCH_PRIO is not set
+# CONFIG_NET_SCH_RED is not set
+# CONFIG_NET_SCH_SFQ is not set
+# CONFIG_NET_SCH_TEQL is not set
+# CONFIG_NET_SCH_TBF is not set
+# CONFIG_NET_SCH_GRED is not set
+# CONFIG_NET_SCH_DSMARK is not set
+# CONFIG_NET_SCH_NETEM is not set
+
+#
+# Classification
+#
+# CONFIG_NET_CLS_BASIC is not set
+# CONFIG_NET_CLS_TCINDEX is not set
+# CONFIG_NET_CLS_ROUTE4 is not set
+# CONFIG_NET_CLS_FW is not set
+# CONFIG_NET_CLS_U32 is not set
+# CONFIG_NET_CLS_RSVP is not set
+# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_CLS_FLOW is not set
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_SCH_FIFO=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+CONFIG_CAN=y
+CONFIG_CAN_RAW=y
+CONFIG_CAN_BCM=y
+
+#
+# CAN Device Drivers
+#
+CONFIG_CAN_VCAN=y
+# CONFIG_CAN_DEBUG_DEVICES is not set
+CONFIG_CAN_FLEXCAN=m
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+# CONFIG_IEEE80211_CRYPT_WEP is not set
+# CONFIG_IEEE80211_CRYPT_CCMP is not set
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+# CONFIG_MTD_XIP is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PHYSMAP is not set
+# CONFIG_MTD_ARM_INTEGRATOR is not set
+# CONFIG_MTD_PLATRAM is not set
+CONFIG_MTD_MXC=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS 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_MXC_V2=y
+# CONFIG_MTD_NAND_MXC_SWECC is not set
+# CONFIG_MTD_NAND_MXC_FORCE_CE is not set
+# CONFIG_MXC_NAND_LOW_LEVEL_ERASE is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+
+#
+# Voltage and Current regulators
+#
+CONFIG_REGULATOR_API=y
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+CONFIG_REGULATOR_MC13892=y
+CONFIG_REGULATOR_MAX8660=y
+CONFIG_REGULATOR_MC9SDZ60=y
+# CONFIG_REGULATOR_WM8350 is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+CONFIG_ATA=m
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_PMP is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_MV is not set
+# CONFIG_PATA_PLATFORM is not set
+CONFIG_PATA_FSL=m
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_FEC is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+CONFIG_USB_USBNET=m
+# CONFIG_USB_NET_AX8817X is not set
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_GL620A is not set
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_POLLDEV=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_TOUCHSCREEN_MXC=y
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+CONFIG_TOUCHSCREEN_TSC2007=y
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+CONFIG_FM_SI4702=m
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_MXC=y
+CONFIG_SERIAL_MXC_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_MXC=y
+# CONFIG_I2C_MXC_HS is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_I2C_SLAVE is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_MXC=y
+# CONFIG_SPI_MXC_TEST_LOOPBACK is not set
+CONFIG_SPI_MXC_SELECT1=y
+# CONFIG_SPI_MXC_SELECT2 is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_MXC_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_PASIC3 is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# Encoders/decoders and other helper chips
+#
+
+#
+# Audio decoders
+#
+# CONFIG_VIDEO_TVAUDIO is not set
+# CONFIG_VIDEO_TDA7432 is not set
+# CONFIG_VIDEO_TDA9840 is not set
+# CONFIG_VIDEO_TDA9875 is not set
+# CONFIG_VIDEO_TEA6415C is not set
+# CONFIG_VIDEO_TEA6420 is not set
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS5345 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_M52790 is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_VP27SMPX is not set
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_BT819 is not set
+# CONFIG_VIDEO_BT856 is not set
+# CONFIG_VIDEO_BT866 is not set
+# CONFIG_VIDEO_KS0127 is not set
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_TCM825X is not set
+# CONFIG_VIDEO_SAA7110 is not set
+# CONFIG_VIDEO_SAA7111 is not set
+# CONFIG_VIDEO_SAA7114 is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_SAA7191 is not set
+# CONFIG_VIDEO_TVP5150 is not set
+# CONFIG_VIDEO_VPX3220 is not set
+
+#
+# Video and audio decoders
+#
+# CONFIG_VIDEO_CX25840 is not set
+
+#
+# MPEG video encoders
+#
+# CONFIG_VIDEO_CX2341X is not set
+
+#
+# Video encoders
+#
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_SAA7185 is not set
+# CONFIG_VIDEO_ADV7170 is not set
+# CONFIG_VIDEO_ADV7175 is not set
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_MXC_CAMERA=m
+
+#
+# MXC Camera/V4L2 PRP Features support
+#
+CONFIG_VIDEO_MXC_IPU_CAMERA=y
+# CONFIG_MXC_CAMERA_MC521DA is not set
+# CONFIG_MXC_EMMA_CAMERA_MICRON111 is not set
+# CONFIG_MXC_CAMERA_OV2640_EMMA is not set
+# CONFIG_MXC_CAMERA_MICRON111 is not set
+CONFIG_MXC_CAMERA_OV2640=m
+# CONFIG_MXC_CAMERA_OV3640 is not set
+CONFIG_MXC_TVIN_ADV7180=m
+CONFIG_MXC_IPU_PRP_VF_SDC=m
+CONFIG_MXC_IPU_PRP_ENC=m
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set
+# CONFIG_VIDEO_MXC_OPL is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_USB_VIDEO_CLASS is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+# CONFIG_USB_W9968CF is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_MXC=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+# CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL is not set
+CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL=y
+# CONFIG_FB_MXC_TVOUT is not set
+# CONFIG_FB_MXC_TVOUT_CH7024 is not set
+# CONFIG_FB_MXC_ASYNC_PANEL is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_MXC=y
+CONFIG_BACKLIGHT_MXC_IPU=y
+CONFIG_BACKLIGHT_MXC_MC13892=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+CONFIG_SND_MXC_SPDIF=m
+
+#
+# SPI devices
+#
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# System on Chip audio support
+#
+CONFIG_SND_SOC=y
+CONFIG_SND_MXC_SOC=y
+CONFIG_SND_MXC_SOC_SSI=y
+CONFIG_SND_MXC_SOC_ESAI=m
+CONFIG_SND_MXC_SOC_IRAM=y
+# CONFIG_SND_SOC_IMX_3STACK_WM8350 is not set
+CONFIG_SND_SOC_IMX_3STACK_AK4647=y
+CONFIG_SND_SOC_IMX_3STACK_WM8580=m
+# CONFIG_SND_SOC_IMX_3STACK_WM8903 is not set
+CONFIG_SND_SOC_IMX_3STACK_SGTL5000=y
+CONFIG_SND_SOC_IMX_3STACK_BLUETOOTH=m
+
+#
+# ALSA SoC audio for Freescale SOCs
+#
+
+#
+# SoC Audio for the Texas Instruments OMAP
+#
+CONFIG_SND_SOC_AK4647=y
+CONFIG_SND_SOC_WM8580=m
+CONFIG_SND_SOC_SGTL5000=y
+CONFIG_SND_SOC_BLUETOOTH=m
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+CONFIG_USB_SUSPEND=y
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ARC=y
+CONFIG_USB_EHCI_ARC_H2=y
+CONFIG_USB_EHCI_ARC_OTG=y
+# CONFIG_USB_STATIC_IRAM is not set
+# CONFIG_USB_EHCI_FSL_MC13783 is not set
+# CONFIG_USB_EHCI_FSL_1301 is not set
+# CONFIG_USB_EHCI_FSL_1504 is not set
+CONFIG_USB_EHCI_FSL_UTMI=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+CONFIG_USB_MON=y
+
+#
+# Belcarra USBLAN Networking for USB
+#
+# CONFIG_USB_USBLAN is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+CONFIG_USB_GADGET_ARC=y
+CONFIG_USB_ARC=m
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_GADGET_ARC_OTG=y
+# CONFIG_USB_GADGET_FSL_MC13783 is not set
+# CONFIG_USB_GADGET_FSL_1301 is not set
+# CONFIG_USB_GADGET_FSL_1504 is not set
+CONFIG_USB_GADGET_FSL_UTMI=y
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+CONFIG_SDIO_UNIFI_FS=m
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_MXC is not set
+CONFIG_MMC_IMX_ESDHCI=m
+# CONFIG_MMC_IMX_ESDHCI_PIO_MODE is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_MXC=y
+# CONFIG_RTC_DRV_MXC_V2 is not set
+CONFIG_RTC_MC13892=y
+# CONFIG_UIO is not set
+
+#
+# MXC support drivers
+#
+CONFIG_MXC_IPU=y
+CONFIG_MXC_IPU_V1=y
+CONFIG_MXC_IPU_PF=y
+
+#
+# MXC SSI support
+#
+# CONFIG_MXC_SSI is not set
+
+#
+# MXC Digital Audio Multiplexer support
+#
+# CONFIG_MXC_DAM is not set
+
+#
+# MXC PMIC support
+#
+CONFIG_MXC_PMIC=y
+# CONFIG_MXC_PMIC_MC13783 is not set
+CONFIG_MXC_PMIC_MC13892=y
+# CONFIG_MXC_PMIC_MC34704 is not set
+# CONFIG_MXC_PMIC_CHARDEV is not set
+
+#
+# MXC PMIC Client Drivers
+#
+CONFIG_MXC_MC13892_ADC=y
+CONFIG_MXC_MC13892_RTC=y
+CONFIG_MXC_MC13892_LIGHT=y
+# CONFIG_MXC_MC13892_BATTERY is not set
+# CONFIG_MXC_MC13892_CONNECTIVITY is not set
+CONFIG_MXC_MC13892_POWER=y
+CONFIG_MXC_PMIC_MC9SDZ60=y
+# CONFIG_MXC_MC9SDZ60_RTC is not set
+
+#
+# Advanced Power Management devices
+#
+
+#
+# MXC Security Drivers
+#
+CONFIG_MXC_SECURITY_SCC=y
+# CONFIG_SCC_DEBUG is not set
+CONFIG_MXC_SECURITY_RNG=y
+# CONFIG_MXC_RNG_TEST_DRIVER is not set
+# CONFIG_MXC_RNG_DEBUG is not set
+CONFIG_MXC_SECURITY_CORE=y
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+# CONFIG_MXC_HMP4E is not set
+
+#
+# MXC HARDWARE EVENT
+#
+# CONFIG_MXC_HWEVENT is not set
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+
+#
+# MXC Asynchronous Sample Rate Converter support
+#
+CONFIG_MXC_ASRC=y
+
+#
+# MXC Bluetooth support
+#
+CONFIG_MXC_BLUETOOTH=m
+
+#
+# Broadcom GPS ioctrl support
+#
+CONFIG_GPS_IOCTRL=m
+
+#
+# MXC Media Local Bus Driver
+#
+CONFIG_MXC_MLB=m
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=y
+CONFIG_JOLIET=y
+CONFIG_ZISOFS=y
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/imx35evb_defconfig b/arch/arm/configs/imx35evb_defconfig
new file mode 100644
index 000000000000..1e2ab3b76f24
--- /dev/null
+++ b/arch/arm/configs/imx35evb_defconfig
@@ -0,0 +1,976 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.24
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_FAIR_GROUP_SCHED=y
+CONFIG_FAIR_USER_SCHED=y
+# CONFIG_FAIR_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+# CONFIG_RELAY is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=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
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+CONFIG_ARCH_MXC=y
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MXC91321 is not set
+# CONFIG_ARCH_MX37 is not set
+CONFIG_ARCH_MX35=y
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MX27 is not set
+# CONFIG_ARCH_MX21 is not set
+CONFIG_MXC_SDMA_API=y
+
+#
+# MX35 Options
+#
+# CONFIG_MACH_MX35_3DS is not set
+CONFIG_MACH_MX35EVB=y
+# CONFIG_MX35_DOZE_DURING_IDLE is not set
+
+#
+# Device options
+#
+CONFIG_ARCH_HAS_EVTMON=y
+CONFIG_DMA_ZONE_SIZE=24
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_ARM926T is not set
+CONFIG_CPU_V6=y
+# CONFIG_CPU_32v6K is not set
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_CACHE_L2X0=y
+
+#
+# Bus support
+#
+CONFIG_ISA=y
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCCARD=m
+# CONFIG_PCMCIA_DEBUG is not set
+CONFIG_PCMCIA=m
+CONFIG_PCMCIA_LOAD_CIS=y
+# CONFIG_PCMCIA_IOCTL is not set
+
+#
+# PC-card bridges
+#
+# CONFIG_I82365 is not set
+# CONFIG_TCIC is not set
+CONFIG_PCMCIA_PROBE=y
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+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_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_SUSPEND_UP_POSSIBLE=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_NET_KEY is not set
+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
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_INET6_XFRM_TUNNEL is not set
+# CONFIG_INET6_TUNNEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+# CONFIG_IEEE80211_CRYPT_WEP is not set
+# CONFIG_IEEE80211_CRYPT_CCMP is not set
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
+# CONFIG_IEEE80211_SOFTMAC is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=m
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+# CONFIG_MTD is not set
+
+#
+# Voltage and Current regulators
+#
+# CONFIG_REGULATOR is not set
+# CONFIG_PARPORT is not set
+# CONFIG_PNP is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_AHA152X is not set
+# CONFIG_SCSI_AIC7XXX_OLD is not set
+# CONFIG_SCSI_ADVANSYS is not set
+# CONFIG_SCSI_IN2000 is not set
+# CONFIG_SCSI_DTC3280 is not set
+# CONFIG_SCSI_FUTURE_DOMAIN is not set
+# CONFIG_SCSI_GENERIC_NCR5380 is not set
+# CONFIG_SCSI_GENERIC_NCR5380_MMIO is not set
+# CONFIG_SCSI_NCR53C406A is not set
+# CONFIG_SCSI_PAS16 is not set
+# CONFIG_SCSI_PSI240I is not set
+# CONFIG_SCSI_QLOGIC_FAS is not set
+# CONFIG_SCSI_SYM53C416 is not set
+# CONFIG_SCSI_T128 is not set
+# CONFIG_SCSI_DEBUG is not set
+# CONFIG_SCSI_LOWLEVEL_PCMCIA is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_ARCNET is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_NET_VENDOR_3COM is not set
+# CONFIG_NET_VENDOR_SMC is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_SMC911X is not set
+# CONFIG_SMSC911X is not set
+# CONFIG_NET_VENDOR_RACAL is not set
+# CONFIG_AT1700 is not set
+# CONFIG_DEPCA is not set
+# CONFIG_HP100 is not set
+# CONFIG_NET_ISA is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+CONFIG_NET_PCI=y
+# CONFIG_AC3200 is not set
+# CONFIG_APRICOT is not set
+# CONFIG_B44 is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_FEC is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+# CONFIG_TR is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+CONFIG_NET_PCMCIA=y
+# CONFIG_PCMCIA_3C589 is not set
+# CONFIG_PCMCIA_3C574 is not set
+# CONFIG_PCMCIA_FMVJ18X is not set
+CONFIG_PCMCIA_PCNET=m
+# CONFIG_PCMCIA_NMCLAN is not set
+# CONFIG_PCMCIA_SMC91C92 is not set
+# CONFIG_PCMCIA_XIRC2PS is not set
+# CONFIG_PCMCIA_AXNET is not set
+# CONFIG_WAN is not set
+CONFIG_PPP=m
+# CONFIG_PPP_MULTILINK is not set
+# CONFIG_PPP_FILTER is not set
+CONFIG_PPP_ASYNC=m
+CONFIG_PPP_SYNC_TTY=m
+CONFIG_PPP_DEFLATE=m
+# CONFIG_PPP_BSDCOMP is not set
+# CONFIG_PPP_MPPE is not set
+# CONFIG_PPPOE is not set
+# CONFIG_PPPOL2TP is not set
+# CONFIG_SLIP is not set
+CONFIG_SLHC=m
+# CONFIG_SHAPER is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+# CONFIG_INPUT_POLLDEV is not set
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+# CONFIG_INPUT_EVDEV is not set
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+# CONFIG_INPUT_TOUCHSCREEN is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_MXC_MU is not set
+# CONFIG_MXC_SUPER_GEM is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_MXC=y
+CONFIG_SERIAL_MXC_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_DTLK is not set
+# CONFIG_R3964 is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_SYNCLINK_CS is not set
+# CONFIG_CARDMAN_4000 is not set
+# CONFIG_CARDMAN_4040 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_DEVPORT=y
+# CONFIG_I2C is not set
+
+#
+# SPI support
+#
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_MXC=y
+# CONFIG_SPI_MXC_TEST_LOOPBACK is not set
+CONFIG_SPI_MXC_SELECT1=y
+# CONFIG_SPI_MXC_SELECT2 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_MXC_WATCHDOG=y
+
+#
+# ISA-based Watchdog Cards
+#
+# CONFIG_PCWATCHDOG is not set
+# CONFIG_MIXCOMWD is not set
+# CONFIG_WDT is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+
+#
+# Multimedia devices
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Sound
+#
+# CONFIG_SOUND is not set
+CONFIG_HID_SUPPORT=y
+# CONFIG_HID is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+# CONFIG_USB_ARCH_HAS_EHCI is not set
+# CONFIG_USB is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# USB Gadget Support
+#
+# CONFIG_USB_GADGET is not set
+
+#
+# On-The-Go and USB Peripheral Support
+#
+# CONFIG_OTG is not set
+
+#
+#
+#
+
+#
+#
+#
+# CONFIG_MMC is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+CONFIG_RTC_MXC=y
+# CONFIG_RTC_DRV_MXC_V2 is not set
+
+#
+# MXC support drivers
+#
+# CONFIG_MXC_IPU is not set
+
+#
+# MXC SSI support
+#
+# CONFIG_MXC_SSI is not set
+
+#
+# MXC Digital Audio Multiplexer support
+#
+# CONFIG_MXC_DAM is not set
+
+#
+# MXC PMIC support
+#
+# CONFIG_MXC_PMIC is not set
+
+#
+# Advanced Power Management devices
+#
+
+#
+# MXC Security Drivers
+#
+# CONFIG_MXC_SECURITY_SCC is not set
+# CONFIG_MXC_SECURITY_RNG is not set
+# CONFIG_MXC_SECURITY_RTIC is not set
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+# CONFIG_MXC_HMP4E is not set
+
+#
+# MXC HARDWARE EVENT
+#
+CONFIG_MXC_HWEVENT=y
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_ROMFS_FS is not set
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+CONFIG_DNOTIFY=y
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFS_DIRECTIO is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+CONFIG_INSTRUMENTATION=y
+CONFIG_PROFILING=y
+CONFIG_OPROFILE=y
+CONFIG_OPROFILE_ARMV6=y
+CONFIG_OPROFILE_ARM11_CORE=y
+CONFIG_OPROFILE_ARM11_EVTMON=y
+# CONFIG_MARKERS is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+# CONFIG_CRYPTO is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/imx37_3stack_defconfig b/arch/arm/configs/imx37_3stack_defconfig
new file mode 100644
index 000000000000..56f4f359b4ef
--- /dev/null
+++ b/arch/arm/configs/imx37_3stack_defconfig
@@ -0,0 +1,1761 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.26
+# Fri Oct 24 15:23:40 2008
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+CONFIG_ARCH_MXC=y
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Freescale MXC Implementations
+#
+CONFIG_ARCH_MX37=y
+# CONFIG_ARCH_MX35 is not set
+# CONFIG_ARCH_MX51 is not set
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MX27 is not set
+# CONFIG_ARCH_MX25 is not set
+# CONFIG_ARCH_MX21 is not set
+CONFIG_I2C_MXC_SELECT1=y
+CONFIG_I2C_MXC_SELECT2=y
+CONFIG_MXC_SDMA_API=y
+# CONFIG_I2C_MXC_SELECT3 is not set
+CONFIG_SDMA_IRAM=y
+CONFIG_SDMA_IRAM_SIZE=0x1000
+
+#
+# MX37 Options
+#
+CONFIG_MX37_OPTIONS=y
+CONFIG_MACH_MX37_3DS=y
+
+#
+# SDMA options
+#
+CONFIG_ARCH_MXC_HAS_NFC_V3=y
+CONFIG_ARCH_MXC_HAS_NFC_V3_1=y
+
+#
+# Device options
+#
+CONFIG_MXC_TZIC=y
+CONFIG_ARCH_HAS_EVTMON=y
+CONFIG_DMA_ZONE_SIZE=32
+CONFIG_UTMI_MXC=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_ARM926T is not set
+CONFIG_CPU_V6=y
+CONFIG_CPU_32v6K=y
+# CONFIG_CPU_V7 is not set
+CONFIG_CPU_32v6=y
+CONFIG_CPU_ABRT_EV6=y
+CONFIG_CPU_PABRT_NOIFAR=y
+CONFIG_CPU_CACHE_V6=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V6=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_OUTER_CACHE=y
+CONFIG_CACHE_L2X0=y
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+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_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# 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
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_IMX=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_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
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+# CONFIG_NET_SCH_CBQ is not set
+# CONFIG_NET_SCH_HTB is not set
+# CONFIG_NET_SCH_HFSC is not set
+# CONFIG_NET_SCH_PRIO is not set
+# CONFIG_NET_SCH_RED is not set
+# CONFIG_NET_SCH_SFQ is not set
+# CONFIG_NET_SCH_TEQL is not set
+# CONFIG_NET_SCH_TBF is not set
+# CONFIG_NET_SCH_GRED is not set
+# CONFIG_NET_SCH_DSMARK is not set
+# CONFIG_NET_SCH_NETEM is not set
+
+#
+# Classification
+#
+# CONFIG_NET_CLS_BASIC is not set
+# CONFIG_NET_CLS_TCINDEX is not set
+# CONFIG_NET_CLS_ROUTE4 is not set
+# CONFIG_NET_CLS_FW is not set
+# CONFIG_NET_CLS_U32 is not set
+# CONFIG_NET_CLS_RSVP is not set
+# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_CLS_FLOW is not set
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_SCH_FIFO=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+# CONFIG_IEEE80211_CRYPT_WEP is not set
+# CONFIG_IEEE80211_CRYPT_CCMP is not set
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+# CONFIG_MTD_MXC is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS 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_MXC_V3=y
+# CONFIG_MTD_NAND_MXC_SWECC is not set
+# CONFIG_MTD_NAND_MXC_FORCE_CE is not set
+# CONFIG_MXC_NAND_LOW_LEVEL_ERASE is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+
+#
+# Voltage and Current regulators
+#
+CONFIG_REGULATOR_API=y
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+CONFIG_REGULATOR_MC13892=y
+CONFIG_REGULATOR_WM8350=y
+
+#
+# WM8350 Config Mode
+#
+CONFIG_PMIC_WM8350_MODE_0=y
+# CONFIG_PMIC_WM8350_MODE_1 is not set
+# CONFIG_PMIC_WM8350_MODE_2 is not set
+# CONFIG_PMIC_WM8350_MODE_3 is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+CONFIG_BLK_DEV_SR=y
+# CONFIG_BLK_DEV_SR_VENDOR is not set
+CONFIG_CHR_DEV_SG=y
+CONFIG_CHR_DEV_SCH=y
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+CONFIG_ATA=m
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_PMP is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_MV is not set
+# CONFIG_PATA_PLATFORM is not set
+CONFIG_PATA_FSL=m
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_FEC is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+CONFIG_USB_USBNET=m
+# CONFIG_USB_NET_AX8817X is not set
+CONFIG_USB_NET_CDCETHER=m
+# CONFIG_USB_NET_DM9601 is not set
+# CONFIG_USB_NET_GL620A is not set
+# CONFIG_USB_NET_NET1080 is not set
+# CONFIG_USB_NET_PLUSB is not set
+# CONFIG_USB_NET_MCS7830 is not set
+# CONFIG_USB_NET_RNDIS_HOST is not set
+# CONFIG_USB_NET_CDC_SUBSET is not set
+# CONFIG_USB_NET_ZAURUS is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_POLLDEV=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+# CONFIG_KEYBOARD_MXC is not set
+CONFIG_KEYBOARD_MPR084=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_TOUCHSCREEN_MXC=y
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+CONFIG_TOUCHSCREEN_TSC2007=y
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_FM_SI4702 is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_MXC=y
+CONFIG_SERIAL_MXC_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_MXC=y
+# CONFIG_I2C_MXC_HS is not set
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_I2C_SLAVE is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_MXC=y
+# CONFIG_SPI_MXC_TEST_LOOPBACK is not set
+# CONFIG_SPI_MXC_SELECT1 is not set
+CONFIG_SPI_MXC_SELECT2=y
+# CONFIG_SPI_MXC_SELECT3 is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 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_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 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_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+CONFIG_SENSORS_ISL29003=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_MXC_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_PASIC3 is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# Encoders/decoders and other helper chips
+#
+
+#
+# Audio decoders
+#
+# CONFIG_VIDEO_TVAUDIO is not set
+# CONFIG_VIDEO_TDA7432 is not set
+# CONFIG_VIDEO_TDA9840 is not set
+# CONFIG_VIDEO_TDA9875 is not set
+# CONFIG_VIDEO_TEA6415C is not set
+# CONFIG_VIDEO_TEA6420 is not set
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS5345 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_M52790 is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_VP27SMPX is not set
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_BT819 is not set
+# CONFIG_VIDEO_BT856 is not set
+# CONFIG_VIDEO_BT866 is not set
+# CONFIG_VIDEO_KS0127 is not set
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_TCM825X is not set
+# CONFIG_VIDEO_SAA7110 is not set
+# CONFIG_VIDEO_SAA7111 is not set
+# CONFIG_VIDEO_SAA7114 is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_SAA7191 is not set
+# CONFIG_VIDEO_TVP5150 is not set
+# CONFIG_VIDEO_VPX3220 is not set
+
+#
+# Video and audio decoders
+#
+# CONFIG_VIDEO_CX25840 is not set
+
+#
+# MPEG video encoders
+#
+# CONFIG_VIDEO_CX2341X is not set
+
+#
+# Video encoders
+#
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_SAA7185 is not set
+# CONFIG_VIDEO_ADV7170 is not set
+# CONFIG_VIDEO_ADV7175 is not set
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+# CONFIG_VIDEO_VIVI is not set
+# CONFIG_VIDEO_MXC_CAMERA is not set
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set
+# CONFIG_VIDEO_MXC_OPL is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_USB_VIDEO_CLASS is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+# CONFIG_USB_W9968CF is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_MXC=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL=y
+CONFIG_FB_MXC_TVOUT_TVE=y
+# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_TVOUT is not set
+# CONFIG_FB_MXC_TVOUT_CH7024 is not set
+# CONFIG_FB_MXC_ASYNC_PANEL is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_MXC=y
+CONFIG_BACKLIGHT_MXC_MC13892=y
+CONFIG_BACKLIGHT_WM8350=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+CONFIG_SND_MXC_SPDIF=m
+
+#
+# SPI devices
+#
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# System on Chip audio support
+#
+CONFIG_SND_SOC=y
+CONFIG_SND_MXC_SOC=y
+CONFIG_SND_MXC_SOC_SSI=y
+# CONFIG_SND_MXC_SOC_IRAM is not set
+CONFIG_SND_SOC_IMX_3STACK_WM8350=y
+# CONFIG_SND_SOC_IMX_3STACK_AK4647 is not set
+# CONFIG_SND_SOC_IMX_3STACK_WM8580 is not set
+# CONFIG_SND_SOC_IMX_3STACK_WM8903 is not set
+CONFIG_SND_SOC_IMX_3STACK_SGTL5000=y
+
+#
+# ALSA SoC audio for Freescale SOCs
+#
+
+#
+# SoC Audio for the Texas Instruments OMAP
+#
+CONFIG_SND_SOC_WM8350=y
+CONFIG_SND_SOC_SGTL5000=y
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+CONFIG_USB_DEVICEFS=y
+# CONFIG_USB_DEVICE_CLASS is not set
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ARC=y
+CONFIG_USB_EHCI_ARC_OTG=y
+# CONFIG_USB_STATIC_IRAM is not set
+# CONFIG_USB_EHCI_FSL_MC13783 is not set
+# CONFIG_USB_EHCI_FSL_1301 is not set
+# CONFIG_USB_EHCI_FSL_1504 is not set
+CONFIG_USB_EHCI_FSL_UTMI=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_MON is not set
+
+#
+# Belcarra USBLAN Networking for USB
+#
+# CONFIG_USB_USBLAN is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_TEST is not set
+# CONFIG_USB_ISIGHTFW is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+CONFIG_USB_GADGET_ARC=y
+CONFIG_USB_STATIC_IRAM_PPH=y
+CONFIG_USB_ARC=m
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_GADGET_ARC_OTG=y
+# CONFIG_USB_GADGET_FSL_MC13783 is not set
+# CONFIG_USB_GADGET_FSL_1301 is not set
+# CONFIG_USB_GADGET_FSL_1504 is not set
+CONFIG_USB_GADGET_FSL_UTMI=y
+# CONFIG_USB_ZERO is not set
+# CONFIG_USB_ETH is not set
+# CONFIG_USB_GADGETFS is not set
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+# CONFIG_USB_G_SERIAL is not set
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+CONFIG_SDIO_UNIFI_FS=m
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_MXC is not set
+CONFIG_MMC_IMX_ESDHCI=m
+# CONFIG_MMC_IMX_ESDHCI_PIO_MODE is not set
+# CONFIG_NEW_LEDS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_MXC is not set
+CONFIG_RTC_DRV_MXC_V2=y
+# CONFIG_UIO is not set
+
+#
+# MXC support drivers
+#
+CONFIG_MXC_IPU=y
+CONFIG_MXC_IPU_V3=y
+
+#
+# MXC SSI support
+#
+# CONFIG_MXC_SSI is not set
+
+#
+# MXC Digital Audio Multiplexer support
+#
+# CONFIG_MXC_DAM is not set
+
+#
+# MXC PMIC support
+#
+CONFIG_MXC_PMIC=y
+# CONFIG_MXC_PMIC_MC13783 is not set
+CONFIG_MXC_PMIC_MC13892=y
+# CONFIG_MXC_PMIC_MC9SDZ60 is not set
+# CONFIG_MXC_PMIC_CHARDEV is not set
+
+#
+# MXC PMIC Client Drivers
+#
+CONFIG_MXC_MC13892_ADC=y
+CONFIG_MXC_MC13892_RTC=y
+CONFIG_MXC_MC13892_LIGHT=y
+CONFIG_MXC_MC13892_BATTERY=y
+# CONFIG_MXC_MC13892_CONNECTIVITY is not set
+CONFIG_MXC_MC13892_POWER=y
+
+#
+# Advanced Power Management devices
+#
+
+#
+# MXC Security Drivers
+#
+# CONFIG_MXC_SECURITY_SCC is not set
+# CONFIG_MXC_SECURITY_SCC2 is not set
+# CONFIG_MXC_SECURITY_RNG is not set
+
+#
+# SAHARA2 Security Hardware Support
+#
+# CONFIG_MXC_SAHARA is not set
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+# CONFIG_MXC_HMP4E is not set
+
+#
+# MXC HARDWARE EVENT
+#
+# CONFIG_MXC_HWEVENT is not set
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+CONFIG_MXC_VPU=y
+CONFIG_MXC_VPU_IRAM=y
+# CONFIG_MXC_VPU_DEBUG is not set
+
+#
+# MXC Asynchronous Sample Rate Converter support
+#
+
+#
+# MXC Bluetooth support
+#
+CONFIG_MXC_BLUETOOTH=m
+
+#
+# Broadcom GPS ioctrl support
+#
+
+#
+# MXC Media Local Bus Driver
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/configs/imx51_3stack_defconfig b/arch/arm/configs/imx51_3stack_defconfig
new file mode 100644
index 000000000000..332d71f6ea88
--- /dev/null
+++ b/arch/arm/configs/imx51_3stack_defconfig
@@ -0,0 +1,1794 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.26
+# Mon Feb 2 13:31:57 2009
+#
+CONFIG_ARM=y
+CONFIG_SYS_SUPPORTS_APM_EMULATION=y
+# CONFIG_GENERIC_GPIO is not set
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_MMU=y
+# CONFIG_NO_IOPORT is not set
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+CONFIG_HARDIRQS_SW_RESEND=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_ARCH_SUPPORTS_AOUT=y
+CONFIG_ZONE_DMA=y
+CONFIG_ARCH_MTD_XIP=y
+CONFIG_VECTORS_BASE=0xffff0000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+# CONFIG_POSIX_MQUEUE is not set
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+# CONFIG_GROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+# CONFIG_RELAY is not set
+# CONFIG_NAMESPACES is not set
+# CONFIG_BLK_DEV_INITRD is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_UID16=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLUB_DEBUG=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+# CONFIG_KPROBES is not set
+CONFIG_HAVE_KPROBES=y
+CONFIG_HAVE_KRETPROBES=y
+# CONFIG_HAVE_DMA_ATTRS is not set
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_BLOCK=y
+# CONFIG_LBD is not set
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_LSF is not set
+# CONFIG_BLK_DEV_BSG is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+
+#
+# System Type
+#
+# CONFIG_ARCH_AAEC2000 is not set
+# CONFIG_ARCH_INTEGRATOR is not set
+# CONFIG_ARCH_REALVIEW is not set
+# CONFIG_ARCH_VERSATILE is not set
+# CONFIG_ARCH_AT91 is not set
+# CONFIG_ARCH_CLPS7500 is not set
+# CONFIG_ARCH_CLPS711X is not set
+# CONFIG_ARCH_CO285 is not set
+# CONFIG_ARCH_EBSA110 is not set
+# CONFIG_ARCH_EP93XX is not set
+# CONFIG_ARCH_FOOTBRIDGE is not set
+# CONFIG_ARCH_NETX is not set
+# CONFIG_ARCH_H720X is not set
+# CONFIG_ARCH_IMX is not set
+# CONFIG_ARCH_IOP13XX is not set
+# CONFIG_ARCH_IOP32X is not set
+# CONFIG_ARCH_IOP33X is not set
+# CONFIG_ARCH_IXP23XX is not set
+# CONFIG_ARCH_IXP2000 is not set
+# CONFIG_ARCH_IXP4XX is not set
+# CONFIG_ARCH_L7200 is not set
+# CONFIG_ARCH_KS8695 is not set
+# CONFIG_ARCH_NS9XXX is not set
+CONFIG_ARCH_MXC=y
+# CONFIG_ARCH_ORION5X is not set
+# CONFIG_ARCH_PNX4008 is not set
+# CONFIG_ARCH_PXA is not set
+# CONFIG_ARCH_RPC is not set
+# CONFIG_ARCH_SA1100 is not set
+# CONFIG_ARCH_S3C2410 is not set
+# CONFIG_ARCH_SHARK is not set
+# CONFIG_ARCH_LH7A40X is not set
+# CONFIG_ARCH_DAVINCI is not set
+# CONFIG_ARCH_OMAP is not set
+# CONFIG_ARCH_MSM7X00A is not set
+
+#
+# Boot options
+#
+
+#
+# Power management
+#
+
+#
+# Freescale MXC Implementations
+#
+# CONFIG_ARCH_MX37 is not set
+# CONFIG_ARCH_MX35 is not set
+CONFIG_ARCH_MX51=y
+# CONFIG_ARCH_MX3 is not set
+# CONFIG_ARCH_MX27 is not set
+# CONFIG_ARCH_MX25 is not set
+# CONFIG_ARCH_MX21 is not set
+# CONFIG_I2C_MXC_SELECT1 is not set
+CONFIG_I2C_MXC_SELECT2=y
+CONFIG_MXC_SDMA_API=y
+# CONFIG_I2C_MXC_SELECT3 is not set
+CONFIG_SDMA_IRAM=y
+CONFIG_SDMA_IRAM_SIZE=0x1000
+CONFIG_ARCH_MXC_HAS_NFC_V3=y
+
+#
+# MX51 Options
+#
+CONFIG_MX51_OPTIONS=y
+CONFIG_MACH_MX51_3DS=y
+CONFIG_ARCH_MXC_HAS_NFC_V3_2=y
+
+#
+# SDMA options
+#
+
+#
+# Device options
+#
+CONFIG_MXC_TZIC=y
+CONFIG_DMA_ZONE_SIZE=64
+CONFIG_UTMI_MXC=y
+
+#
+# Processor Type
+#
+CONFIG_CPU_32=y
+# CONFIG_CPU_ARM926T is not set
+# CONFIG_CPU_V6 is not set
+CONFIG_CPU_32v6K=y
+CONFIG_CPU_V7=y
+CONFIG_CPU_32v7=y
+CONFIG_CPU_ABRT_EV7=y
+CONFIG_CPU_PABRT_IFAR=y
+CONFIG_CPU_CACHE_V7=y
+CONFIG_CPU_CACHE_VIPT=y
+CONFIG_CPU_COPY_V6=y
+CONFIG_CPU_TLB_V7=y
+CONFIG_CPU_HAS_ASID=y
+CONFIG_CPU_CP15=y
+CONFIG_CPU_CP15_MMU=y
+
+#
+# Processor Features
+#
+CONFIG_ARM_THUMB=y
+# CONFIG_ARM_THUMBEE is not set
+# CONFIG_CPU_ICACHE_DISABLE is not set
+# CONFIG_CPU_DCACHE_DISABLE is not set
+# CONFIG_CPU_BPREDICT_DISABLE is not set
+CONFIG_HAS_TLS_REG=y
+# CONFIG_OUTER_CACHE is not set
+
+#
+# Bus support
+#
+# CONFIG_PCI_SYSCALL is not set
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+# CONFIG_PCCARD is not set
+
+#
+# Kernel Features
+#
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_PREEMPT=y
+CONFIG_HZ=100
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+# CONFIG_SPARSEMEM_MANUAL is not set
+CONFIG_FLATMEM=y
+CONFIG_FLAT_NODE_MEM_MAP=y
+# CONFIG_SPARSEMEM_STATIC is not set
+# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+# CONFIG_RESOURCES_64BIT is not set
+CONFIG_ZONE_DMA_FLAG=1
+CONFIG_BOUNCE=y
+CONFIG_VIRT_TO_BUS=y
+# CONFIG_LEDS is not set
+CONFIG_ALIGNMENT_TRAP=y
+
+#
+# Boot options
+#
+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_XIP_KERNEL is not set
+# CONFIG_KEXEC is not set
+
+#
+# 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
+# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
+CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
+CONFIG_CPU_FREQ_GOV_POWERSAVE=y
+CONFIG_CPU_FREQ_GOV_USERSPACE=y
+# CONFIG_CPU_FREQ_GOV_ONDEMAND is not set
+# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
+CONFIG_CPU_FREQ_IMX=y
+
+#
+# Floating point emulation
+#
+
+#
+# At least one emulation must be selected
+#
+CONFIG_VFP=y
+CONFIG_VFPv3=y
+CONFIG_NEON=y
+
+#
+# Userspace binary formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_BINFMT_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+CONFIG_PM=y
+# CONFIG_PM_DEBUG is not set
+CONFIG_PM_SLEEP=y
+CONFIG_SUSPEND=y
+CONFIG_SUSPEND_FREEZER=y
+# CONFIG_APM_EMULATION is not set
+CONFIG_ARCH_SUSPEND_POSSIBLE=y
+
+#
+# Networking
+#
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_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
+# CONFIG_IP_PNP_RARP is not set
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE is not set
+# CONFIG_IP_MROUTE is not set
+# CONFIG_ARPD is not set
+# CONFIG_SYN_COOKIES is not set
+# CONFIG_INET_AH is not set
+# CONFIG_INET_ESP is not set
+# CONFIG_INET_IPCOMP is not set
+# CONFIG_INET_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+CONFIG_NET_SCHED=y
+
+#
+# Queueing/Scheduling
+#
+# CONFIG_NET_SCH_CBQ is not set
+# CONFIG_NET_SCH_HTB is not set
+# CONFIG_NET_SCH_HFSC is not set
+# CONFIG_NET_SCH_PRIO is not set
+# CONFIG_NET_SCH_RED is not set
+# CONFIG_NET_SCH_SFQ is not set
+# CONFIG_NET_SCH_TEQL is not set
+# CONFIG_NET_SCH_TBF is not set
+# CONFIG_NET_SCH_GRED is not set
+# CONFIG_NET_SCH_DSMARK is not set
+# CONFIG_NET_SCH_NETEM is not set
+
+#
+# Classification
+#
+# CONFIG_NET_CLS_BASIC is not set
+# CONFIG_NET_CLS_TCINDEX is not set
+# CONFIG_NET_CLS_ROUTE4 is not set
+# CONFIG_NET_CLS_FW is not set
+# CONFIG_NET_CLS_U32 is not set
+# CONFIG_NET_CLS_RSVP is not set
+# CONFIG_NET_CLS_RSVP6 is not set
+# CONFIG_NET_CLS_FLOW is not set
+# CONFIG_NET_EMATCH is not set
+# CONFIG_NET_CLS_ACT is not set
+CONFIG_NET_SCH_FIFO=y
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+
+#
+# Wireless
+#
+# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_EXT=y
+# CONFIG_MAC80211 is not set
+CONFIG_IEEE80211=y
+# CONFIG_IEEE80211_DEBUG is not set
+# CONFIG_IEEE80211_CRYPT_WEP is not set
+# CONFIG_IEEE80211_CRYPT_CCMP is not set
+# CONFIG_IEEE80211_CRYPT_TKIP is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+# CONFIG_SYS_HYPERVISOR is not set
+CONFIG_CONNECTOR=y
+CONFIG_PROC_EVENTS=y
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+CONFIG_MTD_CMDLINE_PARTS=y
+# CONFIG_MTD_AFS_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+# CONFIG_MTD_CFI is not set
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+# CONFIG_MTD_PLATRAM is not set
+# CONFIG_MTD_MXC is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_DATAFLASH is not set
+# CONFIG_MTD_M25P80 is not set
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_SMC is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS 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_MXC_V3=y
+# CONFIG_MTD_NAND_MXC_SWECC is not set
+# CONFIG_MTD_NAND_MXC_FORCE_CE is not set
+# CONFIG_MXC_NAND_LOW_LEVEL_ERASE is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ALAUDA is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+
+#
+# Voltage and Current regulators
+#
+CONFIG_REGULATOR_API=y
+CONFIG_REGULATOR=y
+# CONFIG_REGULATOR_DEBUG is not set
+CONFIG_REGULATOR_MC13892=y
+# CONFIG_REGULATOR_WM8350 is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_UB is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+CONFIG_MISC_DEVICES=y
+# CONFIG_EEPROM_93CX6 is not set
+# CONFIG_ENCLOSURE_SERVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+CONFIG_SCSI=y
+CONFIG_SCSI_DMA=y
+# CONFIG_SCSI_TGT is not set
+# CONFIG_SCSI_NETLINK is not set
+CONFIG_SCSI_PROC_FS=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
+CONFIG_BLK_DEV_SD=y
+# CONFIG_CHR_DEV_ST is not set
+# CONFIG_CHR_DEV_OSST is not set
+# CONFIG_BLK_DEV_SR is not set
+# CONFIG_CHR_DEV_SG is not set
+# CONFIG_CHR_DEV_SCH is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
+CONFIG_SCSI_MULTI_LUN=y
+# CONFIG_SCSI_CONSTANTS is not set
+# CONFIG_SCSI_LOGGING is not set
+# CONFIG_SCSI_SCAN_ASYNC is not set
+CONFIG_SCSI_WAIT_SCAN=m
+
+#
+# SCSI Transports
+#
+# CONFIG_SCSI_SPI_ATTRS is not set
+# CONFIG_SCSI_FC_ATTRS is not set
+# CONFIG_SCSI_ISCSI_ATTRS is not set
+# CONFIG_SCSI_SAS_LIBSAS is not set
+# CONFIG_SCSI_SRP_ATTRS is not set
+CONFIG_SCSI_LOWLEVEL=y
+# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_DEBUG is not set
+CONFIG_ATA=m
+# CONFIG_ATA_NONSTANDARD is not set
+# CONFIG_SATA_PMP is not set
+CONFIG_ATA_SFF=y
+# CONFIG_SATA_MV is not set
+# CONFIG_PATA_PLATFORM is not set
+CONFIG_PATA_FSL=m
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NETDEVICES_MULTIQUEUE is not set
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_ENC28J60 is not set
+# CONFIG_SMC911X is not set
+CONFIG_SMSC911X=y
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_B44 is not set
+# CONFIG_CS89x0 is not set
+# CONFIG_FEC is not set
+# CONFIG_NETDEV_1000 is not set
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# USB Network Adapters
+#
+# CONFIG_USB_CATC is not set
+# CONFIG_USB_KAWETH is not set
+# CONFIG_USB_PEGASUS is not set
+# CONFIG_USB_RTL8150 is not set
+# CONFIG_USB_USBNET is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+
+#
+# Input device support
+#
+CONFIG_INPUT=y
+# CONFIG_INPUT_FF_MEMLESS is not set
+CONFIG_INPUT_POLLDEV=y
+
+#
+# Userland interfaces
+#
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_JOYDEV is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_EVBUG is not set
+
+#
+# Input Device Drivers
+#
+CONFIG_INPUT_KEYBOARD=y
+# CONFIG_KEYBOARD_ATKBD is not set
+# CONFIG_KEYBOARD_SUNKBD is not set
+# CONFIG_KEYBOARD_LKKBD is not set
+# CONFIG_KEYBOARD_XTKBD is not set
+# CONFIG_KEYBOARD_NEWTON is not set
+# CONFIG_KEYBOARD_STOWAWAY is not set
+CONFIG_KEYBOARD_MXC=y
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_INPUT_JOYSTICK is not set
+# CONFIG_INPUT_TABLET is not set
+CONFIG_INPUT_TOUCHSCREEN=y
+# CONFIG_TOUCHSCREEN_ADS7846 is not set
+# CONFIG_TOUCHSCREEN_FUJITSU is not set
+# CONFIG_TOUCHSCREEN_GUNZE is not set
+# CONFIG_TOUCHSCREEN_ELO is not set
+# CONFIG_TOUCHSCREEN_MTOUCH is not set
+# CONFIG_TOUCHSCREEN_MK712 is not set
+CONFIG_TOUCHSCREEN_MXC=y
+# CONFIG_TOUCHSCREEN_PENMOUNT is not set
+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
+# CONFIG_TOUCHSCREEN_UCB1400 is not set
+# CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set
+# CONFIG_TOUCHSCREEN_TSC2007 is not set
+# CONFIG_INPUT_MISC is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+CONFIG_VT=y
+CONFIG_VT_CONSOLE=y
+CONFIG_HW_CONSOLE=y
+# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_MXC=y
+CONFIG_SERIAL_MXC_CONSOLE=y
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_NVRAM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+CONFIG_I2C=y
+CONFIG_I2C_BOARDINFO=y
+CONFIG_I2C_CHARDEV=y
+
+#
+# I2C Hardware Bus support
+#
+CONFIG_I2C_MXC=y
+CONFIG_I2C_MXC_HS=y
+# CONFIG_I2C_OCORES is not set
+# CONFIG_I2C_PARPORT_LIGHT is not set
+# CONFIG_I2C_SIMTEC is not set
+# CONFIG_I2C_TAOS_EVM is not set
+# CONFIG_I2C_STUB is not set
+# CONFIG_I2C_TINY_USB is not set
+# CONFIG_I2C_PCA_PLATFORM is not set
+
+#
+# Miscellaneous I2C Chip support
+#
+# CONFIG_DS1682 is not set
+# CONFIG_SENSORS_EEPROM is not set
+# CONFIG_SENSORS_PCF8574 is not set
+# CONFIG_PCF8575 is not set
+# CONFIG_SENSORS_PCF8591 is not set
+# CONFIG_SENSORS_MAX6875 is not set
+# CONFIG_SENSORS_TSL2550 is not set
+# CONFIG_I2C_DEBUG_CORE is not set
+# CONFIG_I2C_DEBUG_ALGO is not set
+# CONFIG_I2C_DEBUG_BUS is not set
+# CONFIG_I2C_DEBUG_CHIP is not set
+# CONFIG_I2C_SLAVE is not set
+CONFIG_SPI=y
+CONFIG_SPI_MASTER=y
+
+#
+# SPI Master Controller Drivers
+#
+CONFIG_SPI_BITBANG=y
+CONFIG_SPI_MXC=y
+# CONFIG_SPI_MXC_TEST_LOOPBACK is not set
+CONFIG_SPI_MXC_SELECT1=y
+# CONFIG_SPI_MXC_SELECT2 is not set
+# CONFIG_SPI_MXC_SELECT3 is not set
+
+#
+# SPI Protocol Masters
+#
+# CONFIG_SPI_AT25 is not set
+# CONFIG_SPI_SPIDEV is not set
+# CONFIG_SPI_TLE62X0 is not set
+CONFIG_W1=m
+CONFIG_W1_CON=y
+
+#
+# 1-wire Bus Masters
+#
+# CONFIG_W1_MASTER_DS2490 is not set
+# CONFIG_W1_MASTER_DS2482 is not set
+CONFIG_W1_MASTER_MXC=m
+# CONFIG_W1_MASTER_DS1WM is not set
+
+#
+# 1-wire Slaves
+#
+# CONFIG_W1_SLAVE_THERM is not set
+# CONFIG_W1_SLAVE_SMEM is not set
+# CONFIG_W1_SLAVE_DS2751 is not set
+# CONFIG_W1_SLAVE_DS2433 is not set
+CONFIG_W1_SLAVE_DS2438=m
+# CONFIG_W1_SLAVE_DS2760 is not set
+CONFIG_POWER_SUPPLY=m
+# CONFIG_POWER_SUPPLY_DEBUG is not set
+# CONFIG_PDA_POWER is not set
+# CONFIG_BATTERY_DS2760 is not set
+CONFIG_HWMON=y
+# CONFIG_HWMON_VID is not set
+# CONFIG_SENSORS_AD7418 is not set
+# CONFIG_SENSORS_ADM1021 is not set
+# CONFIG_SENSORS_ADM1025 is not set
+# CONFIG_SENSORS_ADM1026 is not set
+# CONFIG_SENSORS_ADM1029 is not set
+# CONFIG_SENSORS_ADM1031 is not set
+# CONFIG_SENSORS_ADM9240 is not set
+# CONFIG_SENSORS_ADT7470 is not set
+# CONFIG_SENSORS_ADT7473 is not set
+# CONFIG_SENSORS_ATXP1 is not set
+# CONFIG_SENSORS_DS1621 is not set
+# CONFIG_SENSORS_F71805F is not set
+# CONFIG_SENSORS_F71882FG is not set
+# CONFIG_SENSORS_F75375S is not set
+# CONFIG_SENSORS_GL518SM is not set
+# CONFIG_SENSORS_GL520SM is not set
+# CONFIG_SENSORS_IT87 is not set
+# CONFIG_SENSORS_LM63 is not set
+# CONFIG_SENSORS_LM70 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_MAX1619 is not set
+# CONFIG_SENSORS_MAX6650 is not set
+# CONFIG_SENSORS_PC87360 is not set
+# CONFIG_SENSORS_PC87427 is not set
+# CONFIG_SENSORS_DME1737 is not set
+# CONFIG_SENSORS_SMSC47M1 is not set
+# CONFIG_SENSORS_SMSC47M192 is not set
+# CONFIG_SENSORS_SMSC47B397 is not set
+# CONFIG_SENSORS_ADS7828 is not set
+# CONFIG_SENSORS_THMC50 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_W83L785TS is not set
+# CONFIG_SENSORS_W83L786NG is not set
+# CONFIG_SENSORS_W83627HF is not set
+# CONFIG_SENSORS_W83627EHF is not set
+# CONFIG_HWMON_DEBUG_CHIP is not set
+CONFIG_SENSORS_ISL29003=y
+CONFIG_WATCHDOG=y
+CONFIG_WATCHDOG_NOWAYOUT=y
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_MXC_WATCHDOG=y
+
+#
+# USB-based Watchdog Cards
+#
+# CONFIG_USBPCWATCHDOG is not set
+
+#
+# Sonics Silicon Backplane
+#
+CONFIG_SSB_POSSIBLE=y
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_SM501 is not set
+# CONFIG_MFD_ASIC3 is not set
+# CONFIG_HTC_PASIC3 is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+CONFIG_VIDEO_DEV=y
+CONFIG_VIDEO_V4L2_COMMON=y
+CONFIG_VIDEO_ALLOW_V4L1=y
+CONFIG_VIDEO_V4L1_COMPAT=y
+# CONFIG_DVB_CORE is not set
+CONFIG_VIDEO_MEDIA=y
+
+#
+# Multimedia drivers
+#
+# CONFIG_MEDIA_ATTACH is not set
+CONFIG_MEDIA_TUNER=y
+# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
+CONFIG_MEDIA_TUNER_SIMPLE=y
+CONFIG_MEDIA_TUNER_TDA8290=y
+CONFIG_MEDIA_TUNER_TDA9887=y
+CONFIG_MEDIA_TUNER_TEA5761=y
+CONFIG_MEDIA_TUNER_TEA5767=y
+CONFIG_MEDIA_TUNER_MT20XX=y
+CONFIG_MEDIA_TUNER_XC2028=y
+CONFIG_MEDIA_TUNER_XC5000=y
+CONFIG_VIDEO_V4L2=y
+CONFIG_VIDEO_V4L1=y
+CONFIG_VIDEO_CAPTURE_DRIVERS=y
+# CONFIG_VIDEO_ADV_DEBUG is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+
+#
+# Encoders/decoders and other helper chips
+#
+
+#
+# Audio decoders
+#
+# CONFIG_VIDEO_TVAUDIO is not set
+# CONFIG_VIDEO_TDA7432 is not set
+# CONFIG_VIDEO_TDA9840 is not set
+# CONFIG_VIDEO_TDA9875 is not set
+# CONFIG_VIDEO_TEA6415C is not set
+# CONFIG_VIDEO_TEA6420 is not set
+# CONFIG_VIDEO_MSP3400 is not set
+# CONFIG_VIDEO_CS5345 is not set
+# CONFIG_VIDEO_CS53L32A is not set
+# CONFIG_VIDEO_M52790 is not set
+# CONFIG_VIDEO_TLV320AIC23B is not set
+# CONFIG_VIDEO_WM8775 is not set
+# CONFIG_VIDEO_WM8739 is not set
+# CONFIG_VIDEO_VP27SMPX is not set
+
+#
+# Video decoders
+#
+# CONFIG_VIDEO_BT819 is not set
+# CONFIG_VIDEO_BT856 is not set
+# CONFIG_VIDEO_BT866 is not set
+# CONFIG_VIDEO_KS0127 is not set
+# CONFIG_VIDEO_OV7670 is not set
+# CONFIG_VIDEO_TCM825X is not set
+# CONFIG_VIDEO_SAA7110 is not set
+# CONFIG_VIDEO_SAA7111 is not set
+# CONFIG_VIDEO_SAA7114 is not set
+# CONFIG_VIDEO_SAA711X is not set
+# CONFIG_VIDEO_SAA717X is not set
+# CONFIG_VIDEO_SAA7191 is not set
+# CONFIG_VIDEO_TVP5150 is not set
+# CONFIG_VIDEO_VPX3220 is not set
+
+#
+# Video and audio decoders
+#
+# CONFIG_VIDEO_CX25840 is not set
+
+#
+# MPEG video encoders
+#
+# CONFIG_VIDEO_CX2341X is not set
+
+#
+# Video encoders
+#
+# CONFIG_VIDEO_SAA7127 is not set
+# CONFIG_VIDEO_SAA7185 is not set
+# CONFIG_VIDEO_ADV7170 is not set
+# CONFIG_VIDEO_ADV7175 is not set
+
+#
+# Video improvement chips
+#
+# CONFIG_VIDEO_UPD64031A is not set
+# CONFIG_VIDEO_UPD64083 is not set
+# CONFIG_VIDEO_VIVI is not set
+CONFIG_VIDEO_MXC_CAMERA=m
+
+#
+# MXC Camera/V4L2 PRP Features support
+#
+CONFIG_VIDEO_MXC_IPU_CAMERA=y
+# CONFIG_MXC_CAMERA_MC521DA is not set
+# CONFIG_MXC_EMMA_CAMERA_MICRON111 is not set
+# CONFIG_MXC_CAMERA_OV2640_EMMA is not set
+# CONFIG_MXC_CAMERA_MICRON111 is not set
+# CONFIG_MXC_CAMERA_OV2640 is not set
+CONFIG_MXC_CAMERA_OV3640=m
+# CONFIG_MXC_TVIN_ADV7180 is not set
+CONFIG_MXC_IPU_PRP_VF_SDC=m
+CONFIG_MXC_IPU_PRP_ENC=m
+CONFIG_VIDEO_MXC_OUTPUT=y
+CONFIG_VIDEO_MXC_IPU_OUTPUT=y
+# CONFIG_VIDEO_MXC_IPUV1_WVGA_OUTPUT is not set
+# CONFIG_VIDEO_MXC_OPL is not set
+# CONFIG_VIDEO_CPIA is not set
+# CONFIG_VIDEO_CPIA2 is not set
+# CONFIG_VIDEO_SAA5246A is not set
+# CONFIG_VIDEO_SAA5249 is not set
+# CONFIG_TUNER_3036 is not set
+CONFIG_V4L_USB_DRIVERS=y
+# CONFIG_USB_VIDEO_CLASS is not set
+# CONFIG_VIDEO_PVRUSB2 is not set
+# CONFIG_VIDEO_EM28XX is not set
+# CONFIG_VIDEO_USBVISION is not set
+# CONFIG_USB_VICAM is not set
+# CONFIG_USB_IBMCAM is not set
+# CONFIG_USB_KONICAWC is not set
+# CONFIG_USB_QUICKCAM_MESSENGER is not set
+# CONFIG_USB_ET61X251 is not set
+# CONFIG_VIDEO_OVCAMCHIP is not set
+# CONFIG_USB_W9968CF is not set
+# CONFIG_USB_OV511 is not set
+# CONFIG_USB_SE401 is not set
+# CONFIG_USB_SN9C102 is not set
+# CONFIG_USB_STV680 is not set
+# CONFIG_USB_ZC0301 is not set
+# CONFIG_USB_PWC is not set
+# CONFIG_USB_ZR364XX is not set
+# CONFIG_USB_STKWEBCAM is not set
+# CONFIG_SOC_CAMERA is not set
+# CONFIG_RADIO_ADAPTERS is not set
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+CONFIG_FB=y
+# CONFIG_FIRMWARE_EDID is not set
+# CONFIG_FB_DDC is not set
+CONFIG_FB_CFB_FILLRECT=y
+CONFIG_FB_CFB_COPYAREA=y
+CONFIG_FB_CFB_IMAGEBLIT=y
+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
+# CONFIG_FB_SYS_FILLRECT is not set
+# CONFIG_FB_SYS_COPYAREA is not set
+# CONFIG_FB_SYS_IMAGEBLIT is not set
+# CONFIG_FB_FOREIGN_ENDIAN is not set
+# CONFIG_FB_SYS_FOPS is not set
+# CONFIG_FB_SVGALIB is not set
+# CONFIG_FB_MACMODES is not set
+# CONFIG_FB_BACKLIGHT is not set
+# CONFIG_FB_MODE_HELPERS is not set
+# CONFIG_FB_TILEBLITTING is not set
+
+#
+# Frame buffer hardware drivers
+#
+CONFIG_FB_MXC=y
+CONFIG_FB_MXC_SYNC_PANEL=y
+CONFIG_FB_MXC_EPSON_VGA_SYNC_PANEL=y
+CONFIG_FB_MXC_TVOUT_TVE=y
+# CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL is not set
+# CONFIG_FB_MXC_TVOUT is not set
+# CONFIG_FB_MXC_TVOUT_CH7024 is not set
+# CONFIG_FB_MXC_ASYNC_PANEL is not set
+# CONFIG_FB_UVESA is not set
+# CONFIG_FB_S1D13XXX is not set
+# CONFIG_FB_VIRTUAL is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+# CONFIG_LCD_CLASS_DEVICE is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
+CONFIG_BACKLIGHT_MXC=y
+CONFIG_BACKLIGHT_MXC_MC13892=y
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+
+#
+# Console display driver support
+#
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_DUMMY_CONSOLE=y
+CONFIG_FRAMEBUFFER_CONSOLE=y
+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set
+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set
+CONFIG_FONTS=y
+# CONFIG_FONT_8x8 is not set
+CONFIG_FONT_8x16=y
+# CONFIG_FONT_6x11 is not set
+# CONFIG_FONT_7x14 is not set
+# CONFIG_FONT_PEARL_8x8 is not set
+# CONFIG_FONT_ACORN_8x8 is not set
+# CONFIG_FONT_MINI_4x6 is not set
+# CONFIG_FONT_SUN8x16 is not set
+# CONFIG_FONT_SUN12x22 is not set
+# CONFIG_FONT_10x18 is not set
+CONFIG_LOGO=y
+# CONFIG_LOGO_LINUX_MONO is not set
+# CONFIG_LOGO_LINUX_VGA16 is not set
+CONFIG_LOGO_LINUX_CLUT224=y
+
+#
+# Sound
+#
+CONFIG_SOUND=y
+
+#
+# Advanced Linux Sound Architecture
+#
+CONFIG_SND=y
+CONFIG_SND_TIMER=y
+CONFIG_SND_PCM=y
+# CONFIG_SND_SEQUENCER is not set
+CONFIG_SND_OSSEMUL=y
+CONFIG_SND_MIXER_OSS=y
+CONFIG_SND_PCM_OSS=y
+CONFIG_SND_PCM_OSS_PLUGINS=y
+# CONFIG_SND_DYNAMIC_MINORS is not set
+CONFIG_SND_SUPPORT_OLD_API=y
+CONFIG_SND_VERBOSE_PROCFS=y
+# CONFIG_SND_VERBOSE_PRINTK is not set
+# CONFIG_SND_DEBUG is not set
+
+#
+# Generic devices
+#
+# CONFIG_SND_DUMMY is not set
+# CONFIG_SND_MTPAV is not set
+# CONFIG_SND_SERIAL_U16550 is not set
+# CONFIG_SND_MPU401 is not set
+
+#
+# ALSA ARM devices
+#
+CONFIG_SND_MXC_SPDIF=m
+
+#
+# SPI devices
+#
+
+#
+# USB devices
+#
+# CONFIG_SND_USB_AUDIO is not set
+# CONFIG_SND_USB_CAIAQ is not set
+
+#
+# System on Chip audio support
+#
+CONFIG_SND_SOC=y
+CONFIG_SND_MXC_SOC=y
+CONFIG_SND_MXC_SOC_SSI=y
+CONFIG_SND_MXC_SOC_IRAM=y
+# CONFIG_SND_SOC_IMX_3STACK_WM8350 is not set
+# CONFIG_SND_SOC_IMX_3STACK_AK4647 is not set
+# CONFIG_SND_SOC_IMX_3STACK_WM8580 is not set
+CONFIG_SND_SOC_IMX_3STACK_WM8903=y
+CONFIG_SND_SOC_IMX_3STACK_SGTL5000=y
+# CONFIG_SND_SOC_IMX_3STACK_BLUETOOTH is not set
+
+#
+# ALSA SoC audio for Freescale SOCs
+#
+
+#
+# SoC Audio for the Texas Instruments OMAP
+#
+CONFIG_SND_SOC_WM8903=y
+CONFIG_SND_SOC_SGTL5000=y
+
+#
+# Open Sound System
+#
+# CONFIG_SOUND_PRIME is not set
+CONFIG_HID_SUPPORT=y
+CONFIG_HID=y
+# CONFIG_HID_DEBUG is not set
+# CONFIG_HIDRAW is not set
+
+#
+# USB Input Devices
+#
+CONFIG_USB_HID=m
+# CONFIG_USB_HIDINPUT_POWERBOOK is not set
+# CONFIG_HID_FF is not set
+# CONFIG_USB_HIDDEV is not set
+
+#
+# USB HID Boot Protocol drivers
+#
+# CONFIG_USB_KBD is not set
+# CONFIG_USB_MOUSE is not set
+CONFIG_USB_SUPPORT=y
+CONFIG_USB_ARCH_HAS_HCD=y
+# CONFIG_USB_ARCH_HAS_OHCI is not set
+CONFIG_USB_ARCH_HAS_EHCI=y
+CONFIG_USB=y
+# CONFIG_USB_DEBUG is not set
+# CONFIG_USB_ANNOUNCE_NEW_DEVICES is not set
+
+#
+# Miscellaneous USB options
+#
+# CONFIG_USB_DEVICEFS is not set
+CONFIG_USB_DEVICE_CLASS=y
+# CONFIG_USB_DYNAMIC_MINORS is not set
+# CONFIG_USB_SUSPEND is not set
+# CONFIG_USB_OTG is not set
+# CONFIG_USB_OTG_WHITELIST is not set
+# CONFIG_USB_OTG_BLACKLIST_HUB is not set
+
+#
+# USB Host Controller Drivers
+#
+# CONFIG_USB_C67X00_HCD is not set
+CONFIG_USB_EHCI_HCD=m
+CONFIG_USB_EHCI_ARC=y
+CONFIG_USB_EHCI_ARC_H1=y
+CONFIG_USB_EHCI_ARC_OTG=y
+# CONFIG_USB_STATIC_IRAM is not set
+# CONFIG_USB_EHCI_FSL_MC13783 is not set
+# CONFIG_USB_EHCI_FSL_1301 is not set
+# CONFIG_USB_EHCI_FSL_1504 is not set
+CONFIG_USB_EHCI_FSL_UTMI=y
+CONFIG_USB_EHCI_ROOT_HUB_TT=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+# CONFIG_USB_ISP116X_HCD is not set
+# CONFIG_USB_ISP1760_HCD is not set
+# CONFIG_USB_SL811_HCD is not set
+# CONFIG_USB_R8A66597_HCD is not set
+
+#
+# USB Device Class drivers
+#
+# CONFIG_USB_ACM is not set
+# CONFIG_USB_PRINTER is not set
+# CONFIG_USB_WDM is not set
+
+#
+# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+#
+
+#
+# may also be needed; see USB_STORAGE Help for more information
+#
+CONFIG_USB_STORAGE=y
+# CONFIG_USB_STORAGE_DEBUG is not set
+# CONFIG_USB_STORAGE_DATAFAB is not set
+# CONFIG_USB_STORAGE_FREECOM is not set
+# CONFIG_USB_STORAGE_ISD200 is not set
+# CONFIG_USB_STORAGE_DPCM is not set
+# CONFIG_USB_STORAGE_USBAT is not set
+# CONFIG_USB_STORAGE_SDDR09 is not set
+# CONFIG_USB_STORAGE_SDDR55 is not set
+# CONFIG_USB_STORAGE_JUMPSHOT is not set
+# CONFIG_USB_STORAGE_ALAUDA is not set
+# CONFIG_USB_STORAGE_ONETOUCH is not set
+# CONFIG_USB_STORAGE_KARMA is not set
+# CONFIG_USB_STORAGE_CYPRESS_ATACB is not set
+# CONFIG_USB_LIBUSUAL is not set
+
+#
+# USB Imaging devices
+#
+# CONFIG_USB_MDC800 is not set
+# CONFIG_USB_MICROTEK is not set
+# CONFIG_USB_MON is not set
+
+#
+# Belcarra USBLAN Networking for USB
+#
+# CONFIG_USB_USBLAN is not set
+
+#
+# USB port drivers
+#
+# CONFIG_USB_SERIAL is not set
+
+#
+# USB Miscellaneous drivers
+#
+# CONFIG_USB_EMI62 is not set
+# CONFIG_USB_EMI26 is not set
+# CONFIG_USB_ADUTUX is not set
+# CONFIG_USB_AUERSWALD is not set
+# CONFIG_USB_RIO500 is not set
+# CONFIG_USB_LEGOTOWER is not set
+# CONFIG_USB_LCD is not set
+# CONFIG_USB_BERRY_CHARGE is not set
+# CONFIG_USB_LED is not set
+# CONFIG_USB_CYPRESS_CY7C63 is not set
+# CONFIG_USB_CYTHERM is not set
+# CONFIG_USB_PHIDGET is not set
+# CONFIG_USB_IDMOUSE is not set
+# CONFIG_USB_FTDI_ELAN is not set
+# CONFIG_USB_APPLEDISPLAY is not set
+# CONFIG_USB_SISUSBVGA is not set
+# CONFIG_USB_LD is not set
+# CONFIG_USB_TRANCEVIBRATOR is not set
+# CONFIG_USB_IOWARRIOR is not set
+# CONFIG_USB_ISIGHTFW is not set
+CONFIG_USB_GADGET=m
+# CONFIG_USB_GADGET_DEBUG_FILES is not set
+CONFIG_USB_GADGET_SELECTED=y
+# CONFIG_USB_GADGET_AMD5536UDC is not set
+# CONFIG_USB_GADGET_ATMEL_USBA is not set
+# CONFIG_USB_GADGET_FSL_USB2 is not set
+# CONFIG_USB_GADGET_NET2280 is not set
+# CONFIG_USB_GADGET_PXA2XX is not set
+# CONFIG_USB_GADGET_M66592 is not set
+# CONFIG_USB_GADGET_PXA27X is not set
+# CONFIG_USB_GADGET_GOKU is not set
+# CONFIG_USB_GADGET_LH7A40X is not set
+# CONFIG_USB_GADGET_OMAP is not set
+CONFIG_USB_GADGET_ARC=y
+CONFIG_USB_ARC=m
+# CONFIG_USB_GADGET_S3C2410 is not set
+# CONFIG_USB_GADGET_AT91 is not set
+# CONFIG_USB_GADGET_DUMMY_HCD is not set
+CONFIG_USB_GADGET_DUALSPEED=y
+CONFIG_USB_GADGET_ARC_OTG=y
+# CONFIG_USB_GADGET_FSL_MC13783 is not set
+# CONFIG_USB_GADGET_FSL_1301 is not set
+# CONFIG_USB_GADGET_FSL_1504 is not set
+CONFIG_USB_GADGET_FSL_UTMI=y
+# CONFIG_USB_ZERO is not set
+CONFIG_USB_ETH=m
+CONFIG_USB_ETH_RNDIS=y
+CONFIG_USB_GADGETFS=m
+CONFIG_USB_FILE_STORAGE=m
+# CONFIG_USB_FILE_STORAGE_TEST is not set
+CONFIG_USB_G_SERIAL=m
+# CONFIG_USB_MIDI_GADGET is not set
+# CONFIG_USB_G_PRINTER is not set
+CONFIG_MMC=y
+# CONFIG_MMC_DEBUG is not set
+# CONFIG_MMC_UNSAFE_RESUME is not set
+
+#
+# MMC/SD Card Drivers
+#
+CONFIG_MMC_BLOCK=y
+CONFIG_MMC_BLOCK_BOUNCE=y
+# CONFIG_SDIO_UART is not set
+# CONFIG_MMC_TEST is not set
+
+#
+# MMC/SD Host Controller Drivers
+#
+# CONFIG_MMC_SPI is not set
+# CONFIG_MMC_MXC is not set
+CONFIG_MMC_IMX_ESDHCI=m
+# CONFIG_MMC_IMX_ESDHCI_PIO_MODE is not set
+CONFIG_NEW_LEDS=y
+CONFIG_LEDS_CLASS=y
+
+#
+# LED drivers
+#
+CONFIG_LEDS_MC13892=y
+
+#
+# LED Triggers
+#
+# CONFIG_LEDS_TRIGGERS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+CONFIG_RTC_INTF_DEV_UIE_EMUL=y
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# I2C RTC drivers
+#
+# CONFIG_RTC_DRV_DS1307 is not set
+# CONFIG_RTC_DRV_DS1374 is not set
+# CONFIG_RTC_DRV_DS1672 is not set
+# CONFIG_RTC_DRV_MAX6900 is not set
+# CONFIG_RTC_DRV_RS5C372 is not set
+# CONFIG_RTC_DRV_ISL1208 is not set
+# CONFIG_RTC_DRV_X1205 is not set
+# CONFIG_RTC_DRV_PCF8563 is not set
+# CONFIG_RTC_DRV_PCF8583 is not set
+# CONFIG_RTC_DRV_M41T80 is not set
+# CONFIG_RTC_DRV_S35390A is not set
+# CONFIG_RTC_DRV_FM3130 is not set
+
+#
+# SPI RTC drivers
+#
+# CONFIG_RTC_DRV_MAX6902 is not set
+# CONFIG_RTC_DRV_R9701 is not set
+# CONFIG_RTC_DRV_RS5C348 is not set
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_CMOS is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T59 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_RTC_MXC is not set
+CONFIG_RTC_DRV_MXC_V2=y
+# CONFIG_RTC_DRV_IMXDI is not set
+CONFIG_RTC_MC13892=m
+# CONFIG_UIO is not set
+
+#
+# MXC support drivers
+#
+CONFIG_MXC_IPU=y
+CONFIG_MXC_IPU_V3=y
+
+#
+# MXC SSI support
+#
+# CONFIG_MXC_SSI is not set
+
+#
+# MXC Digital Audio Multiplexer support
+#
+# CONFIG_MXC_DAM is not set
+
+#
+# MXC PMIC support
+#
+CONFIG_MXC_PMIC=y
+# CONFIG_MXC_PMIC_MC13783 is not set
+CONFIG_MXC_PMIC_MC13892=y
+# CONFIG_MXC_PMIC_MC34704 is not set
+# CONFIG_MXC_PMIC_CHARDEV is not set
+
+#
+# MXC PMIC Client Drivers
+#
+CONFIG_MXC_MC13892_ADC=y
+CONFIG_MXC_MC13892_RTC=y
+CONFIG_MXC_MC13892_LIGHT=y
+CONFIG_MXC_MC13892_BATTERY=y
+CONFIG_MXC_MC13892_CONNECTIVITY=y
+CONFIG_MXC_MC13892_POWER=y
+# CONFIG_MXC_PMIC_MC9SDZ60 is not set
+
+#
+# Advanced Power Management devices
+#
+
+#
+# MXC Security Drivers
+#
+# CONFIG_MXC_SECURITY_SCC is not set
+CONFIG_MXC_SECURITY_SCC2=y
+CONFIG_SCC_DEBUG=y
+# CONFIG_MXC_SECURITY_RNG is not set
+
+#
+# SAHARA2 Security Hardware Support
+#
+CONFIG_MXC_SAHARA=y
+CONFIG_MXC_SAHARA_USER_MODE=y
+# CONFIG_MXC_SAHARA_POLL_MODE is not set
+
+#
+# MXC MPEG4 Encoder Kernel module support
+#
+# CONFIG_MXC_HMP4E is not set
+
+#
+# MXC HARDWARE EVENT
+#
+# CONFIG_MXC_HWEVENT is not set
+
+#
+# MXC VPU(Video Processing Unit) support
+#
+CONFIG_MXC_VPU=y
+CONFIG_MXC_VPU_IRAM=y
+# CONFIG_MXC_VPU_DEBUG is not set
+
+#
+# MXC Asynchronous Sample Rate Converter support
+#
+
+#
+# MXC Bluetooth support
+#
+CONFIG_MXC_BLUETOOTH=m
+
+#
+# Broadcom GPS ioctrl support
+#
+
+#
+# MXC Media Local Bus Driver
+#
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+# CONFIG_EXT2_FS_XIP is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4DEV_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+CONFIG_AUTOFS4_FS=m
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=y
+CONFIG_MSDOS_FS=y
+CONFIG_VFAT_FS=y
+CONFIG_FAT_DEFAULT_CODEPAGE=437
+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+CONFIG_JFFS2_FS=y
+CONFIG_JFFS2_FS_DEBUG=0
+CONFIG_JFFS2_FS_WRITEBUFFER=y
+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
+# CONFIG_JFFS2_SUMMARY is not set
+# CONFIG_JFFS2_FS_XATTR is not set
+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
+CONFIG_JFFS2_ZLIB=y
+# CONFIG_JFFS2_LZO is not set
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+CONFIG_CRAMFS=y
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+CONFIG_NETWORK_FILESYSTEMS=y
+CONFIG_NFS_FS=y
+CONFIG_NFS_V3=y
+# CONFIG_NFS_V3_ACL is not set
+# CONFIG_NFS_V4 is not set
+# CONFIG_NFSD is not set
+CONFIG_ROOT_NFS=y
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_RPCSEC_GSS_KRB5 is not set
+# CONFIG_RPCSEC_GSS_SPKM3 is not set
+# CONFIG_SMB_FS is not set
+# CONFIG_CIFS is not set
+# CONFIG_NCP_FS is not set
+# CONFIG_CODA_FS is not set
+# CONFIG_AFS_FS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+CONFIG_NLS_ASCII=m
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+CONFIG_NLS_UTF8=m
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_SLUB_DEBUG_ON is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_DEBUG_BUGVERBOSE is not set
+CONFIG_FRAME_POINTER=y
+# CONFIG_SAMPLES is not set
+# CONFIG_DEBUG_USER is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_MANAGER is not set
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+# CONFIG_CRYPTO_CBC is not set
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+# CONFIG_CRYPTO_HMAC is not set
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+# CONFIG_CRYPTO_MD5 is not set
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+# CONFIG_CRYPTO_DES is not set
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+# CONFIG_GENERIC_FIND_NEXT_BIT is not set
+CONFIG_CRC_CCITT=m
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_ZLIB_INFLATE=y
+CONFIG_ZLIB_DEFLATE=y
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index de6c59f814a1..d79121248664 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -206,6 +206,7 @@ struct outer_cache_fns {
void (*inv_range)(unsigned long, unsigned long);
void (*clean_range)(unsigned long, unsigned long);
void (*flush_range)(unsigned long, unsigned long);
+ void (*flush_all)(void);
};
/*
@@ -283,6 +284,11 @@ static inline void outer_flush_range(unsigned long start, unsigned long end)
if (outer_cache.flush_range)
outer_cache.flush_range(start, end);
}
+static inline void outer_flush_all(void)
+{
+ if (outer_cache.flush_all)
+ outer_cache.flush_all();
+}
#else
@@ -292,6 +298,8 @@ static inline void outer_clean_range(unsigned long start, unsigned long end)
{ }
static inline void outer_flush_range(unsigned long start, unsigned long end)
{ }
+static inline void outer_flush_all(void)
+{ }
#endif
diff --git a/arch/arm/include/asm/hardware/cache-l2x0.h b/arch/arm/include/asm/hardware/cache-l2x0.h
index 64f2252a25cd..0024e4d49119 100644
--- a/arch/arm/include/asm/hardware/cache-l2x0.h
+++ b/arch/arm/include/asm/hardware/cache-l2x0.h
@@ -51,6 +51,8 @@
#ifndef __ASSEMBLY__
extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
+extern void l2x0_enable(void);
+extern void l2x0_disable(void);
#endif
#endif
diff --git a/arch/arm/include/asm/mach/keypad.h b/arch/arm/include/asm/mach/keypad.h
new file mode 100644
index 000000000000..cfee65ab044a
--- /dev/null
+++ b/arch/arm/include/asm/mach/keypad.h
@@ -0,0 +1,28 @@
+/*
+ * include/asm-arm/mach/keypad.h
+ *
+ * Generic Keypad struct
+ *
+ * Author: Armin Kuster <Akuster@mvista.com>
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under
+ * the terms of the GNU General Public License version 2. This program
+ * is licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ */
+
+#ifndef __ASM_MACH_KEYPAD_H_
+#define __ASM_MACH_KEYPAD_H_
+
+#include <linux/input.h>
+
+struct keypad_data {
+ u16 rowmax;
+ u16 colmax;
+ u32 irq;
+ u16 delay;
+ u16 learning;
+ u16 *matrix;
+};
+
+#endif /* __ARM_MACH_KEYPAD_H_ */
diff --git a/arch/arm/mach-mx27/Kconfig b/arch/arm/mach-mx27/Kconfig
new file mode 100644
index 000000000000..979c557085e6
--- /dev/null
+++ b/arch/arm/mach-mx27/Kconfig
@@ -0,0 +1,43 @@
+menu "MX27 Options"
+ depends on ARCH_MX27
+
+config MX27_OPTIONS
+ bool
+ default y
+ select CPU_ARM926T
+ select MXC_EMMA
+ select USB_ARCH_HAS_EHCI
+
+config MACH_MX27ADS
+ bool "Support MX27ADS platforms"
+ default y
+ help
+ Include support for MX27ADS platform. This includes specific
+ configurations for the board and its peripherals.
+
+config ARCH_MXC_HAS_NFC_V1
+ bool "MXC NFC Hardware Version 1"
+ default y
+ help
+ This selects the Freescale MXC Nand Flash Controller Hardware Version 1
+ If unsure, say N.
+
+menu "Device options"
+
+config I2C_MXC_SELECT1
+ bool "Enable I2C1 module"
+ default y
+ depends on I2C_MXC
+ help
+ Enable MX31 I2C1 module.
+
+config I2C_MXC_SELECT2
+ bool "Enable I2C2 module"
+ default n
+ depends on I2C_MXC
+ help
+ Enable MX31 I2C2 module.
+
+endmenu
+
+endmenu
diff --git a/arch/arm/mach-mx27/Makefile b/arch/arm/mach-mx27/Makefile
new file mode 100644
index 000000000000..80a0ae7c4322
--- /dev/null
+++ b/arch/arm/mach-mx27/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := mm.o dma.o gpio_mux.o clock.o devices.o serial.o system.o cpu.o dptc.o
+obj-$(CONFIG_MACH_MX27ADS) += mx27ads.o mx27ads_gpio.o
+
+# power management
+obj-$(CONFIG_PM) += pm.o mxc_pm.o
+
+obj-$(CONFIG_USB_EHCI_ARC_H1) += usb_h1.o
+obj-$(CONFIG_USB_EHCI_ARC_H2) += usb_h2.o
+
+ifneq ($(strip $(CONFIG_USB_GADGET_ARC) $(CONFIG_USB_EHCI_ARC_OTG)),)
+ obj-y += usb_dr.o
+endif
diff --git a/arch/arm/mach-mx27/Makefile.boot b/arch/arm/mach-mx27/Makefile.boot
new file mode 100644
index 000000000000..696831dcd485
--- /dev/null
+++ b/arch/arm/mach-mx27/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0xA0008000
+params_phys-y := 0xA0000100
+initrd_phys-y := 0xA0800000
diff --git a/arch/arm/mach-mx27/board-mx27ads.h b/arch/arm/mach-mx27/board-mx27ads.h
new file mode 100644
index 000000000000..fd152caef71b
--- /dev/null
+++ b/arch/arm/mach-mx27/board-mx27ads.h
@@ -0,0 +1,385 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX27ADS_H__
+#define __ASM_ARCH_MXC_BOARD_MX27ADS_H__
+
+/*!
+ * @defgroup BRDCFG_MX27 Board Configuration Options
+ * @ingroup MSL_MX27
+ */
+
+/*!
+ * @file mach-mx27/board-mx27ads.h
+ *
+ * @brief This file contains all the board level configuration options.
+ *
+ * It currently hold the options defined for MX27 ADS Platform.
+ *
+ * @ingroup BRDCFG_MX27
+ */
+
+/*
+ * Include Files
+ */
+#include <mach/mxc_uart.h>
+
+/*!
+ * @name MXC UART EVB board level configurations
+ */
+/*! @{ */
+/*!
+ * Specifies if the Irda transmit path is inverting
+ */
+#define MXC_IRDA_TX_INV 0
+/*!
+ * Specifies if the Irda receive path is inverting
+ */
+#define MXC_IRDA_RX_INV 0
+/* UART 1 configuration */
+/*!
+ * This define specifies if the UART port is configured to be in DTE or
+ * DCE mode. There exists a define like this for each UART port. Valid
+ * values that can be used are \b MODE_DTE or \b MODE_DCE.
+ */
+#define UART1_MODE MODE_DCE
+/*!
+ * This define specifies if the UART is to be used for IRDA. There exists a
+ * define like this for each UART port. Valid values that can be used are
+ * \b IRDA or \b NO_IRDA.
+ */
+#define UART1_IR NO_IRDA
+/*!
+ * This define is used to enable or disable a particular UART port. If
+ * disabled, the UART will not be registered in the file system and the user
+ * will not be able to access it. There exists a define like this for each UART
+ * port. Specify a value of 1 to enable the UART and 0 to disable it.
+ */
+#define UART1_ENABLED 1
+/*! @} */
+/* UART 2 configuration */
+#define UART2_MODE MODE_DCE
+#define UART2_IR NO_IRDA
+#define UART2_ENABLED 1
+/* UART 3 configuration */
+#define UART3_MODE MODE_DCE
+#define UART3_IR IRDA
+#define UART3_ENABLED 1
+/* UART 4 configuration */
+#define UART4_MODE MODE_DTE
+#define UART4_IR NO_IRDA
+#define UART4_ENABLED 0 /* Disable UART 4 as its pins are shared with ATA */
+/* UART 5 configuration */
+#define UART5_MODE MODE_DTE
+#define UART5_IR NO_IRDA
+#define UART5_ENABLED 1
+/* UART 6 configuration */
+#define UART6_MODE MODE_DTE
+#define UART6_IR NO_IRDA
+#define UART6_ENABLED 1
+
+#define MXC_LL_EXTUART_PADDR (CS4_BASE_ADDR + 0x20000)
+#define MXC_LL_EXTUART_VADDR (CS4_BASE_ADDR_VIRT + 0x20000)
+#define MXC_LL_EXTUART_16BIT_BUS
+
+#define MXC_LL_UART_PADDR UART1_BASE_ADDR
+#define MXC_LL_UART_VADDR AIPI_IO_ADDRESS(UART1_BASE_ADDR)
+
+/*!
+ * @name PBC Controller parameters
+ */
+/*! @{ */
+/*!
+ * Base address of PBC controller, CS4
+ */
+#define PBC_BASE_ADDRESS IO_ADDRESS(CS4_BASE_ADDR)
+#define PBC_REG_ADDR(offset) (PBC_BASE_ADDRESS + (offset))
+
+/*!
+ * PBC Interupt name definitions
+ */
+#define PBC_GPIO1_0 0
+#define PBC_GPIO1_1 1
+#define PBC_GPIO1_2 2
+#define PBC_GPIO1_3 3
+#define PBC_GPIO1_4 4
+#define PBC_GPIO1_5 5
+
+#define PBC_INTR_MAX_NUM 6
+#define PBC_INTR_SHARED_MAX_NUM 8
+
+/* When the PBC address connection is fixed in h/w, defined as 1 */
+#define PBC_ADDR_SH 0
+
+/* Offsets for the PBC Controller register */
+/*!
+ * PBC Board version register offset
+ */
+#define PBC_VERSION_REG PBC_REG_ADDR(0x00000 >> PBC_ADDR_SH)
+/*!
+ * PBC Board control register 1 set address.
+ */
+#define PBC_BCTRL1_SET_REG PBC_REG_ADDR(0x00008 >> PBC_ADDR_SH)
+/*!
+ * PBC Board control register 1 clear address.
+ */
+#define PBC_BCTRL1_CLEAR_REG PBC_REG_ADDR(0x0000C >> PBC_ADDR_SH)
+/*!
+ * PBC Board control register 2 set address.
+ */
+#define PBC_BCTRL2_SET_REG PBC_REG_ADDR(0x00010 >> PBC_ADDR_SH)
+/*!
+ * PBC Board control register 2 clear address.
+ */
+#define PBC_BCTRL2_CLEAR_REG PBC_REG_ADDR(0x00014 >> PBC_ADDR_SH)
+/*!
+ * PBC Board control register 3 set address.
+ */
+#define PBC_BCTRL3_SET_REG PBC_REG_ADDR(0x00018 >> PBC_ADDR_SH)
+/*!
+ * PBC Board control register 3 clear address.
+ */
+#define PBC_BCTRL3_CLEAR_REG PBC_REG_ADDR(0x0001C >> PBC_ADDR_SH)
+/*!
+ * PBC Board control register 3 set address.
+ */
+#define PBC_BCTRL4_SET_REG PBC_REG_ADDR(0x00020 >> PBC_ADDR_SH)
+/*!
+ * PBC Board control register 4 clear address.
+ */
+#define PBC_BCTRL4_CLEAR_REG PBC_REG_ADDR(0x00024 >> PBC_ADDR_SH)
+/*!PBC_ADDR_SH
+ * PBC Board status register 1.
+ */
+#define PBC_BSTAT1_REG PBC_REG_ADDR(0x00028 >> PBC_ADDR_SH)
+/*!
+ * PBC Board interrupt status register.
+ */
+#define PBC_INTSTATUS_REG PBC_REG_ADDR(0x0002C >> PBC_ADDR_SH)
+/*!
+ * PBC Board interrupt current status register.
+ */
+#define PBC_INTCURR_STATUS_REG PBC_REG_ADDR(0x00034 >> PBC_ADDR_SH)
+/*!
+ * PBC Interrupt mask register set address.
+ */
+#define PBC_INTMASK_SET_REG PBC_REG_ADDR(0x00038 >> PBC_ADDR_SH)
+/*!
+ * PBC Interrupt mask register clear address.
+ */
+#define PBC_INTMASK_CLEAR_REG PBC_REG_ADDR(0x0003C >> PBC_ADDR_SH)
+/*!
+ * External UART A.
+ */
+#define PBC_SC16C652_UARTA_REG PBC_REG_ADDR(0x20000 >> PBC_ADDR_SH)
+/*!
+ * UART 4 Expanding Signal Status.
+ */
+#define PBC_UART_STATUS_REG PBC_REG_ADDR(0x22000 >> PBC_ADDR_SH)
+/*!
+ * UART 4 Expanding Signal Control Set.
+ */
+#define PBC_UCTRL_SET_REG PBC_REG_ADDR(0x24000 >> PBC_ADDR_SH)
+/*!
+ * UART 4 Expanding Signal Control Clear.
+ */
+#define PBC_UCTRL_CLR_REG PBC_REG_ADDR(0x26000 >> PBC_ADDR_SH)
+/*!
+ * Ethernet Controller IO base address.
+ */
+#define PBC_CS8900A_IOBASE_REG PBC_REG_ADDR(0x40000 >> PBC_ADDR_SH)
+/*!
+ * Ethernet Controller Memory base address.
+ */
+#define PBC_CS8900A_MEMBASE_REG PBC_REG_ADDR(0x42000 >> PBC_ADDR_SH)
+/*!
+ * Ethernet Controller DMA base address.
+ */
+#define PBC_CS8900A_DMABASE_REG PBC_REG_ADDR(0x44000 >> PBC_ADDR_SH)
+
+/* PBC Board Version Register bit definition */
+#define PBC_VERSION_ADS 0x8000 /* Bit15=1 means version for ads */
+#define PBC_VERSION_EVB_REVB 0x4000 /* BIT14=1 means version for evb revb */
+
+/* PBC Board Control Register 1 bit definitions */
+#define PBC_BCTRL1_ERST 0x0001 /* Ethernet Reset */
+#define PBC_BCTRL1_URST 0x0002 /* Reset External UART controller */
+#define PBC_BCTRL1_FRST 0x0004 /* FEC Reset */
+#define PBC_BCTRL1_ESLEEP 0x0010 /* Enable ethernet Sleep */
+#define PBC_BCTRL1_LCDON 0x0800 /* Enable the LCD */
+
+/* PBC Board Control Register 2 bit definitions */
+#define PBC_BCTRL2_VCC_EN 0x0004 /* Enable VCC */
+#define PBC_BCTRL2_VPP_EN 0x0008 /* Enable Vpp */
+#define PBC_BCTRL2_ATAFEC_EN 0X0010
+#define PBC_BCTRL2_ATAFEC_SEL 0X0020
+#define PBC_BCTRL2_ATA_EN 0X0040
+#define PBC_BCTRL2_IRDA_SD 0X0080
+#define PBC_BCTRL2_IRDA_EN 0X0100
+#define PBC_BCTRL2_CCTL10 0X0200
+#define PBC_BCTRL2_CCTL11 0X0400
+
+/* PBC Board Control Register 3 bit definitions */
+#define PBC_BCTRL3_HSH_EN 0X0020
+#define PBC_BCTRL3_FSH_MOD 0X0040
+#define PBC_BCTRL3_OTG_HS_EN 0X0080
+#define PBC_BCTRL3_OTG_VBUS_EN 0X0100
+#define PBC_BCTRL3_FSH_VBUS_EN 0X0200
+#define PBC_BCTRL3_USB_OTG_ON 0X0800
+#define PBC_BCTRL3_USB_FSH_ON 0X1000
+
+/* PBC Board Control Register 4 bit definitions */
+#define PBC_BCTRL4_REGEN_SEL 0X0001
+#define PBC_BCTRL4_USER_OFF 0X0002
+#define PBC_BCTRL4_VIB_EN 0X0004
+#define PBC_BCTRL4_PWRGT1_EN 0X0008
+#define PBC_BCTRL4_PWRGT2_EN 0X0010
+#define PBC_BCTRL4_STDBY_PRI 0X0020
+
+#ifndef __ASSEMBLY__
+/*!
+ * Enumerations for SD cards and memory stick card. This corresponds to
+ * the card EN bits in the IMR: SD1_EN | MS_EN | SD3_EN | SD2_EN.
+ */
+enum mxc_card_no {
+ MXC_CARD_SD2 = 0,
+ MXC_CARD_SD3,
+ MXC_CARD_MS,
+ MXC_CARD_SD1,
+ MXC_CARD_MIN = MXC_CARD_SD2,
+ MXC_CARD_MAX = MXC_CARD_SD1,
+};
+#endif
+
+#define MXC_CPLD_VER_1_50 0x01
+
+/*!
+ * PBC BSTAT Register bit definitions
+ */
+#define PBC_BSTAT_PRI_INT 0X0001
+#define PBC_BSTAT_USB_BYP 0X0002
+#define PBC_BSTAT_ATA_IOCS16 0X0004
+#define PBC_BSTAT_ATA_CBLID 0X0008
+#define PBC_BSTAT_ATA_DASP 0X0010
+#define PBC_BSTAT_PWR_RDY 0X0020
+#define PBC_BSTAT_SD3_WP 0X0100
+#define PBC_BSTAT_SD2_WP 0X0200
+#define PBC_BSTAT_SD1_WP 0X0400
+#define PBC_BSTAT_SD3_DET 0X0800
+#define PBC_BSTAT_SD2_DET 0X1000
+#define PBC_BSTAT_SD1_DET 0X2000
+#define PBC_BSTAT_MS_DET 0X4000
+#define PBC_BSTAT_SD3_DET_BIT 11
+#define PBC_BSTAT_SD2_DET_BIT 12
+#define PBC_BSTAT_SD1_DET_BIT 13
+#define PBC_BSTAT_MS_DET_BIT 14
+#define MXC_BSTAT_BIT(n) ((n == MXC_CARD_SD2) ? PBC_BSTAT_SD2_DET : \
+ ((n == MXC_CARD_SD3) ? PBC_BSTAT_SD3_DET : \
+ ((n == MXC_CARD_SD1) ? PBC_BSTAT_SD1_DET : \
+ ((n == MXC_CARD_MS) ? PBC_BSTAT_MS_DET : 0x0))))
+
+/*!
+ * PBC UART Control Register bit definitions
+ */
+#define PBC_UCTRL_DCE_DCD 0X0001
+#define PBC_UCTRL_DCE_DSR 0X0002
+#define PBC_UCTRL_DCE_RI 0X0004
+#define PBC_UCTRL_DTE_DTR 0X0100
+
+/*!
+ * PBC UART Status Register bit definitions
+ */
+#define PBC_USTAT_DTE_DCD 0X0001
+#define PBC_USTAT_DTE_DSR 0X0002
+#define PBC_USTAT_DTE_RI 0X0004
+#define PBC_USTAT_DCE_DTR 0X0100
+
+/*!
+ * PBC Interupt mask register bit definitions
+ */
+#define PBC_INTR_SD3_R_EN_BIT 4
+#define PBC_INTR_SD2_R_EN_BIT 0
+#define PBC_INTR_SD1_R_EN_BIT 6
+#define PBC_INTR_MS_R_EN_BIT 5
+#define PBC_INTR_SD3_EN_BIT 13
+#define PBC_INTR_SD2_EN_BIT 12
+#define PBC_INTR_MS_EN_BIT 14
+#define PBC_INTR_SD1_EN_BIT 15
+
+#define PBC_INTR_SD2_R_EN 0x0001
+#define PBC_INTR_LOW_BAT 0X0002
+#define PBC_INTR_OTG_FSOVER 0X0004
+#define PBC_INTR_FSH_OVER 0X0008
+#define PBC_INTR_SD3_R_EN 0x0010
+#define PBC_INTR_MS_R_EN 0x0020
+#define PBC_INTR_SD1_R_EN 0x0040
+#define PBC_INTR_FEC_INT 0X0080
+#define PBC_INTR_ENET_INT 0X0100
+#define PBC_INTR_OTGFS_INT 0X0200
+#define PBC_INTR_XUART_INT 0X0400
+#define PBC_INTR_CCTL12 0X0800
+#define PBC_INTR_SD2_EN 0x1000
+#define PBC_INTR_SD3_EN 0x2000
+#define PBC_INTR_MS_EN 0x4000
+#define PBC_INTR_SD1_EN 0x8000
+
+/*! @} */
+
+#define CKIH_27MHZ_BIT_SET (1 << 3)
+
+/* For interrupts like xuart, enet etc */
+#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX27_PIN_TIN)
+
+/*
+ * This corresponds to PBC_INTMASK_SET_REG at offset 0x38.
+ *
+ */
+#define EXPIO_INT_LOW_BAT (MXC_EXP_IO_BASE + 1)
+#define EXPIO_INT_OTG_FS_OVR (MXC_EXP_IO_BASE + 2)
+#define EXPIO_INT_FSH_OVR (MXC_EXP_IO_BASE + 3)
+#define EXPIO_INT_RES4 (MXC_EXP_IO_BASE + 4)
+#define EXPIO_INT_RES5 (MXC_EXP_IO_BASE + 5)
+#define EXPIO_INT_RES6 (MXC_EXP_IO_BASE + 6)
+#define EXPIO_INT_FEC (MXC_EXP_IO_BASE + 7)
+#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8)
+#define EXPIO_INT_OTG_FS_INT (MXC_EXP_IO_BASE + 9)
+#define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10)
+#define EXPIO_INT_CCTL12_INT (MXC_EXP_IO_BASE + 11)
+#define EXPIO_INT_SD2_EN (MXC_EXP_IO_BASE + 12)
+#define EXPIO_INT_SD3_EN (MXC_EXP_IO_BASE + 13)
+#define EXPIO_INT_MS_EN (MXC_EXP_IO_BASE + 14)
+#define EXPIO_INT_SD1_EN (MXC_EXP_IO_BASE + 15)
+
+/*! This is System IRQ used by CS8900A for interrupt generation taken from platform.h */
+#define CS8900AIRQ EXPIO_INT_ENET_INT
+/*! This is I/O Base address used to access registers of CS8900A on MXC ADS */
+#define CS8900A_BASE_ADDRESS (PBC_CS8900A_IOBASE_REG + 0x300)
+
+#define MXC_PMIC_INT_LINE IOMUX_TO_IRQ(MX27_PIN_TOUT)
+
+/*!
+* This is used to detect if the CPLD version is for mx27 evb board rev-a
+*/
+#define PBC_CPLD_VERSION_IS_REVA() \
+ ((__raw_readw(PBC_VERSION_REG) & \
+ (PBC_VERSION_ADS | PBC_VERSION_EVB_REVB))\
+ == 0)
+
+#define MXC_BD_LED1 (1 << 5)
+#define MXC_BD_LED2 (1 << 6)
+#define MXC_BD_LED_ON(led) \
+ __raw_writew(led, PBC_BCTRL1_SET_REG)
+#define MXC_BD_LED_OFF(led) \
+ __raw_writew(led, PBC_BCTRL1_CLEAR_REG)
+
+#endif /* __ASM_ARCH_MXC_BOARD_MX27ADS_H__ */
diff --git a/arch/arm/mach-mx27/clock.c b/arch/arm/mach-mx27/clock.c
new file mode 100644
index 000000000000..49444a21902a
--- /dev/null
+++ b/arch/arm/mach-mx27/clock.c
@@ -0,0 +1,1530 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <mach/clock.h>
+#include "crm_regs.h"
+
+#define CKIH_CLK_FREQ 26000000 /* 26M reference clk */
+#define CKIH_CLK_FREQ_27MHZ 27000000
+#define CKIL_CLK_FREQ 32768 /* 32.768k oscillator in */
+
+static struct clk ckil_clk;
+static struct clk mpll_clk;
+static struct clk mpll_main_clk[];
+static struct clk spll_clk;
+
+static int _clk_enable(struct clk *clk)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void _clk_disable(struct clk *clk)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(1 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static int _clk_spll_enable(struct clk *clk)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(CCM_CSCR);
+ reg |= CCM_CSCR_SPEN;
+ __raw_writel(reg, CCM_CSCR);
+
+ while ((__raw_readl(CCM_SPCTL1) & CCM_SPCTL1_LF) == 0) ;
+
+ return 0;
+}
+
+static void _clk_spll_disable(struct clk *clk)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(CCM_CSCR);
+ reg &= ~CCM_CSCR_SPEN;
+ __raw_writel(reg, CCM_CSCR);
+}
+
+static void _clk_pccr01_enable(unsigned long mask0, unsigned long mask1)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(CCM_PCCR0);
+ reg |= mask0;
+ __raw_writel(reg, CCM_PCCR0);
+
+ reg = __raw_readl(CCM_PCCR1);
+ reg |= mask1;
+ __raw_writel(reg, CCM_PCCR1);
+
+}
+
+static void _clk_pccr01_disable(unsigned long mask0, unsigned long mask1)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(CCM_PCCR0);
+ reg &= ~mask0;
+ __raw_writel(reg, CCM_PCCR0);
+
+ reg = __raw_readl(CCM_PCCR1);
+ reg &= ~mask1;
+ __raw_writel(reg, CCM_PCCR1);
+}
+
+static void _clk_pccr10_enable(unsigned long mask1, unsigned long mask0)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(CCM_PCCR1);
+ reg |= mask1;
+ __raw_writel(reg, CCM_PCCR1);
+
+ reg = __raw_readl(CCM_PCCR0);
+ reg |= mask0;
+ __raw_writel(reg, CCM_PCCR0);
+}
+
+static void _clk_pccr10_disable(unsigned long mask1, unsigned long mask0)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(CCM_PCCR1);
+ reg &= ~mask1;
+ __raw_writel(reg, CCM_PCCR1);
+
+ reg = __raw_readl(CCM_PCCR0);
+ reg &= ~mask0;
+ __raw_writel(reg, CCM_PCCR0);
+}
+
+static int _clk_dma_enable(struct clk *clk)
+{
+ _clk_pccr01_enable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK);
+
+ return 0;
+}
+
+static void _clk_dma_disable(struct clk *clk)
+{
+ _clk_pccr01_disable(CCM_PCCR0_DMA_MASK, CCM_PCCR1_HCLK_DMA_MASK);
+}
+
+static int _clk_rtic_enable(struct clk *clk)
+{
+ _clk_pccr01_enable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK);
+
+ return 0;
+}
+
+static void _clk_rtic_disable(struct clk *clk)
+{
+ _clk_pccr01_disable(CCM_PCCR0_RTIC_MASK, CCM_PCCR1_HCLK_RTIC_MASK);
+}
+
+static int _clk_emma_enable(struct clk *clk)
+{
+ _clk_pccr01_enable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK);
+
+ return 0;
+}
+
+static void _clk_emma_disable(struct clk *clk)
+{
+ _clk_pccr01_disable(CCM_PCCR0_EMMA_MASK, CCM_PCCR1_HCLK_EMMA_MASK);
+}
+
+static int _clk_slcdc_enable(struct clk *clk)
+{
+ _clk_pccr01_enable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK);
+
+ return 0;
+}
+
+static void _clk_slcdc_disable(struct clk *clk)
+{
+ _clk_pccr01_disable(CCM_PCCR0_SLCDC_MASK, CCM_PCCR1_HCLK_SLCDC_MASK);
+}
+
+static int _clk_fec_enable(struct clk *clk)
+{
+ _clk_pccr01_enable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK);
+
+ return 0;
+}
+
+static void _clk_fec_disable(struct clk *clk)
+{
+ _clk_pccr01_disable(CCM_PCCR0_FEC_MASK, CCM_PCCR1_HCLK_FEC_MASK);
+}
+
+static int _clk_vpu_enable(struct clk *clk)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(CCM_PCCR1);
+ reg |= CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK;
+ __raw_writel(reg, CCM_PCCR1);
+
+ return 0;
+}
+
+static void _clk_vpu_disable(struct clk *clk)
+{
+ unsigned long reg;
+
+ reg = __raw_readl(CCM_PCCR1);
+ reg &= ~(CCM_PCCR1_VPU_BAUD_MASK | CCM_PCCR1_HCLK_VPU_MASK);
+ __raw_writel(reg, CCM_PCCR1);
+}
+
+static int _clk_sahara2_enable(struct clk *clk)
+{
+ _clk_pccr01_enable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK);
+
+ return 0;
+}
+
+static void _clk_sahara2_disable(struct clk *clk)
+{
+ _clk_pccr01_disable(CCM_PCCR0_SAHARA_MASK, CCM_PCCR1_HCLK_SAHARA_MASK);
+}
+
+static int _clk_mstick1_enable(struct clk *clk)
+{
+ _clk_pccr10_enable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK);
+
+ return 0;
+}
+
+static void _clk_mstick1_disable(struct clk *clk)
+{
+ _clk_pccr10_disable(CCM_PCCR1_MSHC_BAUD_MASK, CCM_PCCR0_MSHC_MASK);
+}
+
+#define CSCR() (__raw_readl(CCM_CSCR))
+#define PCDR0() (__raw_readl(CCM_PCDR0))
+#define PCDR1() (__raw_readl(CCM_PCDR1))
+
+static void _clk_pll_recalc(struct clk *clk)
+{
+ unsigned long mfi = 0, mfn = 0, mfd = 0, pdf = 0;
+ unsigned long ref_clk;
+ unsigned long reg;
+ unsigned long long temp;
+
+ ref_clk = clk->parent->rate;
+ if (clk->parent == &ckil_clk) {
+ ref_clk *= 1024;
+ }
+
+ if (clk == &mpll_clk) {
+ reg = __raw_readl(CCM_MPCTL0);
+ pdf = (reg & CCM_MPCTL0_PD_MASK) >> CCM_MPCTL0_PD_OFFSET;
+ mfd = (reg & CCM_MPCTL0_MFD_MASK) >> CCM_MPCTL0_MFD_OFFSET;
+ mfi = (reg & CCM_MPCTL0_MFI_MASK) >> CCM_MPCTL0_MFI_OFFSET;
+ mfn = (reg & CCM_MPCTL0_MFN_MASK) >> CCM_MPCTL0_MFN_OFFSET;
+ } else if (clk == &spll_clk) {
+ reg = __raw_readl(CCM_SPCTL0);
+ /*TODO: This is TO2 Bug */
+ if (cpu_is_mx27_rev(CHIP_REV_2_0) == 1) {
+ __raw_writel(reg, CCM_SPCTL0);
+ }
+ pdf = (reg & CCM_SPCTL0_PD_MASK) >> CCM_SPCTL0_PD_OFFSET;
+ mfd = (reg & CCM_SPCTL0_MFD_MASK) >> CCM_SPCTL0_MFD_OFFSET;
+ mfi = (reg & CCM_SPCTL0_MFI_MASK) >> CCM_SPCTL0_MFI_OFFSET;
+ mfn = (reg & CCM_SPCTL0_MFN_MASK) >> CCM_SPCTL0_MFN_OFFSET;
+ } else {
+ BUG(); /* oops */
+ }
+
+ mfi = (mfi <= 5) ? 5 : mfi;
+ temp = 2LL * ref_clk * mfn;
+ do_div(temp, mfd + 1);
+ temp = 2LL * ref_clk * mfi + temp;
+ do_div(temp, pdf + 1);
+
+ clk->rate = temp;
+}
+
+static void _clk_mpll_main_recalc(struct clk *clk)
+{
+ /* i.MX27 TO2:
+ * clk->id == 0: arm clock source path 1 which is from 2*MPLL/DIV_2
+ * clk->id == 1: arm clock source path 2 which is from 2*MPLL/DIV_3
+ */
+ switch (clk->id) {
+ case 0:
+ clk->rate = clk->parent->rate;
+ break;
+ case 1:
+ clk->rate = 2 * clk->parent->rate / 3;
+ }
+}
+
+static int _clk_cpu_set_parent(struct clk *clk, struct clk *parent)
+{
+ int cscr = CSCR();
+
+ if (clk->parent == parent)
+ return 0;
+
+ if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) {
+ if (parent == &mpll_main_clk[0]) {
+ cscr |= CCM_CSCR_ARM_SRC;
+ } else {
+ if (parent == &mpll_main_clk[1]) {
+ cscr &= ~CCM_CSCR_ARM_SRC;
+ } else {
+ return -EINVAL;
+ }
+ }
+ __raw_writel(cscr, CCM_CSCR);
+ } else {
+ return -ENODEV;
+ }
+ clk->parent = parent;
+ return 0;
+}
+
+static unsigned long _clk_cpu_round_rate(struct clk *clk, unsigned long rate)
+{
+ int div;
+ div = clk->parent->rate / rate;
+ if (clk->parent->rate % rate) {
+ div++;
+ }
+
+ if (div > 4) {
+ div = 4;
+ }
+ return clk->parent->rate / div;
+}
+
+static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate)
+{
+ int div, reg;
+ div = clk->parent->rate / rate;
+
+ if (div > 4 || div < 1 || ((clk->parent->rate / div) != rate)) {
+ return -EINVAL;
+ }
+ div--;
+
+ reg = (CSCR() & ~CCM_CSCR_ARM_MASK) | (div << CCM_CSCR_ARM_OFFSET);
+ __raw_writel(reg, CCM_CSCR);
+ clk->rate = rate;
+ return 0;
+}
+
+static void _clk_cpu_recalc(struct clk *clk)
+{
+ unsigned long div;
+
+ if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) {
+ div = (CSCR() & CCM_CSCR_ARM_MASK) >> CCM_CSCR_ARM_OFFSET;
+ } else {
+ div = (CSCR() & CCM_CSCR_PRESC_MASK) >> CCM_CSCR_PRESC_OFFSET;
+ }
+
+ clk->rate = clk->parent->rate / (div + 1);
+}
+
+static void _clk_ahb_recalc(struct clk *clk)
+{
+ unsigned long bclk_pdf;
+
+ if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) {
+ bclk_pdf = (CSCR() & CCM_CSCR_AHB_MASK) >> CCM_CSCR_AHB_OFFSET;
+ } else {
+ bclk_pdf =
+ (CSCR() & CCM_CSCR_BCLK_MASK) >> CCM_CSCR_BCLK_OFFSET;
+ }
+ clk->rate = clk->parent->rate / (bclk_pdf + 1);
+}
+
+static void _clk_perclkx_recalc(struct clk *clk)
+{
+ unsigned long perclk_pdf;
+
+ if (clk->id < 0 || clk->id > 3)
+ return;
+
+ perclk_pdf = (PCDR1() >> (clk->id << 3)) & CCM_PCDR1_PERDIV1_MASK;
+
+ clk->rate = clk->parent->rate / (perclk_pdf + 1);
+}
+
+static unsigned long _clk_perclkx_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+
+ div = clk->parent->rate / rate;
+ if (clk->parent->rate % rate)
+ div++;
+
+ if (div > 64) {
+ div = 64;
+ }
+
+ return clk->parent->rate / div;
+}
+
+static int _clk_perclkx_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+
+ if (clk->id < 0 || clk->id > 3)
+ return -EINVAL;
+
+ div = clk->parent->rate / rate;
+ if (div > 64 || div < 1 || ((clk->parent->rate / div) != rate)) {
+ return -EINVAL;
+ }
+ div--;
+
+ reg =
+ __raw_readl(CCM_PCDR1) & ~(CCM_PCDR1_PERDIV1_MASK <<
+ (clk->id << 3));
+ reg |= div << (clk->id << 3);
+ __raw_writel(reg, CCM_PCDR1);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+static void _clk_usb_recalc(struct clk *clk)
+{
+ unsigned long usb_pdf;
+
+ usb_pdf = (CSCR() & CCM_CSCR_USB_MASK) >> CCM_CSCR_USB_OFFSET;
+
+ clk->rate = clk->parent->rate / (usb_pdf + 1);
+}
+
+static void _clk_ssi1_recalc(struct clk *clk)
+{
+ unsigned long ssi1_pdf;
+
+ ssi1_pdf = (PCDR0() & CCM_PCDR0_SSI1BAUDDIV_MASK) >>
+ CCM_PCDR0_SSI1BAUDDIV_OFFSET;
+
+ if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) {
+ ssi1_pdf += 4;
+ } else {
+ ssi1_pdf = (ssi1_pdf < 2) ? 124 : ssi1_pdf;
+ }
+
+ clk->rate = 2 * clk->parent->rate / ssi1_pdf;
+}
+
+static void _clk_ssi2_recalc(struct clk *clk)
+{
+ unsigned long ssi2_pdf;
+
+ ssi2_pdf = (PCDR0() & CCM_PCDR0_SSI2BAUDDIV_MASK) >>
+ CCM_PCDR0_SSI2BAUDDIV_OFFSET;
+
+ if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) {
+ ssi2_pdf += 4;
+ } else {
+ ssi2_pdf = (ssi2_pdf < 2) ? 124 : ssi2_pdf;
+ }
+
+ clk->rate = 2 * clk->parent->rate / ssi2_pdf;
+}
+
+static void _clk_nfc_recalc(struct clk *clk)
+{
+ unsigned long nfc_pdf;
+
+ if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) {
+ nfc_pdf =
+ (PCDR0() & CCM_PCDR0_NFCDIV2_MASK) >>
+ CCM_PCDR0_NFCDIV2_OFFSET;
+ } else {
+ nfc_pdf =
+ (PCDR0() & CCM_PCDR0_NFCDIV_MASK) >>
+ CCM_PCDR0_NFCDIV_OFFSET;
+ }
+
+ clk->rate = clk->parent->rate / (nfc_pdf + 1);
+}
+
+static void _clk_vpu_recalc(struct clk *clk)
+{
+ unsigned long vpu_pdf;
+
+ if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) {
+ vpu_pdf =
+ (PCDR0() & CCM_PCDR0_VPUDIV2_MASK) >>
+ CCM_PCDR0_VPUDIV2_OFFSET;
+ vpu_pdf += 4;
+ } else {
+ vpu_pdf =
+ (PCDR0() & CCM_PCDR0_VPUDIV_MASK) >>
+ CCM_PCDR0_VPUDIV_OFFSET;
+ vpu_pdf = (vpu_pdf < 2) ? 124 : vpu_pdf;
+ }
+ clk->rate = 2 * clk->parent->rate / vpu_pdf;
+}
+
+static void _clk_ipg_recalc(struct clk *clk)
+{
+ unsigned long ipg_pdf;
+
+ if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) {
+ ipg_pdf = 1;
+ } else {
+ ipg_pdf = (CSCR() & CCM_CSCR_IPDIV) >> CCM_CSCR_IPDIV_OFFSET;
+ }
+
+ clk->rate = clk->parent->rate / (ipg_pdf + 1);
+}
+
+static unsigned long _clk_parent_round_rate(struct clk *clk, unsigned long rate)
+{
+ return clk->parent->round_rate(clk->parent, rate);
+}
+
+static int _clk_parent_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret;
+ if ((ret = clk->parent->set_rate(clk->parent, rate)) == 0)
+ clk->rate = rate;
+ return ret;
+}
+
+static struct clk ckih_clk = {
+ .name = "ckih",
+ .rate = 0, /* determined at boot time (26 or 27 MHz) */
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk ckil_clk = {
+ .name = "ckil",
+ .rate = CKIL_CLK_FREQ,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk mpll_clk = {
+ .name = "mpll",
+ .parent = &ckih_clk,
+ .recalc = _clk_pll_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk mpll_main_clk[] = {
+ {
+ /* For i.MX27 TO2, it is the MPLL path 1 of ARM core
+ * It provide the clock source whose rate is same as MPLL
+ */
+ .name = "mpll_main",
+ .id = 0,
+ .parent = &mpll_clk,
+ .recalc = _clk_mpll_main_recalc,},
+ {
+ /* For i.MX27 TO2, it is the MPLL path 1 of ARM core
+ * It provide the clock source whose rate is same as MPLL
+ */
+ .name = "mpll_main",
+ .id = 1,
+ .parent = &mpll_clk,
+ .recalc = _clk_mpll_main_recalc,}
+};
+
+static struct clk spll_clk = {
+ .name = "spll",
+ .parent = &ckih_clk,
+ .recalc = _clk_pll_recalc,
+ .enable = _clk_spll_enable,
+ .disable = _clk_spll_disable,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk cpu_clk = {
+ .name = "cpu_clk",
+ .parent = &mpll_main_clk[1],
+ .set_parent = _clk_cpu_set_parent,
+ .round_rate = _clk_cpu_round_rate,
+ .set_rate = _clk_cpu_set_rate,
+ .recalc = _clk_cpu_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk ahb_clk = {
+ .name = "ahb_clk",
+ .parent = &mpll_main_clk[1],
+ .recalc = _clk_ahb_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk ipg_clk = {
+ .name = "ipg_clk",
+ .parent = &ahb_clk,
+ .recalc = _clk_ipg_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk per_clk[] = {
+ {
+ .name = "per_clk",
+ .id = 0,
+ .parent = &mpll_main_clk[1],
+ .recalc = _clk_perclkx_recalc,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_PERCLK1_OFFSET,
+ .disable = _clk_disable,
+ .flags = RATE_PROPAGATES,},
+ {
+ .name = "per_clk",
+ .id = 1,
+ .parent = &mpll_main_clk[1],
+ .recalc = _clk_perclkx_recalc,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_PERCLK2_OFFSET,
+ .disable = _clk_disable,
+ .flags = RATE_PROPAGATES,},
+ {
+ .name = "per_clk",
+ .id = 2,
+ .parent = &mpll_main_clk[1],
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .recalc = _clk_perclkx_recalc,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_PERCLK3_OFFSET,
+ .disable = _clk_disable,
+ .flags = RATE_PROPAGATES,},
+ {
+ .name = "per_clk",
+ .id = 3,
+ .parent = &mpll_main_clk[1],
+ .round_rate = _clk_perclkx_round_rate,
+ .set_rate = _clk_perclkx_set_rate,
+ .recalc = _clk_perclkx_recalc,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_PERCLK4_OFFSET,
+ .disable = _clk_disable,
+ .flags = RATE_PROPAGATES,},
+};
+
+struct clk uart1_clk[] = {
+ {
+ .name = "uart_clk",
+ .id = 0,
+ .parent = &per_clk[0],
+ .secondary = &uart1_clk[1],},
+ {
+ .name = "uart_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_UART1_OFFSET,
+ .disable = _clk_disable,},
+};
+
+struct clk uart2_clk[] = {
+ {
+ .name = "uart_clk",
+ .id = 1,
+ .parent = &per_clk[0],
+ .secondary = &uart2_clk[1],},
+ {
+ .name = "uart_ipg_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_UART2_OFFSET,
+ .disable = _clk_disable,},
+};
+
+struct clk uart3_clk[] = {
+ {
+ .name = "uart_clk",
+ .id = 2,
+ .parent = &per_clk[0],
+ .secondary = &uart3_clk[1],},
+ {
+ .name = "uart_ipg_clk",
+ .id = 2,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_UART3_OFFSET,
+ .disable = _clk_disable,},
+};
+
+struct clk uart4_clk[] = {
+ {
+ .name = "uart_clk",
+ .id = 3,
+ .parent = &per_clk[0],
+ .secondary = &uart4_clk[1],},
+ {
+ .name = "uart_ipg_clk",
+ .id = 3,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_UART4_OFFSET,
+ .disable = _clk_disable,},
+};
+
+struct clk uart5_clk[] = {
+ {
+ .name = "uart_clk",
+ .id = 4,
+ .parent = &per_clk[0],
+ .secondary = &uart5_clk[1],},
+ {
+ .name = "uart_ipg_clk",
+ .id = 4,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_UART5_OFFSET,
+ .disable = _clk_disable,},
+};
+
+struct clk uart6_clk[] = {
+ {
+ .name = "uart_clk",
+ .id = 5,
+ .parent = &per_clk[0],
+ .secondary = &uart6_clk[1],},
+ {
+ .name = "uart_ipg_clk",
+ .id = 5,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_UART6_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk gpt1_clk[] = {
+ {
+ .name = "gpt_clk",
+ .id = 0,
+ .parent = &per_clk[0],
+ .secondary = &gpt1_clk[1],},
+ {
+ .name = "gpt_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_GPT1_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk gpt2_clk[] = {
+ {
+ .name = "gpt_clk",
+ .id = 1,
+ .parent = &per_clk[0],
+ .secondary = &gpt2_clk[1],},
+ {
+ .name = "gpt_ipg_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_GPT2_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk gpt3_clk[] = {
+ {
+ .name = "gpt_clk",
+ .id = 2,
+ .parent = &per_clk[0],
+ .secondary = &gpt3_clk[1],},
+ {
+ .name = "gpt_ipg_clk",
+ .id = 2,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_GPT3_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk gpt4_clk[] = {
+ {
+ .name = "gpt_clk",
+ .id = 3,
+ .parent = &per_clk[0],
+ .secondary = &gpt4_clk[1],},
+ {
+ .name = "gpt_ipg_clk",
+ .id = 3,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_GPT4_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk gpt5_clk[] = {
+ {
+ .name = "gpt_clk",
+ .id = 4,
+ .parent = &per_clk[0],
+ .secondary = &gpt5_clk[1],},
+ {
+ .name = "gpt_ipg_clk",
+ .id = 4,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_GPT5_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk gpt6_clk[] = {
+ {
+ .name = "gpt_clk",
+ .id = 5,
+ .parent = &per_clk[0],
+ .secondary = &gpt6_clk[1],},
+ {
+ .name = "gpt_ipg_clk",
+ .id = 5,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_GPT6_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk pwm_clk[] = {
+ {
+ .name = "pwm_clk",
+ .parent = &per_clk[0],
+ .secondary = &pwm_clk[1],},
+ {
+ .name = "pwm_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_PWM_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk sdhc1_clk[] = {
+ {
+ .name = "sdhc_clk",
+ .id = 0,
+ .parent = &per_clk[1],
+ .secondary = &sdhc1_clk[1],},
+ {
+ .name = "sdhc_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_SDHC1_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk sdhc2_clk[] = {
+ {
+ .name = "sdhc_clk",
+ .id = 1,
+ .parent = &per_clk[1],
+ .secondary = &sdhc2_clk[1],},
+ {
+ .name = "sdhc_ipg_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_SDHC2_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk sdhc3_clk[] = {
+ {
+ .name = "sdhc_clk",
+ .id = 2,
+ .parent = &per_clk[1],
+ .secondary = &sdhc3_clk[1],},
+ {
+ .name = "sdhc_ipg_clk",
+ .id = 2,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_SDHC3_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk cspi1_clk[] = {
+ {
+ .name = "cspi_clk",
+ .id = 0,
+ .parent = &per_clk[1],
+ .secondary = &cspi1_clk[1],},
+ {
+ .name = "cspi_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_CSPI1_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk cspi2_clk[] = {
+ {
+ .name = "cspi_clk",
+ .id = 1,
+ .parent = &per_clk[1],
+ .secondary = &cspi2_clk[1],},
+ {
+ .name = "cspi_ipg_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_CSPI2_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk cspi3_clk[] = {
+ {
+ .name = "cspi_clk",
+ .id = 2,
+ .parent = &per_clk[1],
+ .secondary = &cspi3_clk[1],},
+ {
+ .name = "cspi_ipg_clk",
+ .id = 2,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_CSPI3_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk lcdc_clk[] = {
+ {
+ .name = "lcdc_clk",
+ .parent = &per_clk[2],
+ .secondary = &lcdc_clk[1],
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,},
+ {
+ .name = "lcdc_ipg_clk",
+ .parent = &ipg_clk,
+ .secondary = &lcdc_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_LCDC_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "lcdc_ahb_clk",
+ .parent = &ahb_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_HCLK_LCDC_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk csi_clk[] = {
+ {
+ .name = "csi_perclk",
+ .parent = &per_clk[3],
+ .secondary = &csi_clk[1],
+ .round_rate = _clk_parent_round_rate,
+ .set_rate = _clk_parent_set_rate,},
+ {
+ .name = "csi_ahb_clk",
+ .parent = &ahb_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_HCLK_CSI_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk usb_clk[] = {
+ {
+ .name = "usb_clk",
+ .parent = &spll_clk,
+ .recalc = _clk_usb_recalc,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_USBOTG_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "usb_ahb_clk",
+ .parent = &ahb_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_HCLK_USBOTG_OFFSET,
+ .disable = _clk_disable,}
+};
+
+static struct clk ssi1_clk[] = {
+ {
+ .name = "ssi_clk",
+ .id = 0,
+ .parent = &mpll_main_clk[1],
+ .secondary = &ssi1_clk[1],
+ .recalc = _clk_ssi1_recalc,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_SSI1_BAUD_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "ssi_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_SSI1_IPG_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk ssi2_clk[] = {
+ {
+ .name = "ssi_clk",
+ .id = 1,
+ .parent = &mpll_main_clk[1],
+ .secondary = &ssi2_clk[1],
+ .recalc = _clk_ssi2_recalc,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_SSI2_BAUD_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "ssi_ipg_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_SSI2_IPG_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk nfc_clk = {
+ .name = "nfc_clk",
+ .parent = &cpu_clk,
+ .recalc = _clk_nfc_recalc,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_NFC_BAUD_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk vpu_clk = {
+ .name = "vpu_clk",
+ .parent = &mpll_main_clk[1],
+ .recalc = _clk_vpu_recalc,
+ .enable = _clk_vpu_enable,
+ .disable = _clk_vpu_disable,
+};
+
+static struct clk dma_clk = {
+ .name = "dma_clk",
+ .parent = &ahb_clk,
+ .enable = _clk_dma_enable,
+ .disable = _clk_dma_disable,
+};
+
+static struct clk rtic_clk = {
+ .name = "rtic_clk",
+ .parent = &ahb_clk,
+ .enable = _clk_rtic_enable,
+ .disable = _clk_rtic_disable,
+};
+
+static struct clk brom_clk = {
+ .name = "brom_clk",
+ .parent = &ahb_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_HCLK_BROM_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk emma_clk = {
+ .name = "emma_clk",
+ .parent = &ahb_clk,
+ .enable = _clk_emma_enable,
+ .disable = _clk_emma_disable,
+};
+
+static struct clk slcdc_clk = {
+ .name = "slcdc_clk",
+ .parent = &ahb_clk,
+ .enable = _clk_slcdc_enable,
+ .disable = _clk_slcdc_disable,
+};
+
+static struct clk fec_clk = {
+ .name = "fec_clk",
+ .parent = &ahb_clk,
+ .enable = _clk_fec_enable,
+ .disable = _clk_fec_disable,
+};
+
+static struct clk emi_clk = {
+ .name = "emi_clk",
+ .parent = &ahb_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_HCLK_EMI_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk sahara2_clk = {
+ .name = "sahara_clk",
+ .parent = &ahb_clk,
+ .enable = _clk_sahara2_enable,
+ .disable = _clk_sahara2_disable,
+};
+
+static struct clk ata_clk = {
+ .name = "ata_clk",
+ .parent = &ahb_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_HCLK_ATA_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk mstick1_clk = {
+ .name = "mstick1_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_mstick1_enable,
+ .disable = _clk_mstick1_disable,
+};
+
+static struct clk wdog_clk = {
+ .name = "wdog_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR1_WDT_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk gpio_clk = {
+ .name = "gpio_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR1,
+ .enable_shift = CCM_PCCR0_GPIO_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk i2c_clk[] = {
+ {
+ .name = "i2c_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_I2C1_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "i2c_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_I2C2_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk iim_clk = {
+ .name = "iim_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_IIM_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk kpp_clk = {
+ .name = "kpp_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_KPP_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk owire_clk = {
+ .name = "owire_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_OWIRE_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk rtc_clk = {
+ .name = "rtc_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_RTC_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk scc_clk = {
+ .name = "scc_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = CCM_PCCR0,
+ .enable_shift = CCM_PCCR0_SCC_OFFSET,
+ .disable = _clk_disable,
+};
+
+static unsigned long _clk_clko_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 div;
+
+ div = clk->parent->rate / rate;
+ if (clk->parent->rate % rate)
+ div++;
+
+ if (div > 8) {
+ div = 8;
+ }
+
+ return clk->parent->rate / div;
+}
+
+static int _clk_clko_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+
+ div = clk->parent->rate / rate;
+
+ if (div > 8 || div < 1 || ((clk->parent->rate / div) != rate)) {
+ return -EINVAL;
+ }
+ div--;
+
+ reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKODIV_MASK;
+ reg |= div << CCM_PCDR0_CLKODIV_OFFSET;
+ __raw_writel(reg, CCM_PCDR0);
+
+ clk->rate = rate;
+
+ return 0;
+}
+
+static void _clk_clko_recalc(struct clk *clk)
+{
+ u32 div;
+
+ div = __raw_readl(CCM_PCDR0) & CCM_PCDR0_CLKODIV_MASK >>
+ CCM_PCDR0_CLKODIV_OFFSET;
+ div++;
+
+ clk->rate = clk->parent->rate / div;
+}
+
+static int _clk_clko_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(CCM_CCSR) & ~CCM_CCSR_CLKOSEL_MASK;
+
+ if (parent == &ckil_clk) {
+ reg |= 0 << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == &ckih_clk) {
+ reg |= 2 << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == mpll_clk.parent) {
+ reg |= 3 << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == spll_clk.parent) {
+ reg |= 4 << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == &mpll_clk) {
+ reg |= 5 << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == &spll_clk) {
+ reg |= 6 << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == &cpu_clk) {
+ reg |= 7 << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == &ahb_clk) {
+ reg |= 8 << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == &ipg_clk) {
+ reg |= 9 << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == &per_clk[0]) {
+ reg |= 0xA << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == &per_clk[1]) {
+ reg |= 0xB << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == &per_clk[2]) {
+ reg |= 0xC << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == &per_clk[3]) {
+ reg |= 0xD << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == &ssi1_clk[0]) {
+ reg |= 0xE << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == &ssi2_clk[0]) {
+ reg |= 0xF << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == &nfc_clk) {
+ reg |= 0x10 << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == &mstick1_clk) {
+ reg |= 0x11 << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == &vpu_clk) {
+ reg |= 0x12 << CCM_CCSR_CLKOSEL_OFFSET;
+ } else if (parent == &usb_clk[0]) {
+ reg |= 0x15 << CCM_CCSR_CLKOSEL_OFFSET;
+ } else {
+ return -EINVAL;
+ }
+
+ __raw_writel(reg, CCM_CCSR);
+
+ return 0;
+}
+
+static int _clk_clko_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(CCM_PCDR0) | CCM_PCDR0_CLKO_EN;
+ __raw_writel(reg, CCM_PCDR0);
+
+ return 0;
+}
+
+static void _clk_clko_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(CCM_PCDR0) & ~CCM_PCDR0_CLKO_EN;
+ __raw_writel(reg, CCM_PCDR0);
+}
+
+static struct clk clko_clk = {
+ .name = "clko_clk",
+ .recalc = _clk_clko_recalc,
+ .set_rate = _clk_clko_set_rate,
+ .round_rate = _clk_clko_round_rate,
+ .set_parent = _clk_clko_set_parent,
+ .enable = _clk_clko_enable,
+ .disable = _clk_clko_disable,
+};
+
+static struct clk *mxc_clks[] = {
+ &ckih_clk,
+ &ckil_clk,
+ &mpll_clk,
+ &mpll_main_clk[0],
+ &mpll_main_clk[1],
+ &spll_clk,
+ &cpu_clk,
+ &ahb_clk,
+ &ipg_clk,
+ &per_clk[0],
+ &per_clk[1],
+ &per_clk[2],
+ &per_clk[3],
+ &clko_clk,
+ &uart1_clk[0],
+ &uart1_clk[1],
+ &uart2_clk[0],
+ &uart2_clk[1],
+ &uart3_clk[0],
+ &uart3_clk[1],
+ &uart4_clk[0],
+ &uart4_clk[1],
+ &uart5_clk[0],
+ &uart5_clk[1],
+ &uart6_clk[0],
+ &uart6_clk[1],
+ &gpt1_clk[0],
+ &gpt1_clk[1],
+ &gpt2_clk[0],
+ &gpt2_clk[1],
+ &gpt3_clk[0],
+ &gpt3_clk[1],
+ &gpt4_clk[0],
+ &gpt4_clk[1],
+ &gpt5_clk[0],
+ &gpt5_clk[1],
+ &gpt6_clk[0],
+ &gpt6_clk[1],
+ &pwm_clk[0],
+ &pwm_clk[1],
+ &sdhc1_clk[0],
+ &sdhc1_clk[1],
+ &sdhc2_clk[0],
+ &sdhc2_clk[1],
+ &sdhc3_clk[0],
+ &sdhc3_clk[1],
+ &cspi1_clk[0],
+ &cspi1_clk[1],
+ &cspi2_clk[0],
+ &cspi2_clk[1],
+ &cspi3_clk[0],
+ &cspi3_clk[1],
+ &lcdc_clk[0],
+ &lcdc_clk[1],
+ &lcdc_clk[2],
+ &csi_clk[0],
+ &csi_clk[1],
+ &usb_clk[0],
+ &usb_clk[1],
+ &ssi1_clk[0],
+ &ssi1_clk[1],
+ &ssi2_clk[0],
+ &ssi2_clk[1],
+ &nfc_clk,
+ &vpu_clk,
+ &dma_clk,
+ &rtic_clk,
+ &brom_clk,
+ &emma_clk,
+ &slcdc_clk,
+ &fec_clk,
+ &emi_clk,
+ &sahara2_clk,
+ &ata_clk,
+ &mstick1_clk,
+ &wdog_clk,
+ &gpio_clk,
+ &i2c_clk[0],
+ &i2c_clk[1],
+ &iim_clk,
+ &kpp_clk,
+ &owire_clk,
+ &rtc_clk,
+ &scc_clk,
+};
+
+static void probe_mxc_clocks(void)
+{
+ int i;
+
+ if (cpu_is_mx27_rev(CHIP_REV_2_0) > 0) {
+ if (CSCR() & 0x8000) {
+ cpu_clk.parent = &mpll_main_clk[0];
+ }
+
+ if (!(CSCR() & 0x00800000)) {
+ ssi2_clk[0].parent = &spll_clk;
+ }
+
+ if (!(CSCR() & 0x00400000)) {
+ ssi1_clk[0].parent = &spll_clk;
+ }
+
+ if (!(CSCR() & 0x00200000)) {
+ vpu_clk.parent = &spll_clk;
+ }
+ } else {
+ cpu_clk.parent = &mpll_clk;
+ cpu_clk.set_parent = NULL;
+ cpu_clk.round_rate = NULL;
+ cpu_clk.set_rate = NULL;
+ ahb_clk.parent = &mpll_clk;
+
+ for (i = 0; i < sizeof(per_clk) / sizeof(per_clk[0]); i++) {
+ per_clk[i].parent = &mpll_clk;
+ }
+
+ ssi1_clk[0].parent = &mpll_clk;
+ ssi2_clk[0].parent = &mpll_clk;
+
+ vpu_clk.parent = &mpll_clk;
+ }
+}
+
+extern void propagate_rate(struct clk *tclk);
+
+int __init mxc_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2)
+{
+ u32 cscr;
+ struct clk **clkp;
+
+ /* Determine which high frequency clock source is coming in */
+ ckih_clk.rate = ckih1;
+
+ if (CSCR() & CCM_CSCR_MCU) {
+ mpll_clk.parent = &ckih_clk;
+ } else {
+ mpll_clk.parent = &ckil_clk;
+ }
+
+ probe_mxc_clocks();
+
+ for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) {
+ if (*clkp == &mpll_main_clk[0] || *clkp == &mpll_main_clk[1]) {
+ if (cpu_is_mx27_rev(CHIP_REV_1_0) == 1)
+ continue;
+ }
+ clk_register(*clkp);
+ }
+
+ /* Turn off all possible clocks */
+ __raw_writel(CCM_PCCR0_GPT1_MASK, CCM_PCCR0);
+ __raw_writel(CCM_PCCR1_PERCLK1_MASK | CCM_PCCR1_HCLK_EMI_MASK,
+ CCM_PCCR1);
+ spll_clk.disable(&spll_clk);
+
+ cscr = CSCR();
+ if (cscr & CCM_CSCR_MCU) {
+ mpll_clk.parent = &ckih_clk;
+ } else {
+ mpll_clk.parent = &ckil_clk;
+ }
+ if (cscr & CCM_CSCR_SP) {
+ spll_clk.parent = &ckih_clk;
+ } else {
+ spll_clk.parent = &ckil_clk;
+ }
+
+ pr_info("Clock input source is %ld\n", ckih_clk.rate);
+
+ /* This will propagate to all children and init all the clock rates */
+ propagate_rate(&ckih_clk);
+ propagate_rate(&ckil_clk);
+
+ clk_enable(&emi_clk);
+ clk_enable(&gpio_clk);
+ clk_enable(&iim_clk);
+ clk_enable(&gpt1_clk[0]);
+
+ return 0;
+}
diff --git a/arch/arm/mach-mx27/cpu.c b/arch/arm/mach-mx27/cpu.c
new file mode 100644
index 000000000000..55d4a4c2d8e8
--- /dev/null
+++ b/arch/arm/mach-mx27/cpu.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2001 Deep Blue Solutions Ltd.
+ * Copyright 2007-2009 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
+ * published by the Free Software Foundation.
+ *
+ */
+
+/*!
+ * @file mach-mx27/cpu.c
+ *
+ * @brief This file contains the CPU initialization code.
+ *
+ * @ingroup MSL_MX27
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <mach/hardware.h>
+
+/*!
+ * CPU initialization. It is called by fixup_mxc_board()
+ */
+void __init mxc_cpu_init(void)
+{
+ if (!system_rev) {
+ mxc_set_system_rev(0x27, CHIP_REV_2_0);
+ }
+}
diff --git a/arch/arm/mach-mx27/crm_regs.h b/arch/arm/mach-mx27/crm_regs.h
new file mode 100644
index 000000000000..3a0ab35d9be7
--- /dev/null
+++ b/arch/arm/mach-mx27/crm_regs.h
@@ -0,0 +1,284 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ARCH_ARM_MACH_MX27_CRM_REGS_H__
+#define __ARCH_ARM_MACH_MX27_CRM_REGS_H__
+
+#include <mach/hardware.h>
+
+#define SYSCTRL_BASE IO_ADDRESS(SYSCTRL_BASE_ADDR)
+#define MXC_CCM_BASE ((char *)IO_ADDRESS(CCM_BASE_ADDR))
+
+/* Register offsets */
+#define CCM_CSCR (MXC_CCM_BASE + 0x0)
+#define CCM_MPCTL0 (MXC_CCM_BASE + 0x4)
+#define CCM_MPCTL1 (MXC_CCM_BASE + 0x8)
+#define CCM_SPCTL0 (MXC_CCM_BASE + 0xC)
+#define CCM_SPCTL1 (MXC_CCM_BASE + 0x10)
+#define CCM_OSC26MCTL (MXC_CCM_BASE + 0x14)
+#define CCM_PCDR0 (MXC_CCM_BASE + 0x18)
+#define CCM_PCDR1 (MXC_CCM_BASE + 0x1c)
+#define CCM_PCCR0 (MXC_CCM_BASE + 0x20)
+#define CCM_PCCR1 (MXC_CCM_BASE + 0x24)
+#define CCM_CCSR (MXC_CCM_BASE + 0x28)
+#define CCM_PMCTL (MXC_CCM_BASE + 0x2c)
+#define CCM_PMCOUNT (MXC_CCM_BASE + 0x30)
+#define CCM_WKGDCTL (MXC_CCM_BASE + 0x34)
+#define MXC_CCM_PMCR0 (SYSCTRL_BASE + 0x60)
+#define MXC_CCM_DCVR0 (SYSCTRL_BASE + 0x64)
+#define MXC_CCM_DCVR1 (SYSCTRL_BASE + 0x68)
+#define MXC_CCM_DCVR2 (SYSCTRL_BASE + 0x72)
+#define MXC_CCM_DCVR3 (SYSCTRL_BASE + 0x76)
+#define MXC_CCM_PMCR0_DPTEN 0x00000001
+#define MXC_CCM_DIE 0x00000002
+#define MXC_CCM_DIM 0x0000000C
+#define MXC_CCM_DCR 0x00000200
+#define MXC_CCM_PMCR0_DRCE0 0x00000010
+#define MXC_CCM_PMCR0_DRCE1 0x00000020
+#define MXC_CCM_PMCR0_DRCE2 0x00000040
+#define MXC_CCM_PMCR0_DRCE3 0x00000080
+#define MXC_CCM_PMCR0_PTVAIM MXC_CCM_DIM
+
+#define CCM_CSCR_USB_OFFSET 28
+#define CCM_CSCR_USB_MASK (0x7 << 28)
+#define CCM_CSCR_SD_OFFSET 24
+#define CCM_CSCR_SD_MASK (0x3 << 24)
+#define CCM_CSCR_SSI2 (1 << 23)
+#define CCM_CSCR_SSI2_OFFSET 23
+#define CCM_CSCR_SSI1 (1 << 22)
+#define CCM_CSCR_SSI1_OFFSET 22
+#define CCM_CSCR_VPU (1 << 21)
+#define CCM_CSCR_VPU_OFFSET 21
+#define CCM_CSCR_MSHC (1 << 20)
+#define CCM_CSCR_SPLLRES (1 << 19)
+#define CCM_CSCR_MPLLRES (1 << 18)
+#define CCM_CSCR_SP (1 << 17)
+#define CCM_CSCR_MCU (1 << 16)
+/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/
+#define CCM_CSCR_ARM_SRC (1 << 15)
+#define CCM_CSCR_ARM_OFFSET 12
+#define CCM_CSCR_ARM_MASK (0x3 << 12)
+/* CCM_CSCR_ARM_xxx just be avaliable on i.MX27 TO2*/
+#define CCM_CSCR_PRESC_OFFSET 13
+#define CCM_CSCR_PRESC_MASK (0x7 << 13)
+#define CCM_CSCR_BCLK_OFFSET 9
+#define CCM_CSCR_BCLK_MASK (0xf << 9)
+#define CCM_CSCR_IPDIV_OFFSET 8
+#define CCM_CSCR_IPDIV (1 << 8)
+/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/
+#define CCM_CSCR_AHB_OFFSET 8
+#define CCM_CSCR_AHB_MASK (0x3 << 8)
+/* CCM_CSCR_AHB_xxx just be avaliable on i.MX27 TO2*/
+#define CCM_CSCR_OSC26MDIV (1 << 4)
+#define CCM_CSCR_OSC26M (1 << 3)
+#define CCM_CSCR_FPM (1 << 2)
+#define CCM_CSCR_SPEN (1 << 1)
+#define CCM_CSCR_MPEN 1
+
+#define CCM_MPCTL0_CPLM (1 << 31)
+#define CCM_MPCTL0_PD_OFFSET 26
+#define CCM_MPCTL0_PD_MASK (0xf << 26)
+#define CCM_MPCTL0_MFD_OFFSET 16
+#define CCM_MPCTL0_MFD_MASK (0x3ff << 16)
+#define CCM_MPCTL0_MFI_OFFSET 10
+#define CCM_MPCTL0_MFI_MASK (0xf << 10)
+#define CCM_MPCTL0_MFN_OFFSET 0
+#define CCM_MPCTL0_MFN_MASK 0x3ff
+
+#define CCM_MPCTL1_LF (1 << 15)
+#define CCM_MPCTL1_BRMO (1 << 6)
+
+#define CCM_SPCTL0_CPLM (1 << 31)
+#define CCM_SPCTL0_PD_OFFSET 26
+#define CCM_SPCTL0_PD_MASK (0xf << 26)
+#define CCM_SPCTL0_MFD_OFFSET 16
+#define CCM_SPCTL0_MFD_MASK (0x3ff << 16)
+#define CCM_SPCTL0_MFI_OFFSET 10
+#define CCM_SPCTL0_MFI_MASK (0xf << 10)
+#define CCM_SPCTL0_MFN_OFFSET 0
+#define CCM_SPCTL0_MFN_MASK 0x3ff
+
+#define CCM_SPCTL1_LF (1 << 15)
+#define CCM_SPCTL1_BRMO (1 << 6)
+
+#define CCM_OSC26MCTL_PEAK_OFFSET 16
+#define CCM_OSC26MCTL_PEAK_MASK (0x3 << 16)
+#define CCM_OSC26MCTL_AGC_OFFSET 8
+#define CCM_OSC26MCTL_AGC_MASK (0x3f << 8)
+#define CCM_OSC26MCTL_ANATEST_OFFSET 0
+#define CCM_OSC26MCTL_ANATEST_MASK 0x3f
+
+#define CCM_PCDR0_SSI2BAUDDIV_OFFSET 26
+#define CCM_PCDR0_SSI2BAUDDIV_MASK (0x3f << 26)
+#define CCM_PCDR0_CLKO_EN 25
+#define CCM_PCDR0_CLKODIV_OFFSET 22
+#define CCM_PCDR0_CLKODIV_MASK (0x7 << 22)
+#define CCM_PCDR0_SSI1BAUDDIV_OFFSET 16
+#define CCM_PCDR0_SSI1BAUDDIV_MASK (0x3f << 16)
+/*The difinition for i.MX27 TO2*/
+#define CCM_PCDR0_VPUDIV2_OFFSET 10
+#define CCM_PCDR0_VPUDIV2_MASK (0x3f << 10)
+#define CCM_PCDR0_NFCDIV2_OFFSET 6
+#define CCM_PCDR0_NFCDIV2_MASK (0xf << 6)
+#define CCM_PCDR0_MSHCDIV2_MASK 0x3f
+/*The difinition for i.MX27 TO2*/
+#define CCM_PCDR0_NFCDIV_OFFSET 12
+#define CCM_PCDR0_NFCDIV_MASK (0xf << 12)
+#define CCM_PCDR0_VPUDIV_OFFSET 8
+#define CCM_PCDR0_VPUDIV_MASK (0xf << 8)
+#define CCM_PCDR0_MSHCDIV_OFFSET 0
+#define CCM_PCDR0_MSHCDIV_MASK 0x1f
+
+#define CCM_PCDR1_PERDIV4_OFFSET 24
+#define CCM_PCDR1_PERDIV4_MASK (0x3f << 24)
+#define CCM_PCDR1_PERDIV3_OFFSET 16
+#define CCM_PCDR1_PERDIV3_MASK (0x3f << 16)
+#define CCM_PCDR1_PERDIV2_OFFSET 8
+#define CCM_PCDR1_PERDIV2_MASK (0x3f << 8)
+#define CCM_PCDR1_PERDIV1_OFFSET 0
+#define CCM_PCDR1_PERDIV1_MASK 0x3f
+
+#define CCM_PCCR0_CSPI1_OFFSET 31
+#define CCM_PCCR0_CSPI1_MASK (1 << 31)
+#define CCM_PCCR0_CSPI2_OFFSET 30
+#define CCM_PCCR0_CSPI2_MASK (1 << 30)
+#define CCM_PCCR0_CSPI3_OFFSET 29
+#define CCM_PCCR0_CSPI3_MASK (1 << 29)
+#define CCM_PCCR0_DMA_OFFSET 28
+#define CCM_PCCR0_DMA_MASK (1 << 28)
+#define CCM_PCCR0_EMMA_OFFSET 27
+#define CCM_PCCR0_EMMA_MASK (1 << 27)
+#define CCM_PCCR0_FEC_OFFSET 26
+#define CCM_PCCR0_FEC_MASK (1 << 26)
+#define CCM_PCCR0_GPIO_OFFSET 25
+#define CCM_PCCR0_GPIO_MASK (1 << 25)
+#define CCM_PCCR0_GPT1_OFFSET 24
+#define CCM_PCCR0_GPT1_MASK (1 << 24)
+#define CCM_PCCR0_GPT2_OFFSET 23
+#define CCM_PCCR0_GPT2_MASK (1 << 23)
+#define CCM_PCCR0_GPT3_OFFSET 22
+#define CCM_PCCR0_GPT3_MASK (1 << 22)
+#define CCM_PCCR0_GPT4_OFFSET 21
+#define CCM_PCCR0_GPT4_MASK (1 << 21)
+#define CCM_PCCR0_GPT5_OFFSET 20
+#define CCM_PCCR0_GPT5_MASK (1 << 20)
+#define CCM_PCCR0_GPT6_OFFSET 19
+#define CCM_PCCR0_GPT6_MASK (1 << 19)
+#define CCM_PCCR0_I2C1_OFFSET 18
+#define CCM_PCCR0_I2C1_MASK (1 << 18)
+#define CCM_PCCR0_I2C2_OFFSET 17
+#define CCM_PCCR0_I2C2_MASK (1 << 17)
+#define CCM_PCCR0_IIM_OFFSET 16
+#define CCM_PCCR0_IIM_MASK (1 << 16)
+#define CCM_PCCR0_KPP_OFFSET 15
+#define CCM_PCCR0_KPP_MASK (1 << 15)
+#define CCM_PCCR0_LCDC_OFFSET 14
+#define CCM_PCCR0_LCDC_MASK (1 << 14)
+#define CCM_PCCR0_MSHC_OFFSET 13
+#define CCM_PCCR0_MSHC_MASK (1 << 13)
+#define CCM_PCCR0_OWIRE_OFFSET 12
+#define CCM_PCCR0_OWIRE_MASK (1 << 12)
+#define CCM_PCCR0_PWM_OFFSET 11
+#define CCM_PCCR0_PWM_MASK (1 << 11)
+#define CCM_PCCR0_RTC_OFFSET 9
+#define CCM_PCCR0_RTC_MASK (1 << 9)
+#define CCM_PCCR0_RTIC_OFFSET 8
+#define CCM_PCCR0_RTIC_MASK (1 << 8)
+#define CCM_PCCR0_SAHARA_OFFSET 7
+#define CCM_PCCR0_SAHARA_MASK (1 << 7)
+#define CCM_PCCR0_SCC_OFFSET 6
+#define CCM_PCCR0_SCC_MASK (1 << 6)
+#define CCM_PCCR0_SDHC1_OFFSET 5
+#define CCM_PCCR0_SDHC1_MASK (1 << 5)
+#define CCM_PCCR0_SDHC2_OFFSET 4
+#define CCM_PCCR0_SDHC2_MASK (1 << 4)
+#define CCM_PCCR0_SDHC3_OFFSET 3
+#define CCM_PCCR0_SDHC3_MASK (1 << 3)
+#define CCM_PCCR0_SLCDC_OFFSET 2
+#define CCM_PCCR0_SLCDC_MASK (1 << 2)
+#define CCM_PCCR0_SSI1_IPG_OFFSET 1
+#define CCM_PCCR0_SSI1_IPG_MASK (1 << 1)
+#define CCM_PCCR0_SSI2_IPG_OFFSET 0
+#define CCM_PCCR0_SSI2_IPG_MASK (1 << 0)
+
+#define CCM_PCCR1_UART1_OFFSET 31
+#define CCM_PCCR1_UART1_MASK (1 << 31)
+#define CCM_PCCR1_UART2_OFFSET 30
+#define CCM_PCCR1_UART2_MASK (1 << 30)
+#define CCM_PCCR1_UART3_OFFSET 29
+#define CCM_PCCR1_UART3_MASK (1 << 29)
+#define CCM_PCCR1_UART4_OFFSET 28
+#define CCM_PCCR1_UART4_MASK (1 << 28)
+#define CCM_PCCR1_UART5_OFFSET 27
+#define CCM_PCCR1_UART5_MASK (1 << 27)
+#define CCM_PCCR1_UART6_OFFSET 26
+#define CCM_PCCR1_UART6_MASK (1 << 26)
+#define CCM_PCCR1_USBOTG_OFFSET 25
+#define CCM_PCCR1_USBOTG_MASK (1 << 25)
+#define CCM_PCCR1_WDT_OFFSET 24
+#define CCM_PCCR1_WDT_MASK (1 << 24)
+#define CCM_PCCR1_HCLK_ATA_OFFSET 23
+#define CCM_PCCR1_HCLK_ATA_MASK (1 << 23)
+#define CCM_PCCR1_HCLK_BROM_OFFSET 22
+#define CCM_PCCR1_HCLK_BROM_MASK (1 << 22)
+#define CCM_PCCR1_HCLK_CSI_OFFSET 21
+#define CCM_PCCR1_HCLK_CSI_MASK (1 << 21)
+#define CCM_PCCR1_HCLK_DMA_OFFSET 20
+#define CCM_PCCR1_HCLK_DMA_MASK (1 << 20)
+#define CCM_PCCR1_HCLK_EMI_OFFSET 19
+#define CCM_PCCR1_HCLK_EMI_MASK (1 << 19)
+#define CCM_PCCR1_HCLK_EMMA_OFFSET 18
+#define CCM_PCCR1_HCLK_EMMA_MASK (1 << 18)
+#define CCM_PCCR1_HCLK_FEC_OFFSET 17
+#define CCM_PCCR1_HCLK_FEC_MASK (1 << 17)
+#define CCM_PCCR1_HCLK_VPU_OFFSET 16
+#define CCM_PCCR1_HCLK_VPU_MASK (1 << 16)
+#define CCM_PCCR1_HCLK_LCDC_OFFSET 15
+#define CCM_PCCR1_HCLK_LCDC_MASK (1 << 15)
+#define CCM_PCCR1_HCLK_RTIC_OFFSET 14
+#define CCM_PCCR1_HCLK_RTIC_MASK (1 << 14)
+#define CCM_PCCR1_HCLK_SAHARA_OFFSET 13
+#define CCM_PCCR1_HCLK_SAHARA_MASK (1 << 13)
+#define CCM_PCCR1_HCLK_SLCDC_OFFSET 12
+#define CCM_PCCR1_HCLK_SLCDC_MASK (1 << 12)
+#define CCM_PCCR1_HCLK_USBOTG_OFFSET 11
+#define CCM_PCCR1_HCLK_USBOTG_MASK (1 << 11)
+#define CCM_PCCR1_PERCLK1_OFFSET 10
+#define CCM_PCCR1_PERCLK1_MASK (1 << 10)
+#define CCM_PCCR1_PERCLK2_OFFSET 9
+#define CCM_PCCR1_PERCLK2_MASK (1 << 9)
+#define CCM_PCCR1_PERCLK3_OFFSET 8
+#define CCM_PCCR1_PERCLK3_MASK (1 << 8)
+#define CCM_PCCR1_PERCLK4_OFFSET 7
+#define CCM_PCCR1_PERCLK4_MASK (1 << 7)
+#define CCM_PCCR1_VPU_BAUD_OFFSET 6
+#define CCM_PCCR1_VPU_BAUD_MASK (1 << 6)
+#define CCM_PCCR1_SSI1_BAUD_OFFSET 5
+#define CCM_PCCR1_SSI1_BAUD_MASK (1 << 5)
+#define CCM_PCCR1_SSI2_BAUD_OFFSET 4
+#define CCM_PCCR1_SSI2_BAUD_MASK (1 << 4)
+#define CCM_PCCR1_NFC_BAUD_OFFSET 3
+#define CCM_PCCR1_NFC_BAUD_MASK (1 << 3)
+#define CCM_PCCR1_MSHC_BAUD_OFFSET 2
+#define CCM_PCCR1_MSHC_BAUD_MASK (1 << 2)
+
+#define CCM_CCSR_32KSR (1 << 15)
+#define CCM_CCSR_CLKMODE1 (1 << 9)
+#define CCM_CCSR_CLKMODE0 (1 << 8)
+#define CCM_CCSR_CLKOSEL_OFFSET 0
+#define CCM_CCSR_CLKOSEL_MASK 0x1f
+
+#define SYS_FMCR 0x14 /* Functional Muxing Control Reg */
+#define SYS_CHIP_ID 0x00 /* The offset of CHIP ID register */
+
+#endif /* __ARCH_ARM_MACH_MX27_CRM_REGS_H__ */
diff --git a/arch/arm/mach-mx27/devices.c b/arch/arm/mach-mx27/devices.c
new file mode 100644
index 000000000000..fd69e94c413b
--- /dev/null
+++ b/arch/arm/mach-mx27/devices.c
@@ -0,0 +1,698 @@
+/*
+ * Author: MontaVista Software, Inc.
+ * <source@mvista.com>
+ *
+ * Based on the OMAP devices.c
+ *
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Copyright 2006-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/pmic_external.h>
+#include <mach/pmic_power.h>
+
+#include <linux/spi/spi.h>
+
+#include <mach/hardware.h>
+#include <mach/mmc.h>
+#include <mach/mxc_dptc.h>
+
+ /*!
+ * @file mach-mx27/devices.c
+ * @brief device configurations including nor/nand/watchdog for mx27.
+ *
+ * @ingroup MSL_MX27
+ */
+
+#ifndef CONFIG_MX27_DPTC
+extern struct dptc_wp dptc_wp_allfreq[DPTC_WP_SUPPORTED];
+#endif
+
+static void mxc_nop_release(struct device *dev)
+{
+ /* Nothing */
+}
+
+#if defined(CONFIG_W1_MASTER_MXC) || defined(CONFIG_W1_MASTER_MXC_MODULE)
+static struct mxc_w1_config mxc_w1_data = {
+ .search_rom_accelerator = 0,
+};
+
+static struct platform_device mxc_w1_devices = {
+ .name = "mxc_w1",
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_w1_data,
+ },
+ .id = 0
+};
+
+static void mxc_init_owire(void)
+{
+ (void)platform_device_register(&mxc_w1_devices);
+}
+#else
+static inline void mxc_init_owire(void)
+{
+}
+#endif
+
+#if defined(CONFIG_RTC_MXC) || defined(CONFIG_RTC_MXC_MODULE)
+static struct resource rtc_resources[] = {
+ {
+ .start = RTC_BASE_ADDR,
+ .end = RTC_BASE_ADDR + 0x30,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_INT_RTC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+static struct platform_device mxc_rtc_device = {
+ .name = "mxc_rtc",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resource = rtc_resources,
+};
+static void mxc_init_rtc(void)
+{
+ (void)platform_device_register(&mxc_rtc_device);
+}
+#else
+static inline void mxc_init_rtc(void)
+{
+}
+#endif
+#if defined(CONFIG_MXC_WATCHDOG) || defined(CONFIG_MXC_WATCHDOG_MODULE)
+
+static struct resource wdt_resources[] = {
+ {
+ .start = WDOG1_BASE_ADDR,
+ .end = WDOG1_BASE_ADDR + 0x30,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device mxc_wdt_device = {
+ .name = "mxc_wdt",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+static void mxc_init_wdt(void)
+{
+ (void)platform_device_register(&mxc_wdt_device);
+}
+#else
+static inline void mxc_init_wdt(void)
+{
+}
+#endif
+/*!
+ * This is platform device structure for adding SCC
+ */
+#if defined(CONFIG_MXC_SECURITY_SCC) || defined(CONFIG_MXC_SECURITY_SCC_MODULE)
+static struct platform_device mxc_scc_device = {
+ .name = "mxc_scc",
+ .id = 0,
+};
+
+static void mxc_init_scc(void)
+{
+ platform_device_register(&mxc_scc_device);
+}
+#else
+static inline void mxc_init_scc(void)
+{
+}
+#endif
+/* MMC device data */
+
+#if defined(CONFIG_MMC_MXC) || defined(CONFIG_MMC_MXC_MODULE)
+
+extern unsigned int sdhc_get_card_det_status(struct device *dev);
+extern int sdhc_init_card_det(int id);
+
+static struct mxc_mmc_platform_data mmc_data = {
+ .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30,
+ .min_clk = 150000,
+ .max_clk = 25000000,
+ .card_inserted_state = 0,
+ .status = sdhc_get_card_det_status,
+};
+
+/*!
+ * Resource definition for the SDHC1
+ */
+static struct resource mxcsdhc1_resources[] = {
+ [0] = {
+ .start = SDHC1_BASE_ADDR,
+ .end = SDHC1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_SDHC1,
+ .end = MXC_INT_SDHC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*!
+ * Resource definition for the SDHC2
+ */
+static struct resource mxcsdhc2_resources[] = {
+ [0] = {
+ .start = SDHC2_BASE_ADDR,
+ .end = SDHC2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_SDHC2,
+ .end = MXC_INT_SDHC2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Device Definition for MXC SDHC1 */
+static struct platform_device mxcsdhc1_device = {
+ .name = "mxcmci",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mmc_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcsdhc1_resources),
+ .resource = mxcsdhc1_resources,
+};
+
+/*! Device Definition for MXC SDHC2 */
+static struct platform_device mxcsdhc2_device = {
+ .name = "mxcmci",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mmc_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcsdhc2_resources),
+ .resource = mxcsdhc2_resources,
+};
+
+#ifdef CONFIG_MXC_SDHC3
+/*!
+ * Resource definition for the SDHC3
+ */
+static struct resource mxcsdhc3_resources[] = {
+ [0] = {
+ .start = SDHC3_BASE_ADDR,
+ .end = SDHC3_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_SDHC3,
+ .end = MXC_INT_SDHC3,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .start = MXC_SDIO3_CARD_IRQ,
+ .end = MXC_SDIO3_CARD_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Device Definition for MXC SDHC3 */
+static struct platform_device mxcsdhc3_device = {
+ .name = "mxcmci",
+ .id = 2,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mmc_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcsdhc3_resources),
+ .resource = mxcsdhc3_resources,
+};
+#endif
+
+static inline void mxc_init_mmc(void)
+{
+ int cd_irq;
+
+ cd_irq = sdhc_init_card_det(0);
+ if (cd_irq) {
+ mxcsdhc1_device.resource[2].start = cd_irq;
+ mxcsdhc1_device.resource[2].end = cd_irq;
+ }
+ cd_irq = sdhc_init_card_det(1);
+ if (cd_irq) {
+ mxcsdhc2_device.resource[2].start = cd_irq;
+ mxcsdhc2_device.resource[2].end = cd_irq;
+ }
+
+ (void)platform_device_register(&mxcsdhc1_device);
+ (void)platform_device_register(&mxcsdhc2_device);
+#ifdef CONFIG_MXC_SDHC3
+ (void)platform_device_register(&mxcsdhc3_device);
+#endif
+}
+#else
+static inline void mxc_init_mmc(void)
+{
+}
+#endif
+
+/* SPI controller and device data */
+#if defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE)
+
+#ifdef CONFIG_SPI_MXC_SELECT1
+/*!
+ * Resource definition for the CSPI1
+ */
+static struct resource mxcspi1_resources[] = {
+ [0] = {
+ .start = CSPI1_BASE_ADDR,
+ .end = CSPI1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_CSPI1,
+ .end = MXC_INT_CSPI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC CSPI1 */
+static struct mxc_spi_master mxcspi1_data = {
+ .maxchipselect = 4,
+ .spi_version = 0,
+};
+
+/*! Device Definition for MXC CSPI1 */
+static struct platform_device mxcspi1_device = {
+ .name = "mxc_spi",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxcspi1_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcspi1_resources),
+ .resource = mxcspi1_resources,
+};
+
+#endif /* CONFIG_SPI_MXC_SELECT1 */
+
+#ifdef CONFIG_SPI_MXC_SELECT2
+/*!
+ * Resource definition for the CSPI2
+ */
+static struct resource mxcspi2_resources[] = {
+ [0] = {
+ .start = CSPI2_BASE_ADDR,
+ .end = CSPI2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_CSPI2,
+ .end = MXC_INT_CSPI2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC CSPI2 */
+static struct mxc_spi_master mxcspi2_data = {
+ .maxchipselect = 4,
+ .spi_version = 0,
+};
+
+/*! Device Definition for MXC CSPI2 */
+static struct platform_device mxcspi2_device = {
+ .name = "mxc_spi",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxcspi2_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcspi2_resources),
+ .resource = mxcspi2_resources,
+};
+#endif /* CONFIG_SPI_MXC_SELECT2 */
+
+#ifdef CONFIG_SPI_MXC_SELECT3
+/*!
+ * Resource definition for the CSPI3
+ */
+static struct resource mxcspi3_resources[] = {
+ [0] = {
+ .start = CSPI3_BASE_ADDR,
+ .end = CSPI3_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_CSPI3,
+ .end = MXC_INT_CSPI3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC CSPI3 */
+static struct mxc_spi_master mxcspi3_data = {
+ .maxchipselect = 4,
+ .spi_version = 0,
+};
+
+/*! Device Definition for MXC CSPI3 */
+static struct platform_device mxcspi3_device = {
+ .name = "mxc_spi",
+ .id = 2,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxcspi3_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcspi3_resources),
+ .resource = mxcspi3_resources,
+};
+#endif /* CONFIG_SPI_MXC_SELECT3 */
+
+static inline void mxc_init_spi(void)
+{
+#ifdef CONFIG_SPI_MXC_SELECT1
+ if (platform_device_register(&mxcspi1_device) < 0)
+ printk(KERN_ERR "Registering the SPI Controller_1\n");
+#endif /* CONFIG_SPI_MXC_SELECT1 */
+#ifdef CONFIG_SPI_MXC_SELECT2
+ if (platform_device_register(&mxcspi2_device) < 0)
+ printk(KERN_ERR "Registering the SPI Controller_2\n");
+#endif /* CONFIG_SPI_MXC_SELECT2 */
+#ifdef CONFIG_SPI_MXC_SELECT3
+ if (platform_device_register(&mxcspi3_device) < 0)
+ printk(KERN_ERR "Registering the SPI Controller_3\n");
+#endif /* CONFIG_SPI_MXC_SELECT3 */
+}
+#else
+static inline void mxc_init_spi(void)
+{
+}
+#endif
+
+#if defined(CONFIG_SND_MXC_PMIC) || defined(CONFIG_SND_MXC_PMIC_MODULE)
+static struct mxc_audio_platform_data mxc_audio_data;
+
+static struct platform_device mxc_alsa_device = {
+ .name = "mxc_alsa",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_audio_data,
+ },
+
+};
+
+static void mxc_init_audio(void)
+{
+ mxc_audio_data.ssi_clk[0] = clk_get(NULL, "ssi_clk.0");
+ clk_put(mxc_audio_data.ssi_clk[0]);
+ mxc_audio_data.ssi_clk[1] = clk_get(NULL, "ssi_clk.1");
+ clk_put(mxc_audio_data.ssi_clk[1]);
+ mxc_audio_data.ssi_num = 2;
+ mxc_audio_data.src_port = 0;
+ platform_device_register(&mxc_alsa_device);
+}
+#else
+
+static void mxc_init_audio(void)
+{
+}
+#endif
+
+#if defined(CONFIG_MXC_SSI) || defined(CONFIG_MXC_SSI_MODULE)
+/*!
+ * Resource definition for the SSI
+ */
+static struct resource mxcssi2_resources[] = {
+ [0] = {
+ .start = SSI2_BASE_ADDR,
+ .end = SSI2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource mxcssi1_resources[] = {
+ [0] = {
+ .start = SSI1_BASE_ADDR,
+ .end = SSI1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+/*! Device Definition for MXC SSI */
+static struct platform_device mxc_ssi1_device = {
+ .name = "mxc_ssi",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_audio_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcssi1_resources),
+ .resource = mxcssi1_resources,
+};
+
+static struct platform_device mxc_ssi2_device = {
+ .name = "mxc_ssi",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_audio_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcssi2_resources),
+ .resource = mxcssi2_resources,
+};
+
+static void mxc_init_ssi(void)
+{
+ platform_device_register(&mxc_ssi1_device);
+ platform_device_register(&mxc_ssi2_device);
+}
+#else
+
+static void mxc_init_ssi(void)
+{
+}
+#endif
+
+/* I2C controller and device data */
+#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE)
+
+#ifdef CONFIG_I2C_MXC_SELECT1
+/*!
+ * Resource definition for the I2C1
+ */
+static struct resource mxci2c1_resources[] = {
+ [0] = {
+ .start = I2C_BASE_ADDR,
+ .end = I2C_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_I2C,
+ .end = MXC_INT_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC I2C */
+static struct mxc_i2c_platform_data mxci2c1_data = {
+ .i2c_clk = 100000,
+};
+#endif
+
+#ifdef CONFIG_I2C_MXC_SELECT2
+/*!
+ * Resource definition for the I2C2
+ */
+static struct resource mxci2c2_resources[] = {
+ [0] = {
+ .start = I2C2_BASE_ADDR,
+ .end = I2C2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_I2C2,
+ .end = MXC_INT_I2C2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC I2C */
+static struct mxc_i2c_platform_data mxci2c2_data = {
+ .i2c_clk = 100000,
+};
+#endif
+
+/*! Device Definition for MXC I2C */
+static struct platform_device mxci2c_devices[] = {
+#ifdef CONFIG_I2C_MXC_SELECT1
+ {
+ .name = "mxc_i2c",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxci2c1_data,
+ },
+ .num_resources = ARRAY_SIZE(mxci2c1_resources),
+ .resource = mxci2c1_resources,},
+#endif
+#ifdef CONFIG_I2C_MXC_SELECT2
+ {
+ .name = "mxc_i2c",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxci2c2_data,
+ },
+ .num_resources = ARRAY_SIZE(mxci2c2_resources),
+ .resource = mxci2c2_resources,},
+#endif
+};
+
+static inline void mxc_init_i2c(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mxci2c_devices); i++) {
+ if (platform_device_register(&mxci2c_devices[i]) < 0)
+ dev_err(&mxci2c_devices[i].dev,
+ "Unable to register I2C device\n");
+ }
+}
+#else
+static inline void mxc_init_i2c(void)
+{
+}
+#endif
+
+#ifdef CONFIG_MXC_VPU
+/*! Platform Data for MXC VPU */
+static struct platform_device mxcvpu_device = {
+ .name = "mxc_vpu",
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .id = 0,
+};
+
+static inline void mxc_init_vpu(void)
+{
+ if (platform_device_register(&mxcvpu_device) < 0)
+ printk(KERN_ERR "Error: Registering the VPU.\n");
+}
+#else
+static inline void mxc_init_vpu(void)
+{
+}
+#endif
+
+struct mxc_gpio_port mxc_gpio_ports[GPIO_PORT_NUM] = {
+ {
+ .num = 0,
+ .base = IO_ADDRESS(GPIO_BASE_ADDR),
+ .irq = MXC_INT_GPIO,
+ .virtual_irq_start = MXC_GPIO_INT_BASE,
+ },
+ {
+ .num = 1,
+ .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x100,
+ .irq = MXC_INT_GPIO,
+ .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN,
+ },
+ {
+ .num = 2,
+ .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x200,
+ .irq = MXC_INT_GPIO,
+ .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 2,
+ },
+ {
+ .num = 3,
+ .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x300,
+ .irq = MXC_INT_GPIO,
+ .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 3,
+ },
+ {
+ .num = 4,
+ .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x400,
+ .irq = MXC_INT_GPIO,
+ .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 4,
+ },
+ {
+ .num = 5,
+ .base = IO_ADDRESS(GPIO_BASE_ADDR) + 0x500,
+ .irq = MXC_INT_GPIO,
+ .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 5,
+ },
+};
+
+#ifndef CONFIG_MX27_DPTC
+/*! Device Definition for DPTC */
+static struct platform_device mxc_dptc_device = {
+ .name = "mxc_dptc",
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &dptc_wp_allfreq,
+ },
+};
+
+static inline void mxc_init_dptc(void)
+{
+ (void)platform_device_register(&mxc_dptc_device);
+}
+#endif
+
+static int __init mxc_init_devices(void)
+{
+ mxc_init_wdt();
+ mxc_init_mmc();
+ mxc_init_spi();
+ mxc_init_i2c();
+ mxc_init_rtc();
+ mxc_init_ssi();
+ mxc_init_audio();
+ mxc_init_scc();
+ mxc_init_owire();
+ mxc_init_vpu();
+#ifndef CONFIG_MX27_DPTC
+ mxc_init_dptc();
+#endif
+
+ return 0;
+}
+
+arch_initcall(mxc_init_devices);
diff --git a/arch/arm/mach-mx27/dma.c b/arch/arm/mach-mx27/dma.c
new file mode 100644
index 000000000000..a48e070a6a44
--- /dev/null
+++ b/arch/arm/mach-mx27/dma.c
@@ -0,0 +1,553 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ *@file mach-mx27/dma.c
+ *@brief This file contains the dma parameter which is depend on the platform .
+ * @ingroup DMA_MX27
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <asm/dma.h>
+
+#define MXC_SOUND_PLAYBACK_CHAIN_DMA 1
+#define MXC_SOUND_CAPTURE_CHAIN_DMA 1
+
+/*!
+ * @brief the structure stored device_id and dma_info pointer
+ */
+typedef struct dma_info_entry_s {
+ mxc_dma_device_t device;
+ /* if there are two dma_info , first is for reading, another is for writing */
+ mx2_dma_info_t *info;
+} dma_info_entry_t;
+
+/*!
+ * @brief dma_info from memory to memory for dma testing
+ */
+static mx2_dma_info_t ram2ram_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 0,
+ .burstLength = 4,.request = 0,.busuntils = 0,
+ .sourceType = DMA_TYPE_LINEAR,.sourcePort = TRANSFER_32BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_32BIT,
+ .M2D_Valid = 0
+};
+
+/*!
+ * @brief dma_info from 2D memory to 2D memory for dma testing
+ */
+static mx2_dma_info_t ram2d2ram2d_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .rto_en = 0,
+ .dma_chaining = 0,.ren = 0,
+ .burstLength = 4,.request = 0,.busuntils = 0,
+ .sourceType = DMA_TYPE_2D,.sourcePort = TRANSFER_32BIT,
+ .destType = DMA_TYPE_2D,.destPort = TRANSFER_32BIT,
+ .M2D_Valid = 1,.msel = 0,.W = 0x80,.X = 0x40,.Y = 0x10
+};
+
+/*!
+ * @brief dma_info from memory to 2D memory for dma testing
+ */
+static mx2_dma_info_t ram2ram2d_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 0,
+ .burstLength = 4,.request = 0,.busuntils = 0,
+ .sourceType = DMA_TYPE_LINEAR,.sourcePort = TRANSFER_32BIT,
+ .destType = DMA_TYPE_2D,.destPort = TRANSFER_32BIT,
+ .M2D_Valid = 1,.msel = 0,.W = 0x100,.X = 0x80,.Y = 0x10
+};
+
+/*!
+ * @brief dma_info from 2D memory to memory for dma testing
+ */
+static mx2_dma_info_t ram2d2ram_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 0,
+ .burstLength = 4,.request = 0,.busuntils = 0,
+ .sourceType = DMA_TYPE_2D,.sourcePort = TRANSFER_32BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_32BIT,
+ .M2D_Valid = 1,.msel = 0,.W = 0x100,.X = 0x100,.Y = 0x10
+};
+
+/*!
+ * @brief dma_info with dma chaining feature for dma testing
+ */
+static mx2_dma_info_t hw_chaining_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 1,.ren = 0,
+ .burstLength = 4,.request = 0,.busuntils = 0,
+ .sourceType = DMA_TYPE_LINEAR,.sourcePort = TRANSFER_32BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_32BIT,
+ .M2D_Valid = 0,
+};
+
+/*!
+ * @brief dma_info without dma chaining feature for dma testing
+ */
+static mx2_dma_info_t sw_chaining_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 0,
+ .burstLength = 4,.request = 0,.busuntils = 0,
+ .sourceType = DMA_TYPE_LINEAR,.sourcePort = TRANSFER_32BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_32BIT,
+ .M2D_Valid = 0,
+};
+
+/*!
+ * @brief dma_info for ATA recieveing
+ */
+static mx2_dma_info_t ata_rx_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 32,.request = 29,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_32BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_32BIT,
+ .per_address = (ATA_BASE_ADDR + 0x18),
+ .M2D_Valid = 0,
+};
+
+/*!
+ * @brief: dma_info for ATA transmitting
+ */
+static mx2_dma_info_t ata_tx_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 1,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 32,.request = 28,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_32BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_32BIT,
+ .per_address = (ATA_BASE_ADDR + 0x18),
+ .M2D_Valid = 0,
+};
+
+/*!
+ * @brief dma_info for UART1 recieveing
+ */
+static mx2_dma_info_t uart1_rx_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 1,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 1,.request = 26,.busuntils = 8,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT,
+ .per_address = (UART1_BASE_ADDR),
+ .M2D_Valid = 0,
+};
+
+/*!
+ * @brief: dma_info for UART1 transmitting
+ */
+static mx2_dma_info_t uart1_tx_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 1,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 1,.request = 27,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT,
+ .per_address = (UART1_BASE_ADDR + 0x40),
+ .M2D_Valid = 0,
+};
+
+/*!
+ * @brief dma_info for UART2 recieveing
+ */
+static mx2_dma_info_t uart2_rx_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 1,.request = 24,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT,
+ .per_address = (UART2_BASE_ADDR),
+ .M2D_Valid = 0,
+};
+
+/*!
+ * @brief: dma_info for UART2 transmitting
+ */
+static mx2_dma_info_t uart2_tx_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 1,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 1,.request = 25,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT,
+ .per_address = (UART2_BASE_ADDR + 0x40),
+ .M2D_Valid = 0,
+};
+
+/*!
+ * @brief dma_info for UART3 recieveing
+ */
+static mx2_dma_info_t uart3_rx_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 1,.request = 22,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT,
+ .per_address = (UART3_BASE_ADDR),
+ .M2D_Valid = 0,
+};
+
+/*!
+ * @brief: dma_info for UART3 transmitting
+ */
+static mx2_dma_info_t uart3_tx_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 1,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 1,.request = 23,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT,
+ .per_address = (UART3_BASE_ADDR + 0x40),
+ .M2D_Valid = 0,
+};
+
+/*!
+ * @brief dma_info for UART4 recieveing
+ */
+static mx2_dma_info_t uart4_rx_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 1,.request = 20,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT,
+ .per_address = (UART4_BASE_ADDR),
+ .M2D_Valid = 0,
+};
+
+/*!
+ * @brief: dma_info for UART4transmitting
+ */
+static mx2_dma_info_t uart4_tx_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 1,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 1,.request = 21,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT,
+ .per_address = (UART4_BASE_ADDR + 0x40),
+ .M2D_Valid = 0,
+};
+
+/*!
+ * @brief dma_info for UART5 recieveing
+ */
+static mx2_dma_info_t uart5_rx_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 1,.request = 32,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT,
+ .per_address = (UART5_BASE_ADDR),
+ .M2D_Valid = 0,
+};
+
+/*!
+ * @brief: dma_info for UART5 transmitting
+ */
+static mx2_dma_info_t uart5_tx_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 1,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 1,.request = 33,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT,
+ .per_address = (UART5_BASE_ADDR + 0x40),
+ .M2D_Valid = 0,
+};
+
+/*!
+ * @brief dma_info for UART6 recieveing
+ */
+static mx2_dma_info_t uart6_rx_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 1,.request = 34,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT,
+ .per_address = (UART6_BASE_ADDR),
+ .M2D_Valid = 0,
+};
+
+/*!
+ * @brief: dma_info for UART6 transmitting
+ */
+static mx2_dma_info_t uart6_tx_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 1,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 1,.request = 35,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = TRANSFER_8BIT,
+ .destType = DMA_TYPE_LINEAR,.destPort = TRANSFER_8BIT,
+ .per_address = (UART6_BASE_ADDR + 0x40),
+ .M2D_Valid = 0,
+};
+
+static mx2_dma_info_t ssi1_16bit_rx0_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = MXC_SOUND_CAPTURE_CHAIN_DMA,.ren = 1,
+ .burstLength = 8,.request = DMA_REQ_SSI1_RX0,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_16,
+ .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32,
+ .per_address = (SSI1_BASE_ADDR + 0x08),
+ .M2D_Valid = 0,
+};
+
+static mx2_dma_info_t ssi1_16bit_tx0_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 1,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = MXC_SOUND_PLAYBACK_CHAIN_DMA,.ren = 1,
+ .burstLength = 8,.request = DMA_REQ_SSI1_TX0,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_16,
+ .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32,
+ .per_address = (SSI1_BASE_ADDR),
+ .M2D_Valid = 0,
+};
+
+static mx2_dma_info_t ssi2_16bit_rx0_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = MXC_SOUND_CAPTURE_CHAIN_DMA,.ren = 1,
+ .burstLength = 8,.request = DMA_REQ_SSI2_RX0,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_16,
+ .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32,
+ .per_address = (SSI2_BASE_ADDR + 0x08),
+ .M2D_Valid = 0,
+};
+
+static mx2_dma_info_t ssi2_16bit_tx0_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 1,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = MXC_SOUND_PLAYBACK_CHAIN_DMA,.ren = 1,
+ .burstLength = 8,.request = DMA_REQ_SSI2_TX0,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_16,
+ .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32,
+ .per_address = (SSI2_BASE_ADDR),
+ .M2D_Valid = 0,
+};
+
+static mx2_dma_info_t mmc1_width1_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 16,.request = DMA_REQ_SDHC1,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_32,
+ .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32,
+ .per_address = (SDHC1_BASE_ADDR + 0x38),
+ .M2D_Valid = 0,
+};
+
+static mx2_dma_info_t mmc1_width4_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 0,.request = DMA_REQ_SDHC1,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_32,
+ .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32,
+ .per_address = (SDHC1_BASE_ADDR + 0x38),
+ .M2D_Valid = 0,
+};
+
+static mx2_dma_info_t mmc2_width1_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 16,.request = DMA_REQ_SDHC2,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_32,
+ .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32,
+ .per_address = (SDHC2_BASE_ADDR + 0x38),
+ .M2D_Valid = 0,
+};
+
+static mx2_dma_info_t mmc2_width4_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 0,.ren = 1,
+ .burstLength = 0,.request = DMA_REQ_SDHC2,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_32,
+ .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32,
+ .per_address = (SDHC2_BASE_ADDR + 0x38),
+ .M2D_Valid = 0,
+};
+
+static mx2_dma_info_t csi_rx_dma_info = {
+ .dma_chan = MXC_DMA_DYNAMIC_CHANNEL,
+ .mode = 0,
+ .rto_en = 0,
+ .dir = 0,
+ .dma_chaining = 1,.ren = 1,
+ .burstLength = 64,.request = DMA_REQ_CSI_RX,.busuntils = 0,
+ .sourceType = DMA_TYPE_FIFO,.sourcePort = DMA_MEM_SIZE_32,
+ .destType = DMA_TYPE_LINEAR,.destPort = DMA_MEM_SIZE_32,
+ .per_address = (CSI_BASE_ADDR + 0x10),
+ .M2D_Valid = 0,
+};
+
+/*!
+ * @brief dma info array which is actived
+ * DEVICE_ID RX/(RX&TX) TX
+ */
+static dma_info_entry_t active_dma_info[] = {
+ {MXC_DMA_TEST_RAM2RAM, &ram2ram_dma_info},
+ {MXC_DMA_TEST_RAM2D2RAM2D, &ram2d2ram2d_dma_info},
+ {MXC_DMA_TEST_RAM2RAM2D, &ram2ram2d_dma_info},
+ {MXC_DMA_TEST_RAM2D2RAM, &ram2d2ram_dma_info},
+ {MXC_DMA_TEST_HW_CHAINING, &hw_chaining_dma_info},
+ {MXC_DMA_TEST_SW_CHAINING, &sw_chaining_dma_info},
+ {MXC_DMA_ATA_RX, &ata_rx_dma_info},
+ {MXC_DMA_ATA_TX, &ata_tx_dma_info},
+ {MXC_DMA_UART1_RX, &uart1_rx_dma_info},
+ {MXC_DMA_UART1_TX, &uart1_tx_dma_info},
+ {MXC_DMA_UART2_RX, &uart2_rx_dma_info},
+ {MXC_DMA_UART2_TX, &uart2_tx_dma_info},
+ {MXC_DMA_UART3_RX, &uart3_rx_dma_info},
+ {MXC_DMA_UART3_TX, &uart3_tx_dma_info},
+ {MXC_DMA_UART4_RX, &uart4_rx_dma_info},
+ {MXC_DMA_UART4_TX, &uart4_tx_dma_info},
+ {MXC_DMA_UART5_RX, &uart5_rx_dma_info},
+ {MXC_DMA_UART5_TX, &uart5_tx_dma_info},
+ {MXC_DMA_UART6_RX, &uart6_rx_dma_info},
+ {MXC_DMA_UART6_TX, &uart6_tx_dma_info},
+ {MXC_DMA_SSI1_16BIT_RX0, &ssi1_16bit_rx0_dma_info},
+ {MXC_DMA_SSI1_16BIT_TX0, &ssi1_16bit_tx0_dma_info},
+ {MXC_DMA_SSI2_16BIT_RX0, &ssi2_16bit_rx0_dma_info},
+ {MXC_DMA_SSI2_16BIT_TX0, &ssi2_16bit_tx0_dma_info},
+ {MXC_DMA_MMC1_WIDTH_1, &mmc1_width1_dma_info},
+ {MXC_DMA_MMC1_WIDTH_4, &mmc1_width4_dma_info},
+ {MXC_DMA_MMC2_WIDTH_1, &mmc2_width1_dma_info},
+ {MXC_DMA_MMC2_WIDTH_4, &mmc2_width4_dma_info},
+ {MXC_DMA_CSI_RX, &csi_rx_dma_info},
+};
+
+/*!
+ * @brief the number of actived dma info
+ */
+static int dma_info_entrys =
+ sizeof(active_dma_info) / sizeof(active_dma_info[0]);
+
+/*!
+ * @brief get the dma info by channel_id
+ */
+mx2_dma_info_t *mxc_dma_get_info(mxc_dma_device_t channel_id)
+{
+ dma_info_entry_t *p = active_dma_info;
+ int i;
+ for (i = 0; i < dma_info_entrys; i++, p++) {
+ if (p->device == channel_id)
+ return p->info;
+ }
+ return NULL;
+}
+
+/*!
+ * @brief: scan dma parameter list . And collect information about which channels are dynamic .
+ */
+void mxc_dma_load_info(mxc_dma_channel_t * dma)
+{
+ int i, idx;
+ dma_info_entry_t *p = active_dma_info;
+
+ BUG_ON(dma == NULL);
+ BUG_ON(p == NULL);
+
+ for (i = 0; i < MXC_DMA_CHANNELS; i++) {
+ dma[i].dynamic = 1;
+ }
+
+ for (i = 0; i < dma_info_entrys; i++, p++) {
+ BUG_ON((p->info == NULL));
+
+ idx = p->info->dma_chan;
+
+ BUG_ON(((idx >= MAX_DMA_CHANNELS)
+ && (idx != MXC_DMA_DYNAMIC_CHANNEL)));
+ if ((idx < 0) || (idx == MXC_DMA_DYNAMIC_CHANNEL))
+ continue;
+ dma[idx].dynamic = 0;
+ }
+}
+
+EXPORT_SYMBOL(mxc_dma_get_info);
+EXPORT_SYMBOL(mxc_dma_load_info);
diff --git a/arch/arm/mach-mx27/dptc.c b/arch/arm/mach-mx27/dptc.c
new file mode 100644
index 000000000000..deb058c23272
--- /dev/null
+++ b/arch/arm/mach-mx27/dptc.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file dptc.c
+ *
+ * @brief DPTC table for the Freescale Semiconductor MXC DPTC module.
+ *
+ * @ingroup PM
+ */
+
+#include <mach/hardware.h>
+#include <mach/mxc_dptc.h>
+
+struct dptc_wp dptc_wp_allfreq[DPTC_WP_SUPPORTED] = {
+ /* 532MHz */
+ /* dcvr0 dcvr1 dcvr2 dcvr3 voltage */
+ /* wp0 */
+ {0xffe00000, 0x18e2e85b, 0xffe00000, 0x25c4688a, 1600},
+ {0xffe00000, 0x18e2e85b, 0xffe00000, 0x25c4688a, 1575},
+ {0xffe00000, 0x1902e85b, 0xffe00000, 0x25e4688a, 1550},
+ {0xffe00000, 0x1922e85b, 0xffe00000, 0x25e4688a, 1525},
+ {0xffe00000, 0x1942ec5b, 0xffe00000, 0x2604688a, 1500},
+ /* wp5 */
+ {0xffe00000, 0x1942ec5b, 0xffe00000, 0x26646c8a, 1475},
+ {0xffe00000, 0x1962ec5b, 0xffe00000, 0x26c4708b, 1450},
+ {0xffe00000, 0x1962ec5b, 0xffe00000, 0x26e4708b, 1425},
+ {0xffe00000, 0x1982f05c, 0xffe00000, 0x2704748b, 1400},
+ {0xffe00000, 0x19c2f05c, 0xffe00000, 0x2744748b, 1375},
+ /* wp10 */
+ {0xffe00000, 0x1a02f45c, 0xffe00000, 0x2784788b, 1350},
+ {0xffe00000, 0x1a42f45c, 0xffe00000, 0x27c47c8b, 1325},
+ {0xffe00000, 0x1a82f85c, 0xffe00000, 0x2824808c, 1300},
+ {0xffe00000, 0x1aa2f85c, 0xffe00000, 0x2884848c, 1275},
+ {0xffe00000, 0x1ac2fc5c, 0xffe00000, 0x28e4888c, 1250},
+ /* wp15 */
+ {0xffe00000, 0x1ae2fc5c, 0xffe00000, 0x2924888c, 1225},
+ {0xffe00000, 0x1b23005d, 0xffe00000, 0x29648c8c, 1200},
+};
diff --git a/arch/arm/mach-mx27/gpio_mux.c b/arch/arm/mach-mx27/gpio_mux.c
new file mode 100644
index 000000000000..e02824d0061d
--- /dev/null
+++ b/arch/arm/mach-mx27/gpio_mux.c
@@ -0,0 +1,308 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup GPIO_MX27 Board GPIO and Muxing Setup
+ * @ingroup MSL_MX27
+ */
+/*!
+ * @file mach-mx27/gpio_mux.c
+ *
+ * @brief I/O Muxing control functions
+ *
+ * @ingroup GPIO_MX27
+ */
+
+#include <linux/kernel.h>
+#include <linux/cache.h>
+#include <linux/spinlock.h>
+
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include "gpio_mux.h"
+
+/*!
+ * This structure defines the offset of registers in gpio module.
+ */
+enum gpio_reg {
+ GPIO_GIUS = 0x20,
+ GPIO_GPR = 0x38,
+ GPIO_PUEN = 0x40,
+ GPIO_DDIR = 0x00,
+ GPIO_OCR1 = 0x04,
+ GPIO_OCR2 = 0x08,
+ GPIO_ICONFA1 = 0x0C,
+ GPIO_ICONFA2 = 0x10,
+ GPIO_ICONFB1 = 0x14,
+ GPIO_ICONFB2 = 0x18,
+};
+
+/*!
+ * This enumeration data type defines the configuration for input mode.
+ */
+typedef enum {
+ GPIO_INPUT_GPIO = 0x00,
+ GPIO_INPUT_INTR = 0x01,
+ GPIO_INPUT_LOW = 0x02,
+ GPIO_INPUT_HIGH = 0x03
+} gpio_input_cfg_t;
+
+/*!
+ * This enumeration data type defines the configuration for output mode.
+ */
+typedef enum {
+ GPIO_OUTPUT_A = 0x00,
+ GPIO_OUTPUT_B = 0x01,
+ GPIO_OUTPUT_C = 0x02,
+ GPIO_OUTPUT_DR = 0x03
+} gpio_output_cfg_t;
+
+extern struct mxc_gpio_port mxc_gpio_ports[];
+
+/*!
+ * defines a spinlock to protected the accessing to gpio pin.
+ */
+DEFINE_SPINLOCK(gpio_mux_lock);
+
+/*!
+ * This function enable or disable the pullup feature to the pin.
+ * @param port a pointer of gpio port
+ * @param index the index of the pin in the port
+ * @param en 0 if disable pullup, otherwise enable it.
+ * @return none
+ */
+static inline void _gpio_set_puen(struct mxc_gpio_port *port, u32 index,
+ bool en)
+{
+ u32 reg;
+
+ reg = __raw_readl(port->base + GPIO_PUEN);
+ if (en) {
+ reg |= 1 << index;
+ } else {
+ reg &= ~(1 << index);
+ }
+ __raw_writel(reg, port->base + GPIO_PUEN);
+}
+
+/*!
+ * This function set the input configuration A.
+ * @param port a pointer of gpio port
+ * @param index the index of the pin in the port
+ * @param config a mode as define in \b #gpio_input_cfg_t
+ * @return none
+ */
+static inline void _gpio_set_iconfa(struct mxc_gpio_port *port, u32 index,
+ gpio_input_cfg_t config)
+{
+ u32 reg, val;
+ u32 mask;
+
+ mask = 0x3 << ((index % 16) << 1);
+
+ if (index >= 16) {
+ reg = port->base + GPIO_ICONFA2;
+ val = config << ((index - 16) * 2);
+ } else {
+ reg = port->base + GPIO_ICONFA1;
+ val = config << (index * 2);
+ }
+ val |= __raw_readl(reg) & ~(mask);
+ __raw_writel(val, reg);
+}
+
+/*!
+ * This function set the input configuration B.
+ * @param port a pointer of gpio port
+ * @param index the index of the pin in the port
+ * @param config a mode as define in \b #gpio_input_cfg_t
+ * @return none
+ */
+static inline void _gpio_set_iconfb(struct mxc_gpio_port *port, u32 index,
+ gpio_input_cfg_t config)
+{
+ u32 reg, val;
+ u32 mask;
+
+ mask = 0x3 << ((index % 16) << 1);
+
+ if (index >= 16) {
+ reg = port->base + GPIO_ICONFB2;
+ val = config << ((index - 16) * 2);
+ } else {
+ reg = port->base + GPIO_ICONFB1;
+ val = config << (index * 2);
+ }
+ val |= __raw_readl(reg) & (~mask);
+ __raw_writel(val, reg);
+}
+
+/*!
+ * This function set the output configuration.
+ * @param port a pointer of gpio port
+ * @param index the index of the pin in the port
+ * @param config a mode as define in \b #gpio_output_cfg_t
+ * @return none
+ */
+static inline void _gpio_set_ocr(struct mxc_gpio_port *port, u32 index,
+ gpio_output_cfg_t config)
+{
+ u32 reg, val;
+ u32 mask;
+
+ mask = 0x3 << ((index % 16) << 1);
+ if (index >= 16) {
+ reg = port->base + GPIO_OCR2;
+ val = config << ((index - 16) * 2);
+ } else {
+ reg = port->base + GPIO_OCR1;
+ val = config << (index * 2);
+ }
+ val |= __raw_readl(reg) & (~mask);
+ __raw_writel(val, reg);
+}
+
+/*!
+ *@brief gpio_config_mux - just configure the mode of the gpio pin.
+ *@param pin a pin number as defined in \b #iomux_pin_name_t
+ *@param mode a module as define in \b #gpio_mux_mode_t;
+ * GPIO_MUX_PRIMARY set pin to work as primary function.
+ * GPIO_MUX_ALT set pin to work as alternate function.
+ * GPIO_MUX_GPIO set pin to work as output function based the data register
+ * GPIO_MUX_INPUT1 set pin to work as input function connected with A_OUT
+ * GPIO_MUX_INPUT2 set pin to work as input function connected with B_OUT
+ * GPIO_MUX_OUTPUT1 set pin to work as output function connected with A_IN
+ * GPIO_MUX_OUTPUT2 set pin to work as output function connected with B_IN
+ * GPIO_MUX_OUTPUT3 set pin to work as output function connected with C_IN
+ *@return 0 if successful, Non-zero otherwise
+ */
+
+int gpio_config_mux(iomux_pin_name_t pin, gpio_mux_mode_t mode)
+{
+ unsigned long lock_flags;
+ u32 gius_reg, gpr_reg;
+ struct mxc_gpio_port *port;
+ u32 index, gpio = IOMUX_TO_GPIO(pin);
+
+ port = &(mxc_gpio_ports[GPIO_TO_PORT(gpio)]);
+ index = GPIO_TO_INDEX(gpio);
+
+ pr_debug("%s: Configuring PORT %c, bit %d\n",
+ __FUNCTION__, port->num + 'A', index);
+
+ spin_lock_irqsave(&gpio_mux_lock, lock_flags);
+
+ gius_reg = __raw_readl(port->base + GPIO_GIUS);
+ gpr_reg = __raw_readl(port->base + GPIO_GPR);
+
+ switch (mode) {
+ case GPIO_MUX_PRIMARY:
+ gius_reg &= ~(1L << index);
+ gpr_reg &= ~(1L << index);
+ break;
+ case GPIO_MUX_ALT:
+ gius_reg &= ~(1L << index);
+ gpr_reg |= (1L << index);
+ break;
+ case GPIO_MUX_GPIO:
+ gius_reg |= (1L << index);
+ _gpio_set_ocr(port, index, GPIO_OUTPUT_DR);
+ break;
+ case GPIO_MUX_INPUT1:
+ gius_reg |= (1L << index);
+ _gpio_set_iconfa(port, index, GPIO_INPUT_GPIO);
+ break;
+ case GPIO_MUX_INPUT2:
+ gius_reg |= (1L << index);
+ _gpio_set_iconfb(port, index, GPIO_INPUT_GPIO);
+ break;
+ case GPIO_MUX_OUTPUT1:
+ gius_reg |= (1L << index);
+ _gpio_set_ocr(port, index, GPIO_OUTPUT_A);
+ break;
+ case GPIO_MUX_OUTPUT2:
+ gius_reg |= (1L << index);
+ _gpio_set_ocr(port, index, GPIO_OUTPUT_B);
+ break;
+ case GPIO_MUX_OUTPUT3:
+ gius_reg |= (1L << index);
+ _gpio_set_ocr(port, index, GPIO_OUTPUT_C);
+ break;
+ default:
+ spin_unlock_irqrestore(&gpio_mux_lock, lock_flags);
+ return -1;
+ }
+
+ __raw_writel(gius_reg, port->base + GPIO_GIUS);
+ __raw_writel(gpr_reg, port->base + GPIO_GPR);
+
+ spin_unlock_irqrestore(&gpio_mux_lock, lock_flags);
+ return 0;
+}
+
+/*!
+ * This function is just used to enable or disable the pull up feature .
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param en 0 if disable, Non-zero enable
+ * @return 0 if successful, Non-zero otherwise
+ */
+int gpio_set_puen(iomux_pin_name_t pin, bool en)
+{
+ unsigned long lock_flags;
+
+ struct mxc_gpio_port *port;
+ u32 index, gpio = IOMUX_TO_GPIO(pin);
+
+ port = &(mxc_gpio_ports[GPIO_TO_PORT(gpio)]);
+ index = GPIO_TO_INDEX(gpio);
+
+ pr_debug("%s: Configuring output mode of PORT %c, bit %d\n",
+ __FUNCTION__, port->num + 'A', index);
+
+ spin_lock_irqsave(&gpio_mux_lock, lock_flags);
+
+ _gpio_set_puen(port, index, en);
+ spin_unlock_irqrestore(&gpio_mux_lock, lock_flags);
+ return 0;
+
+}
+
+/*!
+ * This function is just used to request a pin and configure it.
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param mode a module as define in \b #gpio_mux_mode_t;
+ * @return 0 if successful, Non-zero otherwise
+ */
+int gpio_request_mux(iomux_pin_name_t pin, gpio_mux_mode_t mode)
+{
+ int ret;
+ ret = mxc_request_gpio(pin);
+ if (ret == 0) {
+ ret = gpio_config_mux(pin, mode);
+ if (ret) {
+ mxc_free_gpio(pin);
+ }
+ }
+ return ret;
+}
+
+/*!
+ * This function is just used to release a pin.
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @return none
+ */
+void gpio_free_mux(iomux_pin_name_t pin)
+{
+ mxc_free_gpio(pin);
+}
diff --git a/arch/arm/mach-mx27/gpio_mux.h b/arch/arm/mach-mx27/gpio_mux.h
new file mode 100644
index 000000000000..3d093da20248
--- /dev/null
+++ b/arch/arm/mach-mx27/gpio_mux.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ *@file mach-mx27/gpio_mux.h
+ *@brief This file contains the private definition .
+ * @ingroup GPIO_MX27
+ */
+
+#ifndef __ARCH_ARM_MACH_MX27_GPIO_MUX_H__
+#define __ARCH_ARM_MACH_MX27_GPIO_MUX_H__
+
+#include "mx27_pins.h"
+
+/*!
+ * This enumeration data type defines the modes of the pin .
+ * GPIO_MUX_PRIMARY is the primary mode.
+ * GPIO_MUX_ALT is the alternate mode.
+ * GPIO_MUX_GPIO is the output mode and the signal source is data register.
+ * GPIO_MUX_INPUT1 is the input mode and the signal destination is A_OUT.
+ * GPIO_MUX_INPUT2 is the input mode and the signal destination is B_OUT.
+ * GPIO_MUX_OUTPUT1 is the output mode and the signal destination is A_IN.
+ * GPIO_MUX_OUTPUT2 is the output mode and the signal destination is B_IN.
+ * GPIO_MUX_OUTPUT3 is the output mode and the signal destination is C_IN.
+ */
+typedef enum {
+ GPIO_MUX_PRIMARY,
+ GPIO_MUX_ALT,
+ GPIO_MUX_GPIO,
+ GPIO_MUX_INPUT1,
+ GPIO_MUX_INPUT2,
+ GPIO_MUX_OUTPUT1,
+ GPIO_MUX_OUTPUT2,
+ GPIO_MUX_OUTPUT3,
+} gpio_mux_mode_t;
+
+/*!
+ * This function is just used to request a pin and configure it.
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param mode a module as define in \b #gpio_mux_mode_t;
+ * @return 0 if successful, Non-zero otherwise
+ */
+extern int gpio_request_mux(iomux_pin_name_t pin, gpio_mux_mode_t mode);
+
+/*!
+ * This function is just used to configure a pin .
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param mode a module as define in \b #gpio_mux_mode_t;
+ * @return 0 if successful, Non-zero otherwise
+ */
+extern int gpio_config_mux(iomux_pin_name_t pin, gpio_mux_mode_t mode);
+
+/*!
+ * This function is just used to enable or disable the pull up feature .
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param en 0 if disable, Non-zero enable
+ * @return 0 if successful, Non-zero otherwise
+ */
+extern int gpio_set_puen(iomux_pin_name_t pin, bool en);
+
+/*!
+ * This function is just used to release a pin.
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @return none
+ */
+extern void gpio_free_mux(iomux_pin_name_t pin);
+
+#endif /* __ARCH_ARM_MACH_MX27_GPIO_MUX_H__ */
diff --git a/arch/arm/mach-mx27/mm.c b/arch/arm/mach-mx27/mm.c
new file mode 100644
index 000000000000..9f673b6687a2
--- /dev/null
+++ b/arch/arm/mach-mx27/mm.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <mach/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+/*!
+ * @file mach-mx27/mm.c
+ *
+ * @brief This file creates static mapping between physical to virtual memory.
+ *
+ * @ingroup Memory_MX27
+ */
+
+/*!
+ * This structure defines the MX27 memory map.
+ */
+static struct map_desc mxc_io_desc[] __initdata = {
+ {
+ .virtual = AIPI_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AIPI_BASE_ADDR),
+ .length = AIPI_SIZE,
+ .type = MT_DEVICE},
+ {
+ .virtual = SAHB1_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(SAHB1_BASE_ADDR),
+ .length = SAHB1_SIZE,
+ .type = MT_DEVICE},
+ {
+ .virtual = X_MEMC_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(X_MEMC_BASE_ADDR),
+ .length = X_MEMC_SIZE,
+ .type = MT_DEVICE},
+ {
+ .virtual = CS4_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(CS4_BASE_ADDR),
+ .length = CS4_SIZE,
+ .type = MT_DEVICE}
+};
+
+/*!
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory map for
+ * the IO modules.
+ */
+void __init mxc_map_io(void)
+{
+ iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
+}
diff --git a/arch/arm/mach-mx27/mx27_pins.h b/arch/arm/mach-mx27/mx27_pins.h
new file mode 100644
index 000000000000..40ff1be1febc
--- /dev/null
+++ b/arch/arm/mach-mx27/mx27_pins.h
@@ -0,0 +1,207 @@
+/*
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_MX27_PINS_H__
+#define __ASM_ARCH_MXC_MX27_PINS_H__
+
+/*!
+ * @file arch-mxc/mx27_pins.h
+ *
+ * @brief MX27 I/O Pin List
+ *
+ * @ingroup GPIO_MX27
+ */
+
+#ifndef __ASSEMBLY__
+
+#define _MX27_BUILD_PIN(gp,gi) (((gp) << MUX_IO_P) | ((gi) << MUX_IO_I))
+
+enum iomux_pins {
+ MX27_PIN_USBH2_CLK = _MX27_BUILD_PIN(0, 0),
+ MX27_PIN_USBH2_DIR = _MX27_BUILD_PIN(0, 1),
+ MX27_PIN_USBH2_DATA7 = _MX27_BUILD_PIN(0, 2),
+ MX27_PIN_USBH2_NXT = _MX27_BUILD_PIN(0, 3),
+ MX27_PIN_USBH2_STP = _MX27_BUILD_PIN(0, 4),
+ MX27_PIN_LSCLK = _MX27_BUILD_PIN(0, 5),
+ MX27_PIN_LD0 = _MX27_BUILD_PIN(0, 6),
+ MX27_PIN_LD1 = _MX27_BUILD_PIN(0, 7),
+ MX27_PIN_LD2 = _MX27_BUILD_PIN(0, 8),
+ MX27_PIN_LD3 = _MX27_BUILD_PIN(0, 9),
+ MX27_PIN_LD4 = _MX27_BUILD_PIN(0, 10),
+ MX27_PIN_LD5 = _MX27_BUILD_PIN(0, 11),
+ MX27_PIN_LD6 = _MX27_BUILD_PIN(0, 12),
+ MX27_PIN_LD7 = _MX27_BUILD_PIN(0, 13),
+ MX27_PIN_LD8 = _MX27_BUILD_PIN(0, 14),
+ MX27_PIN_LD9 = _MX27_BUILD_PIN(0, 15),
+ MX27_PIN_LD10 = _MX27_BUILD_PIN(0, 16),
+ MX27_PIN_LD11 = _MX27_BUILD_PIN(0, 17),
+ MX27_PIN_LD12 = _MX27_BUILD_PIN(0, 18),
+ MX27_PIN_LD13 = _MX27_BUILD_PIN(0, 19),
+ MX27_PIN_LD14 = _MX27_BUILD_PIN(0, 20),
+ MX27_PIN_LD15 = _MX27_BUILD_PIN(0, 21),
+ MX27_PIN_LD16 = _MX27_BUILD_PIN(0, 22),
+ MX27_PIN_LD17 = _MX27_BUILD_PIN(0, 23),
+ MX27_PIN_REV = _MX27_BUILD_PIN(0, 24),
+ MX27_PIN_CLS = _MX27_BUILD_PIN(0, 25),
+ MX27_PIN_PS = _MX27_BUILD_PIN(0, 26),
+ MX27_PIN_SPL_SPR = _MX27_BUILD_PIN(0, 27),
+ MX27_PIN_HSYNC = _MX27_BUILD_PIN(0, 28),
+ MX27_PIN_VSYNC = _MX27_BUILD_PIN(0, 29),
+ MX27_PIN_CONTRAST = _MX27_BUILD_PIN(0, 30),
+ MX27_PIN_OE_ACD = _MX27_BUILD_PIN(0, 31),
+
+ MX27_PIN_SD2_D0 = _MX27_BUILD_PIN(1, 4),
+ MX27_PIN_SD2_D1 = _MX27_BUILD_PIN(1, 5),
+ MX27_PIN_SD2_D2 = _MX27_BUILD_PIN(1, 6),
+ MX27_PIN_SD2_D3 = _MX27_BUILD_PIN(1, 7),
+ MX27_PIN_SD2_CMD = _MX27_BUILD_PIN(1, 8),
+ MX27_PIN_SD2_CLK = _MX27_BUILD_PIN(1, 9),
+ MX27_PIN_CSI_D0 = _MX27_BUILD_PIN(1, 10),
+ MX27_PIN_CSI_D1 = _MX27_BUILD_PIN(1, 11),
+ MX27_PIN_CSI_D2 = _MX27_BUILD_PIN(1, 12),
+ MX27_PIN_CSI_D3 = _MX27_BUILD_PIN(1, 13),
+ MX27_PIN_CSI_D4 = _MX27_BUILD_PIN(1, 14),
+ MX27_PIN_CSI_MCLK = _MX27_BUILD_PIN(1, 15),
+ MX27_PIN_CSI_PIXCLK = _MX27_BUILD_PIN(1, 16),
+ MX27_PIN_CSI_D5 = _MX27_BUILD_PIN(1, 17),
+ MX27_PIN_CSI_D6 = _MX27_BUILD_PIN(1, 18),
+ MX27_PIN_CSI_D7 = _MX27_BUILD_PIN(1, 19),
+ MX27_PIN_CSI_VSYNC = _MX27_BUILD_PIN(1, 20),
+ MX27_PIN_CSI_HSYNC = _MX27_BUILD_PIN(1, 21),
+ MX27_PIN_USBH1_SUSP = _MX27_BUILD_PIN(1, 22),
+ MX27_PIN_USB_PWR = _MX27_BUILD_PIN(1, 23),
+ MX27_PIN_USB_OC_B = _MX27_BUILD_PIN(1, 24),
+ MX27_PIN_USBH1_RCV = _MX27_BUILD_PIN(1, 25),
+ MX27_PIN_USBH1_FS = _MX27_BUILD_PIN(1, 26),
+ MX27_PIN_USBH1_OE_B = _MX27_BUILD_PIN(1, 27),
+ MX27_PIN_USBH1_TXDM = _MX27_BUILD_PIN(1, 28),
+ MX27_PIN_USBH1_TXDP = _MX27_BUILD_PIN(1, 29),
+ MX27_PIN_USBH1_RXDM = _MX27_BUILD_PIN(1, 30),
+ MX27_PIN_USBH1_RXDP = _MX27_BUILD_PIN(1, 31),
+
+ MX27_PIN_I2C2_SDA = _MX27_BUILD_PIN(2, 5),
+ MX27_PIN_I2C2_SCL = _MX27_BUILD_PIN(2, 6),
+ MX27_PIN_USBOTG_DATA5 = _MX27_BUILD_PIN(2, 7),
+ MX27_PIN_USBOTG_DATA6 = _MX27_BUILD_PIN(2, 8),
+ MX27_PIN_USBOTG_DATA0 = _MX27_BUILD_PIN(2, 9),
+ MX27_PIN_USBOTG_DATA2 = _MX27_BUILD_PIN(2, 10),
+ MX27_PIN_USBOTG_DATA1 = _MX27_BUILD_PIN(2, 11),
+ MX27_PIN_USBOTG_DATA4 = _MX27_BUILD_PIN(2, 12),
+ MX27_PIN_USBOTG_DATA3 = _MX27_BUILD_PIN(2, 13),
+ MX27_PIN_TOUT = _MX27_BUILD_PIN(2, 14),
+ MX27_PIN_TIN = _MX27_BUILD_PIN(2, 15),
+ MX27_PIN_SSI4_FS = _MX27_BUILD_PIN(2, 16),
+ MX27_PIN_SSI4_RXDAT = _MX27_BUILD_PIN(2, 17),
+ MX27_PIN_SSI4_TXDAT = _MX27_BUILD_PIN(2, 18),
+ MX27_PIN_SSI4_CLK = _MX27_BUILD_PIN(2, 19),
+ MX27_PIN_SSI1_FS = _MX27_BUILD_PIN(2, 20),
+ MX27_PIN_SSI1_RXDAT = _MX27_BUILD_PIN(2, 21),
+ MX27_PIN_SSI1_TXDAT = _MX27_BUILD_PIN(2, 22),
+ MX27_PIN_SSI1_CLK = _MX27_BUILD_PIN(2, 23),
+ MX27_PIN_SSI2_FS = _MX27_BUILD_PIN(2, 24),
+ MX27_PIN_SSI2_RXDAT = _MX27_BUILD_PIN(2, 25),
+ MX27_PIN_SSI2_TXDAT = _MX27_BUILD_PIN(2, 26),
+ MX27_PIN_SSI2_CLK = _MX27_BUILD_PIN(2, 27),
+ MX27_PIN_SSI3_FS = _MX27_BUILD_PIN(2, 28),
+ MX27_PIN_SSI3_RXDAT = _MX27_BUILD_PIN(2, 29),
+ MX27_PIN_SSI3_TXDAT = _MX27_BUILD_PIN(2, 30),
+ MX27_PIN_SSI3_CLK = _MX27_BUILD_PIN(2, 31),
+
+ MX27_PIN_SD3_CMD = _MX27_BUILD_PIN(3, 0),
+ MX27_PIN_SD3_CLK = _MX27_BUILD_PIN(3, 1),
+ MX27_PIN_ATA_DATA0 = _MX27_BUILD_PIN(3, 2),
+ MX27_PIN_ATA_DATA1 = _MX27_BUILD_PIN(3, 3),
+ MX27_PIN_ATA_DATA2 = _MX27_BUILD_PIN(3, 4),
+ MX27_PIN_ATA_DATA3 = _MX27_BUILD_PIN(3, 5),
+ MX27_PIN_ATA_DATA4 = _MX27_BUILD_PIN(3, 6),
+ MX27_PIN_ATA_DATA5 = _MX27_BUILD_PIN(3, 7),
+ MX27_PIN_ATA_DATA6 = _MX27_BUILD_PIN(3, 8),
+ MX27_PIN_ATA_DATA7 = _MX27_BUILD_PIN(3, 9),
+ MX27_PIN_ATA_DATA8 = _MX27_BUILD_PIN(3, 10),
+ MX27_PIN_ATA_DATA9 = _MX27_BUILD_PIN(3, 11),
+ MX27_PIN_ATA_DATA10 = _MX27_BUILD_PIN(3, 12),
+ MX27_PIN_ATA_DATA11 = _MX27_BUILD_PIN(3, 13),
+ MX27_PIN_ATA_DATA12 = _MX27_BUILD_PIN(3, 14),
+ MX27_PIN_ATA_DATA13 = _MX27_BUILD_PIN(3, 15),
+ MX27_PIN_ATA_DATA14 = _MX27_BUILD_PIN(3, 16),
+ MX27_PIN_I2C_DATA = _MX27_BUILD_PIN(3, 17),
+ MX27_PIN_I2C_CLK = _MX27_BUILD_PIN(3, 18),
+ MX27_PIN_CSPI2_SS2 = _MX27_BUILD_PIN(3, 19),
+ MX27_PIN_CSPI2_SS1 = _MX27_BUILD_PIN(3, 20),
+ MX27_PIN_CSPI2_SS0 = _MX27_BUILD_PIN(3, 21),
+ MX27_PIN_CSPI2_SCLK = _MX27_BUILD_PIN(3, 22),
+ MX27_PIN_CSPI2_MISO = _MX27_BUILD_PIN(3, 23),
+ MX27_PIN_CSPI2_MOSI = _MX27_BUILD_PIN(3, 24),
+ MX27_PIN_CSPI1_RDY = _MX27_BUILD_PIN(3, 25),
+ MX27_PIN_CSPI1_SS2 = _MX27_BUILD_PIN(3, 26),
+ MX27_PIN_CSPI1_SS1 = _MX27_BUILD_PIN(3, 27),
+ MX27_PIN_CSPI1_SS0 = _MX27_BUILD_PIN(3, 28),
+ MX27_PIN_CSPI1_SCLK = _MX27_BUILD_PIN(3, 29),
+ MX27_PIN_CSPI1_MISO = _MX27_BUILD_PIN(3, 30),
+ MX27_PIN_CSPI1_MOSI = _MX27_BUILD_PIN(3, 31),
+
+ MX27_PIN_USBOTG_NXT = _MX27_BUILD_PIN(4, 0),
+ MX27_PIN_USBOTG_STP = _MX27_BUILD_PIN(4, 1),
+ MX27_PIN_USBOTG_DIR = _MX27_BUILD_PIN(4, 2),
+ MX27_PIN_UART2_CTS = _MX27_BUILD_PIN(4, 3),
+ MX27_PIN_UART2_RTS = _MX27_BUILD_PIN(4, 4),
+ MX27_PIN_PWMO = _MX27_BUILD_PIN(4, 5),
+ MX27_PIN_UART2_TXD = _MX27_BUILD_PIN(4, 6),
+ MX27_PIN_UART2_RXD = _MX27_BUILD_PIN(4, 7),
+ MX27_PIN_UART3_TXD = _MX27_BUILD_PIN(4, 8),
+ MX27_PIN_UART3_RXD = _MX27_BUILD_PIN(4, 9),
+ MX27_PIN_UART3_CTS = _MX27_BUILD_PIN(4, 10),
+ MX27_PIN_UART3_RTS = _MX27_BUILD_PIN(4, 11),
+ MX27_PIN_UART1_TXD = _MX27_BUILD_PIN(4, 12),
+ MX27_PIN_UART1_RXD = _MX27_BUILD_PIN(4, 13),
+ MX27_PIN_UART1_CTS = _MX27_BUILD_PIN(4, 14),
+ MX27_PIN_UART1_RTS = _MX27_BUILD_PIN(4, 15),
+ MX27_PIN_RTCK = _MX27_BUILD_PIN(4, 16),
+ MX27_PIN_RESET_OUT_B = _MX27_BUILD_PIN(4, 17),
+ MX27_PIN_SD1_D0 = _MX27_BUILD_PIN(4, 18),
+ MX27_PIN_SD1_D1 = _MX27_BUILD_PIN(4, 19),
+ MX27_PIN_SD1_D2 = _MX27_BUILD_PIN(4, 20),
+ MX27_PIN_SD1_D3 = _MX27_BUILD_PIN(4, 21),
+ MX27_PIN_SD1_CMD = _MX27_BUILD_PIN(4, 22),
+ MX27_PIN_SD1_CLK = _MX27_BUILD_PIN(4, 23),
+ MX27_PIN_USBOTG_CLK = _MX27_BUILD_PIN(4, 24),
+ MX27_PIN_USBOTG_DATA7 = _MX27_BUILD_PIN(4, 25),
+
+ MX27_PIN_NFRB = _MX27_BUILD_PIN(5, 0),
+ MX27_PIN_NFCLE = _MX27_BUILD_PIN(5, 1),
+ MX27_PIN_NFWP_B = _MX27_BUILD_PIN(5, 2),
+ MX27_PIN_NFCE_B = _MX27_BUILD_PIN(5, 3),
+ MX27_PIN_NFALE = _MX27_BUILD_PIN(5, 4),
+ MX27_PIN_NFRE_B = _MX27_BUILD_PIN(5, 5),
+ MX27_PIN_NFWE_B = _MX27_BUILD_PIN(5, 6),
+ MX27_PIN_PC_POE = _MX27_BUILD_PIN(5, 7),
+ MX27_PIN_PC_RW_B = _MX27_BUILD_PIN(5, 8),
+ MX27_PIN_IOIS16 = _MX27_BUILD_PIN(5, 9),
+ MX27_PIN_PC_RST = _MX27_BUILD_PIN(5, 10),
+ MX27_PIN_PC_BVD2 = _MX27_BUILD_PIN(5, 11),
+ MX27_PIN_PC_BVD1 = _MX27_BUILD_PIN(5, 12),
+ MX27_PIN_PC_VS2 = _MX27_BUILD_PIN(5, 13),
+ MX27_PIN_PC_VS1 = _MX27_BUILD_PIN(5, 14),
+ MX27_PIN_CLKO = _MX27_BUILD_PIN(5, 15),
+ MX27_PIN_PC_PWRON = _MX27_BUILD_PIN(5, 16),
+ MX27_PIN_PC_READY = _MX27_BUILD_PIN(5, 17),
+ MX27_PIN_PC_WAIT_B = _MX27_BUILD_PIN(5, 18),
+ MX27_PIN_PC_CD2_B = _MX27_BUILD_PIN(5, 19),
+ MX27_PIN_PC_CD1_B = _MX27_BUILD_PIN(5, 20),
+ MX27_PIN_CS4_B = _MX27_BUILD_PIN(5, 21),
+ MX27_PIN_CS5_B = _MX27_BUILD_PIN(5, 22),
+ MX27_PIN_ATA_DATA15 = _MX27_BUILD_PIN(5, 23),
+};
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_ARCH_MXC_MX27_PINS_H__ */
diff --git a/arch/arm/mach-mx27/mx27ads.c b/arch/arm/mach-mx27/mx27ads.c
new file mode 100644
index 000000000000..44e062721936
--- /dev/null
+++ b/arch/arm/mach-mx27/mx27ads.c
@@ -0,0 +1,822 @@
+/*
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright 2006-2009 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
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
+#include <linux/serial_8250.h>
+#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE)
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/flash.h>
+#endif
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/memory.h>
+#include <mach/gpio.h>
+#include <asm/mach/keypad.h>
+#include "gpio_mux.h"
+#include "board-mx27ads.h"
+
+/*!
+ * @file mach-mx27/mx27ads.c
+ * @brief This file contains the board specific initialization routines.
+ *
+ * @ingroup MSL_MX27
+ */
+
+extern void mxc_map_io(void);
+extern void mxc_init_irq(void);
+extern void mxc_cpu_init(void) __init;
+extern void mxc_clocks_init(void);
+extern void mxc_cpu_common_init(void);
+extern struct sys_timer mxc_timer;
+extern void __init early_console_setup(char *);
+
+static char command_line[COMMAND_LINE_SIZE];
+static int mxc_card_status;
+int mxc_board_is_ads = 1;
+
+static void mxc_nop_release(struct device *dev)
+{
+ /* Nothing */
+}
+
+unsigned long board_get_ckih_rate(void)
+{
+ if ((__raw_readw(PBC_VERSION_REG) & CKIH_27MHZ_BIT_SET) == 0) {
+ return 27000000;
+ }
+ return 26000000;
+}
+
+#if defined(CONFIG_CS89x0) || defined(CONFIG_CS89x0_MODULE)
+/*! Null terminated portlist used to probe for the CS8900A device on ISA Bus
+ * Add 3 to reset the page window before probing (fixes eth probe when deployed
+ * using nand_boot)
+ */
+unsigned int netcard_portlist[] = { CS8900A_BASE_ADDRESS + 3, 0 };
+
+EXPORT_SYMBOL(netcard_portlist);
+/*!
+ * The CS8900A has 4 IRQ pins, which is software selectable, CS8900A interrupt
+ * pin 0 is used for interrupt generation.
+ */
+unsigned int cs8900_irq_map[] = { CS8900AIRQ, 0, 0, 0 };
+
+EXPORT_SYMBOL(cs8900_irq_map);
+#endif
+
+#if defined(CONFIG_FEC) || defined(CONFIG_FEC_MODULE)
+unsigned int expio_intr_fec = MXC_EXP_IO_BASE + 7;
+
+EXPORT_SYMBOL(expio_intr_fec);
+#endif
+
+#if defined(CONFIG_KEYBOARD_MXC) || defined(CONFIG_KEYBOARD_MXC_MODULE)
+
+/*!
+ * This array is used for mapping mx27 ADS keypad scancodes to input keyboard
+ * keycodes.
+ */
+static u16 mxckpd_keycodes[] = {
+ KEY_KP9, KEY_LEFTSHIFT, KEY_0, KEY_KPASTERISK, KEY_RECORD, KEY_POWER,
+ KEY_KP8, KEY_9, KEY_8, KEY_7, KEY_KP5, KEY_VOLUMEDOWN,
+ KEY_KP7, KEY_6, KEY_5, KEY_4, KEY_KP4, KEY_VOLUMEUP,
+ KEY_KP6, KEY_3, KEY_2, KEY_1, KEY_KP3, KEY_DOWN,
+ KEY_BACK, KEY_RIGHT, KEY_ENTER, KEY_LEFT, KEY_HOME, KEY_KP2,
+ KEY_END, KEY_F2, KEY_UP, KEY_F1, KEY_F4, KEY_KP1,
+};
+
+static struct keypad_data evb_6_by_6_keypad = {
+ .rowmax = 6,
+ .colmax = 6,
+ .irq = MXC_INT_KPP,
+ .learning = 0,
+ .delay = 2,
+ .matrix = mxckpd_keycodes,
+};
+
+static struct resource mxc_kpp_resources[] = {
+ [0] = {
+ .start = MXC_INT_KPP,
+ .end = MXC_INT_KPP,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+/* mxc keypad driver */
+static struct platform_device mxc_keypad_device = {
+ .name = "mxc_keypad",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mxc_kpp_resources),
+ .resource = mxc_kpp_resources,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &evb_6_by_6_keypad,
+ },
+};
+
+static void mxc_init_keypad(void)
+{
+ (void)platform_device_register(&mxc_keypad_device);
+}
+#else
+static inline void mxc_init_keypad(void)
+{
+}
+#endif
+
+/* MTD NOR flash */
+
+#if defined(CONFIG_MTD_MXC) || defined(CONFIG_MTD_MXC_MODULE)
+
+static struct mtd_partition mxc_nor_partitions[] = {
+ {
+ .name = "Bootloader",
+ .size = 512 * 1024,
+ .offset = 0x00000000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "nor.Kernel",
+ .size = 2 * 1024 * 1024,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = 0},
+ {
+ .name = "nor.userfs",
+ .size = 14 * 1024 * 1024,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = 0},
+ {
+ .name = "nor.rootfs",
+ .size = 12 * 1024 * 1024,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE},
+ {
+ .name = "FIS directory",
+ .size = 12 * 1024,
+ .offset = 0x01FE0000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "Redboot config",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0x01FFF000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+};
+
+static struct flash_platform_data mxc_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+ .parts = mxc_nor_partitions,
+ .nr_parts = ARRAY_SIZE(mxc_nor_partitions),
+};
+
+static struct resource mxc_flash_resource = {
+ .start = 0xc0000000,
+ .end = 0xc0000000 + 0x02000000 - 1,
+ .flags = IORESOURCE_MEM,
+
+};
+
+static struct platform_device mxc_nor_mtd_device = {
+ .name = "mxc_nor_flash",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &mxc_flash_resource,
+};
+
+static void mxc_init_nor_mtd(void)
+{
+ (void)platform_device_register(&mxc_nor_mtd_device);
+}
+#else
+static void mxc_init_nor_mtd(void)
+{
+}
+#endif
+
+/* MTD NAND flash */
+
+#if defined(CONFIG_MTD_NAND_MXC) || defined(CONFIG_MTD_NAND_MXC_MODULE)
+
+static struct mtd_partition mxc_nand_partitions[4] = {
+ {
+ .name = "nand.bootloader",
+ .offset = 0,
+ .size = 1024 * 1024},
+ {
+ .name = "nand.kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 5 * 1024 * 1024},
+ {
+ .name = "nand.rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 22 * 1024 * 1024},
+ {
+ .name = "nand.userfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL},
+};
+
+static struct flash_platform_data mxc_nand_data = {
+ .parts = mxc_nand_partitions,
+ .nr_parts = ARRAY_SIZE(mxc_nand_partitions),
+ .width = 1,
+};
+
+static struct platform_device mxc_nand_mtd_device = {
+ .name = "mxc_nand_flash",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_nand_data,
+ },
+};
+
+static void mxc_init_nand_mtd(void)
+{
+ (void)platform_device_register(&mxc_nand_mtd_device);
+}
+#else
+static inline void mxc_init_nand_mtd(void)
+{
+}
+#endif
+
+#if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE)
+static const char fb_default_mode[] = "Sharp-QVGA";
+
+/* mxc lcd driver */
+static struct platform_device mxc_fb_device = {
+ .name = "mxc_sdc_fb",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &fb_default_mode,
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+};
+
+static void mxc_init_fb(void)
+{
+ (void)platform_device_register(&mxc_fb_device);
+}
+#else
+static inline void mxc_init_fb(void)
+{
+}
+#endif
+
+#if defined(CONFIG_BACKLIGHT_MXC)
+static struct platform_device mxcbl_devices[] = {
+#if defined(CONFIG_BACKLIGHT_MXC_PMIC) || defined(CONFIG_BACKLIGHT_MXC_PMIC_MODULE)
+ {
+ .name = "mxc_pmic_bl",
+ .id = 0,
+ .dev = {
+ .platform_data = (void *)-1, /* DISP # for this backlight */
+ },
+ },
+ {
+ .name = "mxc_pmic_bl",
+ .id = 1,
+ .dev = {
+ .platform_data = (void *)0, /* DISP # for this backlight */
+ },
+ },
+#endif
+#if defined(CONFIG_BACKLIGHT_MXC_LCDC) || defined(CONFIG_BACKLIGHT_MXC_LCDC_MODULE)
+ {
+ .name = "mxc_lcdc_bl",
+ .id = 0,
+ .dev = {
+ .platform_data = (void *)3, /* DISP # for this backlight */
+ },
+ },
+#endif
+};
+static inline void mxc_init_bl(void)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(mxcbl_devices); i++) {
+ platform_device_register(&mxcbl_devices[i]);
+ }
+}
+#else
+static inline void mxc_init_bl(void)
+{
+}
+#endif
+
+static struct spi_board_info mxc_spi_board_info[] __initdata = {
+ {
+ .modalias = "pmic_spi",
+ .irq = IOMUX_TO_IRQ(MX27_PIN_TOUT),
+ .max_speed_hz = 4000000,
+ .bus_num = 1,
+ .chip_select = 0,
+ },
+};
+
+#if 0
+#define MXC_CARD_DEBUG
+#endif
+
+static const int pbc_card_bit[4][3] = {
+ /* BSTAT IMR enable IMR removal */
+ {PBC_BSTAT_SD2_DET, PBC_INTR_SD2_EN, PBC_INTR_SD2_R_EN},
+ {PBC_BSTAT_SD3_DET, PBC_INTR_SD3_EN, PBC_INTR_SD3_R_EN},
+ {PBC_BSTAT_MS_DET, PBC_INTR_MS_EN, PBC_INTR_MS_R_EN},
+ {PBC_BSTAT_SD1_DET, PBC_INTR_SD1_EN, PBC_INTR_SD1_R_EN},
+};
+
+/*!
+ * Check if a SD card has been inserted or not.
+ *
+ * @param num a card number as defined in \b enum \b mxc_card_no
+ * @return 0 if a card is not present; non-zero otherwise.
+ */
+int mxc_card_detected(enum mxc_card_no num)
+{
+ u32 status;
+
+ status = __raw_readw(PBC_BSTAT1_REG);
+ return ((status & MXC_BSTAT_BIT(num)) == 0);
+}
+
+/*
+ * Check if there is any state change by reading the IMR register and the
+ * previous and current states of the board status register (offset 0x28).
+ * A state change is defined to be card insertion OR removal. So the driver
+ * may have to call the mxc_card_detected() function to see if it is card
+ * insertion or removal.
+ *
+ * @param mask current IMR value
+ * @param s0 previous status register value (offset 0x28)
+ * @param s1 current status register value (offset 0x28)
+ *
+ * @return 0 if no card status change OR the corresponding bits in the IMR
+ * (passed in as 'mask') is NOT set.
+ * A non-zero value indicates some card state changes. For example,
+ * 0b0001 means SD3 has a card state change (bit0 is set) AND its
+ * associated insertion or removal bits in IMR is SET.
+ * 0b0100 means SD1 has a card state change (bit2 is set) AND its
+ * associated insertion or removal bits in IMR is SET.
+ * 0b1001 means both MS and SD3 have state changes
+ */
+static u32 mxc_card_state_changed(u32 mask, u32 s0, u32 s1)
+{
+ u32 i, retval = 0;
+ u32 stat = (s0 ^ s1) & 0x7800;
+
+ if (stat == 0)
+ return 0;
+
+ for (i = MXC_CARD_MIN; i <= MXC_CARD_MAX; i++) {
+ if ((stat & pbc_card_bit[i][0]) != 0 &&
+ (mask & (pbc_card_bit[i][1] | pbc_card_bit[i][2])) != 0) {
+ retval |= 1 << i;
+ }
+ }
+#ifdef MXC_CARD_DEBUG
+ printk(KERN_INFO "\nmask=%x, s0=%x, s1=%x\n", mask, s0, s1);
+ printk(KERN_INFO "retval=%x, stat=%x\n", retval, stat);
+#endif
+ return retval;
+}
+
+/*!
+ * Interrupt handler for the expio (CPLD) to deal with interrupts from
+ * FEC, external UART, CS8900 Ethernet and SD cards, etc.
+ */
+static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 imr, card_int, i;
+ u32 int_valid;
+ u32 expio_irq;
+ u32 stat = __raw_readw(PBC_BSTAT1_REG);
+
+ desc->chip->mask(irq); /* irq = gpio irq number */
+
+ imr = __raw_readw(PBC_INTMASK_SET_REG);
+
+ card_int = mxc_card_state_changed(imr, mxc_card_status, stat);
+ mxc_card_status = stat;
+
+ if (card_int != 0) {
+ for (i = MXC_CARD_MIN; i <= MXC_CARD_MAX; i++) {
+ if ((card_int & (1 << i)) != 0) {
+ pr_debug("card no %d state changed\n", i);
+ }
+ }
+ }
+
+ /* Bits defined in PBC_INTSTATUS_REG at 0x2C */
+ int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr;
+ /* combined with the card interrupt valid information */
+ int_valid = (int_valid & 0x0F8E) | (card_int << PBC_INTR_SD2_EN_BIT);
+
+ if (unlikely(!int_valid)) {
+ pr_debug("\nEXPIO: Spurious interrupt:0x%0x\n\n", int_valid);
+ pr_debug("CPLD IMR(0x38)=0x%x, BSTAT1(0x28)=0x%x\n", imr, stat);
+ goto out;
+ }
+
+ expio_irq = MXC_EXP_IO_BASE;
+ for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
+ struct irq_desc *d;
+ if ((int_valid & 1) == 0)
+ continue;
+ d = irq_desc + expio_irq;
+ if (unlikely(!(d->handle_irq))) {
+ printk(KERN_ERR "\nEXPIO irq: %d unhandeled\n",
+ expio_irq);
+ BUG(); /* oops */
+ }
+ d->handle_irq(expio_irq, d);
+ }
+
+ out:
+ desc->chip->ack(irq);
+ desc->chip->unmask(irq);
+}
+
+#ifdef MXC_CARD_DEBUG
+
+static irqreturn_t mxc_sd_test_handler(int irq, void *desc)
+{
+ int s = -1;
+
+ printk(KERN_INFO "%s(irq=%d) for ", __FUNCTION__, irq);
+ if (irq == EXPIO_INT_SD1_EN) {
+ printk(KERN_INFO "SD1");
+ s = MXC_CARD_SD1;
+ } else if (irq == EXPIO_INT_SD2_EN) {
+ printk(KERN_INFO "SD2");
+ s = MXC_CARD_SD2;
+ } else if (irq == EXPIO_INT_SD3_EN) {
+ printk(KERN_INFO "SD3");
+ s = MXC_CARD_SD3;
+ } else if (irq == EXPIO_INT_MS_EN) {
+ printk(KERN_INFO "MS");
+ s = MXC_CARD_MS;
+ } else {
+ printk(KERN_INFO "None!!!!");
+ }
+ if (mxc_card_detected(s)) {
+ printk(KERN_INFO " inserted\n");
+ } else {
+ printk(KERN_INFO " removed\n");
+ }
+
+ return IRQ_HANDLED;
+}
+#endif /* MXC_CARD_DEBUG */
+
+/*
+ * Disable an expio pin's interrupt by setting the bit in the imr.
+ * @param irq an expio virtual irq number
+ */
+static void expio_mask_irq(u32 irq)
+{
+ u32 expio = MXC_IRQ_TO_EXPIO(irq);
+
+ /* mask the interrupt */
+ if (irq < EXPIO_INT_SD2_EN) {
+ __raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG);
+ } else {
+ irq -= EXPIO_INT_SD2_EN;
+ /* clear both SDx_EN and SDx_R_EN bits */
+ __raw_writew((pbc_card_bit[irq][1] | pbc_card_bit[irq][2]),
+ PBC_INTMASK_CLEAR_REG);
+ }
+}
+
+/*
+ * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
+ * @param irq an expanded io virtual irq number
+ */
+static void expio_ack_irq(u32 irq)
+{
+ u32 expio = MXC_IRQ_TO_EXPIO(irq);
+ /* clear the interrupt status */
+ __raw_writew(1 << expio, PBC_INTSTATUS_REG);
+ /* mask the interrupt */
+ expio_mask_irq(irq);
+}
+
+/*
+ * Enable a expio pin's interrupt by clearing the bit in the imr.
+ * @param irq an expio virtual irq number
+ */
+static void expio_unmask_irq(u32 irq)
+{
+ u32 expio = MXC_IRQ_TO_EXPIO(irq);
+
+ /* unmask the interrupt */
+ if (irq < EXPIO_INT_SD2_EN) {
+ if (irq == EXPIO_INT_XUART_INTA) {
+ /* Set 8250 MCR register bit 3 - Forces the INT (A-B
+ * outputs to the active mode and sets OP2 to logic 0.
+ * This is needed to avoid spurious int caused by the
+ * internal CPLD pull-up for the interrupt pin.
+ */
+ u16 val = __raw_readw(MXC_LL_EXTUART_VADDR + 8);
+ __raw_writew(val | 0x8, MXC_LL_EXTUART_VADDR + 8);
+ }
+ __raw_writew(1 << expio, PBC_INTMASK_SET_REG);
+ } else {
+ irq -= EXPIO_INT_SD2_EN;
+
+ if (mxc_card_detected(irq)) {
+ __raw_writew(pbc_card_bit[irq][2], PBC_INTMASK_SET_REG);
+ } else {
+ __raw_writew(pbc_card_bit[irq][1], PBC_INTMASK_SET_REG);
+ }
+ }
+}
+
+static struct irq_chip expio_irq_chip = {
+ .ack = expio_ack_irq,
+ .mask = expio_mask_irq,
+ .unmask = expio_unmask_irq,
+};
+
+static int __init mxc_expio_init(void)
+{
+ int i, ver;
+
+ ver = (__raw_readw(PBC_VERSION_REG) >> 8) & 0xFF;
+ if ((ver & 0x80) != 0) {
+ pr_info("MX27 ADS EXPIO(CPLD) hardware\n");
+ pr_info("CPLD version: 0x%x\n", ver);
+ } else {
+ mxc_board_is_ads = 0;
+ ver &= 0x0F;
+ pr_info("MX27 EVB EXPIO(CPLD) hardware\n");
+ if (ver == 0xF || ver <= MXC_CPLD_VER_1_50)
+ pr_info("Wrong CPLD version: %d\n", ver);
+ else {
+ pr_info("CPLD version: %d\n", ver);
+ }
+ }
+
+ mxc_card_status = __raw_readw(PBC_BSTAT1_REG);
+
+#ifdef MXC_CARD_DEBUG
+ for (i = MXC_CARD_MIN; i <= MXC_CARD_MAX; i++) {
+ if (mxc_card_detected(i)) {
+ pr_info("Card %d is detected\n", 3 - i);
+ }
+ }
+#endif
+ /*
+ * Configure INT line as GPIO input
+ */
+ gpio_config_mux(MX27_PIN_TIN, GPIO_MUX_GPIO);
+ mxc_set_gpio_direction(MX27_PIN_TIN, 1);
+
+ /* disable the interrupt and clear the status */
+ __raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG);
+ __raw_writew(0xFFFF, PBC_INTSTATUS_REG);
+
+ for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
+ i++) {
+ set_irq_chip(i, &expio_irq_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+ set_irq_type(EXPIO_PARENT_INT, IRQF_TRIGGER_HIGH);
+ set_irq_chained_handler(EXPIO_PARENT_INT, mxc_expio_irq_handler);
+
+ return 0;
+}
+
+#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
+
+/*!
+ * The serial port definition structure. The fields contain:
+ * {UART, CLK, PORT, IRQ, FLAGS}
+ */
+static struct plat_serial8250_port serial_platform_data[] = {
+ {
+ .membase = (void __iomem *)(CS4_BASE_ADDR_VIRT + 0x20000),
+ .mapbase = (unsigned long)(CS4_BASE_ADDR + 0x20000),
+ .irq = EXPIO_INT_XUART_INTA,
+ .uartclk = 3686400,
+ .regshift = 1,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
+ /*.pm = serial_platform_pm, */
+ },
+ {},
+};
+
+/*!
+ * REVISIT: document me
+ */
+static struct platform_device serial_device = {
+ .name = "serial8250",
+ .id = 0,
+ .dev = {
+ .platform_data = &serial_platform_data[0],
+ },
+};
+
+/*!
+ * REVISIT: document me
+ */
+static int __init mxc_init_extuart(void)
+{
+ int value;
+ /*reset ext uart in cpld */
+ __raw_writew(PBC_BCTRL1_URST, PBC_BCTRL1_SET_REG);
+ /*delay some time for reset finish */
+ for (value = 0; value < 1000; value++) ;
+ __raw_writew(PBC_BCTRL1_URST, PBC_BCTRL1_CLEAR_REG);
+ return platform_device_register(&serial_device);
+}
+#else
+static inline int mxc_init_extuart(void)
+{
+ return 0;
+}
+#endif
+
+#if (defined(CONFIG_MXC_PMIC_MC13783) || \
+ defined(CONFIG_MXC_PMIC_MC13783_MODULE)) \
+ && (defined(CONFIG_SND_MXC_PMIC) || defined(CONFIG_SND_MXC_PMIC_MODULE))
+extern void gpio_ssi_active(int ssi_num);
+
+static void __init mxc_init_pmic_audio(void)
+{
+ struct clk *ckih_clk;
+ struct clk *cko_clk;
+
+ /* Enable 26 mhz clock on CKO1 for PMIC audio */
+ ckih_clk = clk_get(NULL, "ckih");
+ cko_clk = clk_get(NULL, "clko_clk");
+ if (IS_ERR(ckih_clk) || IS_ERR(cko_clk)) {
+ printk(KERN_ERR "Unable to set CLKO output to CKIH\n");
+ } else {
+ clk_set_parent(cko_clk, ckih_clk);
+ clk_set_rate(cko_clk, clk_get_rate(ckih_clk));
+ clk_enable(cko_clk);
+ }
+ clk_put(ckih_clk);
+ clk_put(cko_clk);
+
+ gpio_ssi_active(0);
+ gpio_ssi_active(1);
+}
+#else
+static void __inline mxc_init_pmic_audio(void)
+{
+}
+#endif
+
+/* IDE device data */
+#if defined(CONFIG_BLK_DEV_IDE_MXC) || defined(CONFIG_BLK_DEV_IDE_MXC_MODULE)
+
+/*! Platform Data for MXC IDE */
+static struct mxc_ide_platform_data mxc_ide_data = {
+ .power_drive = NULL,
+ .power_io = NULL,
+};
+
+static struct platform_device mxc_ide_device = {
+ .name = "mxc_ide",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_ide_data,
+ },
+};
+
+static inline void mxc_init_ide(void)
+{
+ if (platform_device_register(&mxc_ide_device) < 0)
+ printk(KERN_ERR "Error: Registering the ide.\n");
+}
+#else
+static inline void mxc_init_ide(void)
+{
+}
+#endif
+
+static __init void mxc_board_init(void)
+{
+ pr_info("AIPI VA base: 0x%x\n", IO_ADDRESS(AIPI_BASE_ADDR));
+ mxc_cpu_common_init();
+ early_console_setup(saved_command_line);
+ mxc_gpio_init();
+ mxc_expio_init();
+ mxc_init_keypad();
+ mxc_init_nor_mtd();
+ mxc_init_nand_mtd();
+ mxc_init_extuart();
+ mxc_init_pmic_audio();
+#ifdef MXC_CARD_DEBUG
+ request_irq(EXPIO_INT_SD1_EN, mxc_sd_test_handler, 0, "SD_card1", NULL);
+ request_irq(EXPIO_INT_SD2_EN, mxc_sd_test_handler, 0, "SD_card2", NULL);
+ request_irq(EXPIO_INT_SD3_EN, mxc_sd_test_handler, 0, "SD_card3", NULL);
+ request_irq(EXPIO_INT_MS_EN, mxc_sd_test_handler, 0, "MS_card", NULL);
+#endif
+
+ spi_register_board_info(mxc_spi_board_info,
+ ARRAY_SIZE(mxc_spi_board_info));
+
+ mxc_init_fb();
+ mxc_init_bl();
+ mxc_init_ide();
+}
+
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+#ifdef CONFIG_KGDB_8250
+ int i;
+ for (i = 0;
+ i <
+ (sizeof(serial_platform_data) / sizeof(serial_platform_data[0]));
+ i += 1)
+ kgdb8250_add_platform_port(i, &serial_platform_data[i]);
+#endif
+
+ mxc_cpu_init();
+ /* Store command line for use on mxc_board_init */
+ strcpy(command_line, *cmdline);
+
+#ifdef CONFIG_DISCONTIGMEM
+ do {
+ int nid;
+ mi->nr_banks = MXC_NUMNODES;
+ for (nid = 0; nid < mi->nr_banks; nid++) {
+ SET_NODE(mi, nid);
+ }
+ } while (0);
+#endif
+}
+
+EXPORT_SYMBOL(mxc_card_detected);
+EXPORT_SYMBOL(mxc_board_is_ads);
+
+/*
+ * The following uses standard kernel macros define in arch.h in order to
+ * initialize __mach_desc_MX27ADS data structure.
+ */
+/* *INDENT-OFF* */
+MACHINE_START(MX27ADS, "Freescale i.MX27ADS")
+ /* maintainer: Freescale Semiconductor, Inc. */
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ .phys_io = CS4_BASE_ADDR,
+ .io_pg_offst = ((CS4_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+#else
+ .phys_io = AIPI_BASE_ADDR,
+ .io_pg_offst = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+#endif
+ .boot_params = PHYS_OFFSET + 0x100,
+ .fixup = fixup_mxc_board,
+ .map_io = mxc_map_io,
+ .init_irq = mxc_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &mxc_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx27/mx27ads_gpio.c b/arch/arm/mach-mx27/mx27ads_gpio.c
new file mode 100644
index 000000000000..8eb5eb790757
--- /dev/null
+++ b/arch/arm/mach-mx27/mx27ads_gpio.c
@@ -0,0 +1,1226 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+
+#include "board-mx27ads.h"
+#include "gpio_mux.h"
+#include "crm_regs.h"
+
+static int g_uart_activated[MXC_UART_NR] = { 0, 0, 0, 0, 0, 0 };
+
+/*!
+ * @file mach-mx27/mx27ads_gpio.c
+ *
+ * @brief This file contains all the GPIO setup functions for the board.
+ *
+ * @ingroup GPIO_MX27
+ */
+
+/*!
+ * Setup GPIO for a UART port to be active
+ *
+ * @param port a UART port
+ * @param no_irda indicates if the port is used for SIR
+ */
+void gpio_uart_active(int port, int no_irda)
+{
+ if (port < 0 || port >= MXC_UART_NR) {
+ pr_info("Wrong port number: %d\n", port);
+ BUG();
+ }
+
+ if (g_uart_activated[port]) {
+ pr_info("UART %d has been activated multi-times\n", port + 1);
+ return;
+ }
+ g_uart_activated[port] = 1;
+
+ switch (port) {
+ case 0:
+ gpio_request_mux(MX27_PIN_UART1_TXD, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_UART1_RXD, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_UART1_CTS, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_UART1_RTS, GPIO_MUX_PRIMARY);
+ break;
+ case 1:
+ gpio_request_mux(MX27_PIN_UART2_TXD, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_UART2_RXD, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_UART2_CTS, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_UART2_RTS, GPIO_MUX_PRIMARY);
+ break;
+ case 2:
+ gpio_request_mux(MX27_PIN_UART3_TXD, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_UART3_RXD, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_UART3_CTS, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_UART3_RTS, GPIO_MUX_PRIMARY);
+
+ /* Enable IRDA in CPLD */
+ __raw_writew(PBC_BCTRL2_IRDA_EN, PBC_BCTRL2_CLEAR_REG);
+ break;
+ case 3:
+ gpio_request_mux(MX27_PIN_USBH1_TXDM, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_USBH1_RXDP, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_USBH1_TXDP, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_USBH1_FS, GPIO_MUX_ALT);
+ break;
+ case 4:
+ gpio_request_mux(MX27_PIN_CSI_D6, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_CSI_D7, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_CSI_VSYNC, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_CSI_HSYNC, GPIO_MUX_ALT);
+ break;
+ case 5:
+ gpio_request_mux(MX27_PIN_CSI_D0, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_CSI_D1, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_CSI_D2, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_CSI_D3, GPIO_MUX_ALT);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * Setup GPIO for a UART port to be inactive
+ *
+ * @param port a UART port
+ * @param no_irda indicates if the port is used for SIR
+ */
+void gpio_uart_inactive(int port, int no_irda)
+{
+ if (port < 0 || port >= MXC_UART_NR) {
+ pr_info("Wrong port number: %d\n", port);
+ BUG();
+ }
+
+ if (g_uart_activated[port] == 0) {
+ pr_info("UART %d has not been activated \n", port + 1);
+ return;
+ }
+ g_uart_activated[port] = 0;
+
+ switch (port) {
+ case 0:
+ gpio_free_mux(MX27_PIN_UART1_TXD);
+ gpio_free_mux(MX27_PIN_UART1_RXD);
+ gpio_free_mux(MX27_PIN_UART1_CTS);
+ gpio_free_mux(MX27_PIN_UART1_RTS);
+ break;
+ case 1:
+ gpio_free_mux(MX27_PIN_UART2_TXD);
+ gpio_free_mux(MX27_PIN_UART2_RXD);
+ gpio_free_mux(MX27_PIN_UART2_CTS);
+ gpio_free_mux(MX27_PIN_UART2_RTS);
+ break;
+ case 2:
+ gpio_free_mux(MX27_PIN_UART3_TXD);
+ gpio_free_mux(MX27_PIN_UART3_RXD);
+ gpio_free_mux(MX27_PIN_UART3_CTS);
+ gpio_free_mux(MX27_PIN_UART3_RTS);
+
+ /* Disable IRDA in CPLD */
+ __raw_writew(PBC_BCTRL2_IRDA_EN, PBC_BCTRL2_SET_REG);
+ break;
+ case 3:
+ gpio_free_mux(MX27_PIN_USBH1_TXDM);
+ gpio_free_mux(MX27_PIN_USBH1_RXDP);
+ gpio_free_mux(MX27_PIN_USBH1_TXDP);
+ gpio_free_mux(MX27_PIN_USBH1_FS);
+ break;
+ case 4:
+ gpio_free_mux(MX27_PIN_CSI_D6);
+ gpio_free_mux(MX27_PIN_CSI_D7);
+ gpio_free_mux(MX27_PIN_CSI_VSYNC);
+ gpio_free_mux(MX27_PIN_CSI_HSYNC);
+ break;
+ case 5:
+ gpio_free_mux(MX27_PIN_CSI_D0);
+ gpio_free_mux(MX27_PIN_CSI_D1);
+ gpio_free_mux(MX27_PIN_CSI_D2);
+ gpio_free_mux(MX27_PIN_CSI_D3);
+ break;
+ default:
+ break;
+ }
+}
+
+void gpio_power_key_active(void)
+{
+}
+EXPORT_SYMBOL(gpio_power_key_active);
+
+/*!
+ * Configure the IOMUX GPR register to receive shared SDMA UART events
+ *
+ * @param port a UART port
+ */
+void config_uartdma_event(int port)
+{
+ return;
+}
+
+static int usbh1_hs_active;
+/*!
+ * Setup GPIO for USB, Total 34 signals
+ * PIN Configuration for USBOTG: High/Full speed OTG
+ * PE2,PE1,PE0,PE24,PE25 -- PRIMARY
+ PC7 - PC13 -- PRIMARY
+ PB23,PB24 -- PRIMARY
+
+ * PIN Configuration for USBH2: : High/Full/Low speed host
+ * PA0 - PA4 -- PRIMARY
+ PD19, PD20,PD21,PD22,PD23,PD24,PD26 --Alternate (SECONDARY)
+
+ * PIN Configuration for USBH1: Full/low speed host
+ * PB25 - PB31 -- PRIMARY
+ PB22 -- PRIMARY
+ */
+int gpio_usbh1_active(void)
+{
+ if (usbh1_hs_active)
+ return 0;
+
+ if (gpio_request_mux(MX27_PIN_USBH1_SUSP, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBH1_RCV, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBH1_FS, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBH1_OE_B, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBH1_TXDM, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBH1_TXDP, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBH1_RXDM, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBH1_RXDP, GPIO_MUX_PRIMARY))
+ return -EINVAL;
+
+ __raw_writew(PBC_BCTRL3_FSH_MOD, PBC_BCTRL3_CLEAR_REG);
+ __raw_writew(PBC_BCTRL3_FSH_VBUS_EN, PBC_BCTRL3_CLEAR_REG);
+ usbh1_hs_active = 1;
+ return 0;
+}
+void gpio_usbh1_inactive(void)
+{
+ if (usbh1_hs_active == 0)
+ return;
+
+ gpio_free_mux(MX27_PIN_USBH1_SUSP);
+ gpio_free_mux(MX27_PIN_USBH1_RCV);
+ gpio_free_mux(MX27_PIN_USBH1_FS);
+ gpio_free_mux(MX27_PIN_USBH1_OE_B);
+ gpio_free_mux(MX27_PIN_USBH1_TXDM);
+ gpio_free_mux(MX27_PIN_USBH1_TXDP);
+ gpio_free_mux(MX27_PIN_USBH1_RXDM);
+ gpio_free_mux(MX27_PIN_USBH1_RXDP);
+ __raw_writew(PBC_BCTRL3_FSH_VBUS_EN, PBC_BCTRL3_SET_REG);
+
+ usbh1_hs_active = 0;
+}
+
+static int usbh2_hs_active;
+/*
+ * conflicts with CSPI1 (MC13783) and CSPI2 (Connector)
+ */
+int gpio_usbh2_active(void)
+{
+ if (usbh2_hs_active)
+ return 0;
+
+ if (gpio_set_puen(MX27_PIN_USBH2_CLK, 0) ||
+ gpio_set_puen(MX27_PIN_USBH2_DIR, 0) ||
+ gpio_set_puen(MX27_PIN_USBH2_DATA7, 0) ||
+ gpio_set_puen(MX27_PIN_USBH2_NXT, 0) ||
+ gpio_set_puen(MX27_PIN_USBH2_STP, 0) ||
+ gpio_set_puen(MX27_PIN_CSPI2_SS2, 0) ||
+ gpio_set_puen(MX27_PIN_CSPI2_SS1, 0) ||
+ gpio_set_puen(MX27_PIN_CSPI2_SS0, 0) ||
+ gpio_set_puen(MX27_PIN_CSPI2_SCLK, 0) ||
+ gpio_set_puen(MX27_PIN_CSPI2_MISO, 0) ||
+ gpio_set_puen(MX27_PIN_CSPI2_MOSI, 0) ||
+ gpio_set_puen(MX27_PIN_CSPI1_SS2, 0))
+ return -EINVAL;
+
+ if (gpio_request_mux(MX27_PIN_USBH2_CLK, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBH2_DIR, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBH2_DATA7, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBH2_NXT, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBH2_STP, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_CSPI2_SS2, GPIO_MUX_ALT) ||
+ gpio_request_mux(MX27_PIN_CSPI2_SS1, GPIO_MUX_ALT) ||
+ gpio_request_mux(MX27_PIN_CSPI2_SS0, GPIO_MUX_ALT) ||
+ gpio_request_mux(MX27_PIN_CSPI2_SCLK, GPIO_MUX_ALT) ||
+ gpio_request_mux(MX27_PIN_CSPI2_MISO, GPIO_MUX_ALT) ||
+ gpio_request_mux(MX27_PIN_CSPI2_MOSI, GPIO_MUX_ALT) ||
+ gpio_request_mux(MX27_PIN_CSPI1_SS2, GPIO_MUX_ALT))
+ return -EINVAL;
+
+ __raw_writew(PBC_BCTRL3_HSH_EN, PBC_BCTRL3_CLEAR_REG);
+ usbh2_hs_active = 1;
+ return 0;
+}
+void gpio_usbh2_inactive(void)
+{
+ if (usbh2_hs_active == 0)
+ return;
+
+ gpio_free_mux(MX27_PIN_USBH2_CLK);
+ gpio_free_mux(MX27_PIN_USBH2_DIR);
+ gpio_free_mux(MX27_PIN_USBH2_DATA7);
+ gpio_free_mux(MX27_PIN_USBH2_NXT);
+ gpio_free_mux(MX27_PIN_USBH2_STP);
+
+ gpio_free_mux(MX27_PIN_CSPI2_SS2);
+ gpio_free_mux(MX27_PIN_CSPI2_SS1);
+ gpio_free_mux(MX27_PIN_CSPI2_SS0);
+ gpio_free_mux(MX27_PIN_CSPI2_SCLK);
+ gpio_free_mux(MX27_PIN_CSPI2_MISO);
+ gpio_free_mux(MX27_PIN_CSPI2_MOSI);
+ gpio_free_mux(MX27_PIN_CSPI1_SS2);
+
+ gpio_set_puen(MX27_PIN_USBH2_CLK, 1);
+ gpio_set_puen(MX27_PIN_USBH2_DIR, 1);
+ gpio_set_puen(MX27_PIN_USBH2_DATA7, 1);
+ gpio_set_puen(MX27_PIN_USBH2_NXT, 1);
+ gpio_set_puen(MX27_PIN_USBH2_STP, 1);
+ gpio_set_puen(MX27_PIN_CSPI2_SS2, 1);
+ gpio_set_puen(MX27_PIN_CSPI2_SS1, 1);
+ gpio_set_puen(MX27_PIN_CSPI2_SS0, 1);
+ gpio_set_puen(MX27_PIN_CSPI2_SCLK, 1);
+ gpio_set_puen(MX27_PIN_CSPI2_MISO, 1);
+ gpio_set_puen(MX27_PIN_CSPI2_MOSI, 1);
+ gpio_set_puen(MX27_PIN_CSPI1_SS2, 1);
+ __raw_writew(PBC_BCTRL3_HSH_EN, PBC_BCTRL3_SET_REG);
+
+ usbh2_hs_active = 0;
+}
+
+static int usbotg_hs_active;
+int gpio_usbotg_hs_active(void)
+{
+ if (usbotg_hs_active)
+ return 0;
+
+ if (gpio_request_mux(MX27_PIN_USBOTG_DATA5, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBOTG_DATA6, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBOTG_DATA0, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBOTG_DATA2, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBOTG_DATA1, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBOTG_DATA3, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBOTG_DATA4, GPIO_MUX_PRIMARY) ||
+
+ gpio_request_mux(MX27_PIN_USBOTG_DIR, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBOTG_STP, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBOTG_NXT, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBOTG_CLK, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USBOTG_DATA7, GPIO_MUX_PRIMARY) ||
+
+ gpio_request_mux(MX27_PIN_USB_OC_B, GPIO_MUX_PRIMARY) ||
+ gpio_request_mux(MX27_PIN_USB_PWR, GPIO_MUX_PRIMARY))
+ return -EINVAL;
+
+ __raw_writew(PBC_BCTRL3_OTG_HS_EN, PBC_BCTRL3_CLEAR_REG);
+ __raw_writew(PBC_BCTRL3_OTG_VBUS_EN, PBC_BCTRL3_CLEAR_REG);
+
+ usbotg_hs_active = 1;
+ return 0;
+}
+
+void gpio_usbotg_hs_inactive(void)
+{
+ if (usbotg_hs_active == 0)
+ return;
+
+ gpio_free_mux(MX27_PIN_USBOTG_DATA5);
+ gpio_free_mux(MX27_PIN_USBOTG_DATA6);
+ gpio_free_mux(MX27_PIN_USBOTG_DATA0);
+ gpio_free_mux(MX27_PIN_USBOTG_DATA2);
+ gpio_free_mux(MX27_PIN_USBOTG_DATA1);
+ gpio_free_mux(MX27_PIN_USBOTG_DATA3);
+ gpio_free_mux(MX27_PIN_USBOTG_DATA4);
+
+ gpio_free_mux(MX27_PIN_USBOTG_DIR);
+ gpio_free_mux(MX27_PIN_USBOTG_STP);
+ gpio_free_mux(MX27_PIN_USBOTG_NXT);
+ gpio_free_mux(MX27_PIN_USBOTG_CLK);
+ gpio_free_mux(MX27_PIN_USBOTG_DATA7);
+
+ gpio_free_mux(MX27_PIN_USB_OC_B);
+ gpio_free_mux(MX27_PIN_USB_PWR);
+ __raw_writew(PBC_BCTRL3_OTG_HS_EN, PBC_BCTRL3_SET_REG);
+
+ usbotg_hs_active = 0;
+}
+
+int gpio_usbotg_fs_active(void)
+{
+ return gpio_usbotg_hs_active();
+}
+
+void gpio_usbotg_fs_inactive(void)
+{
+ gpio_usbotg_hs_inactive();
+}
+
+/*!
+ * end Setup GPIO for USB
+ *
+ */
+
+/************************************************************************/
+/* for i2c gpio */
+/* I2C1: PD17,PD18 -- Primary */
+/* I2C2: PC5,PC6 -- Primary */
+/************************************************************************/
+/*!
+* Setup GPIO for an I2C device to be active
+*
+* @param i2c_num an I2C device
+*/
+void gpio_i2c_active(int i2c_num)
+{
+ switch (i2c_num) {
+ case 0:
+ gpio_request_mux(MX27_PIN_I2C_CLK, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_I2C_DATA, GPIO_MUX_PRIMARY);
+ break;
+ case 1:
+ gpio_request_mux(MX27_PIN_I2C2_SCL, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_I2C2_SDA, GPIO_MUX_PRIMARY);
+ break;
+ default:
+ printk(KERN_ERR "gpio_i2c_active no compatible I2C adapter\n");
+ break;
+ }
+}
+
+/*!
+ * * Setup GPIO for an I2C device to be inactive
+ * *
+ * * @param i2c_num an I2C device
+ */
+void gpio_i2c_inactive(int i2c_num)
+{
+ switch (i2c_num) {
+ case 0:
+ gpio_free_mux(MX27_PIN_I2C_CLK);
+ gpio_free_mux(MX27_PIN_I2C_DATA);
+ break;
+ case 1:
+ gpio_free_mux(MX27_PIN_I2C2_SCL);
+ gpio_free_mux(MX27_PIN_I2C2_SDA);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * Setup GPIO for a CSPI device to be active
+ *
+ * @param cspi_mod an CSPI device
+ */
+void gpio_spi_active(int cspi_mod)
+{
+ switch (cspi_mod) {
+ case 0:
+ /* SPI1 */
+ gpio_request_mux(MX27_PIN_CSPI1_MOSI, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSPI1_MISO, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSPI1_SCLK, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSPI1_RDY, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSPI1_SS0, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSPI1_SS1, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSPI1_SS2, GPIO_MUX_PRIMARY);
+ break;
+ case 1:
+ /*SPI2 */
+ gpio_request_mux(MX27_PIN_CSPI2_MOSI, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSPI2_MISO, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSPI2_SCLK, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSPI2_SS0, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSPI2_SS1, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSPI2_SS2, GPIO_MUX_PRIMARY);
+ break;
+ case 2:
+ /*SPI3 */
+ gpio_request_mux(MX27_PIN_SD1_D0, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_SD1_CMD, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_SD1_CLK, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_SD1_D3, GPIO_MUX_ALT);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*!
+ * Setup GPIO for a CSPI device to be inactive
+ *
+ * @param cspi_mod a CSPI device
+ */
+void gpio_spi_inactive(int cspi_mod)
+{
+ switch (cspi_mod) {
+ case 0:
+ /* SPI1 */
+ gpio_free_mux(MX27_PIN_CSPI1_MOSI);
+ gpio_free_mux(MX27_PIN_CSPI1_MISO);
+ gpio_free_mux(MX27_PIN_CSPI1_SCLK);
+ gpio_free_mux(MX27_PIN_CSPI1_RDY);
+ gpio_free_mux(MX27_PIN_CSPI1_SS0);
+ gpio_free_mux(MX27_PIN_CSPI1_SS1);
+ gpio_free_mux(MX27_PIN_CSPI1_SS2);
+ break;
+ case 1:
+ /*SPI2 */
+ gpio_free_mux(MX27_PIN_CSPI2_MOSI);
+ gpio_free_mux(MX27_PIN_CSPI2_MISO);
+ gpio_free_mux(MX27_PIN_CSPI2_SCLK);
+ gpio_free_mux(MX27_PIN_CSPI2_SS0);
+ gpio_free_mux(MX27_PIN_CSPI2_SS1);
+ gpio_free_mux(MX27_PIN_CSPI2_SS2);
+ break;
+ case 2:
+ /*SPI3 */
+ gpio_free_mux(MX27_PIN_SD1_D0);
+ gpio_free_mux(MX27_PIN_SD1_CMD);
+ gpio_free_mux(MX27_PIN_SD1_CLK);
+ gpio_free_mux(MX27_PIN_SD1_D3);
+ break;
+
+ default:
+ break;
+ }
+}
+
+/*!
+ * Setup GPIO for a nand flash device to be active
+ *
+ */
+void gpio_nand_active(void)
+{
+ unsigned long reg;
+ reg = __raw_readl(IO_ADDRESS(SYSCTRL_BASE_ADDR) + SYS_FMCR);
+ reg &= ~(1 << 4);
+ __raw_writel(reg, IO_ADDRESS(SYSCTRL_BASE_ADDR) + SYS_FMCR);
+
+ gpio_request_mux(MX27_PIN_NFRB, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_NFCE_B, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_NFWP_B, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_NFCLE, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_NFALE, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_NFRE_B, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_NFWE_B, GPIO_MUX_PRIMARY);
+}
+
+/*!
+ * Setup GPIO for a nand flash device to be inactive
+ *
+ */
+void gpio_nand_inactive(void)
+{
+ gpio_free_mux(MX27_PIN_NFRB);
+ gpio_free_mux(MX27_PIN_NFCE_B);
+ gpio_free_mux(MX27_PIN_NFWP_B);
+ gpio_free_mux(MX27_PIN_NFCLE);
+ gpio_free_mux(MX27_PIN_NFALE);
+ gpio_free_mux(MX27_PIN_NFRE_B);
+ gpio_free_mux(MX27_PIN_NFWE_B);
+}
+
+/*!
+ * Setup GPIO for CSI device to be active
+ *
+ */
+void gpio_sensor_active(void)
+{
+ gpio_request_mux(MX27_PIN_CSI_D0, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSI_D1, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSI_D2, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSI_D3, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSI_D4, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSI_MCLK, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSI_PIXCLK, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSI_D5, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSI_D6, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSI_D7, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSI_VSYNC, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CSI_HSYNC, GPIO_MUX_PRIMARY);
+
+#ifdef CONFIG_MXC_CAMERA_MC521DA
+ __raw_writew(0x100, PBC_BCTRL2_SET_REG);
+#else
+ __raw_writew(0x400, PBC_BCTRL2_SET_REG);
+#endif
+}
+
+void gpio_sensor_inactive(void)
+{
+ gpio_free_mux(MX27_PIN_CSI_D0);
+ gpio_free_mux(MX27_PIN_CSI_D1);
+ gpio_free_mux(MX27_PIN_CSI_D2);
+ gpio_free_mux(MX27_PIN_CSI_D3);
+ gpio_free_mux(MX27_PIN_CSI_D4);
+ gpio_free_mux(MX27_PIN_CSI_MCLK);
+ gpio_free_mux(MX27_PIN_CSI_PIXCLK);
+ gpio_free_mux(MX27_PIN_CSI_D5);
+ gpio_free_mux(MX27_PIN_CSI_D6);
+ gpio_free_mux(MX27_PIN_CSI_D7);
+ gpio_free_mux(MX27_PIN_CSI_VSYNC);
+ gpio_free_mux(MX27_PIN_CSI_HSYNC);
+
+#ifdef CONFIG_MXC_CAMERA_MC521DA
+ __raw_writew(0x100, PBC_BCTRL2_CLEAR_REG);
+#else
+ __raw_writew(0x400, PBC_BCTRL2_CLEAR_REG);
+#endif
+}
+
+void gpio_sensor_reset(bool flag)
+{
+ u16 temp;
+
+ if (flag) {
+ temp = 0x200;
+ __raw_writew(temp, PBC_BCTRL2_CLEAR_REG);
+ } else {
+ temp = 0x200;
+ __raw_writew(temp, PBC_BCTRL2_SET_REG);
+ }
+}
+
+/*!
+ * Setup GPIO for LCDC device to be active
+ *
+ */
+void gpio_lcdc_active(void)
+{
+ gpio_request_mux(MX27_PIN_LSCLK, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD0, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD1, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD2, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD3, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD4, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD5, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD6, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD7, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD8, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD9, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD10, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD11, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD12, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD13, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD14, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD15, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD16, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_LD17, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_REV, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CLS, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_PS, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SPL_SPR, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_HSYNC, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_VSYNC, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_CONTRAST, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_OE_ACD, GPIO_MUX_PRIMARY);
+}
+
+/*!
+ * Setup GPIO for LCDC device to be inactive
+ *
+ */
+void gpio_lcdc_inactive(void)
+{
+ gpio_free_mux(MX27_PIN_LSCLK);
+ gpio_free_mux(MX27_PIN_LD0);
+ gpio_free_mux(MX27_PIN_LD1);
+ gpio_free_mux(MX27_PIN_LD2);
+ gpio_free_mux(MX27_PIN_LD3);
+ gpio_free_mux(MX27_PIN_LD4);
+ gpio_free_mux(MX27_PIN_LD5);
+ gpio_free_mux(MX27_PIN_LD6);
+ gpio_free_mux(MX27_PIN_LD7);
+ gpio_free_mux(MX27_PIN_LD8);
+ gpio_free_mux(MX27_PIN_LD9);
+ gpio_free_mux(MX27_PIN_LD10);
+ gpio_free_mux(MX27_PIN_LD11);
+ gpio_free_mux(MX27_PIN_LD12);
+ gpio_free_mux(MX27_PIN_LD13);
+ gpio_free_mux(MX27_PIN_LD14);
+ gpio_free_mux(MX27_PIN_LD15);
+ gpio_free_mux(MX27_PIN_LD16);
+ gpio_free_mux(MX27_PIN_LD17);
+ gpio_free_mux(MX27_PIN_REV);
+ gpio_free_mux(MX27_PIN_CLS);
+ gpio_free_mux(MX27_PIN_PS);
+ gpio_free_mux(MX27_PIN_SPL_SPR);
+ gpio_free_mux(MX27_PIN_HSYNC);
+ gpio_free_mux(MX27_PIN_VSYNC);
+ gpio_free_mux(MX27_PIN_CONTRAST);
+ gpio_free_mux(MX27_PIN_OE_ACD);
+}
+
+/*!
+ * Setup GPIO PA25 low to start hard reset FS453 TV encoder
+ *
+ */
+void gpio_fs453_reset_low(void)
+{
+ gpio_free_mux(MX27_PIN_CLS);
+ if (gpio_request_mux(MX27_PIN_CLS, GPIO_MUX_GPIO)) {
+ printk(KERN_ERR "bug: request GPIO PA25 failed.\n");
+ return;
+ }
+
+ /* PA25 (CLS) as output */
+ mxc_set_gpio_direction(MX27_PIN_CLS, 0);
+ gpio_config_mux(MX27_PIN_CLS, GPIO_MUX_GPIO);
+ mxc_set_gpio_dataout(MX27_PIN_CLS, 0);
+}
+
+/*!
+ * Setup GPIO PA25 high to end hard reset FS453 TV encoder
+ *
+ */
+void gpio_fs453_reset_high(void)
+{
+ gpio_free_mux(MX27_PIN_CLS);
+ if (gpio_request_mux(MX27_PIN_CLS, GPIO_MUX_GPIO)) {
+ printk(KERN_ERR "bug: request GPIO PA25 failed.\n");
+ return;
+ }
+
+ /* PA25 (CLS) as output */
+ mxc_set_gpio_direction(MX27_PIN_CLS, 0);
+ gpio_config_mux(MX27_PIN_CLS, GPIO_MUX_GPIO);
+ mxc_set_gpio_dataout(MX27_PIN_CLS, 1);
+}
+
+/*!
+ * This function configures the IOMux block for PMIC standard operations.
+ *
+ */
+void gpio_pmic_active(void)
+{
+ gpio_config_mux(MX27_PIN_TOUT, GPIO_MUX_GPIO);
+ mxc_set_gpio_direction(MX27_PIN_TOUT, 1);
+}
+
+/*!
+ * GPIO settings not required for keypad
+ *
+ */
+void gpio_keypad_active(void)
+{
+}
+
+/*!
+ * GPIO settings not required for keypad
+ *
+ */
+void gpio_keypad_inactive(void)
+{
+}
+
+/*!
+ * Setup GPIO for ATA device to be active
+ *
+ */
+void gpio_ata_active(void)
+{
+ gpio_request_mux(MX27_PIN_ATA_DATA0, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_ATA_DATA1, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_ATA_DATA2, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_ATA_DATA3, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_ATA_DATA4, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_ATA_DATA5, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_ATA_DATA6, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_ATA_DATA7, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_ATA_DATA8, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_ATA_DATA9, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_ATA_DATA10, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_ATA_DATA11, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_ATA_DATA12, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_ATA_DATA13, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_ATA_DATA14, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_ATA_DATA15, GPIO_MUX_PRIMARY);
+
+ gpio_request_mux(MX27_PIN_PC_CD1_B, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_PC_CD2_B, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_PC_WAIT_B, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_PC_READY, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_PC_PWRON, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_PC_VS1, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_PC_VS2, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_PC_BVD1, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_PC_BVD2, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_PC_RST, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_IOIS16, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_PC_RW_B, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_PC_POE, GPIO_MUX_ALT);
+
+ __raw_writew(PBC_BCTRL2_ATAFEC_EN | PBC_BCTRL2_ATAFEC_SEL |
+ PBC_BCTRL2_ATA_EN, PBC_BCTRL2_CLEAR_REG);
+}
+
+/*!
+ * Setup GPIO for ATA device to be inactive
+ *
+ */
+void gpio_ata_inactive(void)
+{
+ __raw_writew(PBC_BCTRL2_ATAFEC_EN | PBC_BCTRL2_ATAFEC_SEL |
+ PBC_BCTRL2_ATA_EN, PBC_BCTRL2_SET_REG);
+
+ gpio_free_mux(MX27_PIN_ATA_DATA0);
+ gpio_free_mux(MX27_PIN_ATA_DATA1);
+ gpio_free_mux(MX27_PIN_ATA_DATA2);
+ gpio_free_mux(MX27_PIN_ATA_DATA3);
+ gpio_free_mux(MX27_PIN_ATA_DATA4);
+ gpio_free_mux(MX27_PIN_ATA_DATA5);
+ gpio_free_mux(MX27_PIN_ATA_DATA6);
+ gpio_free_mux(MX27_PIN_ATA_DATA7);
+ gpio_free_mux(MX27_PIN_ATA_DATA8);
+ gpio_free_mux(MX27_PIN_ATA_DATA9);
+ gpio_free_mux(MX27_PIN_ATA_DATA10);
+ gpio_free_mux(MX27_PIN_ATA_DATA11);
+ gpio_free_mux(MX27_PIN_ATA_DATA12);
+ gpio_free_mux(MX27_PIN_ATA_DATA13);
+ gpio_free_mux(MX27_PIN_ATA_DATA14);
+ gpio_free_mux(MX27_PIN_ATA_DATA15);
+
+ gpio_free_mux(MX27_PIN_PC_CD1_B);
+ gpio_free_mux(MX27_PIN_PC_CD2_B);
+ gpio_free_mux(MX27_PIN_PC_WAIT_B);
+ gpio_free_mux(MX27_PIN_PC_READY);
+ gpio_free_mux(MX27_PIN_PC_PWRON);
+ gpio_free_mux(MX27_PIN_PC_VS1);
+ gpio_free_mux(MX27_PIN_PC_VS2);
+ gpio_free_mux(MX27_PIN_PC_BVD1);
+ gpio_free_mux(MX27_PIN_PC_BVD2);
+ gpio_free_mux(MX27_PIN_PC_RST);
+ gpio_free_mux(MX27_PIN_IOIS16);
+ gpio_free_mux(MX27_PIN_PC_RW_B);
+ gpio_free_mux(MX27_PIN_PC_POE);
+}
+
+/*!
+ * Setup GPIO for FEC device to be active
+ *
+ */
+void gpio_fec_active(void)
+{
+ gpio_request_mux(MX27_PIN_ATA_DATA15, GPIO_MUX_OUTPUT1);
+ mxc_set_gpio_direction(MX27_PIN_ATA_DATA15, 0);
+ gpio_request_mux(MX27_PIN_ATA_DATA14, GPIO_MUX_OUTPUT1);
+ mxc_set_gpio_direction(MX27_PIN_ATA_DATA14, 0);
+ gpio_request_mux(MX27_PIN_ATA_DATA13, GPIO_MUX_INPUT1);
+ mxc_set_gpio_direction(MX27_PIN_ATA_DATA13, 1);
+ gpio_request_mux(MX27_PIN_ATA_DATA12, GPIO_MUX_INPUT1);
+ mxc_set_gpio_direction(MX27_PIN_ATA_DATA12, 1);
+ gpio_request_mux(MX27_PIN_ATA_DATA11, GPIO_MUX_INPUT1);
+ mxc_set_gpio_direction(MX27_PIN_ATA_DATA11, 1);
+ gpio_request_mux(MX27_PIN_ATA_DATA10, GPIO_MUX_INPUT1);
+ mxc_set_gpio_direction(MX27_PIN_ATA_DATA10, 1);
+ gpio_request_mux(MX27_PIN_ATA_DATA9, GPIO_MUX_INPUT1);
+ mxc_set_gpio_direction(MX27_PIN_ATA_DATA9, 1);
+ gpio_request_mux(MX27_PIN_ATA_DATA8, GPIO_MUX_INPUT1);
+ mxc_set_gpio_direction(MX27_PIN_ATA_DATA8, 1);
+ gpio_request_mux(MX27_PIN_ATA_DATA7, GPIO_MUX_OUTPUT1);
+ mxc_set_gpio_direction(MX27_PIN_ATA_DATA7, 0);
+
+ gpio_request_mux(MX27_PIN_ATA_DATA6, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_ATA_DATA5, GPIO_MUX_INPUT1);
+ mxc_set_gpio_direction(MX27_PIN_ATA_DATA5, 1);
+ gpio_request_mux(MX27_PIN_ATA_DATA4, GPIO_MUX_INPUT1);
+ mxc_set_gpio_direction(MX27_PIN_ATA_DATA4, 1);
+ gpio_request_mux(MX27_PIN_ATA_DATA3, GPIO_MUX_INPUT1);
+ mxc_set_gpio_direction(MX27_PIN_ATA_DATA3, 1);
+ gpio_request_mux(MX27_PIN_ATA_DATA2, GPIO_MUX_INPUT1);
+ mxc_set_gpio_direction(MX27_PIN_ATA_DATA2, 1);
+ gpio_request_mux(MX27_PIN_ATA_DATA1, GPIO_MUX_OUTPUT1);
+ mxc_set_gpio_direction(MX27_PIN_ATA_DATA1, 0);
+ gpio_request_mux(MX27_PIN_ATA_DATA0, GPIO_MUX_OUTPUT1);
+ mxc_set_gpio_direction(MX27_PIN_ATA_DATA0, 0);
+ gpio_request_mux(MX27_PIN_SD3_CLK, GPIO_MUX_OUTPUT1);
+ mxc_set_gpio_direction(MX27_PIN_SD3_CLK, 0);
+ gpio_request_mux(MX27_PIN_SD3_CMD, GPIO_MUX_OUTPUT1);
+ mxc_set_gpio_direction(MX27_PIN_SD3_CMD, 0);
+
+ __raw_writew(PBC_BCTRL2_ATAFEC_EN, PBC_BCTRL2_CLEAR_REG);
+ __raw_writew(PBC_BCTRL2_ATAFEC_SEL, PBC_BCTRL2_SET_REG);
+}
+
+/*!
+ * Setup GPIO for FEC device to be inactive
+ *
+ */
+void gpio_fec_inactive(void)
+{
+ gpio_free_mux(MX27_PIN_ATA_DATA0);
+ gpio_free_mux(MX27_PIN_ATA_DATA1);
+ gpio_free_mux(MX27_PIN_ATA_DATA2);
+ gpio_free_mux(MX27_PIN_ATA_DATA3);
+ gpio_free_mux(MX27_PIN_ATA_DATA4);
+ gpio_free_mux(MX27_PIN_ATA_DATA5);
+ gpio_free_mux(MX27_PIN_ATA_DATA6);
+ gpio_free_mux(MX27_PIN_ATA_DATA7);
+ gpio_free_mux(MX27_PIN_ATA_DATA8);
+ gpio_free_mux(MX27_PIN_ATA_DATA9);
+ gpio_free_mux(MX27_PIN_ATA_DATA10);
+ gpio_free_mux(MX27_PIN_ATA_DATA11);
+ gpio_free_mux(MX27_PIN_ATA_DATA12);
+ gpio_free_mux(MX27_PIN_ATA_DATA13);
+ gpio_free_mux(MX27_PIN_ATA_DATA14);
+ gpio_free_mux(MX27_PIN_ATA_DATA15);
+
+ gpio_free_mux(MX27_PIN_SD3_CMD);
+ gpio_free_mux(MX27_PIN_SD3_CLK);
+}
+
+/*!
+ * Setup GPIO for SLCDC device to be active
+ *
+ */
+void gpio_slcdc_active(int type)
+{
+ switch (type) {
+ case 0:
+ gpio_request_mux(MX27_PIN_SSI3_CLK, GPIO_MUX_ALT); /* CLK */
+ gpio_request_mux(MX27_PIN_SSI3_TXDAT, GPIO_MUX_ALT); /* CS */
+ gpio_request_mux(MX27_PIN_SSI3_RXDAT, GPIO_MUX_ALT); /* RS */
+ gpio_request_mux(MX27_PIN_SSI3_FS, GPIO_MUX_ALT); /* D0 */
+ break;
+
+ case 1:
+ gpio_request_mux(MX27_PIN_SD2_D1, GPIO_MUX_GPIO); /* CLK */
+ gpio_request_mux(MX27_PIN_SD2_D2, GPIO_MUX_GPIO); /* D0 */
+ gpio_request_mux(MX27_PIN_SD2_D3, GPIO_MUX_GPIO); /* RS */
+ gpio_request_mux(MX27_PIN_SD2_CMD, GPIO_MUX_GPIO); /* CS */
+ break;
+
+ case 2:
+ gpio_request_mux(MX27_PIN_LD0, GPIO_MUX_GPIO);
+ gpio_request_mux(MX27_PIN_LD1, GPIO_MUX_GPIO);
+ gpio_request_mux(MX27_PIN_LD2, GPIO_MUX_GPIO);
+ gpio_request_mux(MX27_PIN_LD3, GPIO_MUX_GPIO);
+ gpio_request_mux(MX27_PIN_LD4, GPIO_MUX_GPIO);
+ gpio_request_mux(MX27_PIN_LD5, GPIO_MUX_GPIO);
+ gpio_request_mux(MX27_PIN_LD6, GPIO_MUX_GPIO);
+ gpio_request_mux(MX27_PIN_LD7, GPIO_MUX_GPIO);
+ gpio_request_mux(MX27_PIN_LD8, GPIO_MUX_GPIO);
+ gpio_request_mux(MX27_PIN_LD9, GPIO_MUX_GPIO);
+ gpio_request_mux(MX27_PIN_LD10, GPIO_MUX_GPIO);
+ gpio_request_mux(MX27_PIN_LD11, GPIO_MUX_GPIO);
+ gpio_request_mux(MX27_PIN_LD12, GPIO_MUX_GPIO);
+ gpio_request_mux(MX27_PIN_LD13, GPIO_MUX_GPIO);
+ gpio_request_mux(MX27_PIN_LD14, GPIO_MUX_GPIO);
+ gpio_request_mux(MX27_PIN_LD15, GPIO_MUX_GPIO);
+ break;
+
+ default:
+ break;
+ }
+
+ return;
+}
+
+/*!
+ * Setup GPIO for SLCDC device to be inactive
+ *
+ */
+void gpio_slcdc_inactive(int type)
+{
+ switch (type) {
+ case 0:
+ gpio_free_mux(MX27_PIN_SSI3_CLK); /* CLK */
+ gpio_free_mux(MX27_PIN_SSI3_TXDAT); /* CS */
+ gpio_free_mux(MX27_PIN_SSI3_RXDAT); /* RS */
+ gpio_free_mux(MX27_PIN_SSI3_FS); /* D0 */
+ break;
+
+ case 1:
+ gpio_free_mux(MX27_PIN_SD2_D1); /* CLK */
+ gpio_free_mux(MX27_PIN_SD2_D2); /* D0 */
+ gpio_free_mux(MX27_PIN_SD2_D3); /* RS */
+ gpio_free_mux(MX27_PIN_SD2_CMD); /* CS */
+ break;
+
+ case 2:
+ gpio_free_mux(MX27_PIN_LD0);
+ gpio_free_mux(MX27_PIN_LD1);
+ gpio_free_mux(MX27_PIN_LD2);
+ gpio_free_mux(MX27_PIN_LD3);
+ gpio_free_mux(MX27_PIN_LD4);
+ gpio_free_mux(MX27_PIN_LD5);
+ gpio_free_mux(MX27_PIN_LD6);
+ gpio_free_mux(MX27_PIN_LD7);
+ gpio_free_mux(MX27_PIN_LD8);
+ gpio_free_mux(MX27_PIN_LD9);
+ gpio_free_mux(MX27_PIN_LD10);
+ gpio_free_mux(MX27_PIN_LD11);
+ gpio_free_mux(MX27_PIN_LD12);
+ gpio_free_mux(MX27_PIN_LD13);
+ gpio_free_mux(MX27_PIN_LD14);
+ gpio_free_mux(MX27_PIN_LD15);
+ break;
+
+ default:
+ break;
+ }
+
+ return;
+}
+
+void gpio_ssi_active(int ssi_num)
+{
+ switch (ssi_num) {
+ case 0:
+ gpio_request_mux(MX27_PIN_SSI1_FS, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SSI1_RXDAT, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SSI1_TXDAT, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SSI1_CLK, GPIO_MUX_PRIMARY);
+ gpio_set_puen(MX27_PIN_SSI1_FS, 0);
+ gpio_set_puen(MX27_PIN_SSI1_RXDAT, 0);
+ gpio_set_puen(MX27_PIN_SSI1_TXDAT, 0);
+ gpio_set_puen(MX27_PIN_SSI1_CLK, 0);
+ break;
+ case 1:
+ gpio_request_mux(MX27_PIN_SSI2_FS, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SSI2_RXDAT, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SSI2_TXDAT, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SSI2_CLK, GPIO_MUX_PRIMARY);
+ gpio_set_puen(MX27_PIN_SSI2_FS, 0);
+ gpio_set_puen(MX27_PIN_SSI2_RXDAT, 0);
+ gpio_set_puen(MX27_PIN_SSI2_TXDAT, 0);
+ gpio_set_puen(MX27_PIN_SSI2_CLK, 0);
+ break;
+ default:
+ break;
+ }
+ return;
+}
+
+/*!
+ * * Setup GPIO for a SSI port to be inactive
+ * *
+ * * @param ssi_num an SSI port num
+ */
+
+void gpio_ssi_inactive(int ssi_num)
+{
+ switch (ssi_num) {
+ case 0:
+ gpio_free_mux(MX27_PIN_SSI1_FS);
+ gpio_free_mux(MX27_PIN_SSI1_RXDAT);
+ gpio_free_mux(MX27_PIN_SSI1_TXDAT);
+ gpio_free_mux(MX27_PIN_SSI1_CLK);
+ break;
+ case 1:
+ gpio_free_mux(MX27_PIN_SSI2_FS);
+ gpio_free_mux(MX27_PIN_SSI2_RXDAT);
+ gpio_free_mux(MX27_PIN_SSI2_TXDAT);
+ gpio_free_mux(MX27_PIN_SSI2_CLK);
+ break;
+ default:
+ break;
+ }
+ return;
+}
+
+/*!
+ * Setup GPIO for SDHC to be active
+ *
+ * @param module SDHC module number
+ */
+void gpio_sdhc_active(int module)
+{
+ u16 data;
+ switch (module) {
+ case 0:
+ gpio_request_mux(MX27_PIN_SD1_CLK, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SD1_CMD, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SD1_D0, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SD1_D1, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SD1_D2, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SD1_D3, GPIO_MUX_PRIMARY);
+ /* 22k pull up for sd1 dat3 pins */
+ data = __raw_readw(IO_ADDRESS(SYSCTRL_BASE_ADDR + 0x54));
+ data |= 0x0c;
+ __raw_writew(data, IO_ADDRESS(SYSCTRL_BASE_ADDR + 0x54));
+ /*mxc_clks_enable(SDHC1_CLK);
+ mxc_clks_enable(PERCLK2); */
+ break;
+ case 1:
+ gpio_request_mux(MX27_PIN_SD2_CLK, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SD2_CMD, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SD2_D0, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SD2_D1, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SD2_D2, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SD2_D3, GPIO_MUX_PRIMARY);
+ /* 22k pull up for sd2 pins */
+ data = __raw_readw(IO_ADDRESS(SYSCTRL_BASE_ADDR + 0x54));
+ data &= ~0xfff0;
+ data |= 0xfff0;
+ __raw_writew(data, IO_ADDRESS(SYSCTRL_BASE_ADDR + 0x54));
+ /*mxc_clks_enable(SDHC2_CLK);
+ mxc_clks_enable(PERCLK2); */
+ break;
+ case 2:
+ gpio_request_mux(MX27_PIN_SD3_CLK, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_SD3_CMD, GPIO_MUX_PRIMARY);
+ gpio_request_mux(MX27_PIN_ATA_DATA0, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_ATA_DATA1, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_ATA_DATA2, GPIO_MUX_ALT);
+ gpio_request_mux(MX27_PIN_ATA_DATA3, GPIO_MUX_ALT);
+ /*mxc_clks_enable(SDHC3_CLK);
+ mxc_clks_enable(PERCLK2); */
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * Setup GPIO for SDHC1 to be inactive
+ *
+ * @param module SDHC module number
+ */
+void gpio_sdhc_inactive(int module)
+{
+ switch (module) {
+ case 0:
+ gpio_free_mux(MX27_PIN_SD1_CLK);
+ gpio_free_mux(MX27_PIN_SD1_CMD);
+ gpio_free_mux(MX27_PIN_SD1_D0);
+ gpio_free_mux(MX27_PIN_SD1_D1);
+ gpio_free_mux(MX27_PIN_SD1_D2);
+ gpio_free_mux(MX27_PIN_SD1_D3);
+ /*mxc_clks_disable(SDHC1_CLK); */
+ break;
+ case 1:
+ gpio_free_mux(MX27_PIN_SD2_CLK);
+ gpio_free_mux(MX27_PIN_SD2_CMD);
+ gpio_free_mux(MX27_PIN_SD2_D0);
+ gpio_free_mux(MX27_PIN_SD2_D1);
+ gpio_free_mux(MX27_PIN_SD2_D2);
+ gpio_free_mux(MX27_PIN_SD2_D3);
+ /*mxc_clks_disable(SDHC2_CLK); */
+ break;
+ case 2:
+ gpio_free_mux(MX27_PIN_SD3_CLK);
+ gpio_free_mux(MX27_PIN_SD3_CMD);
+ gpio_free_mux(MX27_PIN_ATA_DATA0);
+ gpio_free_mux(MX27_PIN_ATA_DATA1);
+ gpio_free_mux(MX27_PIN_ATA_DATA2);
+ gpio_free_mux(MX27_PIN_ATA_DATA3);
+ /*mxc_clks_disable(SDHC3_CLK); */
+ break;
+ default:
+ break;
+ }
+}
+
+/*
+ * Probe for the card. If present the GPIO data would be set.
+ */
+int sdhc_get_card_det_status(struct device *dev)
+{
+ return 0;
+}
+
+/*
+ * Return the card detect pin.
+ */
+int sdhc_init_card_det(int id)
+{
+ int ret = 0;
+ switch (id) {
+ case 0:
+ ret = EXPIO_INT_SD1_EN;
+ break;
+ case 1:
+ ret = EXPIO_INT_SD2_EN;
+ break;
+ default:
+ ret = 0;
+ break;
+ }
+ return ret;
+}
+
+/*
+ * Power on/off Sharp QVGA panel.
+ */
+void board_power_lcd(int on)
+{
+ if (on)
+ __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_SET_REG);
+ else
+ __raw_writew(PBC_BCTRL1_LCDON, PBC_BCTRL1_CLEAR_REG);
+}
+
+void gpio_owire_active(void)
+{
+ gpio_request_mux(MX27_PIN_RTCK, GPIO_MUX_ALT);
+}
+
+void gpio_owire_inactive(void)
+{
+ gpio_request_mux(MX27_PIN_RTCK, GPIO_MUX_PRIMARY);
+}
+
+EXPORT_SYMBOL(gpio_uart_active);
+EXPORT_SYMBOL(gpio_uart_inactive);
+EXPORT_SYMBOL(config_uartdma_event);
+EXPORT_SYMBOL(gpio_usbh1_active);
+EXPORT_SYMBOL(gpio_usbh1_inactive);
+EXPORT_SYMBOL(gpio_usbh2_active);
+EXPORT_SYMBOL(gpio_usbh2_inactive);
+EXPORT_SYMBOL(gpio_usbotg_hs_active);
+EXPORT_SYMBOL(gpio_usbotg_hs_inactive);
+EXPORT_SYMBOL(gpio_usbotg_fs_active);
+EXPORT_SYMBOL(gpio_usbotg_fs_inactive);
+EXPORT_SYMBOL(gpio_i2c_active);
+EXPORT_SYMBOL(gpio_i2c_inactive);
+EXPORT_SYMBOL(gpio_spi_active);
+EXPORT_SYMBOL(gpio_spi_inactive);
+EXPORT_SYMBOL(gpio_nand_active);
+EXPORT_SYMBOL(gpio_nand_inactive);
+EXPORT_SYMBOL(gpio_sensor_active);
+EXPORT_SYMBOL(gpio_sensor_inactive);
+EXPORT_SYMBOL(gpio_sensor_reset);
+EXPORT_SYMBOL(gpio_lcdc_active);
+EXPORT_SYMBOL(gpio_lcdc_inactive);
+EXPORT_SYMBOL(gpio_fs453_reset_low);
+EXPORT_SYMBOL(gpio_fs453_reset_high);
+EXPORT_SYMBOL(gpio_pmic_active);
+EXPORT_SYMBOL(gpio_keypad_active);
+EXPORT_SYMBOL(gpio_keypad_inactive);
+EXPORT_SYMBOL(gpio_ata_active);
+EXPORT_SYMBOL(gpio_ata_inactive);
+EXPORT_SYMBOL(gpio_fec_active);
+EXPORT_SYMBOL(gpio_fec_inactive);
+EXPORT_SYMBOL(gpio_slcdc_active);
+EXPORT_SYMBOL(gpio_slcdc_inactive);
+EXPORT_SYMBOL(gpio_ssi_active);
+EXPORT_SYMBOL(gpio_ssi_inactive);
+EXPORT_SYMBOL(gpio_sdhc_active);
+EXPORT_SYMBOL(gpio_sdhc_inactive);
+EXPORT_SYMBOL(sdhc_get_card_det_status);
+EXPORT_SYMBOL(sdhc_init_card_det);
+EXPORT_SYMBOL(board_power_lcd);
+EXPORT_SYMBOL(gpio_owire_active);
+EXPORT_SYMBOL(gpio_owire_inactive);
diff --git a/arch/arm/mach-mx27/mxc_pm.c b/arch/arm/mach-mx27/mxc_pm.c
new file mode 100644
index 000000000000..4cad42238477
--- /dev/null
+++ b/arch/arm/mach-mx27/mxc_pm.c
@@ -0,0 +1,459 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup DPM_MX27 Power Management
+ * @ingroup MSL_MX27
+ */
+/*!
+ * @file mach-mx27/mxc_pm.c
+ *
+ * @brief This file contains the implementation of the Low-level power
+ * management driver. It modifies the registers of the PLL and clock module
+ * of the i.MX27.
+ *
+ * @ingroup DPM_MX27
+ */
+
+/*
+ * Include Files
+ */
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <mach/mxc_pm.h>
+#include <mach/mxc.h>
+#include <mach/system.h>
+#include <asm/irq.h>
+#include "crm_regs.h"
+
+/* Local defines */
+#define MAX_ARM_FREQ 400000000
+#define MAX_AHB_FREQ 133000000
+#define MAX_IPG_FREQ 66500000
+#define FREQ_COMP_TOLERANCE 100 /* tolerance percentage times 100 */
+#define MX27_LLPM_DEBUG 0
+
+/*
+ * Global variables
+ */
+#if 0
+/*!
+ * These variables hold the various clock values when the module is loaded.
+ * This is needed because these clocks are derived from MPLL and when MPLL
+ * output changes, these clocks need to be adjusted.
+ */
+static u32 perclk1, perclk2, perclk3, perclk4, nfcclk, cpuclk;
+
+/*!
+ * Compare two frequences using allowable tolerance
+ *
+ * The MX27 PLL can generate many frequencies. This function
+ * compares the generated frequency to the requested frequency
+ * and determines it they are within and acceptable tolerance.
+ *
+ * @param freq1 desired frequency
+ * @param freq2 generated frequency
+ *
+ * @return Returns 0 is frequencies are within talerance
+ * and non-zero is they are not.
+ */
+static s32 freq_equal(u32 freq1, u32 freq2)
+{
+ if (freq1 > freq2) {
+ return (freq1 - freq2) <= (freq1 / FREQ_COMP_TOLERANCE);
+ }
+ return (freq2 - freq1) <= (freq1 / FREQ_COMP_TOLERANCE);
+}
+
+/*!
+ * Select the PLL frequency based on the desired ARM frequency.
+ *
+ * The MPLL will be configured to output three frequencies, 400/333/266 MHz.
+ *
+ * @param armfreq Desired ARM frequency
+ *
+ * @return Returns one of the selected PLL frequency (400/333/266 MHz).
+ * Returns -1 on error.
+ *
+ */
+static s32 select_freq_pll(u32 armfreq)
+{
+ u32 div;
+
+ div = 266000000 / armfreq;
+ if ((div == 0) || (!freq_equal(armfreq, 266000000 / div))) {
+ div = 400000000 / armfreq;
+ if ((div == 0) || (!freq_equal(armfreq, 400000000 / div))) {
+ return -1;
+ }
+
+ return 400000000;
+ }
+
+ return 266000000;
+}
+
+/*!
+ * Check whether the desired ARM and AHB frequencies are valid.
+ *
+ * @param armfreq Desired ARM frequency
+ * @param ahbfreq Desired AHB frequency
+ *
+ * @return Returns 0 on success
+ * Return -1 on error
+ */
+static s32 mx27_pm_check_parameters(u32 armfreq, u32 ahbfreq)
+{
+ u32 ahbdiv;
+
+ /* No idea about minimum frequencies.. just a guess! */
+ if ((armfreq < 1000000) || (ahbfreq < 1000000)) {
+ printk("arm or ahb frequencies are less\n");
+ return -1;
+ }
+
+ if ((armfreq > MAX_ARM_FREQ) || (ahbfreq > MAX_AHB_FREQ)) {
+ printk("arm or ahb freq. are too much\n");
+ return -1;
+ }
+
+ /* AHB divider value is restricted to less than 8 */
+ ahbdiv = armfreq / ahbfreq;
+ if ((ahbdiv == 0) || (ahbdiv > 8)) {
+ printk("Invalid ahb frequency\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+/*!
+ * Integer clock scaling
+ *
+ * Change the main ARM clock frequencies without changing the MPLL.
+ * The integer dividers (PRESC and BCLKDIV) are changed to obtain the
+ * desired frequency. Since NFC clock is derived from ARM frequency,
+ * NFCDIV is also adjusted.
+ *
+ * @param arm_freq Desired ARM frequency
+ * @param ahb_freq Desired AHB frequency
+ * @param pll_freq Current PLL frequency
+ *
+ * @return Returns 0
+ */
+static s32 mx27_pm_intscale(u32 arm_freq, u32 ahb_freq, s32 pll_freq)
+{
+ u32 pre_div, bclk_div, nfc_div;
+
+ /* Calculate ARM divider */
+ pre_div = pll_freq / arm_freq;
+ if (pre_div == 0)
+ pre_div = 1;
+
+ /* Calculate AHB divider */
+ bclk_div = arm_freq / ahb_freq;
+ if (bclk_div == 0)
+ bclk_div = 1;
+
+ if ((arm_freq / bclk_div) > ahb_freq)
+ bclk_div++;
+
+ /* NFC clock is dependent on ARM clock */
+ nfc_div = arm_freq / nfcclk;
+ if ((arm_freq / nfc_div) > nfcclk)
+ nfc_div++;
+
+ /* Adjust NFC divider */
+ mxc_set_clocks_div(NFC_CLK, nfc_div);
+
+#if MX27_LLPM_DEBUG
+ printk("DIVIDERS: PreDiv = %d BCLKDIV = %d \n", pre_div, bclk_div);
+ printk("Integer scaling\n");
+ printk("PLL = %d : ARM = %d: AHB = %d\n", pll_freq, arm_freq, ahb_freq);
+#endif
+
+ /*
+ * This part is tricky. What to adjust first (PRESC or BCLKDIV)?
+ * After trial and error, if current ARM frequency is greater than
+ * desired ARM frequency, then adjust PRESC first, else if current
+ * ARM frequency is less than desired ARM frequency, then adjust
+ * BCLKDIV first.
+ */
+ if (cpuclk > arm_freq) {
+ mxc_set_clocks_div(CPU_CLK, pre_div);
+ mxc_set_clocks_div(AHB_CLK, bclk_div);
+ } else {
+ mxc_set_clocks_div(AHB_CLK, bclk_div);
+ mxc_set_clocks_div(CPU_CLK, pre_div);
+ }
+
+ cpuclk = arm_freq;
+ mdelay(50);
+ return 0;
+}
+
+/*!
+ * Set dividers for various peripheral clocks.
+ *
+ * PERCLK1, PERCLK2, PERCLK3 and PERCLK4 are adjusted based on the MPLL
+ * output frequency.
+ *
+ * @param pll_freq Desired MPLL output frequency
+ */
+static void mx27_set_dividers(u32 pll_freq)
+{
+ s32 perdiv1, perdiv2, perdiv3, perdiv4;
+
+ perdiv1 = pll_freq / perclk1;
+ if ((pll_freq / perdiv1) > perclk1)
+ perdiv1++;
+
+ perdiv2 = pll_freq / perclk2;
+ if ((pll_freq / perdiv2) > perclk2)
+ perdiv2++;
+
+ perdiv3 = pll_freq / perclk3;
+ if ((pll_freq / perdiv3) > perclk3)
+ perdiv3++;
+
+ perdiv4 = pll_freq / perclk4;
+ if ((pll_freq / perdiv4) > perclk4)
+ perdiv4++;
+
+ mxc_set_clocks_div(PERCLK1, perdiv1);
+ mxc_set_clocks_div(PERCLK2, perdiv2);
+ mxc_set_clocks_div(PERCLK3, perdiv3);
+ mxc_set_clocks_div(PERCLK4, perdiv4);
+}
+
+/*!
+ * Change MPLL output frequency and adjust derived clocks to produce the
+ * desired frequencies.
+ *
+ * @param arm_freq Desired ARM frequency
+ * @param ahb_freq Desired AHB frequency
+ * @param org_pll Current PLL frequency
+ *
+ * @return Returns 0 on success
+ * Returns -1 on error
+ */
+static s32 mx27_pm_pllscale(u32 arm_freq, u32 ahb_freq, s32 org_pll)
+{
+ u32 mfi, mfn, mfd, pd = 1, cscr;
+ s32 pll_freq;
+
+ /* Obtain the PLL frequency for the desired ARM frequency */
+ pll_freq = select_freq_pll(arm_freq);
+ if (pll_freq == -1) {
+ return -1;
+ }
+
+ /* The MPCTL0 register values are programmed based on the oscillator */
+ cscr = __raw_readl(IO_ADDRESS(CCM_BASE_ADDR) + CCM_CSCR);
+ if ((cscr & CCM_CSCR_OSC26M) == 0) {
+ /* MPCTL0 register values are programmed for 400/266 MHz */
+ switch (pll_freq) {
+ case 400000000:
+ mfi = 7;
+ mfn = 9;
+ mfd = 12;
+ pd = 0;
+ break;
+
+ case 266000000:
+ mfi = 10;
+ mfn = 6;
+ mfd = 25;
+ break;
+
+ default:
+ return -1;
+ }
+ } else {
+ /* MPCTL0 register values are programmed for 400/266 MHz */
+ switch (pll_freq) {
+ case 400000000:
+ mfi = 12;
+ mfn = 2;
+ mfd = 3;
+ break;
+
+ case 266000000:
+ mfi = 8;
+ mfn = 10;
+ mfd = 31;
+ break;
+
+ default:
+ return -1;
+ }
+ }
+
+#if MX27_LLPM_DEBUG
+ printk("PLL scaling\n");
+ printk("PLL = %d : ARM = %d: AHB = %d\n", pll_freq, arm_freq, ahb_freq);
+#endif
+
+ /* Adjust the peripheral clock dividers for new PLL frequency */
+ mx27_set_dividers(pll_freq);
+
+ if (pll_freq > org_pll) {
+ /* Set the dividers first */
+ mx27_pm_intscale(arm_freq, ahb_freq, pll_freq);
+
+ /* Set the PLL */
+ mxc_pll_set(MCUPLL, mfi, pd, mfd, mfn);
+ mdelay(50);
+ } else {
+ /* Set the PLL first */
+ mxc_pll_set(MCUPLL, mfi, pd, mfd, mfn);
+ mdelay(50);
+
+ /* Set the dividers later */
+ mx27_pm_intscale(arm_freq, ahb_freq, pll_freq);
+ }
+
+ return 0;
+}
+#endif
+/*!
+ * Implement steps required to transition to low-power modes.
+ *
+ * @param mode The desired low-power mode. Possible values are,
+ * DOZE_MODE
+ * WAIT_MODE
+ * STOP_MODE
+ * DSM_MODE
+ */
+void mxc_pm_lowpower(s32 mode)
+{
+ u32 cscr;
+
+ local_irq_disable();
+
+ /* WAIT and DOZE execute WFI only */
+ switch (mode) {
+ case STOP_MODE:
+ case DSM_MODE:
+ /* Clear MPEN and SPEN to disable MPLL/SPLL */
+ cscr = __raw_readl(CCM_CSCR);
+ cscr &= 0xFFFFFFFC;
+ __raw_writel(cscr, CCM_CSCR);
+ break;
+ }
+
+ /* Executes WFI */
+ arch_idle();
+
+ local_irq_enable();
+}
+
+#if 0
+/*!
+ * Called to change the core frequency. This function internally decides
+ * whether to do integer scaling or pll scaling.
+ *
+ * @param arm_freq Desired ARM frequency
+ * @param ahb_freq Desired AHB frequency
+ * @param ipg_freq Desired IP frequency, constant AHB / 2 always.
+ *
+ * @return Returns 0 on success
+ * Returns -1 on error
+ */
+int mxc_pm_dvfs(unsigned long arm_freq, long ahb_freq, long ipg_freq)
+{
+ u32 divider;
+ s32 pll_freq, ret;
+ unsigned long flags;
+
+ if (mx27_pm_check_parameters(arm_freq, ahb_freq) != 0) {
+ return -1;
+ }
+
+ local_irq_save(flags);
+
+ /* Get the current PLL frequency */
+ pll_freq = mxc_pll_clock(MCUPLL);
+
+#if MX27_LLPM_DEBUG
+ printk("MCU PLL frequency is %d\n", pll_freq);
+#endif
+
+ /* Decide whether to do integer scaling or pll scaling */
+ if (arm_freq > pll_freq) {
+ /* Do PLL scaling */
+ ret = mx27_pm_pllscale(arm_freq, ahb_freq, pll_freq);
+ } else {
+ /* We need integer divider values */
+ divider = pll_freq / arm_freq;
+ if (!freq_equal(arm_freq, pll_freq / divider)) {
+ /* Do PLL scaling */
+ ret = mx27_pm_pllscale(arm_freq, ahb_freq, pll_freq);
+ } else {
+ /* Do integer scaling */
+ ret = mx27_pm_intscale(arm_freq, ahb_freq, pll_freq);
+ }
+ }
+
+ local_irq_restore(flags);
+ return ret;
+}
+#endif
+/*
+ * This API is not supported on i.MX27
+ */
+int mxc_pm_intscale(long armfreq, long ahbfreq, long ipfreq)
+{
+ return -MXC_PM_API_NOT_SUPPORTED;
+}
+
+/*
+ * This API is not supported on i.MX27
+ */
+int mxc_pm_pllscale(long armfreq, long ahbfreq, long ipfreq)
+{
+ return -MXC_PM_API_NOT_SUPPORTED;
+}
+
+/*!
+ * This function is used to load the module.
+ *
+ * @return Returns an Integer on success
+ */
+static int __init mxc_pm_init_module(void)
+{
+ printk(KERN_INFO "MX27: Power management module initialized\n");
+ return 0;
+}
+
+/*!
+ * This function is used to unload the module
+ */
+static void __exit mxc_pm_cleanup_module(void)
+{
+ printk(KERN_INFO "MX27: Power management module exit\n");
+}
+
+module_init(mxc_pm_init_module);
+module_exit(mxc_pm_cleanup_module);
+
+EXPORT_SYMBOL(mxc_pm_lowpower);
+//EXPORT_SYMBOL(mxc_pm_dvfs);
+EXPORT_SYMBOL(mxc_pm_pllscale);
+EXPORT_SYMBOL(mxc_pm_intscale);
+
+MODULE_AUTHOR("Freescale Semiconductor");
+MODULE_DESCRIPTION("i.MX27 low level PM driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-mx27/pm.c b/arch/arm/mach-mx27/pm.c
new file mode 100644
index 000000000000..10909a72ee1b
--- /dev/null
+++ b/arch/arm/mach-mx27/pm.c
@@ -0,0 +1,102 @@
+/*
+ * linux/arch/arm/mach-mx27/pm.c
+ *
+ * MX27 Power Management Routines
+ *
+ * Original code for the SA11x0:
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * Modified for the PXA250 by Nicolas Pitre:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * Modified for the OMAP1510 by David Singleton:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com>
+ *
+ * Modified for the MX27
+ * Copyright 2007-2009 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+
+#include <mach/mxc_pm.h>
+
+/*
+ * TODO: whatta save?
+ */
+
+static int mx27_suspend_enter(suspend_state_t state)
+{
+ pr_debug("Hi, from mx27_pm_enter\n");
+ switch (state) {
+ case PM_SUSPEND_STANDBY:
+ mxc_pm_lowpower(STOP_MODE);
+ break;
+ case PM_SUSPEND_MEM:
+ mxc_pm_lowpower(DSM_MODE);
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int mx27_suspend_prepare(void)
+{
+ return 0;
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+static void mx27_suspend_finish(void)
+{
+ return;
+}
+
+static int mx27_pm_valid(suspend_state_t state)
+{
+ return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX);
+}
+
+struct platform_suspend_ops mx27_suspend_ops = {
+ .valid = mx27_pm_valid,
+ .prepare = mx27_suspend_prepare,
+ .enter = mx27_suspend_enter,
+ .finish = mx27_suspend_finish,
+};
+
+static int __init mx27_pm_init(void)
+{
+ pr_debug("Power Management for Freescale MX27\n");
+ suspend_set_ops(&mx27_suspend_ops);
+
+ return 0;
+}
+
+late_initcall(mx27_pm_init);
diff --git a/arch/arm/mach-mx27/serial.c b/arch/arm/mach-mx27/serial.c
new file mode 100644
index 000000000000..a18cf0630c47
--- /dev/null
+++ b/arch/arm/mach-mx27/serial.c
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2006-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/*!
+ * @file mach-mx27/serial.c
+ *
+ * @brief This file contains the UART initiliazation.
+ *
+ * @ingroup MSL_MX27
+ */
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <mach/hardware.h>
+#include <mach/mxc_uart.h>
+#include "serial.h"
+#include "board-mx27ads.h"
+
+#if defined(CONFIG_SERIAL_MXC) || defined(CONFIG_SERIAL_MXC_MODULE)
+
+/*!
+ * This is an array where each element holds information about a UART port,
+ * like base address of the UART, interrupt numbers etc. This structure is
+ * passed to the serial_core.c file. Based on which UART is used, the core file
+ * passes back the appropriate port structure as an argument to the control
+ * functions.
+ */
+static uart_mxc_port mxc_ports[] = {
+ [0] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART1_BASE_ADDR),
+ .mapbase = UART1_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART1_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 0,
+ },
+ .ints_muxed = UART1_MUX_INTS,
+ .irqs = {UART1_INT2, UART1_INT3},
+ .mode = UART1_MODE,
+ .ir_mode = UART1_IR,
+ .enabled = UART1_ENABLED,
+ .hardware_flow = UART1_HW_FLOW,
+ .cts_threshold = UART1_UCR4_CTSTL,
+ .dma_enabled = UART1_DMA_ENABLE,
+ .dma_rxbuf_size = UART1_DMA_RXBUFSIZE,
+ .rx_threshold = UART1_UFCR_RXTL,
+ .tx_threshold = UART1_UFCR_TXTL,
+ .shared = UART1_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART1_TX,
+ .dma_rx_id = MXC_DMA_UART1_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ .ir_tx_inv = MXC_IRDA_TX_INV,
+ .ir_rx_inv = MXC_IRDA_RX_INV,
+ },
+ [1] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART2_BASE_ADDR),
+ .mapbase = UART2_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART2_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 1,
+ },
+ .ints_muxed = UART2_MUX_INTS,
+ .irqs = {UART2_INT2, UART2_INT3},
+ .mode = UART2_MODE,
+ .ir_mode = UART2_IR,
+ .enabled = UART2_ENABLED,
+ .hardware_flow = UART2_HW_FLOW,
+ .cts_threshold = UART2_UCR4_CTSTL,
+ .dma_enabled = UART2_DMA_ENABLE,
+ .dma_rxbuf_size = UART2_DMA_RXBUFSIZE,
+ .rx_threshold = UART2_UFCR_RXTL,
+ .tx_threshold = UART2_UFCR_TXTL,
+ .shared = UART2_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART2_TX,
+ .dma_rx_id = MXC_DMA_UART2_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ .ir_tx_inv = MXC_IRDA_TX_INV,
+ .ir_rx_inv = MXC_IRDA_RX_INV,
+ },
+ [2] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART3_BASE_ADDR),
+ .mapbase = UART3_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART3_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 2,
+ },
+ .ints_muxed = UART3_MUX_INTS,
+ .irqs = {UART3_INT2, UART3_INT3},
+ .mode = UART3_MODE,
+ .ir_mode = UART3_IR,
+ .enabled = UART3_ENABLED,
+ .hardware_flow = UART3_HW_FLOW,
+ .cts_threshold = UART3_UCR4_CTSTL,
+ .dma_enabled = UART3_DMA_ENABLE,
+ .dma_rxbuf_size = UART3_DMA_RXBUFSIZE,
+ .rx_threshold = UART3_UFCR_RXTL,
+ .tx_threshold = UART3_UFCR_TXTL,
+ .shared = UART3_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART3_TX,
+ .dma_rx_id = MXC_DMA_UART3_RX,
+ .rxd_mux = MXC_UART_IR_RXDMUX,
+ .ir_tx_inv = MXC_IRDA_TX_INV,
+ .ir_rx_inv = MXC_IRDA_RX_INV,
+ },
+ [3] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART4_BASE_ADDR),
+ .mapbase = UART4_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART4_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 3,
+ },
+ .ints_muxed = UART4_MUX_INTS,
+ .irqs = {UART4_INT2, UART4_INT3},
+ .mode = UART4_MODE,
+ .ir_mode = UART4_IR,
+ .enabled = UART4_ENABLED,
+ .hardware_flow = UART4_HW_FLOW,
+ .cts_threshold = UART4_UCR4_CTSTL,
+ .dma_enabled = UART4_DMA_ENABLE,
+ .dma_rxbuf_size = UART4_DMA_RXBUFSIZE,
+ .rx_threshold = UART4_UFCR_RXTL,
+ .tx_threshold = UART4_UFCR_TXTL,
+ .shared = UART4_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART4_TX,
+ .dma_rx_id = MXC_DMA_UART4_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ .ir_tx_inv = MXC_IRDA_TX_INV,
+ .ir_rx_inv = MXC_IRDA_RX_INV,
+ },
+ [4] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART5_BASE_ADDR),
+ .mapbase = UART5_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART5_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 4,
+ },
+ .ints_muxed = UART5_MUX_INTS,
+ .irqs = {UART5_INT2, UART5_INT3},
+ .mode = UART5_MODE,
+ .ir_mode = UART5_IR,
+ .enabled = UART5_ENABLED,
+ .hardware_flow = UART5_HW_FLOW,
+ .cts_threshold = UART5_UCR4_CTSTL,
+ .dma_enabled = UART5_DMA_ENABLE,
+ .dma_rxbuf_size = UART5_DMA_RXBUFSIZE,
+ .rx_threshold = UART5_UFCR_RXTL,
+ .tx_threshold = UART5_UFCR_TXTL,
+ .shared = UART5_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART5_TX,
+ .dma_rx_id = MXC_DMA_UART5_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ .ir_tx_inv = MXC_IRDA_TX_INV,
+ .ir_rx_inv = MXC_IRDA_RX_INV,
+ },
+ [5] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART6_BASE_ADDR),
+ .mapbase = UART6_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART6_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 5,
+ },
+ .ints_muxed = UART6_MUX_INTS,
+ .irqs = {UART6_INT2, UART6_INT3},
+ .mode = UART6_MODE,
+ .ir_mode = UART6_IR,
+ .enabled = UART6_ENABLED,
+ .hardware_flow = UART6_HW_FLOW,
+ .cts_threshold = UART6_UCR4_CTSTL,
+ .dma_enabled = UART6_DMA_ENABLE,
+ .dma_rxbuf_size = UART6_DMA_RXBUFSIZE,
+ .rx_threshold = UART6_UFCR_RXTL,
+ .tx_threshold = UART6_UFCR_TXTL,
+ .shared = UART6_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART6_TX,
+ .dma_rx_id = MXC_DMA_UART6_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ .ir_tx_inv = MXC_IRDA_TX_INV,
+ .ir_rx_inv = MXC_IRDA_RX_INV,
+ },
+};
+
+static struct platform_device mxc_uart_device1 = {
+ .name = "mxcintuart",
+ .id = 0,
+ .dev = {
+ .platform_data = &mxc_ports[0],
+ },
+};
+
+static struct platform_device mxc_uart_device2 = {
+ .name = "mxcintuart",
+ .id = 1,
+ .dev = {
+ .platform_data = &mxc_ports[1],
+ },
+};
+
+static struct platform_device mxc_uart_device3 = {
+ .name = "mxcintuart",
+ .id = 2,
+ .dev = {
+ .platform_data = &mxc_ports[2],
+ },
+};
+
+static struct platform_device mxc_uart_device4 = {
+ .name = "mxcintuart",
+ .id = 3,
+ .dev = {
+ .platform_data = &mxc_ports[3],
+ },
+};
+static struct platform_device mxc_uart_device5 = {
+ .name = "mxcintuart",
+ .id = 4,
+ .dev = {
+ .platform_data = &mxc_ports[4],
+ },
+};
+static struct platform_device mxc_uart_device6 = {
+ .name = "mxcintuart",
+ .id = 5,
+ .dev = {
+ .platform_data = &mxc_ports[5],
+ },
+};
+
+static int __init mxc_init_uart(void)
+{
+ /* Register all the MXC UART platform device structures */
+ platform_device_register(&mxc_uart_device1);
+ platform_device_register(&mxc_uart_device2);
+ platform_device_register(&mxc_uart_device3);
+
+ platform_device_register(&mxc_uart_device4);
+
+ platform_device_register(&mxc_uart_device5);
+ platform_device_register(&mxc_uart_device6);
+ return 0;
+}
+
+#else
+static int __init mxc_init_uart(void)
+{
+ return 0;
+}
+#endif
+
+arch_initcall(mxc_init_uart);
diff --git a/arch/arm/mach-mx27/serial.h b/arch/arm/mach-mx27/serial.h
new file mode 100644
index 000000000000..11604c44cebe
--- /dev/null
+++ b/arch/arm/mach-mx27/serial.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ARCH_ARM_MACH_MX27_SERIAL_H__
+#define __ARCH_ARM_MACH_MX27_SERIAL_H__
+
+/*!
+ * @file mach-mx27/serial.h
+ *
+ * @ingroup MSL_MX27
+ */
+#include <mach/mxc_uart.h>
+
+/* UART 1 configuration */
+/*!
+ * This option allows to choose either an interrupt-driven software controlled
+ * hardware flow control (set this option to 0) or hardware-driven hardware
+ * flow control (set this option to 1).
+ */
+#define UART1_HW_FLOW 1
+/*!
+ * This specifies the threshold at which the CTS pin is deasserted by the
+ * RXFIFO. Set this value in Decimal to anything from 0 to 32 for
+ * hardware-driven hardware flow control. Read the HW spec while specifying
+ * this value. When using interrupt-driven software controlled hardware
+ * flow control set this option to -1.
+ */
+#define UART1_UCR4_CTSTL 16
+/*!
+ * This is option to enable (set this option to 1) or disable DMA data transfer
+ */
+#define UART1_DMA_ENABLE 0
+/*!
+ * Specify the size of the DMA receive buffer. The buffer size should be same with
+ * sub buffer size which is defined in mxc_uart.c for all data can be transfered.
+ */
+#define UART1_DMA_RXBUFSIZE 128
+/*!
+ * Specify the MXC UART's Receive Trigger Level. This controls the threshold at
+ * which a maskable interrupt is generated by the RxFIFO. Set this value in
+ * Decimal to anything from 0 to 32. Read the HW spec while specifying this
+ * value.
+ */
+#define UART1_UFCR_RXTL 16
+/*!
+ * Specify the MXC UART's Transmit Trigger Level. This controls the threshold at
+ * which a maskable interrupt is generated by the TxFIFO. Set this value in
+ * Decimal to anything from 0 to 32. Read the HW spec while specifying this
+ * value.
+ */
+#define UART1_UFCR_TXTL 16
+/* UART 2 configuration */
+#define UART2_HW_FLOW 1
+#define UART2_UCR4_CTSTL 16
+#define UART2_DMA_ENABLE 0
+#define UART2_DMA_RXBUFSIZE 512
+#define UART2_UFCR_RXTL 16
+#define UART2_UFCR_TXTL 16
+/* UART 3 configuration */
+#define UART3_HW_FLOW 0
+#define UART3_UCR4_CTSTL -1
+#define UART3_DMA_ENABLE 0
+#define UART3_DMA_RXBUFSIZE 512
+#define UART3_UFCR_RXTL 16
+#define UART3_UFCR_TXTL 16
+/* UART 4 configuration */
+#define UART4_HW_FLOW 1
+#define UART4_UCR4_CTSTL 16
+#define UART4_DMA_ENABLE 0
+#define UART4_DMA_RXBUFSIZE 512
+#define UART4_UFCR_RXTL 16
+#define UART4_UFCR_TXTL 16
+/* UART 5 configuration */
+#define UART5_HW_FLOW 1
+#define UART5_UCR4_CTSTL 16
+#define UART5_DMA_ENABLE 0
+#define UART5_DMA_RXBUFSIZE 512
+#define UART5_UFCR_RXTL 16
+#define UART5_UFCR_TXTL 16
+/* UART 6 configuration */
+#define UART6_HW_FLOW 1
+#define UART6_UCR4_CTSTL 16
+#define UART6_DMA_ENABLE 0
+#define UART6_DMA_RXBUFSIZE 512
+#define UART6_UFCR_RXTL 16
+#define UART6_UFCR_TXTL 16
+/*
+ * UART Chip level Configuration that a user may not have to edit. These
+ * configuration vary depending on how the UART module is integrated with
+ * the ARM core
+ */
+/*
+ * Is the MUXED interrupt output sent to the ARM core
+ */
+#define INTS_NOTMUXED 0
+#define INTS_MUXED 1
+/* UART 1 configuration */
+/*!
+ * This define specifies whether the muxed ANDed interrupt line or the
+ * individual interrupts from the UART port is integrated with the ARM core.
+ * There exists a define like this for each UART port. Valid values that can
+ * be used are \b INTS_NOTMUXED or \b INTS_MUXED.
+ */
+#define UART1_MUX_INTS INTS_MUXED
+/*!
+ * This define specifies the transmitter interrupt number or the interrupt
+ * number of the ANDed interrupt in case the interrupts are muxed. There exists
+ * a define like this for each UART port.
+ */
+#define UART1_INT1 MXC_INT_UART1
+/*!
+ * This define specifies the receiver interrupt number. If the interrupts of
+ * the UART are muxed, then we specify here a dummy value -1. There exists a
+ * define like this for each UART port.
+ */
+#define UART1_INT2 -1
+/*!
+ * This specifies the master interrupt number. If the interrupts of the UART
+ * are muxed, then we specify here a dummy value of -1. There exists a define
+ * like this for each UART port.
+ */
+#define UART1_INT3 -1
+/*!
+ * This specifies if the UART is a shared peripheral. It holds the shared
+ * peripheral number if it is shared or -1 if it is not shared. There exists
+ * a define like this for each UART port.
+ */
+#define UART1_SHARED_PERI -1
+/* UART 2 configuration */
+#define UART2_MUX_INTS INTS_MUXED
+#define UART2_INT1 MXC_INT_UART2
+#define UART2_INT2 -1
+#define UART2_INT3 -1
+#define UART2_SHARED_PERI -1
+/* UART 3 configuration */
+#define UART3_MUX_INTS INTS_MUXED
+#define UART3_INT1 MXC_INT_UART3
+#define UART3_INT2 -1
+#define UART3_INT3 -1
+#define UART3_SHARED_PERI -1
+/* UART 4 configuration */
+#define UART4_MUX_INTS INTS_MUXED
+#define UART4_INT1 MXC_INT_UART4
+#define UART4_INT2 -1
+#define UART4_INT3 -1
+#define UART4_SHARED_PERI -1
+/* UART 5 configuration */
+#define UART5_MUX_INTS INTS_MUXED
+#define UART5_INT1 MXC_INT_UART5
+#define UART5_INT2 -1
+#define UART5_INT3 -1
+#define UART5_SHARED_PERI -1
+/* UART 6 configuration */
+#define UART6_MUX_INTS INTS_MUXED
+#define UART6_INT1 MXC_INT_UART6
+#define UART6_INT2 -1
+#define UART6_INT3 -1
+#define UART6_SHARED_PERI -1
+
+#endif /* __ARCH_ARM_MACH_MX27_SERIAL_H__ */
diff --git a/arch/arm/mach-mx27/system.c b/arch/arm/mach-mx27/system.c
new file mode 100644
index 000000000000..fb8fc6bb0f0b
--- /dev/null
+++ b/arch/arm/mach-mx27/system.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2006-2009 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
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+
+/*!
+ * @defgroup MSL_MX27 i.MX27 Machine Specific Layer (MSL)
+ */
+
+/*!
+ * @file mach-mx27/system.c
+ * @brief This file contains idle and reset functions.
+ *
+ * @ingroup MSL_MX27
+ */
+
+/*!
+ * This function puts the CPU into idle mode. It is called by default_idle()
+ * in process.c file.
+ */
+void arch_idle(void)
+{
+ /*
+ * This should do all the clock switching
+ * and wait for interrupt tricks.
+ */
+ cpu_do_idle();
+}
+
+/*
+ * This function resets the system. It is called by machine_restart().
+ *
+ * @param mode indicates different kinds of resets
+ */
+void arch_reset(char mode)
+{
+ /* Assert Watchdog Reset signal */
+ mxc_wd_reset();
+}
diff --git a/arch/arm/mach-mx27/time.c b/arch/arm/mach-mx27/time.c
new file mode 100644
index 000000000000..79a4894bc9f6
--- /dev/null
+++ b/arch/arm/mach-mx27/time.c
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/* System Timer Interrupt reconfigured to run in free-run mode.
+ * Author: Vitaly Wool
+ * Copyright 2004 MontaVista Software Inc.
+ */
+
+/*!
+ * @defgroup Timers_MX27 OS Tick Timer
+ * @ingroup MSL_MX27
+ */
+/*!
+ * @file mach-mx27/time.c
+ * @brief This file contains OS tick timer implementation.
+ *
+ * This file contains OS tick timer implementation.
+ *
+ * @ingroup Timers_MX27
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <linux/clocksource.h>
+#include <linux/clockchips.h>
+#include <linux/mtd/xip.h>
+#include <mach/hardware.h>
+#include <asm/mach/time.h>
+
+/*!
+ * GPT register address definitions
+ */
+#define GPT_BASE_ADDR (IO_ADDRESS(GPT1_BASE_ADDR))
+#define MXC_GPT_GPTCR (GPT_BASE_ADDR + 0x00)
+#define MXC_GPT_GPTPR (GPT_BASE_ADDR + 0x04)
+#define MXC_GPT_GPTOCR1 (GPT_BASE_ADDR + 0x08)
+#define MXC_GPT_GPTICR1 (GPT_BASE_ADDR + 0x0C)
+#define MXC_GPT_GPTCNT (GPT_BASE_ADDR + 0x10)
+#define MXC_GPT_GPTSR (GPT_BASE_ADDR + 0x14)
+
+/*!
+ * GPT Control register bit definitions
+ */
+#define GPTCR_COMPEN (1 << 4)
+#define GPTCR_SWR (1 << 15)
+#define GPTCR_FRR (1 << 8)
+
+#define GPTCR_CLKSRC_SHIFT 1
+#define GPTCR_CLKSRC_MASK (7 << GPTCR_CLKSRC_SHIFT)
+#define GPTCR_CLKSRC_NOCLOCK (0 << GPTCR_CLKSRC_SHIFT)
+#define GPTCR_CLKSRC_HIGHFREQ (1 << GPTCR_CLKSRC_SHIFT)
+#define GPTCR_CLKSRC_CLKIN (3 << GPTCR_CLKSRC_SHIFT)
+#define GPTCR_CLKSRC_CLK32K (4 << GPTCR_CLKSRC_SHIFT)
+
+#define GPTCR_ENABLE (1 << 0)
+
+#define GPTSR_OF1 (1 << 0)
+
+extern unsigned long clk_early_get_timer_rate(void);
+
+static int mxc_gpt_set_next_event(unsigned long cycles,
+ struct clock_event_device *evt)
+{
+ unsigned long now, expires;
+ u32 reg;
+
+ now = __raw_readl(MXC_GPT_GPTCNT);
+ expires = now + cycles;
+ __raw_writel(expires, MXC_GPT_GPTOCR1);
+ __raw_writel(GPTSR_OF1, MXC_GPT_GPTSR);
+
+ /* enable interrupt */
+ reg = __raw_readl(MXC_GPT_GPTCR);
+ reg |= GPTCR_COMPEN;
+ __raw_writel(reg, MXC_GPT_GPTCR);
+
+ return 0;
+}
+
+static void mxc_gpt_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ u32 reg;
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ panic("MXC GPT: CLOCK_EVT_MODE_PERIODIC not supported\n");
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ break;
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ /* Disable interrupts */
+ reg = __raw_readl(MXC_GPT_GPTCR);
+ reg &= ~GPTCR_COMPEN;
+ __raw_writel(reg, MXC_GPT_GPTCR);
+ break;
+ case CLOCK_EVT_MODE_RESUME:
+ break;
+ }
+}
+
+static struct clock_event_device gpt_clockevent = {
+ .name = "mxc_gpt",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 300,
+ .shift = 32,
+ .set_next_event = mxc_gpt_set_next_event,
+ .set_mode = mxc_gpt_set_mode,
+};
+
+/*!
+ * This is the timer interrupt service routine to do required tasks.
+ * It also services the WDOG timer at the frequency of twice per WDOG
+ * timeout value. For example, if the WDOG's timeout value is 4 (2
+ * seconds since the WDOG runs at 0.5Hz), it will be serviced once
+ * every 2/2=1 second.
+ *
+ * @param irq GPT interrupt source number (not used)
+ * @param dev_id this parameter is not used
+ * @return always returns \b IRQ_HANDLED as defined in
+ * include/linux/interrupt.h.
+ */
+static irqreturn_t mxc_timer_interrupt(int irq, void *dev_id)
+{
+ unsigned int gptsr;
+ u32 reg;
+
+ gptsr = __raw_readl(MXC_GPT_GPTSR);
+ if (gptsr & GPTSR_OF1) {
+ /* Disable interrupt */
+ reg = __raw_readl(MXC_GPT_GPTCR);
+ reg &= ~GPTCR_COMPEN;
+ __raw_writel(reg, MXC_GPT_GPTCR);
+ /* Clear interrupt */
+ __raw_writel(GPTSR_OF1, MXC_GPT_GPTSR);
+
+ gpt_clockevent.event_handler(&gpt_clockevent);
+ }
+
+ return IRQ_HANDLED;
+}
+
+/*!
+ * The clockevents timer interrupt structure.
+ */
+static struct irqaction timer_irq = {
+ .name = "gpt-irq",
+ .flags = IRQF_DISABLED,
+ .handler = mxc_timer_interrupt,
+};
+
+static cycle_t __xipram mxc_gpt_read(void)
+{
+ return __raw_readl(MXC_GPT_GPTCNT);
+}
+
+static struct clocksource gpt_clocksrc = {
+ .name = "mxc_gpt",
+ .rating = 300,
+ .read = mxc_gpt_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 24,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS | CLOCK_SOURCE_VALID_FOR_HRES,
+};
+
+/*!
+ * This function is used to initialize the GPT as a clocksource and clockevent.
+ * It is called by the start_kernel() during system startup.
+ */
+void __init mxc_init_time(void)
+{
+ int ret;
+ unsigned long rate;
+ u32 reg, div;
+
+ /* Reset GPT */
+ __raw_writel(GPTCR_SWR, MXC_GPT_GPTCR);
+ while ((__raw_readl(MXC_GPT_GPTCR) & GPTCR_SWR) != 0)
+ mb();
+
+ /* Normal clk api are not yet initialized, so use early verion */
+ rate = clk_early_get_timer_rate();
+ if (rate == 0)
+ panic("MXC GPT: Can't get timer clock rate\n");
+
+#ifdef CLOCK_TICK_RATE
+ div = rate / CLOCK_TICK_RATE;
+ WARN_ON((div * CLOCK_TICK_RATE) != rate);
+#else /* Hopefully CLOCK_TICK_RATE will go away soon */
+ div = 1;
+ while ((rate / div) > 20000000) {
+ div++;
+ }
+#endif
+ rate /= div;
+ __raw_writel(div - 1, MXC_GPT_GPTPR);
+
+ reg = GPTCR_FRR | GPTCR_CLKSRC_HIGHFREQ | GPTCR_ENABLE;
+ __raw_writel(reg, MXC_GPT_GPTCR);
+
+ gpt_clocksrc.mult = clocksource_hz2mult(rate, gpt_clocksrc.shift);
+ ret = clocksource_register(&gpt_clocksrc);
+ if (ret < 0) {
+ goto err;
+ }
+
+ gpt_clockevent.mult = div_sc(rate, NSEC_PER_SEC, gpt_clockevent.shift);
+ gpt_clockevent.max_delta_ns = clockevent_delta2ns(-1, &gpt_clockevent);
+ gpt_clockevent.min_delta_ns = clockevent_delta2ns(1, &gpt_clockevent);
+
+ gpt_clockevent.cpumask = cpumask_of_cpu(0);
+ clockevents_register_device(&gpt_clockevent);
+
+ ret = setup_irq(MXC_INT_GPT, &timer_irq);
+ if (ret < 0) {
+ goto err;
+ }
+
+ pr_info("MXC GPT timer initialized, rate = %lu\n", rate);
+ return;
+ err:
+ panic("Unable to initialize timer\n");
+}
+
+struct sys_timer mxc_timer = {
+ .init = mxc_init_time,
+};
diff --git a/arch/arm/mach-mx27/usb.h b/arch/arm/mach-mx27/usb.h
new file mode 100644
index 000000000000..7824814a6ecd
--- /dev/null
+++ b/arch/arm/mach-mx27/usb.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2005-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+
+extern int usbotg_init(struct platform_device *pdev);
+extern void usbotg_uninit(struct fsl_usb2_platform_data *pdata);
+extern int gpio_usbotg_fs_active(void);
+extern void gpio_usbotg_fs_inactive(void);
+extern int gpio_usbotg_hs_active(void);
+extern void gpio_usbotg_hs_inactive(void);
+extern struct platform_device *host_pdev_register(struct resource *res,
+ int n_res, struct fsl_usb2_platform_data *config);
+
+extern int fsl_usb_host_init(struct platform_device *pdev);
+extern void fsl_usb_host_uninit(struct fsl_usb2_platform_data *pdata);
+extern int gpio_usbh1_active(void);
+extern void gpio_usbh1_inactive(void);
+extern int gpio_usbh2_active(void);
+extern void gpio_usbh2_inactive(void);
+
+/*
+ * Determine which platform_data struct to use, based on which
+ * transceiver is configured.
+ * PDATA is a pointer to it.
+ */
+#if defined(CONFIG_ISP1504_MXC)
+static struct fsl_usb2_platform_data __maybe_unused dr_1504_config;
+#define PDATA (&dr_1504_config)
+#elif defined(CONFIG_ISP1301_MXC)
+static struct fsl_usb2_platform_data __maybe_unused dr_1301_config;
+#define PDATA (&dr_1301_config)
+#elif defined(CONFIG_MC13783_MXC)
+static struct fsl_usb2_platform_data __maybe_unused dr_13783_config;
+#define PDATA (&dr_13783_config)
+#endif
+
+
+/*
+ * Used to set pdata->operating_mode before registering the platform_device.
+ * If OTG is configured, the controller operates in OTG mode,
+ * otherwise it's either host or device.
+ */
+#ifdef CONFIG_USB_OTG
+#define DR_UDC_MODE FSL_USB2_DR_OTG
+#define DR_HOST_MODE FSL_USB2_DR_OTG
+#else
+#define DR_UDC_MODE FSL_USB2_DR_DEVICE
+#define DR_HOST_MODE FSL_USB2_DR_HOST
+#endif
+
+
+#ifdef CONFIG_USB_EHCI_ARC_OTG
+static inline void dr_register_host(struct resource *r, int rs)
+{
+ PDATA->operating_mode = DR_HOST_MODE;
+ host_pdev_register(r, rs, PDATA);
+}
+#else
+static inline void dr_register_host(struct resource *r, int rs)
+{
+}
+#endif
+
+#ifdef CONFIG_USB_GADGET_ARC
+static struct platform_device dr_udc_device;
+
+static inline void dr_register_udc(void)
+{
+ PDATA->operating_mode = DR_UDC_MODE;
+ dr_udc_device.dev.platform_data = PDATA;
+
+ if (platform_device_register(&dr_udc_device))
+ printk(KERN_ERR "usb: can't register DR gadget\n");
+ else
+ printk(KERN_INFO "usb: DR gadget (%s) registered\n",
+ PDATA->transceiver);
+}
+#else
+static inline void dr_register_udc(void)
+{
+}
+#endif
+
+#ifdef CONFIG_USB_OTG
+static struct platform_device dr_otg_device;
+
+/*
+ * set the proper operating_mode and
+ * platform_data pointer, then register the
+ * device.
+ */
+static inline void dr_register_otg(void)
+{
+ PDATA->operating_mode = FSL_USB2_DR_OTG;
+ dr_otg_device.dev.platform_data = PDATA;
+
+ if (platform_device_register(&dr_otg_device))
+ printk(KERN_ERR "usb: can't register otg device\n");
+ else
+ printk(KERN_INFO "usb: DR OTG registered\n");
+}
+#else
+static inline void dr_register_otg(void)
+{
+}
+#endif
diff --git a/arch/arm/mach-mx27/usb_dr.c b/arch/arm/mach-mx27/usb_dr.c
new file mode 100644
index 000000000000..e67bee726412
--- /dev/null
+++ b/arch/arm/mach-mx27/usb_dr.c
@@ -0,0 +1,126 @@
+#define DEBUG
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <mach/arc_otg.h>
+#include "usb.h"
+
+/*
+ * platform data structs
+ * - Which one to use is determined by CONFIG options in usb.h
+ * - operating_mode plugged at run time
+ */
+static struct fsl_usb2_platform_data __maybe_unused dr_13783_config = {
+ .name = "DR",
+ .platform_init = usbotg_init,
+ .platform_uninit = usbotg_uninit,
+ .phy_mode = FSL_USB2_PHY_SERIAL,
+ .power_budget = 500, /* 500 mA max power */
+ .gpio_usb_active = gpio_usbotg_fs_active,
+ .gpio_usb_inactive = gpio_usbotg_fs_inactive,
+ .transceiver = "mc13783",
+};
+
+static struct fsl_usb2_platform_data __maybe_unused dr_1301_config = {
+ .name = "DR",
+ .platform_init = usbotg_init,
+ .platform_uninit = usbotg_uninit,
+ .phy_mode = FSL_USB2_PHY_SERIAL,
+ .power_budget = 500, /* 500 mA max power */
+ .gpio_usb_active = gpio_usbotg_fs_active,
+ .gpio_usb_inactive = gpio_usbotg_fs_inactive,
+ .transceiver = "isp1301",
+};
+
+static struct fsl_usb2_platform_data __maybe_unused dr_1504_config = {
+ .name = "DR",
+ .platform_init = usbotg_init,
+ .platform_uninit = usbotg_uninit,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+ .power_budget = 500, /* 500 mA max power */
+ .gpio_usb_active = gpio_usbotg_hs_active,
+ .gpio_usb_inactive = gpio_usbotg_hs_inactive,
+ .transceiver = "isp1504",
+};
+
+
+/*
+ * resources
+ */
+static struct resource otg_resources[] = {
+ [0] = {
+ .start = (u32)(USB_OTGREGS_BASE),
+ .end = (u32)(USB_OTGREGS_BASE + 0x1ff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_USB3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+static u64 dr_udc_dmamask = ~(u32) 0;
+static void dr_udc_release(struct device *dev)
+{
+}
+
+static u64 dr_otg_dmamask = ~(u32) 0;
+static void dr_otg_release(struct device *dev)
+{
+}
+
+/*
+ * platform device structs
+ * dev.platform_data field plugged at run time
+ */
+static struct platform_device __maybe_unused dr_udc_device = {
+ .name = "fsl-usb2-udc",
+ .id = -1,
+ .dev = {
+ .release = dr_udc_release,
+ .dma_mask = &dr_udc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .resource = otg_resources,
+ .num_resources = ARRAY_SIZE(otg_resources),
+};
+
+static struct platform_device __maybe_unused dr_otg_device = {
+ .name = "fsl-usb2-otg",
+ .id = -1,
+ .dev = {
+ .release = dr_otg_release,
+ .dma_mask = &dr_otg_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .resource = otg_resources,
+ .num_resources = ARRAY_SIZE(otg_resources),
+};
+
+static int __init usb_dr_init(void)
+{
+ pr_debug("%s: \n", __func__);
+
+ dr_register_otg();
+ dr_register_host(otg_resources, ARRAY_SIZE(otg_resources));
+ dr_register_udc();
+
+ return 0;
+}
+
+module_init(usb_dr_init);
diff --git a/arch/arm/mach-mx27/usb_h1.c b/arch/arm/mach-mx27/usb_h1.c
new file mode 100644
index 000000000000..5c6c9c59fb3b
--- /dev/null
+++ b/arch/arm/mach-mx27/usb_h1.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <mach/arc_otg.h>
+#include "usb.h"
+
+static struct fsl_usb2_platform_data usbh1_config = {
+ .name = "Host 1",
+ .platform_init = fsl_usb_host_init,
+ .platform_uninit = fsl_usb_host_uninit,
+ .operating_mode = FSL_USB2_MPH_HOST,
+ .phy_mode = FSL_USB2_PHY_SERIAL,
+ .power_budget = 500, /* 500 mA max power */
+ .gpio_usb_active = gpio_usbh1_active,
+ .gpio_usb_inactive = gpio_usbh1_inactive,
+ .transceiver = "serial",
+};
+
+static struct resource usbh1_resources[] = {
+ [0] = {
+ .start = (u32) (USB_H1REGS_BASE),
+ .end = (u32) (USB_H1REGS_BASE + 0x1ff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_USB1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static int __init usbh1_init(void)
+{
+ pr_debug("%s: \n", __func__);
+
+ host_pdev_register(usbh1_resources, ARRAY_SIZE(usbh1_resources),
+ &usbh1_config);
+ return 0;
+}
+module_init(usbh1_init);
diff --git a/arch/arm/mach-mx27/usb_h2.c b/arch/arm/mach-mx27/usb_h2.c
new file mode 100644
index 000000000000..028941a7b47c
--- /dev/null
+++ b/arch/arm/mach-mx27/usb_h2.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <mach/arc_otg.h>
+#include "usb.h"
+
+static struct fsl_usb2_platform_data usbh2_config = {
+ .name = "Host 2",
+ .platform_init = fsl_usb_host_init,
+ .platform_uninit = fsl_usb_host_uninit,
+ .operating_mode = FSL_USB2_MPH_HOST,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+ .power_budget = 500, /* 500 mA max power */
+ .gpio_usb_active = gpio_usbh2_active,
+ .gpio_usb_inactive = gpio_usbh2_inactive,
+ .transceiver = "isp1504",
+};
+
+static struct resource usbh2_resources[] = {
+ [0] = {
+ .start = (u32) (USB_H2REGS_BASE),
+ .end = (u32) (USB_H2REGS_BASE + 0x1ff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_USB2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static int __init usbh2_init(void)
+{
+ pr_debug("%s: \n", __func__);
+
+ host_pdev_register(usbh2_resources, ARRAY_SIZE(usbh2_resources),
+ &usbh2_config);
+ return 0;
+}
+module_init(usbh2_init);
diff --git a/arch/arm/mach-mx3/Kconfig b/arch/arm/mach-mx3/Kconfig
index db9431dee1b4..99050de3f860 100644
--- a/arch/arm/mach-mx3/Kconfig
+++ b/arch/arm/mach-mx3/Kconfig
@@ -1,9 +1,19 @@
menu "MX3 Options"
depends on ARCH_MX3
+config MX3_OPTIONS
+ bool
+ default y
+ select CPU_V6
+ select ARM_ERRATA_364296
+ select ARM_ERRATA_411920
+ select CACHE_L2X0
+ select OUTER_CACHE
+ select USB_ARCH_HAS_EHCI
+ select ARCH_HAS_EVTMON
+
config MACH_MX31ADS
bool "Support MX31ADS platforms"
- default y
help
Include support for MX31ADS platform. This includes specific
configurations for the board and its peripherals.
@@ -16,10 +26,85 @@ config MACH_PCM037
config MACH_MX31LITE
bool "Support MX31 LITEKIT (LogicPD)"
- default n
+
+config MACH_MX31_3DS
+ bool "Support MX31/MX32 3-Stack platforms"
help
- Include support for MX31 LITEKIT platform. This includes specific
+ Include support for MX31/MX32 3-Stack platform. This includes specific
configurations for the board and its peripherals.
+config MX3_DOZE_DURING_IDLE
+ bool "Enter Doze mode during idle"
+ help
+ Turning on this option will put the CPU into Doze mode during idle.
+ The default is to enter Wait mode during idle. Doze mode during
+ idle will save additional power over Wait mode.
+
+config MXC_SDMA_API
+ bool "Use SDMA API"
+ default y
+ help
+ This selects the Freescale MXC SDMA API.
+ If unsure, say N.
+
+menu "SDMA options"
+ depends on MXC_SDMA_API
+
+config SDMA_IRAM
+ bool "Use Internal RAM for SDMA transfer"
+ default n
+ help
+ Support Internal RAM as SDMA buffer or control structures
+
+config SDMA_IRAM_SIZE
+ hex "Reserved bytes of IRAM for SDMA (0x800-0x2000)"
+ range 0x800 0x2000
+ depends on SDMA_IRAM
+ default "0x1000"
+ help
+ Set the size of IRAM for SDMA. It must be multiple of 512bytes.
+endmenu
+
+config ARCH_MXC_HAS_NFC_V1
+ bool "MXC NFC Hardware Version 1"
+ depends on !(MACH_MX31ADS && XIP_KERNEL)
+ default y
+ help
+ This selects the Freescale MXC Nand Flash Controller Hardware Version 1
+ If unsure, say N.
+
+config ARCH_MXC_HAS_NFC_V2
+ bool "MXC NFC Hardware Version 2"
+ depends on !(MACH_MX31ADS && XIP_KERNEL)
+ default y
+ help
+ This selects the Freescale MXC Nand Flash Controller Hardware Version 2
+ If unsure, say N.
+
+menu "Device options"
+
+config I2C_MXC_SELECT1
+ bool "Enable I2C1 module"
+ default y
+ depends on I2C_MXC
+ help
+ Enable MX31 I2C1 module.
+
+config I2C_MXC_SELECT2
+ bool "Enable I2C2 module"
+ default n
+ depends on I2C_MXC
+ help
+ Enable MX31 I2C2 module.
+
+config I2C_MXC_SELECT3
+ bool "Enable I2C3 module"
+ default n
+ depends on I2C_MXC
+ help
+ Enable MX31 I2C3 module.
+
+endmenu
+
endmenu
diff --git a/arch/arm/mach-mx3/Makefile b/arch/arm/mach-mx3/Makefile
index 8b21abb71fb0..9e9c2744bf94 100644
--- a/arch/arm/mach-mx3/Makefile
+++ b/arch/arm/mach-mx3/Makefile
@@ -4,7 +4,19 @@
# Object file lists.
-obj-y := mm.o clock.o devices.o iomux.o
-obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o
+obj-y := system.o iomux.o cpu.o mm.o clock.o dptc.o devices.o serial.o dma.o mxc_pm.o dvfs_v2.o
+obj-$(CONFIG_MACH_MX31ADS) += mx31ads.o mx31ads_gpio.o
obj-$(CONFIG_MACH_MX31LITE) += mx31lite.o
obj-$(CONFIG_MACH_PCM037) += pcm037.o
+obj-$(CONFIG_MACH_MX31_3DS) += mx3_3stack.o mx3_3stack_gpio.o
+
+# power management
+obj-$(CONFIG_PM) += pm.o
+
+obj-$(CONFIG_USB_EHCI_ARC_H1) += usb_h1.o
+obj-$(CONFIG_USB_EHCI_ARC_H2) += usb_h2.o
+
+ifneq ($(strip $(CONFIG_USB_GADGET_ARC) $(CONFIG_USB_EHCI_ARC_OTG)),)
+ obj-y += usb_dr.o
+endif
+
diff --git a/arch/arm/mach-mx3/board-mx31ads.h b/arch/arm/mach-mx3/board-mx31ads.h
new file mode 100644
index 000000000000..ac4bbb278a48
--- /dev/null
+++ b/arch/arm/mach-mx3/board-mx31ads.h
@@ -0,0 +1,326 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX31ADS_H__
+#define __ASM_ARCH_MXC_BOARD_MX31ADS_H__
+
+#ifdef CONFIG_MACH_MX31ADS
+/*!
+ * @defgroup BRDCFG_MX31 Board Configuration Options
+ * @ingroup MSL_MX31
+ */
+
+/*!
+ * @file mach-mx3/board-mx31ads.h
+ *
+ * @brief This file contains all the board level configuration options.
+ *
+ * It currently hold the options defined for MX31 ADS Platform.
+ *
+ * @ingroup BRDCFG_MX31
+ */
+
+/*
+ * Include Files
+ */
+#include <mach/mxc_uart.h>
+
+/*!
+ * @name MXC UART EVB board level configurations
+ */
+/*! @{ */
+/*!
+ * Specifies if the Irda transmit path is inverting
+ */
+#define MXC_IRDA_TX_INV 0
+/*!
+ * Specifies if the Irda receive path is inverting
+ */
+#define MXC_IRDA_RX_INV 0
+
+/* UART 1 configuration */
+/*!
+ * This define specifies if the UART port is configured to be in DTE or
+ * DCE mode. There exists a define like this for each UART port. Valid
+ * values that can be used are \b MODE_DTE or \b MODE_DCE.
+ */
+#define UART1_MODE MODE_DCE
+/*!
+ * This define specifies if the UART is to be used for IRDA. There exists a
+ * define like this for each UART port. Valid values that can be used are
+ * \b IRDA or \b NO_IRDA.
+ */
+#define UART1_IR NO_IRDA
+/*!
+ * This define is used to enable or disable a particular UART port. If
+ * disabled, the UART will not be registered in the file system and the user
+ * will not be able to access it. There exists a define like this for each UART
+ * port. Specify a value of 1 to enable the UART and 0 to disable it.
+ */
+#define UART1_ENABLED 1
+/*! @} */
+/* UART 2 configuration */
+#define UART2_MODE MODE_DCE
+#define UART2_IR IRDA
+#ifdef CONFIG_MXC_FIR_MODULE
+#define UART2_ENABLED 0
+#else
+#define UART2_ENABLED 1
+#endif
+/* UART 3 configuration */
+#define UART3_MODE MODE_DTE
+#define UART3_IR NO_IRDA
+#define UART3_ENABLED 1
+/* UART 4 configuration */
+#define UART4_MODE MODE_DTE
+#define UART4_IR NO_IRDA
+#define UART4_ENABLED 0 /* Disable UART 4 as its pins are shared with ATA */
+/* UART 5 configuration */
+#define UART5_MODE MODE_DTE
+#define UART5_IR NO_IRDA
+#define UART5_ENABLED 1
+
+#define MXC_LL_EXTUART_PADDR (CS4_BASE_ADDR + 0x10000)
+#define MXC_LL_EXTUART_VADDR CS4_IO_ADDRESS(MXC_LL_EXTUART_PADDR)
+#undef MXC_LL_EXTUART_16BIT_BUS
+
+#define MXC_LL_UART_PADDR UART1_BASE_ADDR
+#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
+
+/*!
+ * @name PBC Controller parameters
+ */
+/*! @{ */
+/*!
+ * Base address of PBC controller
+ */
+#define PBC_BASE_ADDRESS IO_ADDRESS(CS4_BASE_ADDR)
+/* Offsets for the PBC Controller register */
+/*!
+ * PBC Board status register offset
+ */
+#define PBC_BSTAT 0x000002
+/*!
+ * PBC Board control register 1 set address.
+ */
+#define PBC_BCTRL1_SET 0x000004
+/*!
+ * PBC Board control register 1 clear address.
+ */
+#define PBC_BCTRL1_CLEAR 0x000006
+/*!
+ * PBC Board control register 2 set address.
+ */
+#define PBC_BCTRL2_SET 0x000008
+/*!
+ * PBC Board control register 2 clear address.
+ */
+#define PBC_BCTRL2_CLEAR 0x00000A
+/*!
+ * PBC Board control register 3 set address.
+ */
+#define PBC_BCTRL3_SET 0x00000C
+/*!
+ * PBC Board control register 3 clear address.
+ */
+#define PBC_BCTRL3_CLEAR 0x00000E
+/*!
+ * PBC Board control register 4 set address.
+ */
+#define PBC_BCTRL4_SET 0x000010
+/*!
+ * PBC Board control register 4 clear address.
+ */
+#define PBC_BCTRL4_CLEAR 0x000012
+/*!
+ * PBC Board status register 1.
+ */
+#define PBC_BSTAT1 0x000014
+/*!
+ * PBC Board interrupt status register.
+ */
+#define PBC_INTSTATUS 0x000016
+/*!
+ * PBC Board interrupt current status register.
+ */
+#define PBC_INTCURR_STATUS 0x000018
+/*!
+ * PBC Interrupt mask register set address.
+ */
+#define PBC_INTMASK_SET 0x00001A
+/*!
+ * PBC Interrupt mask register clear address.
+ */
+#define PBC_INTMASK_CLEAR 0x00001C
+
+/*!
+ * External UART A.
+ */
+#define PBC_SC16C652_UARTA 0x010000
+/*!
+ * External UART B.
+ */
+#define PBC_SC16C652_UARTB 0x010010
+/*!
+ * Ethernet Controller IO base address.
+ */
+#define PBC_CS8900A_IOBASE 0x020000
+/*!
+ * Ethernet Controller Memory base address.
+ */
+#define PBC_CS8900A_MEMBASE 0x021000
+/*!
+ * Ethernet Controller DMA base address.
+ */
+#define PBC_CS8900A_DMABASE 0x022000
+/*!
+ * External chip select 0.
+ */
+#define PBC_XCS0 0x040000
+/*!
+ * LCD Display enable.
+ */
+#define PBC_LCD_EN_B 0x060000
+/*!
+ * Code test debug enable.
+ */
+#define PBC_CODE_B 0x070000
+/*!
+ * PSRAM memory select.
+ */
+#define PBC_PSRAM_B 0x5000000
+
+/* PBC Board Status Register 1 bit definitions */
+#define PBC_BSTAT1_NF_DET 0x0001 /* NAND flash card. 0 = connected */
+#define PBC_BSTAT1_KP_ON 0x0002 /* KPP board. 0 = connected */
+#define PBC_BSTAT1_LS 0x0004 /* KPP:LightSense signal */
+#define PBC_BSTAT1_ATA_IOCS16 0x0008 /* ATA_IOCS16 signal */
+#define PBC_BSTAT1_ATA_CBLID 0x0010 /* ATA_CBLID signal */
+#define PBC_BSTAT1_ATA_DASP 0x0020 /* ATA_DASP signal */
+#define PBC_BSTAT1_PWR_RDY 0x0040 /* MC13783 power. 1 = ready */
+#define PBC_BSTAT1_SD1_WP 0x0080 /* 0 = SD1 card is write protected */
+#define PBC_BSTAT1_SD2_WP 0x0100 /* 0 = SD2 card is write protected */
+#define PBC_BSTAT1_FS1 0x0200 /* KPP:FlipSense1 signal */
+#define PBC_BSTAT1_FS2 0x0400 /* KPP:FlipSense2 signal */
+#define PBC_BSTAT1_PTT 0x0800 /* KPP:PTT signal */
+#define PBC_BSTAT1_MC13783_IN 0x1000 /* MC13783 board. 0 = connected. */
+
+/* PBC Board Control Register 1 bit definitions */
+#define PBC_BCTRL1_ERST 0x0001 /* Ethernet Reset */
+#define PBC_BCTRL1_URST 0x0002 /* Reset External UART controller */
+#define PBC_BCTRL1_UENA 0x0004 /* Enable UART A transceiver */
+#define PBC_BCTRL1_UENB 0x0008 /* Enable UART B transceiver */
+#define PBC_BCTRL1_UENCE 0x0010 /* Enable UART CE transceiver */
+#define PBC_BCTRL1_IREN 0x0020 /* Enable the IRDA transmitter */
+#define PBC_BCTRL1_LED0 0x0040 /* Used to control LED 0 (green) */
+#define PBC_BCTRL1_LED1 0x0080 /* Used to control LED 1 (yellow) */
+#define PBC_BCTRL1_SENSOR1_ON 0x0600 /* Enable Sensor 1 */
+#define PBC_BCTRL1_SENSOR2_ON 0x3000 /* Enable Sensor 2 */
+#define PBC_BCTRL1_BEND 0x4000 /* Big Endian Select */
+#define PBC_BCTRL1_LCDON 0x8000 /* Enable the LCD */
+
+/* PBC Board Control Register 2 bit definitions */
+#define PBC_BCTRL2_USELA 0x0001 /* UART A Select, 0 = UART1, 1 = UART5 */
+#define PBC_BCTRL2_USELB 0x0002 /* UART B Select, 0 = UART3, 1 = UART5 */
+#define PBC_BCTRL2_USELC 0x0004 /* UART C Select, 0 = UART2, 1 = UART1 */
+#define PBC_BCTRL2_UMODENA 0x0008 /* UART A Modem Signals Enable, 0 = enabled */
+#define PBC_BCTRL2_UMODENC 0x0008 /* UART C Modem Signals Enable, 0 = enabled */
+#define PBC_BCTRL2_CSI_EN 0x0020 /* Enable the CSI interface, 0 = enabled */
+#define PBC_BCTRL2_ATA_EN 0x0040 /* Enable the ATA interface, 0 = enabled */
+#define PBC_BCTRL2_ATA_SEL 0x0080 /* ATA Select, 0 = group A, 1 = group B */
+#define PBC_BCTRL2_IRDA_MOD 0x0100 /* IRDA Mode (see CPLD spec) */
+#define PBC_BCTRL2_LDC_RST0 0x0200 /* LCD 0 Reset, 1 = reset signal asserted */
+#define PBC_BCTRL2_LDC_RST1 0x0400 /* LCD 1 Reset, 1 = reset signal asserted */
+#define PBC_BCTRL2_LDC_RST2 0x0800 /* LCD 2 Reset, 1 = reset signal asserted */
+#define PBC_BCTRL2_LDCIO_EN 0x1000 /* LCD GPIO Enable, 0 = enabled */
+#define PBC_BCTRL2_CT_CS 0x2000 /* Code Test Chip Select, = Code Test selected */
+#define PBC_BCTRL2_VPP_EN 0x4000 /* PCMCIA VPP Enable, 1 = power on */
+#define PBC_BCTRL2_VCC_EN 0x8000 /* PCMCIA VCC Enable, 1 = power on */
+
+/* PBC Board Control Register 3 bit definitions */
+#define PBC_BCTRL3_OTG_FS_SEL 0x0001 /* USB OTG Full Speed Select, 0 = PMIC, 1 = CPU */
+#define PBC_BCTRL3_OTG_FS_EN 0x0002 /* USB OTG Full Speed Enable, 0 = enabled */
+#define PBC_BCTRL3_FSH_SEL 0x0004 /* USB Full Speed Host Select, 0 = Group A, 1 = Group B */
+#define PBC_BCTRL3_FSH_EN 0x0008 /* USB Full Speed Host Enable, 0 = enabled */
+#define PBC_BCTRL3_HSH_SEL 0x0010 /* USB High Speed Host Select, 0 = Group A, 1 = Group B */
+#define PBC_BCTRL3_HSH_EN 0x0020 /* USB High Speed Host Enable, 0 = enabled */
+#define PBC_BCTRL3_FSH_MOD 0x0040 /* USB Full Speed Host Mode, 0 = Differential, 1 = Single ended */
+#define PBC_BCTRL3_OTG_HS_EN 0x0080 /* USB OTG High Speed Enable, 0 = enabled */
+#define PBC_BCTRL3_OTG_VBUS_EN 0x0100 /* USB OTG VBUS Regulator Enable, 0 = enabled */
+#define PBC_BCTRL3_FSH_VBUS_EN 0x0200 /* USB Full Speed Host VBUS Regulator Enable, 0 = enabled */
+#define PBC_BCTRL3_CARD1_SEL 0x0400 /* Card1 Select, 0 = SD1, 1 = MS1 */
+#define PBC_BCTRL3_CARD2_SEL 0x0800 /* Card2 Select, 0 = PCMCIA & SD2, 1 = MS2 */
+#define PBC_BCTRL3_SYNTH_RST 0x1000 /* Audio Synthesizer Reset, 0 = reset asserted */
+#define PBC_BCTRL3_VSIM_EN 0x2000 /* VSIM Regulator Enable, 1 = enabled */
+#define PBC_BCTRL3_VESIM_EN 0x4000 /* VESIM Regulator Enable, 1 = enabled */
+#define PBC_BCTRL3_SPI3_RESET 0x8000 /* CSPI3 Connector Reset, 0 = reset asserted */
+
+/* PBC Board Control Register 4 bit definitions */
+#define PBC_BCTRL4_CSI_MSB_EN 0x0001 /* CSI MSB Enable, 0 = CSI_Data[3:0] enabled */
+#define PBC_BCTRL4_REGEN_SEL 0x0002 /* Regulator Enable Select, 0 = enabled */
+#define PBC_BCTRL4_USER_OFF 0x0004 /* User Off Indication, 1 = user off confirmation */
+#define PBC_BCTRL4_VIB_EN 0x0008 /* Vibrator Enable, 1 = enabled */
+#define PBC_BCTRL4_PCMCIA_EN 0x0010 /* PCMCIA Enable, 0 = buffer enabled */
+
+#define CKIH_27MHZ_BIT_SET (1 << 4)
+
+#define PBC_INT_CS8900A 4
+/*! @} */
+
+#define PBC_INTSTATUS_REG (PBC_INTSTATUS + PBC_BASE_ADDRESS)
+#define PBC_INTCURR_STATUS_REG (PBC_INTCURR_STATUS + PBC_BASE_ADDRESS)
+#define PBC_INTMASK_SET_REG (PBC_INTMASK_SET + PBC_BASE_ADDRESS)
+#define PBC_INTMASK_CLEAR_REG (PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS)
+#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_4)
+
+#define EXPIO_INT_LOW_BAT (MXC_EXP_IO_BASE + 0)
+#define EXPIO_INT_PB_IRQ (MXC_EXP_IO_BASE + 1)
+#define EXPIO_INT_OTG_FS_OVR (MXC_EXP_IO_BASE + 2)
+#define EXPIO_INT_FSH_OVR (MXC_EXP_IO_BASE + 3)
+#define EXPIO_INT_RES4 (MXC_EXP_IO_BASE + 4)
+#define EXPIO_INT_RES5 (MXC_EXP_IO_BASE + 5)
+#define EXPIO_INT_RES6 (MXC_EXP_IO_BASE + 6)
+#define EXPIO_INT_RES7 (MXC_EXP_IO_BASE + 7)
+#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 8)
+#define EXPIO_INT_OTG_FS_INT (MXC_EXP_IO_BASE + 9)
+#define EXPIO_INT_XUART_INTA (MXC_EXP_IO_BASE + 10)
+#define EXPIO_INT_XUART_INTB (MXC_EXP_IO_BASE + 11)
+#define EXPIO_INT_SYNTH_IRQ (MXC_EXP_IO_BASE + 12)
+#define EXPIO_INT_CE_INT1 (MXC_EXP_IO_BASE + 13)
+#define EXPIO_INT_CE_INT2 (MXC_EXP_IO_BASE + 14)
+#define EXPIO_INT_RES15 (MXC_EXP_IO_BASE + 15)
+
+/*!
+ * @name Defines Base address and IRQ used for CS8900A Ethernet Controller on MXC Boards
+ */
+/*! @{*/
+/*! This is System IRQ used by CS8900A for interrupt generation taken from platform.h */
+#define CS8900AIRQ EXPIO_INT_ENET_INT
+/*! This is I/O Base address used to access registers of CS8900A on MXC ADS */
+#define CS8900A_BASE_ADDRESS (PBC_BASE_ADDRESS + PBC_CS8900A_IOBASE + 0x300)
+/*! @} */
+
+#define MXC_PMIC_INT_LINE IOMUX_TO_IRQ(MX31_PIN_GPIO1_3)
+
+#define AHB_FREQ 133000000
+#define IPG_FREQ 66500000
+
+#define MXC_BD_LED1 (1 << 6)
+#define MXC_BD_LED2 (1 << 7)
+#define MXC_BD_LED_ON(led) \
+ __raw_writew(led, PBC_BASE_ADDRESS + PBC_BCTRL1_SET)
+#define MXC_BD_LED_OFF(led) \
+ __raw_writew(led, PBC_BASE_ADDRESS + PBC_BCTRL1_CLEAR)
+
+#endif /* CONFIG_MACH_MX31ADS */
+#endif /* __ASM_ARCH_MXC_BOARD_MX31ADS_H__ */
diff --git a/arch/arm/mach-mx3/board-mx3_3stack.h b/arch/arm/mach-mx3/board-mx3_3stack.h
new file mode 100644
index 000000000000..480cf25223f1
--- /dev/null
+++ b/arch/arm/mach-mx3/board-mx3_3stack.h
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX31PDK_H__
+#define __ASM_ARCH_MXC_BOARD_MX31PDK_H__
+
+#ifdef CONFIG_MACH_MX31_3DS
+/*!
+ * @defgroup BRDCFG_MX31 Board Configuration Options
+ * @ingroup MSL_MX31
+ */
+
+/*!
+ * @file mach-mx3/board-mx3_3stack.h
+ *
+ * @brief This file contains all the board level configuration options.
+ *
+ * It currently hold the options defined for MX31 3STACK Platform.
+ *
+ * @ingroup BRDCFG_MX31
+ */
+
+/*
+ * Include Files
+ */
+#include <mach/mxc_uart.h>
+
+/*!
+ * @name MXC UART EVB board level configurations
+ */
+/*! @{ */
+/*!
+ * Specifies if the Irda transmit path is inverting
+ */
+#define MXC_IRDA_TX_INV 0
+/*!
+ * Specifies if the Irda receive path is inverting
+ */
+#define MXC_IRDA_RX_INV 0
+
+/* UART 1 configuration */
+/*!
+ * This define specifies if the UART port is configured to be in DTE or
+ * DCE mode. There exists a define like this for each UART port. Valid
+ * values that can be used are \b MODE_DTE or \b MODE_DCE.
+ */
+#define UART1_MODE MODE_DCE
+/*!
+ * This define specifies if the UART is to be used for IRDA. There exists a
+ * define like this for each UART port. Valid values that can be used are
+ * \b IRDA or \b NO_IRDA.
+ */
+#define UART1_IR NO_IRDA
+/*!
+ * This define is used to enable or disable a particular UART port. If
+ * disabled, the UART will not be registered in the file system and the user
+ * will not be able to access it. There exists a define like this for each UART
+ * port. Specify a value of 1 to enable the UART and 0 to disable it.
+ */
+#define UART1_ENABLED 1
+/*! @} */
+/* UART 2 configuration */
+#define UART2_MODE MODE_DCE
+#define UART2_IR NO_IRDA
+#define UART2_ENABLED 1
+/* UART 3 configuration */
+#define UART3_MODE MODE_DTE
+#define UART3_IR NO_IRDA
+#define UART3_ENABLED 1
+/* UART 4 configuration */
+#define UART4_MODE MODE_DTE
+#define UART4_IR NO_IRDA
+#define UART4_ENABLED 0 /* Disable UART 4 as its pins are shared with ATA */
+/* UART 5 configuration */
+#define UART5_MODE MODE_DTE
+#define UART5_IR NO_IRDA
+#define UART5_ENABLED 0
+
+#define MXC_LL_UART_PADDR UART1_BASE_ADDR
+#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
+
+#define DEBUG_BASE_ADDRESS CS5_BASE_ADDR
+/* LAN9217 ethernet base address */
+#define LAN9217_BASE_ADDR DEBUG_BASE_ADDRESS
+/* External UART */
+#define UARTA_BASE_ADDR (DEBUG_BASE_ADDRESS + 0x8000)
+#define UARTB_BASE_ADDR (DEBUG_BASE_ADDRESS + 0x10000)
+
+#define BOARD_IO_ADDR (DEBUG_BASE_ADDRESS + 0x20000)
+/* LED switchs */
+#define LED_SWITCH_REG 0x00
+/* buttons */
+#define SWITCH_BUTTONS_REG 0x08
+/* status, interrupt */
+#define INTR_STATUS_REG 0x10
+#define INTR_MASK_REG 0x38
+#define INTR_RESET_REG 0x20
+/* magic word for debug CPLD */
+#define MAGIC_NUMBER1_REG 0x40
+#define MAGIC_NUMBER2_REG 0x48
+/* CPLD code version */
+#define CPLD_CODE_VER_REG 0x50
+/* magic word for debug CPLD */
+#define MAGIC_NUMBER3_REG 0x58
+/* module reset register*/
+#define MODULE_RESET_REG 0x60
+/* CPU ID and Personality ID */
+#define MCU_BOARD_ID_REG 0x68
+
+/* interrupts like external uart , external ethernet etc*/
+#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX31_PIN_GPIO1_1)
+
+#define EXPIO_INT_ENET (MXC_EXP_IO_BASE + 0)
+#define EXPIO_INT_XUART_A (MXC_EXP_IO_BASE + 1)
+#define EXPIO_INT_XUART_B (MXC_EXP_IO_BASE + 2)
+#define EXPIO_INT_BUTTON_A (MXC_EXP_IO_BASE + 3)
+#define EXPIO_INT_BUTTON_B (MXC_EXP_IO_BASE + 4)
+
+/*! This is System IRQ used by LAN9217 */
+#define LAN9217_IRQ EXPIO_INT_ENET
+
+/*! LED definition*/
+#define MXC_BD_LED1 (1)
+#define MXC_BD_LED2 (1 << 1)
+#define MXC_BD_LED3 (1 << 2)
+#define MXC_BD_LED4 (1 << 3)
+#define MXC_BD_LED5 (1 << 4)
+#define MXC_BD_LED6 (1 << 5)
+#define MXC_BD_LED7 (1 << 6)
+#define MXC_BD_LED8 (1 << 7)
+
+#define MXC_BD_LED_ON(led)
+#define MXC_BD_LED_OFF(led)
+
+extern unsigned int sdhc_get_card_det_status(struct device *dev);
+extern int sdhc_init_card_det(int id);
+extern int sdhc_write_protect(struct device *dev);
+
+#endif /* CONFIG_MACH_MX31_3DS */
+#endif /* __ASM_ARCH_MXC_BOARD_MX31PDK_H__ */
diff --git a/arch/arm/mach-mx3/clock.c b/arch/arm/mach-mx3/clock.c
index 9f14a871ee7c..28f049d6f6a8 100644
--- a/arch/arm/mach-mx3/clock.c
+++ b/arch/arm/mach-mx3/clock.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2005-2008 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
*
* This program is free software; you can redistribute it and/or
@@ -17,6 +17,7 @@
* MA 02110-1301, USA.
*/
+#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
@@ -24,11 +25,17 @@
#include <linux/err.h>
#include <linux/io.h>
#include <mach/clock.h>
+#include <mach/mxc_dptc.h>
#include <asm/div64.h>
+#include <mach/mxc_dptc.h>
#include "crm_regs.h"
#define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */
+#define PROPAGATE_RATE_DIS 2
+
+static int cpu_clk_set_wp(int wp);
+struct timer_list dptcen_timer;
static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post)
{
@@ -152,10 +159,23 @@ static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
else if (clk == &serial_pll_clk)
__raw_writel(reg, MXC_CCM_SRPCTL);
+ clk->rate = rate;
return 0;
}
-static unsigned long _clk_pll_get_rate(struct clk *clk)
+static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate)
+{
+ if ((rate < ahb_clk.rate) || (rate % ahb_clk.rate != 0)) {
+ printk(KERN_ERR "Wrong rate %lu in _clk_cpu_set_rate\n", rate);
+ return -EINVAL;
+ }
+
+ cpu_clk_set_wp(rate / ahb_clk.rate - 1);
+
+ return PROPAGATE_RATE_DIS;
+}
+
+static void _clk_pll_recalc(struct clk *clk)
{
long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
unsigned long reg, ccmr;
@@ -170,10 +190,14 @@ static unsigned long _clk_pll_get_rate(struct clk *clk)
ref_clk = clk_get_rate(&ckih_clk);
if (clk == &mcu_pll_clk) {
- if ((ccmr & MXC_CCM_CCMR_MPE) == 0)
- return ref_clk;
- if ((ccmr & MXC_CCM_CCMR_MDS) != 0)
- return ref_clk;
+ if ((ccmr & MXC_CCM_CCMR_MPE) == 0) {
+ clk->rate = ref_clk;
+ return;
+ }
+ if ((ccmr & MXC_CCM_CCMR_MDS) != 0) {
+ clk->rate = ref_clk;
+ return;
+ }
reg = __raw_readl(MXC_CCM_MPCTL);
} else if (clk == &usb_pll_clk)
reg = __raw_readl(MXC_CCM_UPCTL);
@@ -181,7 +205,7 @@ static unsigned long _clk_pll_get_rate(struct clk *clk)
reg = __raw_readl(MXC_CCM_SRPCTL);
else {
BUG();
- return 0;
+ return;
}
pdf = (reg & MXC_CCM_PCTL_PD_MASK) >> MXC_CCM_PCTL_PD_OFFSET;
@@ -204,7 +228,7 @@ static unsigned long _clk_pll_get_rate(struct clk *clk)
temp = -temp;
temp = (ref_clk * mfi) + temp;
- return temp;
+ clk->rate = temp;
}
static int _clk_usb_pll_enable(struct clk *clk)
@@ -257,53 +281,65 @@ static void _clk_serial_pll_disable(struct clk *clk)
#define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off)
#define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off)
-static unsigned long _clk_mcu_main_get_rate(struct clk *clk)
+static void _clk_mcu_main_recalc(struct clk *clk)
{
u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0);
- if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL)
- return clk_get_rate(&serial_pll_clk);
- else
- return clk_get_rate(&mcu_pll_clk);
+ if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL) {
+ serial_pll_clk.recalc(&serial_pll_clk);
+ clk->rate = serial_pll_clk.rate;
+ } else {
+ mcu_pll_clk.recalc(&mcu_pll_clk);
+ clk->rate = mcu_pll_clk.rate;
+ }
+}
+
+static void _clk_cpu_recalc(struct clk *clk)
+{
+ unsigned long mcu_pdf;
+
+ mcu_pdf = PDR0(MXC_CCM_PDR0_MCU_PODF_MASK,
+ MXC_CCM_PDR0_MCU_PODF_OFFSET);
+ clk->rate = clk->parent->rate / (mcu_pdf + 1);
}
-static unsigned long _clk_hclk_get_rate(struct clk *clk)
+static void _clk_hclk_recalc(struct clk *clk)
{
unsigned long max_pdf;
max_pdf = PDR0(MXC_CCM_PDR0_MAX_PODF_MASK,
MXC_CCM_PDR0_MAX_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (max_pdf + 1);
+ clk->rate = clk->parent->rate / (max_pdf + 1);
}
-static unsigned long _clk_ipg_get_rate(struct clk *clk)
+static void _clk_ipg_recalc(struct clk *clk)
{
unsigned long ipg_pdf;
ipg_pdf = PDR0(MXC_CCM_PDR0_IPG_PODF_MASK,
MXC_CCM_PDR0_IPG_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (ipg_pdf + 1);
+ clk->rate = clk->parent->rate / (ipg_pdf + 1);
}
-static unsigned long _clk_nfc_get_rate(struct clk *clk)
+static void _clk_nfc_recalc(struct clk *clk)
{
unsigned long nfc_pdf;
nfc_pdf = PDR0(MXC_CCM_PDR0_NFC_PODF_MASK,
MXC_CCM_PDR0_NFC_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (nfc_pdf + 1);
+ clk->rate = clk->parent->rate / (nfc_pdf + 1);
}
-static unsigned long _clk_hsp_get_rate(struct clk *clk)
+static void _clk_hsp_recalc(struct clk *clk)
{
unsigned long hsp_pdf;
hsp_pdf = PDR0(MXC_CCM_PDR0_HSP_PODF_MASK,
MXC_CCM_PDR0_HSP_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (hsp_pdf + 1);
+ clk->rate = clk->parent->rate / (hsp_pdf + 1);
}
-static unsigned long _clk_usb_get_rate(struct clk *clk)
+static void _clk_usb_recalc(struct clk *clk)
{
unsigned long usb_pdf, usb_prepdf;
@@ -311,10 +347,10 @@ static unsigned long _clk_usb_get_rate(struct clk *clk)
MXC_CCM_PDR1_USB_PODF_OFFSET);
usb_prepdf = PDR1(MXC_CCM_PDR1_USB_PRDF_MASK,
MXC_CCM_PDR1_USB_PRDF_OFFSET);
- return clk_get_rate(clk->parent) / (usb_prepdf + 1) / (usb_pdf + 1);
+ clk->rate = clk->parent->rate / (usb_prepdf + 1) / (usb_pdf + 1);
}
-static unsigned long _clk_csi_get_rate(struct clk *clk)
+static void _clk_csi_recalc(struct clk *clk)
{
u32 reg, pre, post;
@@ -325,7 +361,7 @@ static unsigned long _clk_csi_get_rate(struct clk *clk)
post = (reg & MXC_CCM_PDR0_CSI_PODF_MASK) >>
MXC_CCM_PDR0_CSI_PODF_OFFSET;
post++;
- return clk_get_rate(clk->parent) / (pre * post);
+ clk->rate = clk->parent->rate / (pre * post);
}
static unsigned long _clk_csi_round_rate(struct clk *clk, unsigned long rate)
@@ -359,19 +395,20 @@ static int _clk_csi_set_rate(struct clk *clk, unsigned long rate)
reg |= (pre - 1) << MXC_CCM_PDR0_CSI_PRDF_OFFSET;
__raw_writel(reg, MXC_CCM_PDR0);
+ clk->rate = rate;
return 0;
}
-static unsigned long _clk_per_get_rate(struct clk *clk)
+static void _clk_per_recalc(struct clk *clk)
{
unsigned long per_pdf;
per_pdf = PDR0(MXC_CCM_PDR0_PER_PODF_MASK,
MXC_CCM_PDR0_PER_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (per_pdf + 1);
+ clk->rate = clk->parent->rate / (per_pdf + 1);
}
-static unsigned long _clk_ssi1_get_rate(struct clk *clk)
+static void _clk_ssi1_recalc(struct clk *clk)
{
unsigned long ssi1_pdf, ssi1_prepdf;
@@ -379,10 +416,10 @@ static unsigned long _clk_ssi1_get_rate(struct clk *clk)
MXC_CCM_PDR1_SSI1_PODF_OFFSET);
ssi1_prepdf = PDR1(MXC_CCM_PDR1_SSI1_PRE_PODF_MASK,
MXC_CCM_PDR1_SSI1_PRE_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (ssi1_prepdf + 1) / (ssi1_pdf + 1);
+ clk->rate = clk->parent->rate / (ssi1_prepdf + 1) / (ssi1_pdf + 1);
}
-static unsigned long _clk_ssi2_get_rate(struct clk *clk)
+static void _clk_ssi2_recalc(struct clk *clk)
{
unsigned long ssi2_pdf, ssi2_prepdf;
@@ -390,10 +427,10 @@ static unsigned long _clk_ssi2_get_rate(struct clk *clk)
MXC_CCM_PDR1_SSI2_PODF_OFFSET);
ssi2_prepdf = PDR1(MXC_CCM_PDR1_SSI2_PRE_PODF_MASK,
MXC_CCM_PDR1_SSI2_PRE_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (ssi2_prepdf + 1) / (ssi2_pdf + 1);
+ clk->rate = clk->parent->rate / (ssi2_prepdf + 1) / (ssi2_pdf + 1);
}
-static unsigned long _clk_firi_get_rate(struct clk *clk)
+static void _clk_firi_recalc(struct clk *clk)
{
unsigned long firi_pdf, firi_prepdf;
@@ -401,7 +438,7 @@ static unsigned long _clk_firi_get_rate(struct clk *clk)
MXC_CCM_PDR1_FIRI_PODF_OFFSET);
firi_prepdf = PDR1(MXC_CCM_PDR1_FIRI_PRE_PODF_MASK,
MXC_CCM_PDR1_FIRI_PRE_PODF_OFFSET);
- return clk_get_rate(clk->parent) / (firi_prepdf + 1) / (firi_pdf + 1);
+ clk->rate = clk->parent->rate / (firi_prepdf + 1) / (firi_pdf + 1);
}
static unsigned long _clk_firi_round_rate(struct clk *clk, unsigned long rate)
@@ -437,100 +474,104 @@ static int _clk_firi_set_rate(struct clk *clk, unsigned long rate)
reg |= (post - 1) << MXC_CCM_PDR1_FIRI_PODF_OFFSET;
__raw_writel(reg, MXC_CCM_PDR1);
+ clk->rate = rate;
return 0;
}
-static unsigned long _clk_mbx_get_rate(struct clk *clk)
+static void _clk_mbx_recalc(struct clk *clk)
{
- return clk_get_rate(clk->parent) / 2;
+ clk->rate = clk->parent->rate / 2;
}
-static unsigned long _clk_mstick1_get_rate(struct clk *clk)
+static void _clk_mstick1_recalc(struct clk *clk)
{
unsigned long msti_pdf;
msti_pdf = PDR2(MXC_CCM_PDR2_MST1_PDF_MASK,
MXC_CCM_PDR2_MST1_PDF_OFFSET);
- return clk_get_rate(clk->parent) / (msti_pdf + 1);
+ clk->rate = clk->parent->rate / (msti_pdf + 1);
}
-static unsigned long _clk_mstick2_get_rate(struct clk *clk)
+static void _clk_mstick2_recalc(struct clk *clk)
{
unsigned long msti_pdf;
msti_pdf = PDR2(MXC_CCM_PDR2_MST2_PDF_MASK,
MXC_CCM_PDR2_MST2_PDF_OFFSET);
- return clk_get_rate(clk->parent) / (msti_pdf + 1);
-}
-
-static unsigned long ckih_rate;
-
-static unsigned long clk_ckih_get_rate(struct clk *clk)
-{
- return ckih_rate;
+ clk->rate = clk->parent->rate / (msti_pdf + 1);
}
static struct clk ckih_clk = {
.name = "ckih",
- .get_rate = clk_ckih_get_rate,
+ .rate = 0, /* determined later (26 or 27 MHz) */
+ .flags = RATE_PROPAGATES,
};
-static unsigned long clk_ckil_get_rate(struct clk *clk)
-{
- return CKIL_CLK_FREQ;
-}
-
static struct clk ckil_clk = {
.name = "ckil",
- .get_rate = clk_ckil_get_rate,
+ .rate = CKIL_CLK_FREQ,
+ .flags = RATE_PROPAGATES,
};
static struct clk mcu_pll_clk = {
.name = "mcu_pll",
.parent = &ckih_clk,
.set_rate = _clk_pll_set_rate,
- .get_rate = _clk_pll_get_rate,
+ .recalc = _clk_pll_recalc,
+ .flags = RATE_PROPAGATES,
};
static struct clk mcu_main_clk = {
.name = "mcu_main_clk",
.parent = &mcu_pll_clk,
- .get_rate = _clk_mcu_main_get_rate,
+ .recalc = _clk_mcu_main_recalc,
};
static struct clk serial_pll_clk = {
.name = "serial_pll",
.parent = &ckih_clk,
.set_rate = _clk_pll_set_rate,
- .get_rate = _clk_pll_get_rate,
+ .recalc = _clk_pll_recalc,
.enable = _clk_serial_pll_enable,
.disable = _clk_serial_pll_disable,
+ .flags = RATE_PROPAGATES,
};
static struct clk usb_pll_clk = {
.name = "usb_pll",
.parent = &ckih_clk,
.set_rate = _clk_pll_set_rate,
- .get_rate = _clk_pll_get_rate,
+ .recalc = _clk_pll_recalc,
.enable = _clk_usb_pll_enable,
.disable = _clk_usb_pll_disable,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk cpu_clk = {
+ .name = "cpu_clk",
+ .parent = &mcu_main_clk,
+ .recalc = _clk_cpu_recalc,
+ .set_rate = _clk_cpu_set_rate,
};
static struct clk ahb_clk = {
.name = "ahb_clk",
.parent = &mcu_main_clk,
- .get_rate = _clk_hclk_get_rate,
+ .recalc = _clk_hclk_recalc,
+ .flags = RATE_PROPAGATES,
};
static struct clk per_clk = {
.name = "per_clk",
.parent = &usb_pll_clk,
- .get_rate = _clk_per_get_rate,
+ .recalc = _clk_per_recalc,
+ .flags = RATE_PROPAGATES,
};
static struct clk perclk_clk = {
.name = "perclk_clk",
.parent = &ipg_clk,
+ .flags = RATE_PROPAGATES,
};
static struct clk cspi_clk[] = {
@@ -563,7 +604,8 @@ static struct clk cspi_clk[] = {
static struct clk ipg_clk = {
.name = "ipg_clk",
.parent = &ahb_clk,
- .get_rate = _clk_ipg_get_rate,
+ .recalc = _clk_ipg_recalc,
+ .flags = RATE_PROPAGATES,
};
static struct clk emi_clk = {
@@ -615,7 +657,7 @@ static struct clk epit_clk[] = {
static struct clk nfc_clk = {
.name = "nfc_clk",
.parent = &ahb_clk,
- .get_rate = _clk_nfc_get_rate,
+ .recalc = _clk_nfc_recalc,
};
static struct clk scc_clk = {
@@ -626,7 +668,7 @@ static struct clk scc_clk = {
static struct clk ipu_clk = {
.name = "ipu_clk",
.parent = &mcu_main_clk,
- .get_rate = _clk_hsp_get_rate,
+ .recalc = _clk_hsp_recalc,
.enable = _clk_enable,
.enable_reg = MXC_CCM_CGR1,
.enable_shift = MXC_CCM_CGR1_IPU_OFFSET,
@@ -663,7 +705,7 @@ static struct clk usb_clk[] = {
{
.name = "usb_clk",
.parent = &usb_pll_clk,
- .get_rate = _clk_usb_get_rate,},
+ .recalc = _clk_usb_recalc,},
{
.name = "usb_ahb_clk",
.parent = &ahb_clk,
@@ -676,7 +718,7 @@ static struct clk usb_clk[] = {
static struct clk csi_clk = {
.name = "csi_clk",
.parent = &serial_pll_clk,
- .get_rate = _clk_csi_get_rate,
+ .recalc = _clk_csi_recalc,
.round_rate = _clk_csi_round_rate,
.set_rate = _clk_csi_set_rate,
.enable = _clk_enable,
@@ -787,7 +829,7 @@ static struct clk ssi_clk[] = {
{
.name = "ssi_clk",
.parent = &serial_pll_clk,
- .get_rate = _clk_ssi1_get_rate,
+ .recalc = _clk_ssi1_recalc,
.enable = _clk_enable,
.enable_reg = MXC_CCM_CGR0,
.enable_shift = MXC_CCM_CGR0_SSI1_OFFSET,
@@ -796,7 +838,7 @@ static struct clk ssi_clk[] = {
.name = "ssi_clk",
.id = 1,
.parent = &serial_pll_clk,
- .get_rate = _clk_ssi2_get_rate,
+ .recalc = _clk_ssi2_recalc,
.enable = _clk_enable,
.enable_reg = MXC_CCM_CGR2,
.enable_shift = MXC_CCM_CGR2_SSI2_OFFSET,
@@ -808,7 +850,7 @@ static struct clk firi_clk = {
.parent = &usb_pll_clk,
.round_rate = _clk_firi_round_rate,
.set_rate = _clk_firi_set_rate,
- .get_rate = _clk_firi_get_rate,
+ .recalc = _clk_firi_recalc,
.enable = _clk_enable,
.enable_reg = MXC_CCM_CGR2,
.enable_shift = MXC_CCM_CGR2_FIRI_OFFSET,
@@ -830,7 +872,7 @@ static struct clk mbx_clk = {
.enable = _clk_enable,
.enable_reg = MXC_CCM_CGR2,
.enable_shift = MXC_CCM_CGR2_GACC_OFFSET,
- .get_rate = _clk_mbx_get_rate,
+ .recalc = _clk_mbx_recalc,
};
static struct clk vpu_clk = {
@@ -839,7 +881,7 @@ static struct clk vpu_clk = {
.enable = _clk_enable,
.enable_reg = MXC_CCM_CGR2,
.enable_shift = MXC_CCM_CGR2_GACC_OFFSET,
- .get_rate = _clk_mbx_get_rate,
+ .recalc = _clk_mbx_recalc,
};
static struct clk rtic_clk = {
@@ -896,7 +938,7 @@ static struct clk mstick_clk[] = {
.name = "mstick_clk",
.id = 0,
.parent = &usb_pll_clk,
- .get_rate = _clk_mstick1_get_rate,
+ .recalc = _clk_mstick1_recalc,
.enable = _clk_enable,
.enable_reg = MXC_CCM_CGR1,
.enable_shift = MXC_CCM_CGR1_MEMSTICK1_OFFSET,
@@ -905,7 +947,7 @@ static struct clk mstick_clk[] = {
.name = "mstick_clk",
.id = 1,
.parent = &usb_pll_clk,
- .get_rate = _clk_mstick2_get_rate,
+ .recalc = _clk_mstick2_recalc,
.enable = _clk_enable,
.enable_reg = MXC_CCM_CGR1,
.enable_shift = MXC_CCM_CGR1_MEMSTICK2_OFFSET,
@@ -965,14 +1007,14 @@ static int _clk_cko1_set_rate(struct clk *clk, unsigned long rate)
return 0;
}
-static unsigned long _clk_cko1_get_rate(struct clk *clk)
+static void _clk_cko1_recalc(struct clk *clk)
{
u32 div;
div = __raw_readl(MXC_CCM_COSR) & MXC_CCM_COSR_CLKOUTDIV_MASK >>
MXC_CCM_COSR_CLKOUTDIV_OFFSET;
- return clk_get_rate(clk->parent) / (1 << div);
+ clk->rate = clk->parent->rate / (1 << div);
}
static int _clk_cko1_set_parent(struct clk *clk, struct clk *parent)
@@ -991,6 +1033,8 @@ static int _clk_cko1_set_parent(struct clk *clk, struct clk *parent)
reg |= 3 << MXC_CCM_COSR_CLKOSEL_OFFSET;
else if (parent == &ahb_clk)
reg |= 5 << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ else if (parent == &cpu_clk)
+ reg |= 6 << MXC_CCM_COSR_CLKOSEL_OFFSET;
else if (parent == &serial_pll_clk)
reg |= 7 << MXC_CCM_COSR_CLKOSEL_OFFSET;
else if (parent == &ckih_clk)
@@ -1031,7 +1075,7 @@ static void _clk_cko1_disable(struct clk *clk)
static struct clk cko1_clk = {
.name = "cko1_clk",
- .get_rate = _clk_cko1_get_rate,
+ .recalc = _clk_cko1_recalc,
.set_rate = _clk_cko1_set_rate,
.round_rate = _clk_cko1_round_rate,
.set_parent = _clk_cko1_set_parent,
@@ -1046,6 +1090,7 @@ static struct clk *mxc_clks[] = {
&usb_pll_clk,
&serial_pll_clk,
&mcu_main_clk,
+ &cpu_clk,
&ahb_clk,
&per_clk,
&perclk_clk,
@@ -1092,12 +1137,20 @@ static struct clk *mxc_clks[] = {
&iim_clk,
};
-int __init mxc_clocks_init(unsigned long fref)
+static int cpu_curr_wp;
+static struct cpu_wp *cpu_wp_tbl;
+
+static int cpu_wp_nr;
+
+extern void propagate_rate(struct clk *tclk);
+
+int __init mxc_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2)
{
u32 reg;
struct clk **clkp;
- ckih_rate = fref;
+ ckil_clk.rate = ckil;
+ ckih_clk.rate = ckih1;
for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++)
clk_register(*clkp);
@@ -1110,24 +1163,33 @@ int __init mxc_clocks_init(unsigned long fref)
clk_register(&vl2cc_clk);
}
+ /* CCMR stby control */
+ reg = __raw_readl(MXC_CCM_CCMR);
+ reg |= MXC_CCM_CCMR_VSTBY | MXC_CCM_CCMR_WAMO;
+ __raw_writel(reg, MXC_CCM_CCMR);
+
/* Turn off all possible clocks */
__raw_writel(MXC_CCM_CGR0_GPT_MASK, MXC_CCM_CGR0);
__raw_writel(0, MXC_CCM_CGR1);
- __raw_writel(MXC_CCM_CGR2_EMI_MASK |
- MXC_CCM_CGR2_IPMUX1_MASK |
- MXC_CCM_CGR2_IPMUX2_MASK |
- MXC_CCM_CGR2_MXCCLKENSEL_MASK | /* for MX32 */
- MXC_CCM_CGR2_CHIKCAMPEN_MASK | /* for MX32 */
- MXC_CCM_CGR2_OVRVPUBUSY_MASK | /* for MX32 */
- 1 << 27 | 1 << 28, /* Bit 27 and 28 are not defined for
- MX32, but still required to be set */
- MXC_CCM_CGR2);
+ reg = MXC_CCM_CGR2_EMI_MASK | /*For MX32 */
+ MXC_CCM_CGR2_IPMUX1_MASK | /*For MX32 */
+ MXC_CCM_CGR2_IPMUX2_MASK | /*For MX32 */
+ MXC_CCM_CGR2_MXCCLKENSEL_MASK | /*For MX32 */
+ MXC_CCM_CGR2_CHIKCAMPEN_MASK | /*For MX32 */
+ MXC_CCM_CGR2_OVRVPUBUSY_MASK | /*For MX32 */
+ 0x3 << 27 | /*Bit 27 and 28 are not defined for MX32,
+ but still requires to be set */
+ MXC_CCM_CGR2_APMSYSCLKSEL_MASK | MXC_CCM_CGR2_AOMENA_MASK;
+ __raw_writel(reg, MXC_CCM_CGR2);
clk_disable(&cko1_clk);
clk_disable(&usb_pll_clk);
- pr_info("Clock input source is %ld\n", clk_get_rate(&ckih_clk));
+ pr_info("Clock input source is %ld\n", ckih_clk.rate);
+
+ /* This will propagate to all children and init all the clock rates */
+ propagate_rate(&ckih_clk);
clk_enable(&gpt_clk);
clk_enable(&emi_clk);
@@ -1135,13 +1197,171 @@ int __init mxc_clocks_init(unsigned long fref)
clk_enable(&serial_pll_clk);
- if (mx31_revision() >= CHIP_REV_2_0) {
- reg = __raw_readl(MXC_CCM_PMCR1);
- /* No PLL restart on DVFS switch; enable auto EMI handshake */
- reg |= MXC_CCM_PMCR1_PLLRDIS | MXC_CCM_PMCR1_EMIRQ_EN;
- __raw_writel(reg, MXC_CCM_PMCR1);
+ cpu_curr_wp = cpu_clk.rate / ahb_clk.rate - 1;
+ cpu_wp_tbl = get_cpu_wp(&cpu_wp_nr);
+
+ /* Init serial PLL according */
+ clk_set_rate(&serial_pll_clk, (cpu_wp_tbl[2].pll_rate));
+
+ if (cpu_is_mx31_rev(CHIP_REV_2_0) < 0) {
+ /* replace 399MHz wp with 266MHz one */
+ memcpy(&cpu_wp_tbl[2], &cpu_wp_tbl[1], sizeof(cpu_wp_tbl[0]));
}
return 0;
}
+#define MXC_PMCR0_DVFS_MASK (MXC_CCM_PMCR0_DVSUP_MASK | \
+ MXC_CCM_PMCR0_UDSC_MASK | \
+ MXC_CCM_PMCR0_VSCNT_MASK | \
+ MXC_CCM_PMCR0_DPVCR)
+
+#define MXC_PDR0_MAX_MCU_MASK (MXC_CCM_PDR0_MAX_PODF_MASK | \
+ MXC_CCM_PDR0_MCU_PODF_MASK | \
+ MXC_CCM_PDR0_HSP_PODF_MASK | \
+ MXC_CCM_PDR0_IPG_PODF_MASK | \
+ MXC_CCM_PDR0_NFC_PODF_MASK)
+
+static DEFINE_SPINLOCK(mxc_dfs_lock);
+
+static void dptcen_after_timeout(unsigned long ptr)
+{
+ unsigned long flags = 0;
+
+ spin_lock_irqsave(&mxc_dfs_lock, flags);
+
+ /*
+ * If DPTC is still active and core is running in Turbo mode
+ */
+ if (dptcen_timer.data == cpu_wp_nr - 1) {
+ dptc_resume(DPTC_GP_ID);
+ }
+ spin_unlock_irqrestore(&mxc_dfs_lock, flags);
+}
+
+/*!
+ * Setup cpu clock based on working point.
+ * @param wp cpu freq working point (0 is the slowest)
+ * @return 0 on success or error code on failure.
+ */
+static int cpu_clk_set_wp(int wp)
+{
+ struct cpu_wp *p;
+ u32 dvsup;
+ u32 pmcr0, pmcr1;
+ u32 pdr0;
+ u32 cgr2 = 0x80000000;
+ u32 vscnt = MXC_CCM_PMCR0_VSCNT_2;
+ u32 udsc = MXC_CCM_PMCR0_UDSC_DOWN;
+ u32 ipu_base = IO_ADDRESS(IPU_CTRL_BASE_ADDR);
+ u32 ipu_conf;
+
+ if (wp >= cpu_wp_nr || wp < 0) {
+ printk(KERN_ERR "Wrong wp: %d for cpu_clk_set_wp\n", wp);
+ return -EINVAL;
+ }
+ if (wp == cpu_curr_wp) {
+ return 0;
+ }
+
+ pmcr0 = __raw_readl(MXC_CCM_PMCR0);
+ pmcr1 = __raw_readl(MXC_CCM_PMCR1);
+ pdr0 = __raw_readl(MXC_CCM_PDR0);
+
+ if (!(pmcr0 & MXC_CCM_PMCR0_UPDTEN)) {
+ return -EBUSY;
+ }
+
+ if (wp > cpu_curr_wp) {
+ /* going faster */
+ if (wp == (cpu_wp_nr - 1)) {
+ /* Only update vscnt going into Turbo */
+ vscnt = MXC_CCM_PMCR0_VSCNT_8;
+ }
+ udsc = MXC_CCM_PMCR0_UDSC_UP;
+ }
+
+ p = &cpu_wp_tbl[wp];
+
+ dvsup = (cpu_wp_nr - 1 - wp) << MXC_CCM_PMCR0_DVSUP_OFFSET;
+
+ if ((mcu_main_clk.rate == 399000000) && (p->cpu_rate == 532000000)) {
+ cgr2 = __raw_readl(MXC_CCM_CGR2);
+ cgr2 &= 0x7fffffff;
+ vscnt = 0;
+ pmcr0 = (pmcr0 & ~MXC_PMCR0_DVFS_MASK) | dvsup | vscnt;
+ pr_debug("manul dvfs, dvsup = %x\n", dvsup);
+ __raw_writel(cgr2, MXC_CCM_CGR2);
+ __raw_writel(pmcr0, MXC_CCM_PMCR0);
+ udelay(100);
+ }
+
+ if (mcu_main_clk.rate == p->pll_rate) {
+ /* No pll switching and relocking needed */
+ pmcr0 |= MXC_CCM_PMCR0_DFSUP0_PDR;
+ } else {
+ /* pll switching and relocking needed */
+ pmcr0 ^= MXC_CCM_PMCR0_DFSUP1; /* flip MSB bit */
+ pmcr0 &= ~(MXC_CCM_PMCR0_DFSUP0);
+ }
+
+ pmcr0 = (pmcr0 & ~MXC_PMCR0_DVFS_MASK) | dvsup | vscnt | udsc;
+ /* also enable DVFS hardware */
+ pmcr0 |= MXC_CCM_PMCR0_DVFEN;
+
+ __raw_writel(pmcr0, MXC_CCM_PMCR0);
+
+ /* IPU and DI submodule must be on for PDR0 update to take effect */
+ if (!clk_get_usecount(&ipu_clk))
+ ipu_clk.enable(&ipu_clk);
+ ipu_conf = __raw_readl(ipu_base);
+ if (!(ipu_conf & 0x40))
+ __raw_writel(ipu_conf | 0x40, ipu_base);
+
+ __raw_writel((pdr0 & ~MXC_PDR0_MAX_MCU_MASK) | p->pdr0_reg,
+ MXC_CCM_PDR0);
+
+ if ((pmcr0 & MXC_CCM_PMCR0_DFSUP0) == MXC_CCM_PMCR0_DFSUP0_PLL) {
+ /* prevent pll restart */
+ pmcr1 |= 0x80;
+ __raw_writel(pmcr1, MXC_CCM_PMCR1);
+ /* PLL and post divider update */
+ if ((pmcr0 & MXC_CCM_PMCR0_DFSUP1) == MXC_CCM_PMCR0_DFSUP1_SPLL) {
+ __raw_writel(p->pll_reg, MXC_CCM_SRPCTL);
+ serial_pll_clk.rate = p->pll_rate;
+ mcu_main_clk.parent = &serial_pll_clk;
+ } else {
+ __raw_writel(p->pll_reg, MXC_CCM_MPCTL);
+ mcu_pll_clk.rate = p->pll_rate;
+ mcu_main_clk.parent = &mcu_pll_clk;
+ }
+ }
+
+ if ((cgr2 & 0x80000000) == 0x0) {
+ pr_debug("start auto dvfs\n");
+ cgr2 |= 0x80000000;
+ __raw_writel(cgr2, MXC_CCM_CGR2);
+ }
+
+ mcu_main_clk.rate = p->pll_rate;
+ cpu_clk.rate = p->cpu_rate;
+
+ cpu_curr_wp = wp;
+
+ /* Restore IPU_CONF setting */
+ __raw_writel(ipu_conf, ipu_base);
+ if (!clk_get_usecount(&ipu_clk))
+ ipu_clk.disable(&ipu_clk);
+
+ if (wp == cpu_wp_nr - 1) {
+ init_timer(&dptcen_timer);
+ dptcen_timer.expires = jiffies + 2;
+ dptcen_timer.function = dptcen_after_timeout;
+ dptcen_timer.data = wp;
+ add_timer(&dptcen_timer);
+ } else {
+ dptc_suspend(DPTC_GP_ID);
+ }
+
+ return 0;
+}
diff --git a/arch/arm/mach-mx3/cpu.c b/arch/arm/mach-mx3/cpu.c
new file mode 100644
index 000000000000..e481145444da
--- /dev/null
+++ b/arch/arm/mach-mx3/cpu.c
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2001 Deep Blue Solutions Ltd.
+ * Copyright 2004-2009 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
+ * published by the Free Software Foundation.
+ *
+ */
+
+/*!
+ * @file mach-mx3/cpu.c
+ *
+ * @brief This file contains the CPU initialization code.
+ *
+ * @ingroup MSL_MX31
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <mach/hardware.h>
+#include <linux/io.h>
+#include <asm/hardware/cache-l2x0.h>
+
+/*!
+ * CPU initialization. It is called by fixup_mxc_board()
+ */
+void __init mxc_cpu_init(void)
+{
+ /* Setup Peripheral Port Remap register for AVIC */
+ asm("ldr r0, =0xC0000015 \n\
+ mcr p15, 0, r0, c15, c2, 4");
+ if (!system_rev) {
+ mxc_set_system_rev(0x31, CHIP_REV_2_0);
+ }
+}
+
+/*!
+ * Post CPU init code
+ *
+ * @return 0 always
+ */
+static int __init post_cpu_init(void)
+{
+ void *l2_base;
+ volatile unsigned long aips_reg;
+
+ /* Initialize L2 cache */
+ l2_base = ioremap(L2CC_BASE_ADDR, SZ_4K);
+ if (l2_base) {
+ l2x0_init(l2_base, 0x00030024, 0x00000000);
+ }
+
+ /*
+ * S/W workaround: Clear the off platform peripheral modules
+ * Supervisor Protect bit for SDMA to access them.
+ */
+ __raw_writel(0x0, IO_ADDRESS(AIPS1_BASE_ADDR + 0x40));
+ __raw_writel(0x0, IO_ADDRESS(AIPS1_BASE_ADDR + 0x44));
+ __raw_writel(0x0, IO_ADDRESS(AIPS1_BASE_ADDR + 0x48));
+ __raw_writel(0x0, IO_ADDRESS(AIPS1_BASE_ADDR + 0x4C));
+ aips_reg = __raw_readl(IO_ADDRESS(AIPS1_BASE_ADDR + 0x50));
+ aips_reg &= 0x00FFFFFF;
+ __raw_writel(aips_reg, IO_ADDRESS(AIPS1_BASE_ADDR + 0x50));
+
+ __raw_writel(0x0, IO_ADDRESS(AIPS2_BASE_ADDR + 0x40));
+ __raw_writel(0x0, IO_ADDRESS(AIPS2_BASE_ADDR + 0x44));
+ __raw_writel(0x0, IO_ADDRESS(AIPS2_BASE_ADDR + 0x48));
+ __raw_writel(0x0, IO_ADDRESS(AIPS2_BASE_ADDR + 0x4C));
+ aips_reg = __raw_readl(IO_ADDRESS(AIPS2_BASE_ADDR + 0x50));
+ aips_reg &= 0x00FFFFFF;
+ __raw_writel(aips_reg, IO_ADDRESS(AIPS2_BASE_ADDR + 0x50));
+
+ return 0;
+}
+
+postcore_initcall(post_cpu_init);
diff --git a/arch/arm/mach-mx3/crm_regs.h b/arch/arm/mach-mx3/crm_regs.h
index 4a0e0ede23bb..0c4d4d38e624 100644
--- a/arch/arm/mach-mx3/crm_regs.h
+++ b/arch/arm/mach-mx3/crm_regs.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
*
* This program is free software; you can redistribute it and/or
@@ -24,7 +24,7 @@
#define CKIH_CLK_FREQ_27MHZ 27000000
#define CKIL_CLK_FREQ 32768
-#define MXC_CCM_BASE IO_ADDRESS(CCM_BASE_ADDR)
+#define MXC_CCM_BASE ((char *)IO_ADDRESS(CCM_BASE_ADDR))
/* Register addresses */
#define MXC_CCM_CCMR (MXC_CCM_BASE + 0x00)
@@ -55,6 +55,7 @@
#define MXC_CCM_PDR2 (MXC_CCM_BASE + 0x64)
/* Register bit definitions */
+#define MXC_CCM_CCMR_VSTBY (1 << 28)
#define MXC_CCM_CCMR_WBEN (1 << 27)
#define MXC_CCM_CCMR_CSCS (1 << 25)
#define MXC_CCM_CCMR_PERCS (1 << 24)
@@ -66,6 +67,7 @@
#define MXC_CCM_CCMR_LPM_MASK (0x3 << 14)
#define MXC_CCM_CCMR_FIRS_OFFSET 11
#define MXC_CCM_CCMR_FIRS_MASK (0x3 << 11)
+#define MXC_CCM_CCMR_WAMO (1 << 10)
#define MXC_CCM_CCMR_UPE (1 << 9)
#define MXC_CCM_CCMR_SPE (1 << 8)
#define MXC_CCM_CCMR_MDS (1 << 7)
diff --git a/arch/arm/mach-mx3/devices.c b/arch/arm/mach-mx3/devices.c
index a6bdcc07f3c9..5c2d5c09b28d 100644
--- a/arch/arm/mach-mx3/devices.c
+++ b/arch/arm/mach-mx3/devices.c
@@ -1,147 +1,832 @@
/*
- * Copyright 2006-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Sascha Hauer, kernel@pengutronix.de
+ * Author: MontaVista Software, Inc.
+ * <source@mvista.com>
*
- * 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.
+ * Based on the OMAP devices.c
*
- * 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.
+ * 2005 (c) MontaVista Software, Inc. This file is licensed under the
+ * terms of the GNU General Public License version 2. This program is
+ * licensed "as is" without any warranty of any kind, whether express
+ * or implied.
+ *
+ * Copyright 2005-2008 Freescale Semiconductor, Inc. All Rights Reserved.
*/
-
#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
#include <linux/platform_device.h>
-#include <linux/serial.h>
-#include <linux/gpio.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/spi/spi.h>
+
+#include <asm/mach-types.h>
#include <mach/hardware.h>
-#include <mach/imx-uart.h>
+#include <mach/pmic_external.h>
+#include <mach/pmic_power.h>
+#include <mach/spba.h>
+#include <mach/sdma.h>
+#include <mach/mxc_dptc.h>
+
+#include "iomux.h"
+#include "crm_regs.h"
+#include "sdma_script_code.h"
+#include "sdma_script_code_pass2.h"
+
+extern struct dptc_wp dptc_wp_allfreq_26ckih[DPTC_WP_SUPPORTED];
+extern struct dptc_wp dptc_wp_allfreq_26ckih_TO_2_0[DPTC_WP_SUPPORTED];
+extern struct dptc_wp dptc_wp_allfreq_27ckih_TO_2_0[DPTC_WP_SUPPORTED];
+/*
+ * Clock structures
+ */
+static struct clk *ckih_clk;
+
+void mxc_sdma_get_script_info(sdma_script_start_addrs * sdma_script_addr)
+{
+ if (cpu_is_mx31_rev(CHIP_REV_1_0) == 1) {
+ sdma_script_addr->mxc_sdma_app_2_mcu_addr = app_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_ap_2_ap_addr = ap_2_ap_ADDR;
+ sdma_script_addr->mxc_sdma_ap_2_bp_addr = -1;
+ sdma_script_addr->mxc_sdma_bp_2_ap_addr = -1;
+ sdma_script_addr->mxc_sdma_loopback_on_dsp_side_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_2_app_addr = mcu_2_app_ADDR;
+ sdma_script_addr->mxc_sdma_mcu_2_shp_addr = mcu_2_shp_ADDR;
+ sdma_script_addr->mxc_sdma_mcu_interrupt_only_addr = -1;
+ sdma_script_addr->mxc_sdma_shp_2_mcu_addr = shp_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_start_addr =
+ (unsigned short *)sdma_code;
+ sdma_script_addr->mxc_sdma_uartsh_2_mcu_addr =
+ uartsh_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_uart_2_mcu_addr = uart_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_ram_code_size = RAM_CODE_SIZE;
+ sdma_script_addr->mxc_sdma_ram_code_start_addr =
+ RAM_CODE_START_ADDR;
+ sdma_script_addr->mxc_sdma_dptc_dvfs_addr = dptc_dvfs_ADDR;
+ sdma_script_addr->mxc_sdma_firi_2_mcu_addr = firi_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_firi_2_per_addr = -1;
+ sdma_script_addr->mxc_sdma_mshc_2_mcu_addr = mshc_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_per_2_app_addr = -1;
+ sdma_script_addr->mxc_sdma_per_2_firi_addr = -1;
+ sdma_script_addr->mxc_sdma_per_2_shp_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_2_ata_addr = mcu_2_ata_ADDR;
+ sdma_script_addr->mxc_sdma_mcu_2_firi_addr = mcu_2_firi_ADDR;
+ sdma_script_addr->mxc_sdma_mcu_2_mshc_addr = mcu_2_mshc_ADDR;
+ sdma_script_addr->mxc_sdma_ata_2_mcu_addr = ata_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_uartsh_2_per_addr = -1;
+ sdma_script_addr->mxc_sdma_shp_2_per_addr = -1;
+ sdma_script_addr->mxc_sdma_uart_2_per_addr = -1;
+ sdma_script_addr->mxc_sdma_app_2_per_addr = -1;
+ } else {
+ sdma_script_addr->mxc_sdma_app_2_mcu_addr = app_2_mcu_ADDR_2;
+ sdma_script_addr->mxc_sdma_ap_2_ap_addr = ap_2_ap_ADDR_2;
+ sdma_script_addr->mxc_sdma_ap_2_ap_fixed_addr =
+ ap_2_ap_fixed_addr_ADDR_2;
+ sdma_script_addr->mxc_sdma_ap_2_bp_addr = ap_2_bp_ADDR_2;
+ sdma_script_addr->mxc_sdma_ap_2_ap_fixed_addr =
+ ap_2_ap_fixed_addr_ADDR_2;
+ sdma_script_addr->mxc_sdma_bp_2_ap_addr = bp_2_ap_ADDR_2;
+ sdma_script_addr->mxc_sdma_loopback_on_dsp_side_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_2_app_addr = mcu_2_app_ADDR_2;
+ sdma_script_addr->mxc_sdma_mcu_2_shp_addr = mcu_2_shp_ADDR_2;
+ sdma_script_addr->mxc_sdma_mcu_interrupt_only_addr = -1;
+ sdma_script_addr->mxc_sdma_shp_2_mcu_addr = shp_2_mcu_ADDR_2;
+ sdma_script_addr->mxc_sdma_start_addr =
+ (unsigned short *)sdma_code_2;
+ sdma_script_addr->mxc_sdma_uartsh_2_mcu_addr =
+ uartsh_2_mcu_ADDR_2;
+ sdma_script_addr->mxc_sdma_uart_2_mcu_addr = uart_2_mcu_ADDR_2;
+ sdma_script_addr->mxc_sdma_ram_code_size = RAM_CODE_SIZE_2;
+ sdma_script_addr->mxc_sdma_ram_code_start_addr =
+ RAM_CODE_START_ADDR_2;
+ sdma_script_addr->mxc_sdma_dptc_dvfs_addr = -1;
+ sdma_script_addr->mxc_sdma_firi_2_mcu_addr = firi_2_mcu_ADDR_2;
+ sdma_script_addr->mxc_sdma_firi_2_per_addr = -1;
+ sdma_script_addr->mxc_sdma_mshc_2_mcu_addr = mshc_2_mcu_ADDR_2;
+ sdma_script_addr->mxc_sdma_per_2_app_addr = per_2_app_ADDR_2;
+ sdma_script_addr->mxc_sdma_per_2_firi_addr = -1;
+ sdma_script_addr->mxc_sdma_per_2_shp_addr = per_2_shp_ADDR_2;
+ sdma_script_addr->mxc_sdma_mcu_2_ata_addr = mcu_2_ata_ADDR_2;
+ sdma_script_addr->mxc_sdma_mcu_2_firi_addr = mcu_2_firi_ADDR_2;
+ sdma_script_addr->mxc_sdma_mcu_2_mshc_addr = mcu_2_mshc_ADDR_2;
+ sdma_script_addr->mxc_sdma_ata_2_mcu_addr = ata_2_mcu_ADDR_2;
+ sdma_script_addr->mxc_sdma_uartsh_2_per_addr = -1;
+ sdma_script_addr->mxc_sdma_shp_2_per_addr = shp_2_per_ADDR_2;
+ sdma_script_addr->mxc_sdma_uart_2_per_addr = -1;
+ sdma_script_addr->mxc_sdma_app_2_per_addr = app_2_per_ADDR_2;
+ }
+}
+
+static void mxc_nop_release(struct device *dev)
+{
+ /* Nothing */
+}
+
+#if defined(CONFIG_W1_MASTER_MXC) || defined(CONFIG_W1_MASTER_MXC_MODULE)
+static struct mxc_w1_config mxc_w1_data = {
+ .search_rom_accelerator = 0,
+};
-static struct resource uart0[] = {
+static struct platform_device mxc_w1_devices = {
+ .name = "mxc_w1",
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_w1_data,
+ },
+ .id = 0
+};
+
+static void mxc_init_owire(void)
+{
+ (void)platform_device_register(&mxc_w1_devices);
+}
+#else
+static inline void mxc_init_owire(void)
+{
+}
+#endif
+
+#if defined(CONFIG_RTC_MXC) || defined(CONFIG_RTC_MXC_MODULE)
+static struct resource rtc_resources[] = {
{
- .start = UART1_BASE_ADDR,
- .end = UART1_BASE_ADDR + 0x0B5,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_UART1,
- .end = MXC_INT_UART1,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device0 = {
- .name = "imx-uart",
+ .start = RTC_BASE_ADDR,
+ .end = RTC_BASE_ADDR + 0x30,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_INT_RTC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+static struct platform_device mxc_rtc_device = {
+ .name = "mxc_rtc",
.id = 0,
- .resource = uart0,
- .num_resources = ARRAY_SIZE(uart0),
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resource = rtc_resources,
};
+static void mxc_init_rtc(void)
+{
+ (void)platform_device_register(&mxc_rtc_device);
+}
+#else
+static inline void mxc_init_rtc(void)
+{
+}
+#endif
+
+#if defined(CONFIG_MXC_WATCHDOG) || defined(CONFIG_MXC_WATCHDOG_MODULE)
-static struct resource uart1[] = {
+static struct resource wdt_resources[] = {
{
- .start = UART2_BASE_ADDR,
- .end = UART2_BASE_ADDR + 0x0B5,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_UART2,
- .end = MXC_INT_UART2,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device1 = {
- .name = "imx-uart",
- .id = 1,
- .resource = uart1,
- .num_resources = ARRAY_SIZE(uart1),
+ .start = WDOG1_BASE_ADDR,
+ .end = WDOG1_BASE_ADDR + 0x30,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device mxc_wdt_device = {
+ .name = "mxc_wdt",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+static void mxc_init_wdt(void)
+{
+ (void)platform_device_register(&mxc_wdt_device);
+}
+#else
+static inline void mxc_init_wdt(void)
+{
+}
+#endif
+
+#if defined(CONFIG_MXC_IPU) || defined(CONFIG_MXC_IPU_MODULE)
+static struct mxc_ipu_config mxc_ipu_data = {
+ .rev = 1,
};
-static struct resource uart2[] = {
+static struct resource ipu_resources[] = {
+ {
+ .start = IPU_CTRL_BASE_ADDR,
+ .end = IPU_CTRL_BASE_ADDR + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_INT_IPU_SYN,
+ .flags = IORESOURCE_IRQ,
+ },
{
- .start = UART3_BASE_ADDR,
- .end = UART3_BASE_ADDR + 0x0B5,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_UART3,
- .end = MXC_INT_UART3,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-struct platform_device mxc_uart_device2 = {
- .name = "imx-uart",
+ .start = MXC_INT_IPU_ERR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mxc_ipu_device = {
+ .name = "mxc_ipu",
+ .id = -1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_ipu_data,
+ },
+ .num_resources = ARRAY_SIZE(ipu_resources),
+ .resource = ipu_resources,
+};
+
+static void mxc_init_ipu(void)
+{
+ platform_device_register(&mxc_ipu_device);
+}
+#else
+static inline void mxc_init_ipu(void)
+{
+}
+#endif
+
+#if defined(CONFIG_SND_MXC_PMIC) || defined(CONFIG_SND_MXC_PMIC_MODULE)
+static struct mxc_audio_platform_data mxc_audio_data;
+
+static struct platform_device mxc_alsa_device = {
+ .name = "mxc_alsa",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_audio_data,
+ },
+
+};
+
+static void mxc_init_audio(void)
+{
+ struct clk *pll_clk;
+ pll_clk = clk_get(NULL, "usb_pll");
+ mxc_audio_data.ssi_clk[0] = clk_get(NULL, "ssi_clk.0");
+ clk_set_parent(mxc_audio_data.ssi_clk[0], pll_clk);
+ clk_put(mxc_audio_data.ssi_clk[0]);
+ if (machine_is_mx31_3ds()) {
+ mxc_audio_data.ssi_num = 1;
+ } else {
+ mxc_audio_data.ssi_num = 2;
+ mxc_audio_data.ssi_clk[1] = clk_get(NULL, "ssi_clk.1");
+ clk_set_parent(mxc_audio_data.ssi_clk[1], pll_clk);
+ clk_put(mxc_audio_data.ssi_clk[1]);
+ }
+ clk_put(pll_clk);
+ mxc_audio_data.src_port = 0;
+ platform_device_register(&mxc_alsa_device);
+}
+#else
+
+static void mxc_init_audio(void)
+{
+}
+
+#endif
+
+#if defined(CONFIG_MXC_SSI) || defined(CONFIG_MXC_SSI_MODULE)
+/*!
+ * Resource definition for the SSI
+ */
+static struct resource mxcssi2_resources[] = {
+ [0] = {
+ .start = SSI2_BASE_ADDR,
+ .end = SSI2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct resource mxcssi1_resources[] = {
+ [0] = {
+ .start = SSI1_BASE_ADDR,
+ .end = SSI1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+/*! Device Definition for MXC SSI */
+static struct platform_device mxc_ssi1_device = {
+ .name = "mxc_ssi",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_audio_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcssi1_resources),
+ .resource = mxcssi1_resources,
+};
+
+static struct platform_device mxc_ssi2_device = {
+ .name = "mxc_ssi",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_audio_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcssi2_resources),
+ .resource = mxcssi2_resources,
+};
+
+static void mxc_init_ssi(void)
+{
+ platform_device_register(&mxc_ssi1_device);
+ platform_device_register(&mxc_ssi2_device);
+}
+#else
+
+static void mxc_init_ssi(void)
+{
+}
+#endif
+
+/*!
+ * This is platform device structure for adding SCC
+ */
+#if defined(CONFIG_MXC_SECURITY_SCC) || defined(CONFIG_MXC_SECURITY_SCC_MODULE)
+static struct platform_device mxc_scc_device = {
+ .name = "mxc_scc",
+ .id = 0,
+};
+
+static void mxc_init_scc(void)
+{
+ platform_device_register(&mxc_scc_device);
+}
+#else
+static inline void mxc_init_scc(void)
+{
+}
+#endif
+
+/* SPI controller and device data */
+#if defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE)
+
+#ifdef CONFIG_SPI_MXC_SELECT1
+/*!
+ * Resource definition for the CSPI1
+ */
+static struct resource mxcspi1_resources[] = {
+ [0] = {
+ .start = CSPI1_BASE_ADDR,
+ .end = CSPI1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_CSPI1,
+ .end = MXC_INT_CSPI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC CSPI1 */
+static struct mxc_spi_master mxcspi1_data = {
+ .maxchipselect = 4,
+ .spi_version = 4,
+};
+
+/*! Device Definition for MXC CSPI1 */
+static struct platform_device mxcspi1_device = {
+ .name = "mxc_spi",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxcspi1_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcspi1_resources),
+ .resource = mxcspi1_resources,
+};
+
+#endif /* CONFIG_SPI_MXC_SELECT1 */
+
+#ifdef CONFIG_SPI_MXC_SELECT2
+/*!
+ * Resource definition for the CSPI2
+ */
+static struct resource mxcspi2_resources[] = {
+ [0] = {
+ .start = CSPI2_BASE_ADDR,
+ .end = CSPI2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_CSPI2,
+ .end = MXC_INT_CSPI2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC CSPI2 */
+static struct mxc_spi_master mxcspi2_data = {
+ .maxchipselect = 4,
+ .spi_version = 4,
+};
+
+/*! Device Definition for MXC CSPI2 */
+static struct platform_device mxcspi2_device = {
+ .name = "mxc_spi",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxcspi2_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcspi2_resources),
+ .resource = mxcspi2_resources,
+};
+#endif /* CONFIG_SPI_MXC_SELECT2 */
+
+#ifdef CONFIG_SPI_MXC_SELECT3
+/*!
+ * Resource definition for the CSPI3
+ */
+static struct resource mxcspi3_resources[] = {
+ [0] = {
+ .start = CSPI3_BASE_ADDR,
+ .end = CSPI3_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_CSPI3,
+ .end = MXC_INT_CSPI3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC CSPI3 */
+static struct mxc_spi_master mxcspi3_data = {
+ .maxchipselect = 4,
+ .spi_version = 4,
+};
+
+/*! Device Definition for MXC CSPI3 */
+static struct platform_device mxcspi3_device = {
+ .name = "mxc_spi",
.id = 2,
- .resource = uart2,
- .num_resources = ARRAY_SIZE(uart2),
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxcspi3_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcspi3_resources),
+ .resource = mxcspi3_resources,
};
+#endif /* CONFIG_SPI_MXC_SELECT3 */
-static struct resource uart3[] = {
- {
- .start = UART4_BASE_ADDR,
- .end = UART4_BASE_ADDR + 0x0B5,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_UART4,
- .end = MXC_INT_UART4,
- .flags = IORESOURCE_IRQ,
- },
+static inline void mxc_init_spi(void)
+{
+ /* SPBA configuration for CSPI2 - MCU is set */
+ spba_take_ownership(SPBA_CSPI2, SPBA_MASTER_A);
+#ifdef CONFIG_SPI_MXC_SELECT1
+ if (platform_device_register(&mxcspi1_device) < 0)
+ printk("Error: Registering the SPI Controller_1\n");
+#endif /* CONFIG_SPI_MXC_SELECT1 */
+#ifdef CONFIG_SPI_MXC_SELECT2
+ if (platform_device_register(&mxcspi2_device) < 0)
+ printk("Error: Registering the SPI Controller_2\n");
+#endif /* CONFIG_SPI_MXC_SELECT2 */
+#ifdef CONFIG_SPI_MXC_SELECT3
+ if (platform_device_register(&mxcspi3_device) < 0)
+ printk("Error: Registering the SPI Controller_3\n");
+#endif /* CONFIG_SPI_MXC_SELECT3 */
+}
+#else
+static inline void mxc_init_spi(void)
+{
+}
+#endif
+
+/* I2C controller and device data */
+#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE)
+
+#ifdef CONFIG_I2C_MXC_SELECT1
+/*!
+ * Resource definition for the I2C1
+ */
+static struct resource mxci2c1_resources[] = {
+ [0] = {
+ .start = I2C_BASE_ADDR,
+ .end = I2C_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_I2C,
+ .end = MXC_INT_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC I2C */
+static struct mxc_i2c_platform_data mxci2c1_data = {
+ .i2c_clk = 100000,
+};
+#endif
+
+#ifdef CONFIG_I2C_MXC_SELECT2
+/*!
+ * Resource definition for the I2C2
+ */
+static struct resource mxci2c2_resources[] = {
+ [0] = {
+ .start = I2C2_BASE_ADDR,
+ .end = I2C2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_I2C2,
+ .end = MXC_INT_I2C2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC I2C */
+static struct mxc_i2c_platform_data mxci2c2_data = {
+ .i2c_clk = 100000,
+};
+#endif
+
+#ifdef CONFIG_I2C_MXC_SELECT3
+/*!
+ * Resource definition for the I2C3
+ */
+static struct resource mxci2c3_resources[] = {
+ [0] = {
+ .start = I2C3_BASE_ADDR,
+ .end = I2C3_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_I2C3,
+ .end = MXC_INT_I2C3,
+ .flags = IORESOURCE_IRQ,
+ },
};
-struct platform_device mxc_uart_device3 = {
- .name = "imx-uart",
- .id = 3,
- .resource = uart3,
- .num_resources = ARRAY_SIZE(uart3),
+/*! Platform Data for MXC I2C */
+static struct mxc_i2c_platform_data mxci2c3_data = {
+ .i2c_clk = 100000,
};
+#endif
+
+/*! Device Definition for MXC I2C1 */
+static struct platform_device mxci2c_devices[] = {
+#ifdef CONFIG_I2C_MXC_SELECT1
+ {
+ .name = "mxc_i2c",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxci2c1_data,
+ },
+ .num_resources = ARRAY_SIZE(mxci2c1_resources),
+ .resource = mxci2c1_resources,},
+#endif
+#ifdef CONFIG_I2C_MXC_SELECT2
+ {
+ .name = "mxc_i2c",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxci2c2_data,
+ },
+ .num_resources = ARRAY_SIZE(mxci2c2_resources),
+ .resource = mxci2c2_resources,},
+#endif
+#ifdef CONFIG_I2C_MXC_SELECT3
+ {
+ .name = "mxc_i2c",
+ .id = 2,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxci2c3_data,
+ },
+ .num_resources = ARRAY_SIZE(mxci2c3_resources),
+ .resource = mxci2c3_resources,},
+#endif
+};
+
+static inline void mxc_init_i2c(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mxci2c_devices); i++) {
+ if (platform_device_register(&mxci2c_devices[i]) < 0)
+ dev_err(&mxci2c_devices[i].dev,
+ "Unable to register I2C device\n");
+ }
+}
+#else
+static inline void mxc_init_i2c(void)
+{
+}
+#endif
-static struct resource uart4[] = {
+struct mxc_gpio_port mxc_gpio_ports[GPIO_PORT_NUM] = {
+ {
+ .num = 0,
+ .base = IO_ADDRESS(GPIO1_BASE_ADDR),
+ .irq = MXC_INT_GPIO1,
+ .virtual_irq_start = MXC_GPIO_INT_BASE,
+ },
+ {
+ .num = 1,
+ .base = IO_ADDRESS(GPIO2_BASE_ADDR),
+ .irq = MXC_INT_GPIO2,
+ .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN,
+ },
{
- .start = UART5_BASE_ADDR,
- .end = UART5_BASE_ADDR + 0x0B5,
- .flags = IORESOURCE_MEM,
- }, {
- .start = MXC_INT_UART5,
- .end = MXC_INT_UART5,
- .flags = IORESOURCE_IRQ,
- },
+ .num = 2,
+ .base = IO_ADDRESS(GPIO3_BASE_ADDR),
+ .irq = MXC_INT_GPIO3,
+ .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 2,
+ },
+};
+
+#if defined(CONFIG_PCMCIA_MX31ADS) || defined(CONFIG_PCMCIA_MX31ADS_MODULE)
+
+static struct platform_device mx31ads_device = {
+ .name = "Mx31ads_pcmcia_socket",
+ .id = 0,
+ .dev.release = mxc_nop_release,
+};
+static inline void mxc_init_pcmcia(void)
+{
+ platform_device_register(&mx31ads_device);
+}
+#else
+static inline void mxc_init_pcmcia(void)
+{
+}
+#endif
+
+#if defined(CONFIG_MXC_HMP4E) || defined(CONFIG_MXC_HMP4E_MODULE)
+static struct platform_device hmp4e_device = {
+ .name = "mxc_hmp4e",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ }
};
-struct platform_device mxc_uart_device4 = {
- .name = "imx-uart",
- .id = 4,
- .resource = uart4,
- .num_resources = ARRAY_SIZE(uart4),
+static inline void mxc_init_hmp4e(void)
+{
+ u32 iim_reg = IO_ADDRESS(IIM_BASE_ADDR);
+ if (cpu_is_mx32())
+ return;
+
+ /* override fuse for Hantro HW clock */
+ if (__raw_readl(iim_reg + 0x808) == 0x4) {
+ if (!(__raw_readl(iim_reg + 0x800) & (1 << 5))) {
+ writel(__raw_readl(iim_reg + 0x808) & 0xfffffffb,
+ iim_reg + 0x808);
+ }
+ }
+
+ platform_device_register(&hmp4e_device);
+}
+#else
+static inline void mxc_init_hmp4e(void)
+{
+}
+#endif
+
+static struct platform_device mxc_dma_device = {
+ .name = "mxc_dma",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
};
-/* GPIO port description */
-static struct mxc_gpio_port imx_gpio_ports[] = {
+static inline void mxc_init_dma(void)
+{
+ (void)platform_device_register(&mxc_dma_device);
+}
+
+/*!
+ * Resource definition for the DPTC LP
+ */
+static struct resource dptc_resources[] = {
[0] = {
- .chip.label = "gpio-0",
- .base = IO_ADDRESS(GPIO1_BASE_ADDR),
- .irq = MXC_INT_GPIO1,
- .virtual_irq_start = MXC_GPIO_INT_BASE
- },
+ .start = MXC_CCM_BASE,
+ .end = MXC_CCM_BASE + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
[1] = {
- .chip.label = "gpio-1",
- .base = IO_ADDRESS(GPIO2_BASE_ADDR),
- .irq = MXC_INT_GPIO2,
- .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN
- },
- [2] = {
- .chip.label = "gpio-2",
- .base = IO_ADDRESS(GPIO3_BASE_ADDR),
- .irq = MXC_INT_GPIO3,
- .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 2
+ .start = MXC_INT_CCM,
+ .end = MXC_INT_CCM,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for DPTC */
+static struct mxc_dptc_data dptc_data = {
+ .reg_id = "SW1A_NORMAL",
+ .clk_id = "cpu_clk",
+ .dptccr_reg_addr = MXC_CCM_PMCR0,
+ .dcvr0_reg_addr = MXC_CCM_DCVR0,
+ .gpc_cntr_reg_addr = MXC_CCM_PMCR0,
+ .dptccr = 0xFFFFFFFF,
+ .dptc_wp_supported = DPTC_WP_SUPPORTED,
+ .dptc_wp_allfreq = dptc_wp_allfreq_26ckih,
+ .clk_max_val = 532000000,
+ .gpc_adu = 0x0,
+ .vai_mask = MXC_CCM_PMCR0_PTVAI_MASK,
+ .vai_offset = MXC_CCM_PMCR0_PTVAI_OFFSET,
+ .dptc_enable_bit = MXC_CCM_PMCR0_DPTEN,
+ .irq_mask = MXC_CCM_PMCR0_PTVAIM,
+ .dptc_nvcr_bit = 0x0,
+ .gpc_irq_bit = 0x00000000,
+ .init_config =
+ MXC_CCM_PMCR0_PTVIS | MXC_CCM_PMCR0_DRCE3 | MXC_CCM_PMCR0_DRCE1,
+ .enable_config =
+ MXC_CCM_PMCR0_DPTEN | MXC_CCM_PMCR0_DPVCR | MXC_CCM_PMCR0_DPVV,
+ .dcr_mask = MXC_CCM_PMCR0_DCR,
+};
+
+/*! Device Definition for MXC DPTC */
+static struct platform_device mxc_dptc_device = {
+ .name = "mxc_dptc",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &dptc_data,
+ },
+ .num_resources = ARRAY_SIZE(dptc_resources),
+ .resource = dptc_resources,
+};
+
+static inline void mxc_init_dptc(void)
+{
+ if (clk_get_rate(ckih_clk) == 27000000) {
+
+ if (mxc_cpu_is_rev(CHIP_REV_2_0) < 0)
+ dptc_data.dptc_wp_allfreq = NULL;
+ else
+ dptc_data.dptc_wp_allfreq =
+ dptc_wp_allfreq_27ckih_TO_2_0;
+
+ } else if (clk_get_rate(ckih_clk) == 26000000
+ && mxc_cpu_is_rev(CHIP_REV_2_0) == 1) {
+ dptc_data.dptc_wp_allfreq = dptc_wp_allfreq_26ckih_TO_2_0;
}
+
+ (void)platform_device_register(&mxc_dptc_device);
+}
+
+#ifdef CONFIG_MXC_VPU
+static struct resource vpu_resources[] = {
+ {
+ .start = VL2CC_BASE_ADDR,
+ .end = VL2CC_BASE_ADDR + SZ_8K - 1,
+ .flags = IORESOURCE_MEM,
+ },
};
-int __init mxc_register_gpios(void)
+/*! Platform Data for MXC VPU */
+static struct platform_device mxcvpu_device = {
+ .name = "mxc_vpu",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(vpu_resources),
+ .resource = vpu_resources,
+};
+
+static inline void mxc_init_vpu(void)
{
- return mxc_gpio_init(imx_gpio_ports, ARRAY_SIZE(imx_gpio_ports));
+ if (cpu_is_mx32()) {
+ if (platform_device_register(&mxcvpu_device) < 0)
+ printk(KERN_ERR "Error: Registering the VPU.\n");
+ }
+}
+#else
+static inline void mxc_init_vpu(void)
+{
+}
+#endif
+
+int __init mxc_init_devices(void)
+{
+ mxc_init_wdt();
+ mxc_init_ipu();
+ mxc_init_spi();
+ mxc_init_i2c();
+ mxc_init_rtc();
+ mxc_init_owire();
+ mxc_init_pcmcia();
+ mxc_init_scc();
+ mxc_init_ssi();
+ mxc_init_hmp4e();
+ mxc_init_dma();
+ mxc_init_audio();
+ ckih_clk = clk_get(NULL, "ckih");
+ mxc_init_dptc();
+ mxc_init_vpu();
+
+ /* SPBA configuration for SSI2 - SDMA and MCU are set */
+ spba_take_ownership(SPBA_SSI2, SPBA_MASTER_C | SPBA_MASTER_A);
+ return 0;
}
diff --git a/arch/arm/mach-mx3/dma.c b/arch/arm/mach-mx3/dma.c
new file mode 100644
index 000000000000..4d63d706cba4
--- /dev/null
+++ b/arch/arm/mach-mx3/dma.c
@@ -0,0 +1,745 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/init.h>
+#include <linux/device.h>
+#include <asm/dma.h>
+#include <mach/hardware.h>
+
+#include "serial.h"
+
+#define MXC_MMC_BUFFER_ACCESS 0x38
+#define MXC_SSI_TX0_REG 0x0
+#define MXC_SSI_TX1_REG 0x4
+#define MXC_SSI_RX0_REG 0x8
+#define MXC_SSI_RX1_REG 0xC
+#define MXC_FIRI_TXFIFO 0x14
+#define MXC_SDHC_MMC_WML 16
+#define MXC_SDHC_SD_WML 64
+#define MXC_SSI_TXFIFO_WML 0x4
+#define MXC_SSI_RXFIFO_WML 0x6
+#define MXC_FIRI_WML 16
+
+#ifdef CONFIG_SDMA_IRAM
+#define trans_type int_2_per
+#else
+#define trans_type emi_2_per
+#endif
+
+typedef struct mxc_sdma_info_entry_s {
+ mxc_dma_device_t device;
+ mxc_sdma_channel_params_t *chnl_info;
+} mxc_sdma_info_entry_t;
+
+static mxc_sdma_channel_params_t mxc_sdma_uart1_rx_params = {
+ .chnl_params = {
+ .watermark_level = UART1_UFCR_RXTL,
+ .per_address = UART1_BASE_ADDR,
+ .peripheral_type = UART,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_UART1_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART1_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart1_tx_params = {
+ .chnl_params = {
+ .watermark_level = UART1_UFCR_TXTL,
+ .per_address = UART1_BASE_ADDR + MXC_UARTUTXD,
+ .peripheral_type = UART,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_UART1_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART1_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart2_rx_params = {
+ .chnl_params = {
+ .watermark_level = UART2_UFCR_RXTL,
+ .per_address = UART2_BASE_ADDR,
+ .peripheral_type = UART,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_UART2_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART2_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart2_tx_params = {
+ .chnl_params = {
+ .watermark_level = UART2_UFCR_TXTL,
+ .per_address = UART2_BASE_ADDR + MXC_UARTUTXD,
+ .peripheral_type = UART,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_UART2_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART2_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart3_rx_params = {
+ .chnl_params = {
+ .watermark_level = UART3_UFCR_RXTL,
+ .per_address = UART3_BASE_ADDR,
+ .peripheral_type = UART_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_UART3_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART3_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart3_tx_params = {
+ .chnl_params = {
+ .watermark_level = UART3_UFCR_TXTL,
+ .per_address = UART3_BASE_ADDR + MXC_UARTUTXD,
+ .peripheral_type = UART_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_UART3_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART3_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart4_rx_params = {
+ .chnl_params = {
+ .watermark_level = UART4_UFCR_RXTL,
+ .per_address = UART4_BASE_ADDR,
+ .peripheral_type = UART,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_UART4_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART4_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart4_tx_params = {
+ .chnl_params = {
+ .watermark_level = UART4_UFCR_TXTL,
+ .per_address = UART4_BASE_ADDR + MXC_UARTUTXD,
+ .peripheral_type = UART,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_UART4_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART4_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart5_rx_params = {
+ .chnl_params = {
+ .watermark_level = UART5_UFCR_RXTL,
+ .per_address = UART5_BASE_ADDR,
+ .peripheral_type = UART,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_UART5_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART5_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart5_tx_params = {
+ .chnl_params = {
+ .watermark_level = UART5_UFCR_TXTL,
+ .per_address = UART5_BASE_ADDR + MXC_UARTUTXD,
+ .peripheral_type = UART,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_UART5_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART5_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_mmc1_width1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SDHC_MMC_WML,
+ .per_address =
+ MMC_SDHC1_BASE_ADDR + MXC_MMC_BUFFER_ACCESS,
+ .peripheral_type = MMC,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SDHC1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_MMC1,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_mmc1_width4_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SDHC_SD_WML,
+ .per_address =
+ MMC_SDHC1_BASE_ADDR + MXC_MMC_BUFFER_ACCESS,
+ .peripheral_type = MMC,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SDHC1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_MMC1,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_mmc2_width1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SDHC_MMC_WML,
+ .per_address =
+ MMC_SDHC2_BASE_ADDR + MXC_MMC_BUFFER_ACCESS,
+ .peripheral_type = MMC,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SDHC2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_MMC2,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_mmc2_width4_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SDHC_SD_WML,
+ .per_address =
+ MMC_SDHC2_BASE_ADDR + MXC_MMC_BUFFER_ACCESS,
+ .peripheral_type = MMC,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SDHC2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_MMC2,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = trans_type,
+ .event_id = DMA_REQ_SSI2_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = trans_type,
+ .event_id = DMA_REQ_SSI2_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = trans_type,
+ .event_id = DMA_REQ_SSI2_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = trans_type,
+ .event_id = DMA_REQ_SSI2_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = trans_type,
+ .event_id = DMA_REQ_SSI2_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_fir_rx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_FIRI_WML,
+ .per_address = FIRI_BASE_ADDR,
+ .peripheral_type = FIRI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_FIRI_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_FIR_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_fir_tx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_FIRI_WML,
+ .per_address = FIRI_BASE_ADDR + MXC_FIRI_TXFIFO,
+ .peripheral_type = FIRI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_FIRI_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_FIR_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_memory_params = {
+ .chnl_params = {
+ .peripheral_type = MEMORY,
+ .transfer_type = emi_2_emi,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_MEMORY,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_fifo_memory_params = {
+ .chnl_params = {
+ .peripheral_type = FIFO_MEMORY,
+ .per_address = MXC_FIFO_MEM_DEST_FIXED,
+ .transfer_type = emi_2_emi,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ .event_id = 0,
+ },
+ .channel_num = MXC_DMA_CHANNEL_FIFO_MEMORY,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ata_rx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_IDE_DMA_WATERMARK,
+ .per_address = ATA_DMA_BASE_ADDR,
+ .peripheral_type = ATA,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_ATA_TX_END,
+ .event_id2 = DMA_REQ_ATA_RX,
+ .bd_number = MXC_IDE_DMA_BD_NR,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_ATA_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ata_tx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_IDE_DMA_WATERMARK,
+ .per_address = ATA_DMA_BASE_ADDR + 0x18,
+ .peripheral_type = ATA,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_ATA_TX_END,
+ .event_id2 = DMA_REQ_ATA_TX,
+ .bd_number = MXC_IDE_DMA_BD_NR,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_ATA_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+static mxc_sdma_info_entry_t mxc_sdma_active_dma_info[] = {
+ {MXC_DMA_UART1_RX, &mxc_sdma_uart1_rx_params},
+ {MXC_DMA_UART1_TX, &mxc_sdma_uart1_tx_params},
+ {MXC_DMA_UART2_RX, &mxc_sdma_uart2_rx_params},
+ {MXC_DMA_UART2_TX, &mxc_sdma_uart2_tx_params},
+ {MXC_DMA_UART3_RX, &mxc_sdma_uart3_rx_params},
+ {MXC_DMA_UART3_TX, &mxc_sdma_uart3_tx_params},
+ {MXC_DMA_UART4_RX, &mxc_sdma_uart4_rx_params},
+ {MXC_DMA_UART4_TX, &mxc_sdma_uart4_tx_params},
+ {MXC_DMA_UART5_RX, &mxc_sdma_uart5_rx_params},
+ {MXC_DMA_UART5_TX, &mxc_sdma_uart5_tx_params},
+ {MXC_DMA_MMC1_WIDTH_1, &mxc_sdma_mmc1_width1_params},
+ {MXC_DMA_MMC1_WIDTH_4, &mxc_sdma_mmc1_width4_params},
+ {MXC_DMA_MMC2_WIDTH_1, &mxc_sdma_mmc2_width1_params},
+ {MXC_DMA_MMC2_WIDTH_4, &mxc_sdma_mmc2_width4_params},
+ {MXC_DMA_SSI1_8BIT_RX0, &mxc_sdma_ssi1_8bit_rx0_params},
+ {MXC_DMA_SSI1_8BIT_TX0, &mxc_sdma_ssi1_8bit_tx0_params},
+ {MXC_DMA_SSI1_16BIT_RX0, &mxc_sdma_ssi1_16bit_rx0_params},
+ {MXC_DMA_SSI1_16BIT_TX0, &mxc_sdma_ssi1_16bit_tx0_params},
+ {MXC_DMA_SSI1_24BIT_RX0, &mxc_sdma_ssi1_24bit_rx0_params},
+ {MXC_DMA_SSI1_24BIT_TX0, &mxc_sdma_ssi1_24bit_tx0_params},
+ {MXC_DMA_SSI1_8BIT_RX1, &mxc_sdma_ssi1_8bit_rx1_params},
+ {MXC_DMA_SSI1_8BIT_TX1, &mxc_sdma_ssi1_8bit_tx1_params},
+ {MXC_DMA_SSI1_16BIT_RX1, &mxc_sdma_ssi1_16bit_rx1_params},
+ {MXC_DMA_SSI1_16BIT_TX1, &mxc_sdma_ssi1_16bit_tx1_params},
+ {MXC_DMA_SSI1_24BIT_RX1, &mxc_sdma_ssi1_24bit_rx1_params},
+ {MXC_DMA_SSI1_24BIT_TX1, &mxc_sdma_ssi1_24bit_tx1_params},
+ {MXC_DMA_SSI2_8BIT_RX0, &mxc_sdma_ssi2_8bit_rx0_params},
+ {MXC_DMA_SSI2_8BIT_TX0, &mxc_sdma_ssi2_8bit_tx0_params},
+ {MXC_DMA_SSI2_16BIT_RX0, &mxc_sdma_ssi2_16bit_rx0_params},
+ {MXC_DMA_SSI2_16BIT_TX0, &mxc_sdma_ssi2_16bit_tx0_params},
+ {MXC_DMA_SSI2_24BIT_RX0, &mxc_sdma_ssi2_24bit_rx0_params},
+ {MXC_DMA_SSI2_24BIT_TX0, &mxc_sdma_ssi2_24bit_tx0_params},
+ {MXC_DMA_SSI2_8BIT_RX1, &mxc_sdma_ssi2_8bit_rx1_params},
+ {MXC_DMA_SSI2_8BIT_TX1, &mxc_sdma_ssi2_8bit_tx1_params},
+ {MXC_DMA_SSI2_16BIT_RX1, &mxc_sdma_ssi2_16bit_rx1_params},
+ {MXC_DMA_SSI2_16BIT_TX1, &mxc_sdma_ssi2_16bit_tx1_params},
+ {MXC_DMA_SSI2_24BIT_RX1, &mxc_sdma_ssi2_24bit_rx1_params},
+ {MXC_DMA_SSI2_24BIT_TX1, &mxc_sdma_ssi2_24bit_tx1_params},
+ {MXC_DMA_FIR_RX, &mxc_sdma_fir_rx_params},
+ {MXC_DMA_FIR_TX, &mxc_sdma_fir_tx_params},
+ {MXC_DMA_MEMORY, &mxc_sdma_memory_params},
+ {MXC_DMA_FIFO_MEMORY, &mxc_sdma_fifo_memory_params},
+ {MXC_DMA_ATA_RX, &mxc_sdma_ata_rx_params},
+ {MXC_DMA_ATA_TX, &mxc_sdma_ata_tx_params},
+};
+
+static int mxc_sdma_info_entrys =
+ sizeof(mxc_sdma_active_dma_info) / sizeof(mxc_sdma_active_dma_info[0]);
+
+/*!
+ * This functions Returns the SDMA paramaters associated for a module
+ *
+ * @param channel_id the ID of the module requesting DMA
+ * @return returns the sdma parameters structure for the device
+ */
+mxc_sdma_channel_params_t *mxc_sdma_get_channel_params(mxc_dma_device_t
+ channel_id)
+{
+ mxc_sdma_info_entry_t *p = mxc_sdma_active_dma_info;
+ int i;
+
+ for (i = 0; i < mxc_sdma_info_entrys; i++, p++) {
+ if (p->device == channel_id) {
+ return p->chnl_info;
+ }
+ }
+ return NULL;
+}
+
+/*!
+ * This functions marks the SDMA channels that are statically allocated
+ *
+ * @param chnl the channel array used to store channel information
+ */
+void mxc_get_static_channels(mxc_dma_channel_t * chnl)
+{
+#ifdef CONFIG_SDMA_IRAM
+ int i;
+ for (i = MXC_DMA_CHANNEL_IRAM; i < MAX_DMA_CHANNELS; i++)
+ chnl[i].dynamic = 0;
+#endif /*CONFIG_SDMA_IRAM */
+}
+
+EXPORT_SYMBOL(mxc_sdma_get_channel_params);
+EXPORT_SYMBOL(mxc_get_static_channels);
diff --git a/arch/arm/mach-mx3/dptc.c b/arch/arm/mach-mx3/dptc.c
new file mode 100644
index 000000000000..e4fb0bb74df1
--- /dev/null
+++ b/arch/arm/mach-mx3/dptc.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file dptc.c
+ *
+ * @brief DPTC table for the Freescale Semiconductor MXC DPTC module.
+ *
+ * @ingroup PM
+ */
+
+#include <mach/hardware.h>
+#include <mach/mxc_dptc.h>
+
+struct dptc_wp dptc_wp_allfreq_26ckih[DPTC_WP_SUPPORTED] = {
+ /* 532MHz */
+ /* dcvr0 dcvr1 dcvr2 dcvr3 voltage */
+ /* wp0 */
+ {0xffc00000, 0x95c00000, 0xffc00000, 0xe5800000, 1625},
+ {0xffc00000, 0x95e3e8e4, 0xffc00000, 0xe5b6fda0, 1600},
+ {0xffc00000, 0x95e3e8e4, 0xffc00000, 0xe5b6fda0, 1575},
+ {0xffc00000, 0x95e3e8e8, 0xffc00000, 0xe5f70da4, 1550},
+ {0xffc00000, 0x9623f8e8, 0xffc00000, 0xe6371da8, 1525},
+ /* wp5 */
+ {0xffc00000, 0x966408f0, 0xffc00000, 0xe6b73db0, 1500},
+ {0xffc00000, 0x96e428f4, 0xffc00000, 0xe7776dbc, 1475},
+ {0xffc00000, 0x976448fc, 0xffc00000, 0xe8379dc8, 1450},
+ {0xffc00000, 0x97e46904, 0xffc00000, 0xe977ddd8, 1425},
+ {0xffc00000, 0x98a48910, 0xffc00000, 0xeab81de8, 1400},
+ /* wp10 */
+ {0xffc00000, 0x9964b918, 0xffc00000, 0xebf86df8, 1375},
+ {0xffc00000, 0xffe4e924, 0xffc00000, 0xfff8ae08, 1350},
+ {0xffc00000, 0xffe5192c, 0xffc00000, 0xfff8fe1c, 1350},
+ {0xffc00000, 0xffe54938, 0xffc00000, 0xfff95e2c, 1350},
+ {0xffc00000, 0xffe57944, 0xffc00000, 0xfff9ae44, 1350},
+ /* wp15 */
+ {0xffc00000, 0xffe5b954, 0xffc00000, 0xfffa0e58, 1350},
+ {0xffc00000, 0xffe5e960, 0xffc00000, 0xfffa6e70, 1350},
+};
+
+struct dptc_wp dptc_wp_allfreq_26ckih_TO_2_0[DPTC_WP_SUPPORTED] = {
+ /* Mx31 TO 2.0 Offset table */
+ /* 532MHz */
+ /* dcvr0 dcvr1 dcvr2 dcvr3 voltage */
+ /* wp0 */
+ {0xffc00000, 0x9E265978, 0xffc00000, 0xE4371D9C, 1625},
+ {0xffc00000, 0x9E665978, 0xffc00000, 0xE4772D9C, 1600},
+ {0xffc00000, 0x9EA65978, 0xffc00000, 0xE4772DA0, 1575},
+ {0xffc00000, 0x9EE66978, 0xffc00000, 0xE4B73DA0, 1550},
+ {0xffc00000, 0x9F26697C, 0xffc00000, 0xE4F73DA0, 1525},
+ /* wp5 */
+ {0xffc00000, 0x9F66797C, 0xffc00000, 0xE5774DA4, 1500},
+ {0xffc00000, 0x9FE6797C, 0xffc00000, 0xE5F75DA4, 1475},
+ {0xffc00000, 0xA026897C, 0xffc00000, 0xE6776DA4, 1450},
+ {0xffc00000, 0xA0A6897C, 0xffc00000, 0xE6F77DA8, 1425},
+ {0xffc00000, 0xA0E69980, 0xffc00000, 0xE7B78DAC, 1400},
+ /* wp10 */
+ {0xffc00000, 0xA1669980, 0xffc00000, 0xE8379DAC, 1375},
+ {0xffc00000, 0xA1A6A980, 0xffc00000, 0xE8F7ADB0, 1350},
+ {0xffc00000, 0xA226B984, 0xffc00000, 0xE9F7CDB0, 1325},
+ {0xffc00000, 0xA2A6C984, 0xffc00000, 0xEAB7DDB4, 1300},
+ {0xffc00000, 0xA326C988, 0xffc00000, 0xEBB7FDB8, 1275},
+ /* wp15 */
+ {0xffc00000, 0xA3A6D988, 0xffc00000, 0xECB80DBC, 1250},
+ {0xffc00000, 0xA426E988, 0xffc00000, 0xEDB82DC0, 1225},
+};
+
+struct dptc_wp dptc_wp_allfreq_27ckih_TO_2_0[DPTC_WP_SUPPORTED] = {
+ /* Mx31 TO 2.0 Offset table */
+ /* 532MHz */
+ /* dcvr0 dcvr1 dcvr2 dcvr3 voltage */
+ /* wp0 */
+ {0xffc00000, 0x9864E920, 0xffc00000, 0xDBB50D1C, 1625},
+ {0xffc00000, 0x98A4E920, 0xffc00000, 0xDBF51D1C, 1600},
+ {0xffc00000, 0x98E4E920, 0xffc00000, 0xDBF51D20, 1575},
+ {0xffc00000, 0x9924F920, 0xffc00000, 0xDC352D20, 1550},
+ {0xffc00000, 0x9924F924, 0xffc00000, 0xDC752D20, 1525},
+ /* wp5 */
+ {0xffc00000, 0x99650924, 0xffc00000, 0xDCF53D24, 1500},
+ {0xffc00000, 0x99E50924, 0xffc00000, 0xDD754D24, 1475},
+ {0xffc00000, 0x9A251924, 0xffc00000, 0xDDF55D24, 1450},
+ {0xffc00000, 0x9AA51924, 0xffc00000, 0xDE756D28, 1425},
+ {0xffc00000, 0x9AE52928, 0xffc00000, 0xDF357D2C, 1400},
+ /* wp10 */
+ {0xffc00000, 0x9B652928, 0xffc00000, 0xDFB58D2C, 1375},
+ {0xffc00000, 0x9BA53928, 0xffc00000, 0xE0759D30, 1350},
+ {0xffc00000, 0x9C254928, 0xffc00000, 0xE135BD30, 1325},
+ {0xffc00000, 0x9CA55928, 0xffc00000, 0xE1F5CD34, 1300},
+ {0xffc00000, 0x9D25592C, 0xffc00000, 0xE2F5ED38, 1275},
+ /* wp15 */
+ {0xffc00000, 0x9DA5692C, 0xffc00000, 0xE3F5FD38, 1250},
+ {0xffc00000, 0x9E25792C, 0xffc00000, 0xE4F61D3C, 1225},
+};
diff --git a/arch/arm/mach-mx3/dvfs_v2.c b/arch/arm/mach-mx3/dvfs_v2.c
new file mode 100644
index 000000000000..9500d2a824a6
--- /dev/null
+++ b/arch/arm/mach-mx3/dvfs_v2.c
@@ -0,0 +1,537 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file dvfs_v2.c
+ *
+ * @brief A simplied driver for the Freescale Semiconductor MXC DVFS module.
+ *
+ * Upon initialization, the DVFS driver initializes the DVFS hardware
+ * sets up driver nodes attaches to the DVFS interrupt and initializes internal
+ * data structures. When the DVFS interrupt occurs the driver checks the cause
+ * of the interrupt (lower frequency, increase frequency or emergency) and changes
+ * the CPU voltage according to translation table that is loaded into the driver.
+ *
+ * @ingroup PM
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+
+#include <mach/gpio.h>
+#include <mach/pmic_external.h>
+#include <mach/pmic_power.h>
+
+#include "iomux.h"
+#include "crm_regs.h"
+
+static int dvfs_is_active;
+
+/* Used for tracking the number of interrupts */
+static u32 dvfs_nr_up[4];
+static u32 dvfs_nr_dn[4];
+
+/*
+ * Clock structures
+ */
+static struct clk *cpu_clk;
+static struct clk *ahb_clk;
+
+enum {
+ FSVAI_FREQ_NOCHANGE = 0x0,
+ FSVAI_FREQ_INCREASE,
+ FSVAI_FREQ_DECREASE,
+ FSVAI_FREQ_EMERG,
+};
+
+/*
+ * Frequency increase threshold. Increase frequency change request
+ * will be sent if DVFS counter value will be more than this value.
+ */
+#define DVFS_UPTHR (30 << MXC_CCM_LTR0_UPTHR_OFFSET)
+
+/*
+ * Frequency decrease threshold. Decrease frequency change request
+ * will be sent if DVFS counter value will be less than this value.
+ */
+#define DVFS_DNTHR (18 << MXC_CCM_LTR0_DNTHR_OFFSET)
+
+/*
+ * With the ARM clocked at 532, this setting yields a DIV_3_CLK of 2.03 kHz.
+ */
+#define DVFS_DIV3CK (3 << MXC_CCM_LTR0_DIV3CK_OFFSET)
+
+/*
+ * DNCNT defines the amount of times the down threshold should be exceeded
+ * before DVFS will trigger frequency decrease request.
+ */
+#define DVFS_DNCNT (0x33 << MXC_CCM_LTR1_DNCNT_OFFSET)
+
+/*
+ * UPCNT defines the amount of times the up threshold should be exceeded
+ * before DVFS will trigger frequency increase request.
+ */
+#define DVFS_UPCNT (0x33 << MXC_CCM_LTR1_UPCNT_OFFSET)
+
+/*
+ * Panic threshold. Panic frequency change request
+ * will be sent if DVFS counter value will be more than this value.
+ */
+#define DVFS_PNCTHR (63 << MXC_CCM_LTR1_PNCTHR_OFFSET)
+
+/*
+ * Load tracking buffer source: 1 for ld_add; 0 for pre_ld_add
+ */
+#define DVFS_LTBRSR (1 << MXC_CCM_LTR1_LTBRSR_OFFSET)
+
+/* EMAC defines how many samples are included in EMA calculation */
+#define DVFS_EMAC (0x20 << MXC_CCM_LTR2_EMAC_OFFSET)
+
+const static u8 ltr_gp_weight[] = {
+ 0, /* 0 */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, /* 5 */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, /* 10 */
+ 0,
+ 7,
+ 7,
+ 7,
+ 7, /* 15 */
+};
+
+DEFINE_SPINLOCK(mxc_dvfs_lock);
+
+/*!
+ * This function sets the weight of general purpose signals
+ * @param gp_id number of general purpose bit
+ * @param weight the weight of the general purpose bit
+ */
+static void set_gp_weight(int gp_id, u8 weight)
+{
+ u32 reg;
+
+ if (gp_id < 9) {
+ reg = __raw_readl(MXC_CCM_LTR3);
+ reg = (reg & ~(MXC_CCM_LTR3_WSW_MASK(gp_id))) |
+ (weight << MXC_CCM_LTR3_WSW_OFFSET(gp_id));
+ __raw_writel(reg, MXC_CCM_LTR3);
+ } else if (gp_id < 16) {
+ reg = __raw_readl(MXC_CCM_LTR2);
+ reg = (reg & ~(MXC_CCM_LTR2_WSW_MASK(gp_id))) |
+ (weight << MXC_CCM_LTR2_WSW_OFFSET(gp_id));
+ __raw_writel(reg, MXC_CCM_LTR2);
+ }
+}
+
+static int start_dvfs(void)
+{
+ u32 reg;
+ unsigned long flags;
+
+ if (dvfs_is_active) {
+ return 0;
+ }
+
+ spin_lock_irqsave(&mxc_dvfs_lock, flags);
+
+ reg = __raw_readl(MXC_CCM_PMCR0);
+
+ /* enable dvfs and interrupt */
+ reg = (reg & ~MXC_CCM_PMCR0_FSVAIM) | MXC_CCM_PMCR0_DVFEN;
+
+ __raw_writel(reg, MXC_CCM_PMCR0);
+
+ dvfs_is_active = 1;
+
+ spin_unlock_irqrestore(&mxc_dvfs_lock, flags);
+
+ pr_info("DVFS is started\n");
+
+ return 0;
+}
+
+#define MXC_CCM_LTR0_CONFIG_MASK (MXC_CCM_LTR0_UPTHR_MASK | \
+ MXC_CCM_LTR0_DNTHR_MASK | \
+ MXC_CCM_LTR0_DIV3CK_MASK)
+#define MXC_CCM_LTR0_CONFIG_VAL (DVFS_UPTHR | DVFS_DNTHR | DVFS_DIV3CK)
+
+#define MXC_CCM_LTR1_CONFIG_MASK (MXC_CCM_LTR1_UPCNT_MASK | \
+ MXC_CCM_LTR1_DNCNT_MASK | \
+ MXC_CCM_LTR1_PNCTHR_MASK | \
+ MXC_CCM_LTR1_LTBRSR_MASK)
+#define MXC_CCM_LTR1_CONFIG_VAL (DVFS_UPCNT | DVFS_DNCNT | \
+ DVFS_PNCTHR | DVFS_LTBRSR)
+
+/*!
+ * This function is called for module initialization.
+ * It sets up the DVFS hardware.
+ * It sets default values for DVFS thresholds and counters. The default
+ * values was chosen from a set of different reasonable values. They was tested
+ * and the default values in the driver gave the best results.
+ * More work should be done to find optimal values.
+ *
+ * @return 0 if successful; non-zero otherwise.
+ *
+ */
+static int init_dvfs_controller(void)
+{
+ u32 i, reg;
+
+ /* Configure 2 MC13783 DVFS pins */
+ mxc_request_iomux(MX31_PIN_DVFS0, OUTPUTCONFIG_FUNC, INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_DVFS1, OUTPUTCONFIG_FUNC, INPUTCONFIG_NONE);
+
+ /* Configure MC13783 voltage ready input pin */
+ mxc_request_iomux(MX31_PIN_GPIO1_5, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_FUNC);
+
+ /* setup LTR0 */
+ reg = __raw_readl(MXC_CCM_LTR0);
+ reg = (reg & ~(MXC_CCM_LTR0_CONFIG_MASK)) | MXC_CCM_LTR0_CONFIG_VAL;
+ __raw_writel(reg, MXC_CCM_LTR0);
+
+ /* set up LTR1 */
+ reg = __raw_readl(MXC_CCM_LTR1);
+ reg = (reg & ~(MXC_CCM_LTR1_CONFIG_MASK)) | MXC_CCM_LTR1_CONFIG_VAL;
+ __raw_writel(reg, MXC_CCM_LTR1);
+
+ /* setup LTR2 */
+ reg = __raw_readl(MXC_CCM_LTR2);
+ reg = (reg & ~(MXC_CCM_LTR2_EMAC_MASK)) | DVFS_EMAC;
+ __raw_writel(reg, MXC_CCM_LTR2);
+
+ /* Set general purpose weights to 0 */
+ for (i = 0; i < 16; i++) {
+ set_gp_weight(i, ltr_gp_weight[i]);
+ }
+
+ /* ARM interrupt, mask load buf full interrupt */
+ reg = __raw_readl(MXC_CCM_PMCR0);
+ reg |= MXC_CCM_PMCR0_DVFIS | MXC_CCM_PMCR0_LBMI;
+ __raw_writel(reg, MXC_CCM_PMCR0);
+
+ /* configuring EMI Handshake and PLL relock disable */
+ reg = __raw_readl(MXC_CCM_PMCR1);
+ reg |= MXC_CCM_PMCR1_PLLRDIS;
+ reg |= MXC_CCM_PMCR1_EMIRQ_EN;
+ __raw_writel(reg, MXC_CCM_PMCR1);
+
+ return 0;
+}
+
+static irqreturn_t dvfs_irq(int irq, void *dev_id)
+{
+ u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0);
+ u32 fsvai = (pmcr0 & MXC_CCM_PMCR0_FSVAI_MASK) >>
+ MXC_CCM_PMCR0_FSVAI_OFFSET;
+ u32 dvsup = (pmcr0 & MXC_CCM_PMCR0_DVSUP_MASK) >>
+ MXC_CCM_PMCR0_DVSUP_OFFSET;
+ u32 curr_ahb, curr_cpu, rate;
+
+ /* Should not be here if FSVAIM is set */
+ BUG_ON(pmcr0 & MXC_CCM_PMCR0_FSVAIM);
+
+ if (fsvai == FSVAI_FREQ_NOCHANGE) {
+ /* Do nothing. Freq change is not required */
+ printk(KERN_WARNING "fsvai should not be 0\n");
+ return IRQ_HANDLED;
+ }
+
+ if (!(pmcr0 & MXC_CCM_PMCR0_UPDTEN)) {
+ /* Do nothing. DVFS didn't finish previous flow update */
+ return IRQ_HANDLED;
+ }
+
+ if (((dvsup == DVSUP_LOW) && (fsvai == FSVAI_FREQ_DECREASE)) ||
+ ((dvsup == DVSUP_TURBO) && ((fsvai == FSVAI_FREQ_INCREASE) ||
+ (fsvai == FSVAI_FREQ_EMERG)))) {
+ /* Interrupt should be disabled in these cases according to
+ * the spec since DVFS is already at lowest (highest) state */
+ printk(KERN_WARNING "Something is wrong?\n");
+ return IRQ_HANDLED;
+ }
+
+ curr_ahb = clk_get_rate(ahb_clk);
+ if (fsvai == FSVAI_FREQ_DECREASE) {
+ curr_cpu = clk_get_rate(cpu_clk);
+ rate = ((curr_cpu / curr_ahb) - 1) * curr_ahb;
+ if ((cpu_is_mx31_rev(CHIP_REV_2_0) < 0) &&
+ ((curr_cpu / curr_ahb) == 4)) {
+ rate = ((curr_cpu / curr_ahb) - 2) * curr_ahb;
+ }
+ dvfs_nr_dn[dvsup]++;
+ } else {
+ rate = 4 * curr_ahb;
+ dvfs_nr_up[dvsup]++;
+ }
+
+ clk_set_rate(cpu_clk, rate);
+ return IRQ_HANDLED;
+}
+
+/*!
+ * This function disables the DVFS module.
+ */
+static void stop_dvfs(void)
+{
+ u32 pmcr0, dvsup;
+ unsigned long flags;
+ u32 curr_ahb = clk_get_rate(ahb_clk);
+
+ if (dvfs_is_active) {
+ spin_lock_irqsave(&mxc_dvfs_lock, flags);
+
+ pmcr0 = __raw_readl(MXC_CCM_PMCR0);
+ dvsup = (pmcr0 & MXC_CCM_PMCR0_DVSUP_MASK) >>
+ MXC_CCM_PMCR0_DVSUP_OFFSET;
+ if (dvsup != DVSUP_TURBO) {
+ /* Use sw delay to insure volt/freq change */
+ clk_set_rate(cpu_clk, (4 * curr_ahb));
+ udelay(200);
+ }
+
+ pmcr0 = __raw_readl(MXC_CCM_PMCR0);
+ /* disable dvfs and its interrupt */
+ pmcr0 = (pmcr0 & ~MXC_CCM_PMCR0_DVFEN) | MXC_CCM_PMCR0_FSVAIM;
+ __raw_writel(pmcr0, MXC_CCM_PMCR0);
+
+ dvfs_is_active = 0;
+
+ spin_unlock_irqrestore(&mxc_dvfs_lock, flags);
+ }
+
+ pr_info("DVFS is stopped\n");
+}
+
+void pmic_voltage_init(void)
+{
+ t_regulator_voltage volt;
+
+ /* Enable 4 mc13783 output voltages */
+ pmic_write_reg(REG_ARBITRATION_SWITCHERS, (1 << 5), (1 << 5));
+
+ /* Set mc13783 DVS speed 25mV each 4us */
+ pmic_write_reg(REG_SWITCHERS_4, (0 << 6), (3 << 6));
+
+ if (cpu_is_mx31())
+ volt.sw1a = SW1A_1_625V;
+ else
+ volt.sw1a = SW1A_1_425V;
+
+ pmic_power_regulator_set_voltage(SW_SW1A, volt);
+
+ volt.sw1a = SW1A_1_25V;
+ pmic_power_switcher_set_dvs(SW_SW1A, volt);
+
+ if (cpu_is_mx32()) {
+ volt.sw1a = SW1A_0_975V;
+ pmic_power_switcher_set_stby(SW_SW1A, volt);
+ }
+
+ volt.sw1b = SW1A_1_25V;
+ pmic_power_switcher_set_dvs(SW_SW1B, volt);
+
+ volt.sw1b = SW1A_1_25V;
+ pmic_power_switcher_set_stby(SW_SW1B, volt);
+}
+
+static ssize_t dvfs_enable_store(struct sys_device *dev, struct sysdev_attribute *attr,
+ const char *buf, size_t size)
+{
+ if (strstr(buf, "1") != NULL) {
+ if (start_dvfs() != 0) {
+ printk(KERN_ERR "Failed to start DVFS\n");
+ }
+ } else if (strstr(buf, "0") != NULL) {
+ stop_dvfs();
+ }
+
+ return size;
+}
+
+static ssize_t dvfs_status_show(struct sys_device *dev, struct sysdev_attribute *attr,
+ char *buf)
+{
+ int size = 0;
+
+ if (dvfs_is_active) {
+ size = sprintf(buf, "DVFS is enabled\n");
+ } else {
+ size = sprintf(buf, "DVFS is disabled\n");
+ }
+ size +=
+ sprintf((buf + size), "UP:\t%d\t%d\t%d\t%d\n", dvfs_nr_up[0],
+ dvfs_nr_up[1], dvfs_nr_up[2], dvfs_nr_up[3]);
+ size +=
+ sprintf((buf + size), "DOWN:\t%d\t%d\t%d\t%d\n\n", dvfs_nr_dn[0],
+ dvfs_nr_dn[1], dvfs_nr_dn[2], dvfs_nr_dn[3]);
+
+ return size;
+}
+
+static ssize_t dvfs_status_store(struct sys_device *dev, struct sysdev_attribute *attr,
+ const char *buf, size_t size)
+{
+ if (strstr(buf, "reset") != NULL) {
+ int i;
+ for (i = 0; i < 4; i++) {
+ dvfs_nr_up[i] = 0;
+ dvfs_nr_dn[i] = 0;
+ }
+ }
+
+ return size;
+}
+
+static ssize_t dvfs_debug_show(struct sys_device *dev, struct sysdev_attribute *attr,
+ char *buf)
+{
+ int size = 0;
+ u32 curr_ahb, curr_cpu;
+
+ curr_ahb = clk_get_rate(ahb_clk);
+ curr_cpu = clk_get_rate(cpu_clk);
+
+ pr_debug("ahb %d, cpu %d\n", curr_ahb, curr_cpu);
+
+ return size;
+}
+
+static ssize_t dvfs_debug_store(struct sys_device *dev, struct sysdev_attribute *attr,
+ const char *buf, size_t size)
+{
+ u32 curr_ahb, curr_cpu, rate = 0;
+
+ curr_ahb = clk_get_rate(ahb_clk);
+ curr_cpu = clk_get_rate(cpu_clk);
+
+ if (strstr(buf, "inc") != NULL) {
+ rate = 4 * curr_ahb;
+ pr_debug("inc to %d\n", rate);
+ }
+
+ if (strstr(buf, "dec") != NULL) {
+ rate = ((curr_cpu / curr_ahb) - 1) * curr_ahb;
+ if ((cpu_is_mx31_rev(CHIP_REV_2_0) < 0) &&
+ ((curr_cpu / curr_ahb) == 4))
+ rate = ((curr_cpu / curr_ahb) - 2) * curr_ahb;
+
+ pr_debug("dec to %d\n", rate);
+ }
+
+ clk_set_rate(cpu_clk, rate);
+
+ return size;
+}
+
+static SYSDEV_ATTR(enable, 0200, NULL, dvfs_enable_store);
+static SYSDEV_ATTR(status, 0644, dvfs_status_show, dvfs_status_store);
+static SYSDEV_ATTR(debug, 0644, dvfs_debug_show, dvfs_debug_store);
+
+static struct sysdev_class dvfs_sysclass = {
+ .name = "dvfs",
+};
+
+static struct sys_device dvfs_device = {
+ .id = 0,
+ .cls = &dvfs_sysclass,
+};
+
+static int dvfs_sysdev_ctrl_init(void)
+{
+ int err;
+
+ err = sysdev_class_register(&dvfs_sysclass);
+ if (!err)
+ err = sysdev_register(&dvfs_device);
+ if (!err) {
+ err = sysdev_create_file(&dvfs_device, &attr_enable);
+ err = sysdev_create_file(&dvfs_device, &attr_status);
+ err = sysdev_create_file(&dvfs_device, &attr_debug);
+ }
+
+ return err;
+}
+
+static void dvfs_sysdev_ctrl_exit(void)
+{
+ sysdev_remove_file(&dvfs_device, &attr_enable);
+ sysdev_remove_file(&dvfs_device, &attr_status);
+ sysdev_unregister(&dvfs_device);
+ sysdev_class_unregister(&dvfs_sysclass);
+}
+
+static int __init dvfs_init(void)
+{
+ int err = 0;
+ pmic_voltage_init();
+
+ cpu_clk = clk_get(NULL, "cpu_clk");
+ ahb_clk = clk_get(NULL, "ahb_clk");
+ err = init_dvfs_controller();
+ if (err) {
+ printk(KERN_ERR "DVFS: Unable to initialize DVFS");
+ return err;
+ }
+
+ /* request the DVFS interrupt */
+ err = request_irq(MXC_INT_DVFS, dvfs_irq, IRQF_DISABLED, "dvfs", NULL);
+ if (err) {
+ printk(KERN_ERR "DVFS: Unable to attach to DVFS interrupt");
+ }
+
+ err = dvfs_sysdev_ctrl_init();
+ if (err) {
+ printk(KERN_ERR
+ "DVFS: Unable to register sysdev entry for dvfs");
+ return err;
+ }
+
+ return err;
+}
+
+static void __exit dvfs_cleanup(void)
+{
+ stop_dvfs();
+
+ /* release the DVFS interrupt */
+ free_irq(MXC_INT_DVFS, NULL);
+
+ dvfs_sysdev_ctrl_exit();
+
+ clk_put(cpu_clk);
+ clk_put(ahb_clk);
+}
+
+module_init(dvfs_init);
+module_exit(dvfs_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("DVFS driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-mx3/iomux.c b/arch/arm/mach-mx3/iomux.c
index 6e664be8cc13..7d2f46c63116 100644
--- a/arch/arm/mach-mx3/iomux.c
+++ b/arch/arm/mach-mx3/iomux.c
@@ -1,113 +1,260 @@
/*
- * Copyright 2004-2006 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright (C) 2008 by Sascha Hauer <kernel@pengutronix.de>
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup GPIO_MX31 Board GPIO and Muxing Setup
+ * @ingroup MSL_MX31
+ */
+/*!
+ * @file mach-mx3/iomux.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.
+ * @brief I/O Muxing control functions
*
- * 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.
+ * @ingroup GPIO_MX31
*/
+#include <linux/io.h>
#include <linux/module.h>
#include <linux/spinlock.h>
-#include <linux/io.h>
-#include <linux/gpio.h>
#include <mach/hardware.h>
#include <mach/gpio.h>
-#include <mach/iomux-mx3.h>
+#include "iomux.h"
-/*
+/*!
+ * 4 control fields per MUX register
+ */
+#define MUX_CTL_FIELDS 4
+
+/*!
+ * 3 control fields per PAD register
+ */
+#define PAD_CTL_FIELDS 3
+
+/*!
+ * Maximum number of MUX pins
+ * Number of pins = (highest iomux reg - lowest iomux reg + 1) * (4 pins/reg)
+ */
+#define MUX_PIN_NUM_MAX \
+ (((u32 *)IOMUXSW_MUX_END - (u32 *)IOMUXSW_MUX_CTL + 1) * MUX_CTL_FIELDS)
+
+/*!
+ * Number of pad controls =
+ * (highest pad ctl reg - lowest pad ctl reg + 1) * (3 pins/reg)
+ */
+#define PAD_CTL_NUM_MAX \
+ (((u32 *)IOMUXSW_PAD_END - (u32 *)IOMUXSW_PAD_CTL + 1) * PAD_CTL_FIELDS)
+
+#define PIN_TO_IOMUX_INDEX(pin) ((pin >> MUX_I) & ((1 << (MUX_F - MUX_I)) - 1))
+#define PIN_TO_IOMUX_FIELD(pin) ((pin >> MUX_F) & ((1 << (PAD_I - MUX_F)) - 1))
+
+/*!
+ * 8 bits for each MUX control field
+ */
+#define MUX_CTL_BIT_LEN 8
+
+/*!
+ * 10 bits for each PAD control field
+ */
+#define MUX_PAD_BIT_LEN 10
+
+/*!
* IOMUX register (base) addresses
*/
-#define IOMUX_BASE IO_ADDRESS(IOMUXC_BASE_ADDR)
-#define IOMUXINT_OBS1 (IOMUX_BASE + 0x000)
-#define IOMUXINT_OBS2 (IOMUX_BASE + 0x004)
-#define IOMUXGPR (IOMUX_BASE + 0x008)
-#define IOMUXSW_MUX_CTL (IOMUX_BASE + 0x00C)
-#define IOMUXSW_PAD_CTL (IOMUX_BASE + 0x154)
+enum iomux_reg_addr {
+ IOMUXGPR = IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x008, /*!< General purpose */
+ IOMUXSW_MUX_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x00C, /*!< MUX control */
+ IOMUXSW_MUX_END = IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x150, /*!< last MUX control register */
+ IOMUXSW_PAD_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x154, /*!< Pad control */
+ IOMUXSW_PAD_END = IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x308, /*!< last Pad control register */
+ IOMUXINT_OBS1 = IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x000, /*!< Observe interrupts 1 */
+ IOMUXINT_OBS2 = IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x004, /*!< Observe interrupts 2 */
+};
+/* len - mask bit length; fld - mask bit field. Example, to have the mask:
+ * 0xFF000000, use GET_FIELD_MASK(8, 3). Translate in plain language:
+ * "set the 3rd (0-based) 8-bit-long field to all 1's */
+#define GET_FIELD_MASK(len, fld) (((1 << len) - 1) << (len * fld))
static DEFINE_SPINLOCK(gpio_mux_lock);
+static u8 iomux_pin_res_table[MUX_PIN_NUM_MAX];
-#define IOMUX_REG_MASK (IOMUX_PADNUM_MASK & ~0x3)
-/*
- * set the mode for a IOMUX pin.
+/*!
+ * This function is used to configure a pin through the IOMUX module.
+ * FIXED ME: for backward compatible. Will be static function!
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param out an output function as defined in \b #iomux_pin_ocfg_t
+ * @param in an input function as defined in \b #iomux_pin_icfg_t
+ *
+ * @return 0 if successful; Non-zero otherwise
*/
-int mxc_iomux_mode(unsigned int pin_mode)
+int iomux_config_mux(iomux_pin_name_t pin, iomux_pin_ocfg_t out,
+ iomux_pin_icfg_t in)
{
- u32 field, l, mode, ret = 0;
- void __iomem *reg;
-
- reg = IOMUXSW_MUX_CTL + (pin_mode & IOMUX_REG_MASK);
- field = pin_mode & 0x3;
- mode = (pin_mode & IOMUX_MODE_MASK) >> IOMUX_MODE_SHIFT;
+ u32 reg, l, ret = 0;
+ u32 mux_index = PIN_TO_IOMUX_INDEX(pin);
+ u32 mux_field = PIN_TO_IOMUX_FIELD(pin);
+ u32 mux_mask = GET_FIELD_MASK(MUX_CTL_BIT_LEN, mux_field);
+ u8 *rp;
- pr_debug("%s: reg offset = 0x%x field = %d mode = 0x%02x\n",
- __func__, (pin_mode & IOMUX_REG_MASK), field, mode);
+ BUG_ON((mux_index > (MUX_PIN_NUM_MAX / MUX_CTL_FIELDS - 1)) ||
+ (mux_field >= MUX_CTL_FIELDS));
+ reg = IOMUXSW_MUX_CTL + (mux_index * 4);
spin_lock(&gpio_mux_lock);
-
l = __raw_readl(reg);
- l &= ~(0xff << (field * 8));
- l |= mode << (field * 8);
+ l = (l & (~mux_mask)) |
+ (((out << 4) | in) << (mux_field * MUX_CTL_BIT_LEN));
__raw_writel(l, reg);
-
+ /*
+ * Log a warning if a pin changes ownership
+ */
+ rp = iomux_pin_res_table + mux_index * MUX_CTL_FIELDS + mux_field;
+ if (out & *rp && *rp != ((out << 4) | in)) {
+ /*
+ * Don't call printk if we're tweaking the console uart or
+ * we'll deadlock.
+ */
+ if (pin != MX31_PIN_CTS1 &&
+ pin != MX31_PIN_RTS1 &&
+ pin != MX31_PIN_DCD_DCE1 &&
+ pin != MX31_PIN_DSR_DTE1 &&
+ pin != MX31_PIN_DTR_DTE1 &&
+ pin != MX31_PIN_RI_DCE1 &&
+ pin != MX31_PIN_DSR_DCE1 &&
+ pin != MX31_PIN_DTR_DCE1 &&
+ pin != MX31_PIN_RXD1 && pin != MX31_PIN_TXD1) {
+ printk(KERN_ERR "iomux_config_mux: Warning: iomux pin"
+ " config changed, index=%d field=%d, "
+ " prev=0x%x new=0x%x\n", mux_index, mux_field,
+ *rp, (out << 4) | in);
+ }
+ ret = -EINVAL;
+ }
+ *rp = (out << 4) | in;
spin_unlock(&gpio_mux_lock);
return ret;
}
-EXPORT_SYMBOL(mxc_iomux_mode);
-/*
- * This function configures the pad value for a IOMUX pin.
+/*!
+ * Request ownership for an IO pin. This function has to be the first one
+ * being called before that pin is used. The caller has to check the
+ * return value to make sure it returns 0.
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param out an output function as defined in \b #iomux_pin_ocfg_t
+ * @param in an input function as defined in \b #iomux_pin_icfg_t
+ *
+ * @return 0 if successful; Non-zero otherwise
*/
-void mxc_iomux_set_pad(enum iomux_pins pin, u32 config)
+int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_ocfg_t out,
+ iomux_pin_icfg_t in)
{
- u32 field, l;
- void __iomem *reg;
+ int ret = iomux_config_mux(pin, out, in);
+ if (out == OUTPUTCONFIG_GPIO && in == INPUTCONFIG_GPIO) {
+ ret |= mxc_request_gpio(pin);
+ }
+ return ret;
+}
- reg = IOMUXSW_PAD_CTL + (pin + 2) / 3;
- field = (pin + 2) % 3;
+/*!
+ * Release ownership for an IO pin
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param out an output function as defined in \b #iomux_pin_ocfg_t
+ * @param in an input function as defined in \b #iomux_pin_icfg_t
+ */
+void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_ocfg_t out,
+ iomux_pin_icfg_t in)
+{
+ u32 mux_index = PIN_TO_IOMUX_INDEX(pin);
+ u32 mux_field = PIN_TO_IOMUX_FIELD(pin);
+ u8 *rp = iomux_pin_res_table + mux_index * MUX_CTL_FIELDS + mux_field;
- pr_debug("%s: reg offset = 0x%x field = %d\n",
- __func__, (pin + 2) / 3, field);
+ BUG_ON((mux_index > (MUX_PIN_NUM_MAX / MUX_CTL_FIELDS - 1)) ||
+ (mux_field >= MUX_CTL_FIELDS));
- spin_lock(&gpio_mux_lock);
+ *rp = 0;
+ if (out == OUTPUTCONFIG_GPIO && in == INPUTCONFIG_GPIO) {
+ mxc_free_gpio(pin);
+ }
+}
+/*!
+ * This function configures the pad value for a IOMUX pin.
+ *
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param config the ORed value of elements defined in \b #iomux_pad_config_t
+ */
+void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config)
+{
+ u32 reg, l;
+ u32 pad_index = (pin >> PAD_I) & ((1 << (PAD_F - PAD_I)) - 1);
+ u32 pad_field = (pin >> PAD_F) & ((1 << (MUX_IO_I - PAD_F)) - 1);
+ u32 pad_mask = GET_FIELD_MASK(MUX_PAD_BIT_LEN, pad_field);
+
+ BUG_ON((pad_index > (PAD_CTL_NUM_MAX / PAD_CTL_FIELDS - 1)) ||
+ (pad_field >= PAD_CTL_FIELDS));
+
+ reg = IOMUXSW_PAD_CTL + (pad_index * 4);
+ spin_lock(&gpio_mux_lock);
l = __raw_readl(reg);
- l &= ~(0x1ff << (field * 9));
- l |= config << (field * 9);
+ l = (l & (~pad_mask)) | (config << (pad_field * MUX_PAD_BIT_LEN));
__raw_writel(l, reg);
-
spin_unlock(&gpio_mux_lock);
}
-EXPORT_SYMBOL(mxc_iomux_set_pad);
/*
+ * FIXED ME: for backward compatible. to be removed!
+ */
+void iomux_config_pad(iomux_pin_name_t pin, u32 config)
+{
+ mxc_iomux_set_pad(pin, config);
+}
+
+/*!
* This function enables/disables the general purpose function for a particular
* signal.
+ *
+ * @param gp one signal as defined in \b #iomux_gp_func_t
+ * @param en \b #true to enable; \b #false to disable
*/
-void mxc_iomux_set_gpr(enum iomux_gp_func gp, bool en)
+void mxc_iomux_set_gpr(iomux_gp_func_t gp, bool en)
{
u32 l;
spin_lock(&gpio_mux_lock);
l = __raw_readl(IOMUXGPR);
- if (en)
+ if (en) {
l |= gp;
- else
+ } else {
l &= ~gp;
-
+ }
__raw_writel(l, IOMUXGPR);
spin_unlock(&gpio_mux_lock);
}
-EXPORT_SYMBOL(mxc_iomux_set_gpr);
+/*!
+ * FIXED ME: for backward compatible. to be removed!
+ */
+void iomux_config_gpr(iomux_gp_func_t gp, bool en)
+{
+ mxc_iomux_set_gpr(gp, en);
+}
+
+EXPORT_SYMBOL(mxc_request_iomux);
+EXPORT_SYMBOL(mxc_free_iomux);
+EXPORT_SYMBOL(mxc_iomux_set_pad);
+EXPORT_SYMBOL(mxc_iomux_set_gpr);
+EXPORT_SYMBOL(iomux_config_pad);
+EXPORT_SYMBOL(iomux_config_gpr);
+EXPORT_SYMBOL(iomux_config_mux);
diff --git a/arch/arm/mach-mx3/iomux.h b/arch/arm/mach-mx3/iomux.h
new file mode 100644
index 000000000000..4ded04252637
--- /dev/null
+++ b/arch/arm/mach-mx3/iomux.h
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __MACH_MX31_IOMUX_H__
+#define __MACH_MX31_IOMUX_H__
+
+#include <linux/types.h>
+#include <mach/gpio.h>
+#include "mx31_pins.h"
+
+/*!
+ * @file mach-mx3/iomux.h
+ *
+ * @brief I/O Muxing control definitions and functions
+ *
+ * @ingroup GPIO_MX31
+ */
+
+/*!
+ * various IOMUX output functions
+ */
+typedef enum iomux_output_config {
+ OUTPUTCONFIG_GPIO = 0, /*!< used as GPIO */
+ OUTPUTCONFIG_FUNC, /*!< used as function */
+ OUTPUTCONFIG_ALT1, /*!< used as alternate function 1 */
+ OUTPUTCONFIG_ALT2, /*!< used as alternate function 2 */
+ OUTPUTCONFIG_ALT3, /*!< used as alternate function 3 */
+ OUTPUTCONFIG_ALT4, /*!< used as alternate function 4 */
+ OUTPUTCONFIG_ALT5, /*!< used as alternate function 5 */
+ OUTPUTCONFIG_ALT6 /*!< used as alternate function 6 */
+} iomux_pin_ocfg_t;
+
+/*!
+ * various IOMUX input functions
+ */
+typedef enum iomux_input_config {
+ INPUTCONFIG_NONE = 0, /*!< not configured for input */
+ INPUTCONFIG_GPIO = 1 << 0, /*!< used as GPIO */
+ INPUTCONFIG_FUNC = 1 << 1, /*!< used as function */
+ INPUTCONFIG_ALT1 = 1 << 2, /*!< used as alternate function 1 */
+ INPUTCONFIG_ALT2 = 1 << 3 /*!< used as alternate function 2 */
+} iomux_pin_icfg_t;
+
+/*!
+ * various IOMUX pad functions
+ */
+typedef enum iomux_pad_config {
+ PAD_CTL_NOLOOPBACK = 0x0 << 9,
+ PAD_CTL_LOOPBACK = 0x1 << 9,
+ PAD_CTL_PKE_NONE = 0x0 << 8,
+ PAD_CTL_PKE_ENABLE = 0x1 << 8,
+ PAD_CTL_PUE_KEEPER = 0x0 << 7,
+ PAD_CTL_PUE_PUD = 0x1 << 7,
+ PAD_CTL_100K_PD = 0x0 << 5,
+ PAD_CTL_100K_PU = 0x1 << 5,
+ PAD_CTL_47K_PU = 0x2 << 5,
+ PAD_CTL_22K_PU = 0x3 << 5,
+ PAD_CTL_HYS_CMOS = 0x0 << 4,
+ PAD_CTL_HYS_SCHMITZ = 0x1 << 4,
+ PAD_CTL_ODE_CMOS = 0x0 << 3,
+ PAD_CTL_ODE_OpenDrain = 0x1 << 3,
+ PAD_CTL_DRV_NORMAL = 0x0 << 1,
+ PAD_CTL_DRV_HIGH = 0x1 << 1,
+ PAD_CTL_DRV_MAX = 0x2 << 1,
+ PAD_CTL_SRE_SLOW = 0x0 << 0,
+ PAD_CTL_SRE_FAST = 0x1 << 0
+} iomux_pad_config_t;
+
+/*!
+ * various IOMUX general purpose functions
+ */
+typedef enum iomux_gp_func {
+ MUX_PGP_FIRI = 0x1 << 0,
+ MUX_DDR_MODE = 0x1 << 1,
+ MUX_PGP_CSPI_BB = 0x1 << 2,
+ MUX_PGP_ATA_1 = 0x1 << 3,
+ MUX_PGP_ATA_2 = 0x1 << 4,
+ MUX_PGP_ATA_3 = 0x1 << 5,
+ MUX_PGP_ATA_4 = 0x1 << 6,
+ MUX_PGP_ATA_5 = 0x1 << 7,
+ MUX_PGP_ATA_6 = 0x1 << 8,
+ MUX_PGP_ATA_7 = 0x1 << 9,
+ MUX_PGP_ATA_8 = 0x1 << 10,
+ MUX_PGP_UH2 = 0x1 << 11,
+ MUX_SDCTL_CSD0_SEL = 0x1 << 12,
+ MUX_SDCTL_CSD1_SEL = 0x1 << 13,
+ MUX_CSPI1_UART3 = 0x1 << 14,
+ MUX_EXTDMAREQ2_MBX_SEL = 0x1 << 15,
+ MUX_TAMPER_DETECT_EN = 0x1 << 16,
+ MUX_PGP_USB_4WIRE = 0x1 << 17,
+ MUX_PGB_USB_COMMON = 0x1 << 18,
+ MUX_SDHC_MEMSTICK1 = 0x1 << 19,
+ MUX_SDHC_MEMSTICK2 = 0x1 << 20,
+ MUX_PGP_SPLL_BYP = 0x1 << 21,
+ MUX_PGP_UPLL_BYP = 0x1 << 22,
+ MUX_PGP_MSHC1_CLK_SEL = 0x1 << 23,
+ MUX_PGP_MSHC2_CLK_SEL = 0x1 << 24,
+ MUX_CSPI3_UART5_SEL = 0x1 << 25,
+ MUX_PGP_ATA_9 = 0x1 << 26,
+ MUX_PGP_USB_SUSPEND = 0x1 << 27,
+ MUX_PGP_USB_OTG_LOOPBACK = 0x1 << 28,
+ MUX_PGP_USB_HS1_LOOPBACK = 0x1 << 29,
+ MUX_PGP_USB_HS2_LOOPBACK = 0x1 << 30,
+ MUX_CLKO_DDR_MODE = 0x1 << 31,
+} iomux_gp_func_t;
+
+/*!
+ * This function is used to configure a pin through the IOMUX module.
+ *
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param out an output function as defined in \b #iomux_pin_ocfg_t
+ * @param in an input function as defined in \b #iomux_pin_icfg_t
+ * @return 0 if successful; Non-zero otherwise
+ */
+int iomux_config_mux(iomux_pin_name_t pin, iomux_pin_ocfg_t out,
+ iomux_pin_icfg_t in);
+
+/*!
+ * This function configures the pad value for a IOMUX pin.
+ *
+ * @param pin a pin number as defined in \b #iomux_pins
+ * @param config ORed value of elements defined in \b #iomux_pad_config_t
+ */
+void iomux_config_pad(iomux_pin_name_t pin, __u32 config);
+
+/*!
+ * This function enables/disables the general purpose function for a particular
+ * signal.
+ *
+ * @param gp one signal as defined in \b #iomux_gp_func_t
+ * @param en \b #true to enable; \b #false to disable
+ */
+void iomux_config_gpr(iomux_gp_func_t gp, bool en);
+
+/*!
+ * Request ownership for an IO pin. This function has to be the first one
+ * being called before that pin is used. The caller has to check the
+ * return value to make sure it returns 0.
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param out an output function as defined in \b #iomux_pin_ocfg_t
+ * @param in an input function as defined in \b #iomux_pin_icfg_t
+ *
+ * @return 0 if successful; Non-zero otherwise
+ */
+int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_ocfg_t out,
+ iomux_pin_icfg_t in);
+
+/*!
+ * Release ownership for an IO pin
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param out an output function as defined in \b #iomux_pin_ocfg_t
+ * @param in an input function as defined in \b #iomux_pin_icfg_t
+ */
+void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_ocfg_t out,
+ iomux_pin_icfg_t in);
+
+/*!
+ * This function enables/disables the general purpose function for a particular
+ * signal.
+ *
+ * @param gp one signal as defined in \b #iomux_gp_func_t
+ * @param en \b #true to enable; \b #false to disable
+ */
+void mxc_iomux_set_gpr(iomux_gp_func_t gp, bool en);
+
+/*!
+ * This function configures the pad value for a IOMUX pin.
+ *
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param config the ORed value of elements defined in \b #iomux_pad_config_t
+ */
+void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config);
+
+#endif
diff --git a/arch/arm/mach-mx3/mm.c b/arch/arm/mach-mx3/mm.c
index 0589b5cd33c7..40379fa5abdf 100644
--- a/arch/arm/mach-mx3/mm.c
+++ b/arch/arm/mach-mx3/mm.c
@@ -22,18 +22,10 @@
#include <linux/mm.h>
#include <linux/init.h>
-#include <mach/hardware.h>
#include <asm/pgtable.h>
#include <asm/mach/map.h>
#include <mach/common.h>
-
-/*!
- * @file mm.c
- *
- * @brief This file creates static virtual to physical mappings, common to all MX3 boards.
- *
- * @ingroup Memory
- */
+#include <mach/hardware.h>
/*!
* This table defines static virtual address mappings for I/O regions.
@@ -41,16 +33,40 @@
*/
static struct map_desc mxc_io_desc[] __initdata = {
{
- .virtual = X_MEMC_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(X_MEMC_BASE_ADDR),
- .length = X_MEMC_SIZE,
- .type = MT_DEVICE
- }, {
- .virtual = AVIC_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AVIC_BASE_ADDR),
- .length = AVIC_SIZE,
- .type = MT_DEVICE_NONSHARED
- },
+ .virtual = IRAM_BASE_ADDR_VIRT & 0xFFF00000,
+ .pfn = __phys_to_pfn(IRAM_BASE_ADDR & 0xFFF00000),
+ .length = SZ_1M,
+ .type = MT_DEVICE_NONSHARED},
+ {
+ .virtual = X_MEMC_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(X_MEMC_BASE_ADDR),
+ .length = X_MEMC_SIZE,
+ .type = MT_DEVICE},
+ {
+ .virtual = AVIC_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AVIC_BASE_ADDR),
+ .length = AVIC_SIZE,
+ .type = MT_DEVICE_NONSHARED},
+ {
+ .virtual = AIPS1_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
+ .length = AIPS1_SIZE,
+ .type = MT_DEVICE_NONSHARED},
+ {
+ .virtual = SPBA0_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
+ .length = SPBA0_SIZE,
+ .type = MT_DEVICE_NONSHARED},
+ {
+ .virtual = AIPS2_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
+ .length = AIPS2_SIZE,
+ .type = MT_DEVICE_NONSHARED},
+ {
+ .virtual = CS4_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(CS4_BASE_ADDR),
+ .length = CS4_SIZE,
+ .type = MT_DEVICE},
};
/*!
diff --git a/arch/arm/mach-mx3/mx31_pins.h b/arch/arm/mach-mx3/mx31_pins.h
new file mode 100644
index 000000000000..2e2274922069
--- /dev/null
+++ b/arch/arm/mach-mx3/mx31_pins.h
@@ -0,0 +1,429 @@
+/*
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_MXC_MX31_PINS_H__
+#define __ASM_ARCH_MXC_MX31_PINS_H__
+
+/*!
+ * @file arch-mxc/mx31_pins.h
+ *
+ * @brief MX31 I/O Pin List
+ *
+ * @ingroup GPIO_MX31
+ */
+
+#ifndef __ASSEMBLY__
+
+/*!
+ * @name IOMUX/PAD Bit field definitions
+ */
+
+/*! @{ */
+
+/*!
+ * In order to identify pins more effectively, each mux-controlled pin's
+ * enumerated value is constructed in the following way:
+ *
+ * -------------------------------------------------------------------
+ * 31-29 | 28 - 24 |23 - 21| 20 | 19 - 18 | 17 - 10| 9 - 8 | 7 - 0
+ * -------------------------------------------------------------------
+ * IO_P | IO_I | RSVD | PAD_F | PAD_I | MUX_F | MUX_I
+ * -------------------------------------------------------------------
+ *
+ * Bit 0 to 7 contains MUX_I used to identify the register
+ * offset (0-based. base is IOMUX_module_base + 0xC) defined in the Section
+ * "sw_pad_ctl & sw_mux_ctl details" of the IC Spec. Bit 8 to 9 is MUX_F which
+ * contains the offset value defined WITHIN the same register (each IOMUX
+ * control register contains four 8-bit fields for four different pins). The
+ * similar field definitions are used for the pad control register.
+ * For example, the MX31_PIN_A0 is defined in the enumeration:
+ * ( 73 << MUX_I) | (0 << MUX_F)|( 98 << PAD_I) | (0 << PAD_F)
+ * It means the mux control register is at register offset 73. So the absolute
+ * address is: 0xC+73*4=0x130 0 << MUX_F means the control bits are at the
+ * least significant bits within the register. The pad control register offset
+ * is: 0x154+98*4=0x2DC and also occupy the least significant bits within the
+ * register.
+ */
+
+/*!
+ * Starting bit position within each entry of \b iomux_pins to represent the
+ * MUX control register index (0-based)
+ */
+#define MUX_I 0
+
+/*!
+ * Starting bit position within each entry of \b iomux_pins to represent the
+ * field within IOMUX control register for control bits
+ * (legal values are 0, 1, 2, 3)
+ */
+#define MUX_F 8
+
+/*!
+ * Starting bit position within each entry of \b iomux_pins to represent the
+ * PAD control register index (0-based)
+ */
+#define PAD_I 10
+
+/*!
+ * Starting bit position within each entry of \b iomux_pins to represent the
+ * field within PAD control register for control bits
+ * (legal values are 0, 1, 2)
+ */
+#define PAD_F 18
+
+#define _MXC_BUILD_PIN(gp,gi,mi,mf,pi,pf) \
+ ((gp) << MUX_IO_P) | ((gi) << MUX_IO_I) | ((mi) << MUX_I) | \
+ ((mf) << MUX_F) | ((pi) << PAD_I) | ((pf) << PAD_F)
+
+#define _MXC_BUILD_GPIO_PIN(gp,gi,mi,mf,pi,pf) \
+ _MXC_BUILD_PIN(gp,gi,mi,mf,pi,pf)
+#define _MXC_BUILD_NON_GPIO_PIN(mi,mf,pi,pf) \
+ _MXC_BUILD_PIN(7,0,mi,mf,pi,pf)
+
+/*!
+ * This enumeration is constructed based on the Section
+ * "sw_pad_ctl & sw_mux_ctl details" of the MX31 IC Spec. Each enumerated
+ * value is constructed based on the rules described above.
+ */
+enum iomux_pins {
+ MX31_PIN_CSPI3_MISO = _MXC_BUILD_NON_GPIO_PIN(0, 3, 1, 2),
+ MX31_PIN_CSPI3_SCLK = _MXC_BUILD_NON_GPIO_PIN(0, 2, 1, 1),
+ MX31_PIN_CSPI3_SPI_RDY = _MXC_BUILD_NON_GPIO_PIN(0, 1, 1, 0),
+ MX31_PIN_TTM_PAD = _MXC_BUILD_NON_GPIO_PIN(0, 0, 0, 2),
+ MX31_PIN_ATA_RESET_B = _MXC_BUILD_GPIO_PIN(2, 31, 1, 3, 3, 0),
+ MX31_PIN_CE_CONTROL = _MXC_BUILD_NON_GPIO_PIN(1, 2, 2, 2),
+ MX31_PIN_CLKSS = _MXC_BUILD_NON_GPIO_PIN(1, 1, 2, 1),
+ MX31_PIN_CSPI3_MOSI = _MXC_BUILD_NON_GPIO_PIN(1, 0, 2, 0),
+ MX31_PIN_ATA_CS1 = _MXC_BUILD_GPIO_PIN(2, 27, 2, 3, 4, 1),
+ MX31_PIN_ATA_DIOR = _MXC_BUILD_GPIO_PIN(2, 28, 2, 2, 4, 0),
+ MX31_PIN_ATA_DIOW = _MXC_BUILD_GPIO_PIN(2, 29, 2, 1, 3, 2),
+ MX31_PIN_ATA_DMACK = _MXC_BUILD_GPIO_PIN(2, 30, 2, 0, 3, 1),
+ MX31_PIN_SD1_DATA1 = _MXC_BUILD_GPIO_PIN(1, 29, 3, 3, 5, 2),
+ MX31_PIN_SD1_DATA2 = _MXC_BUILD_GPIO_PIN(1, 30, 3, 2, 5, 1),
+ MX31_PIN_SD1_DATA3 = _MXC_BUILD_GPIO_PIN(1, 31, 3, 1, 5, 0),
+ MX31_PIN_ATA_CS0 = _MXC_BUILD_GPIO_PIN(2, 26, 3, 0, 4, 2),
+ MX31_PIN_D3_SPL = _MXC_BUILD_NON_GPIO_PIN(4, 3, 7, 0),
+ MX31_PIN_SD1_CMD = _MXC_BUILD_GPIO_PIN(1, 26, 4, 2, 6, 2),
+ MX31_PIN_SD1_CLK = _MXC_BUILD_GPIO_PIN(1, 27, 4, 1, 6, 1),
+ MX31_PIN_SD1_DATA0 = _MXC_BUILD_GPIO_PIN(1, 28, 4, 0, 6, 0),
+ MX31_PIN_VSYNC3 = _MXC_BUILD_NON_GPIO_PIN(5, 3, 8, 1),
+ MX31_PIN_CONTRAST = _MXC_BUILD_NON_GPIO_PIN(5, 2, 8, 0),
+ MX31_PIN_D3_REV = _MXC_BUILD_NON_GPIO_PIN(5, 1, 7, 2),
+ MX31_PIN_D3_CLS = _MXC_BUILD_NON_GPIO_PIN(5, 0, 7, 1),
+ MX31_PIN_SER_RS = _MXC_BUILD_GPIO_PIN(2, 25, 6, 3, 9, 2),
+ MX31_PIN_PAR_RS = _MXC_BUILD_NON_GPIO_PIN(6, 2, 9, 1),
+ MX31_PIN_WRITE = _MXC_BUILD_NON_GPIO_PIN(6, 1, 9, 0),
+ MX31_PIN_READ = _MXC_BUILD_NON_GPIO_PIN(6, 0, 8, 2),
+ MX31_PIN_SD_D_IO = _MXC_BUILD_GPIO_PIN(2, 21, 7, 3, 11, 0),
+ MX31_PIN_SD_D_CLK = _MXC_BUILD_GPIO_PIN(2, 22, 7, 2, 10, 2),
+ MX31_PIN_LCS0 = _MXC_BUILD_GPIO_PIN(2, 23, 7, 1, 10, 1),
+ MX31_PIN_LCS1 = _MXC_BUILD_GPIO_PIN(2, 24, 7, 0, 10, 0),
+ MX31_PIN_HSYNC = _MXC_BUILD_NON_GPIO_PIN(8, 3, 12, 1),
+ MX31_PIN_FPSHIFT = _MXC_BUILD_NON_GPIO_PIN(8, 2, 12, 0),
+ MX31_PIN_DRDY0 = _MXC_BUILD_NON_GPIO_PIN(8, 1, 11, 2),
+ MX31_PIN_SD_D_I = _MXC_BUILD_GPIO_PIN(2, 20, 8, 0, 11, 1),
+ MX31_PIN_LD15 = _MXC_BUILD_NON_GPIO_PIN(9, 3, 13, 2),
+ MX31_PIN_LD16 = _MXC_BUILD_NON_GPIO_PIN(9, 2, 13, 1),
+ MX31_PIN_LD17 = _MXC_BUILD_NON_GPIO_PIN(9, 1, 13, 0),
+ MX31_PIN_VSYNC0 = _MXC_BUILD_NON_GPIO_PIN(9, 0, 12, 2),
+ MX31_PIN_LD11 = _MXC_BUILD_NON_GPIO_PIN(10, 3, 15, 0),
+ MX31_PIN_LD12 = _MXC_BUILD_NON_GPIO_PIN(10, 2, 14, 2),
+ MX31_PIN_LD13 = _MXC_BUILD_NON_GPIO_PIN(10, 1, 14, 1),
+ MX31_PIN_LD14 = _MXC_BUILD_NON_GPIO_PIN(10, 0, 14, 0),
+ MX31_PIN_LD7 = _MXC_BUILD_NON_GPIO_PIN(11, 3, 16, 1),
+ MX31_PIN_LD8 = _MXC_BUILD_NON_GPIO_PIN(11, 2, 16, 0),
+ MX31_PIN_LD9 = _MXC_BUILD_NON_GPIO_PIN(11, 1, 15, 2),
+ MX31_PIN_LD10 = _MXC_BUILD_NON_GPIO_PIN(11, 0, 15, 1),
+ MX31_PIN_LD3 = _MXC_BUILD_NON_GPIO_PIN(12, 3, 17, 2),
+ MX31_PIN_LD4 = _MXC_BUILD_NON_GPIO_PIN(12, 2, 17, 1),
+ MX31_PIN_LD5 = _MXC_BUILD_NON_GPIO_PIN(12, 1, 17, 0),
+ MX31_PIN_LD6 = _MXC_BUILD_NON_GPIO_PIN(12, 0, 16, 2),
+ MX31_PIN_USBH2_DATA1 = _MXC_BUILD_NON_GPIO_PIN(13, 3, 19, 0),
+ MX31_PIN_LD0 = _MXC_BUILD_NON_GPIO_PIN(13, 2, 18, 2),
+ MX31_PIN_LD1 = _MXC_BUILD_NON_GPIO_PIN(13, 1, 18, 1),
+ MX31_PIN_LD2 = _MXC_BUILD_NON_GPIO_PIN(13, 0, 18, 0),
+ MX31_PIN_USBH2_DIR = _MXC_BUILD_NON_GPIO_PIN(14, 3, 20, 1),
+ MX31_PIN_USBH2_STP = _MXC_BUILD_NON_GPIO_PIN(14, 2, 20, 0),
+ MX31_PIN_USBH2_NXT = _MXC_BUILD_NON_GPIO_PIN(14, 1, 19, 2),
+ MX31_PIN_USBH2_DATA0 = _MXC_BUILD_NON_GPIO_PIN(14, 0, 19, 1),
+ MX31_PIN_USBOTG_DATA5 = _MXC_BUILD_NON_GPIO_PIN(15, 3, 21, 2),
+ MX31_PIN_USBOTG_DATA6 = _MXC_BUILD_NON_GPIO_PIN(15, 2, 21, 1),
+ MX31_PIN_USBOTG_DATA7 = _MXC_BUILD_NON_GPIO_PIN(15, 1, 21, 0),
+ MX31_PIN_USBH2_CLK = _MXC_BUILD_NON_GPIO_PIN(15, 0, 20, 2),
+ MX31_PIN_USBOTG_DATA1 = _MXC_BUILD_NON_GPIO_PIN(16, 3, 23, 0),
+ MX31_PIN_USBOTG_DATA2 = _MXC_BUILD_NON_GPIO_PIN(16, 2, 22, 2),
+ MX31_PIN_USBOTG_DATA3 = _MXC_BUILD_NON_GPIO_PIN(16, 1, 22, 1),
+ MX31_PIN_USBOTG_DATA4 = _MXC_BUILD_NON_GPIO_PIN(16, 0, 22, 0),
+ MX31_PIN_USBOTG_DIR = _MXC_BUILD_NON_GPIO_PIN(17, 3, 24, 1),
+ MX31_PIN_USBOTG_STP = _MXC_BUILD_NON_GPIO_PIN(17, 2, 24, 0),
+ MX31_PIN_USBOTG_NXT = _MXC_BUILD_NON_GPIO_PIN(17, 1, 23, 2),
+ MX31_PIN_USBOTG_DATA0 = _MXC_BUILD_NON_GPIO_PIN(17, 0, 23, 1),
+ MX31_PIN_USB_PWR = _MXC_BUILD_GPIO_PIN(0, 29, 18, 3, 25, 2),
+ MX31_PIN_USB_OC = _MXC_BUILD_GPIO_PIN(0, 30, 18, 2, 25, 1),
+ MX31_PIN_USB_BYP = _MXC_BUILD_GPIO_PIN(0, 31, 18, 1, 25, 0),
+ MX31_PIN_USBOTG_CLK = _MXC_BUILD_NON_GPIO_PIN(18, 0, 24, 2),
+ MX31_PIN_TDO = _MXC_BUILD_NON_GPIO_PIN(19, 3, 27, 0),
+ MX31_PIN_TRSTB = _MXC_BUILD_NON_GPIO_PIN(19, 2, 26, 2),
+ MX31_PIN_DE_B = _MXC_BUILD_NON_GPIO_PIN(19, 1, 26, 1),
+ MX31_PIN_SJC_MOD = _MXC_BUILD_NON_GPIO_PIN(19, 0, 26, 0),
+ MX31_PIN_RTCK = _MXC_BUILD_NON_GPIO_PIN(20, 3, 28, 1),
+ MX31_PIN_TCK = _MXC_BUILD_NON_GPIO_PIN(20, 2, 28, 0),
+ MX31_PIN_TMS = _MXC_BUILD_NON_GPIO_PIN(20, 1, 27, 2),
+ MX31_PIN_TDI = _MXC_BUILD_NON_GPIO_PIN(20, 0, 27, 1),
+ MX31_PIN_KEY_COL4 = _MXC_BUILD_GPIO_PIN(1, 22, 21, 3, 29, 2),
+ MX31_PIN_KEY_COL5 = _MXC_BUILD_GPIO_PIN(1, 23, 21, 2, 29, 1),
+ MX31_PIN_KEY_COL6 = _MXC_BUILD_GPIO_PIN(1, 24, 21, 1, 29, 0),
+ MX31_PIN_KEY_COL7 = _MXC_BUILD_GPIO_PIN(1, 25, 21, 0, 28, 2),
+ MX31_PIN_KEY_COL0 = _MXC_BUILD_NON_GPIO_PIN(22, 3, 31, 0),
+ MX31_PIN_KEY_COL1 = _MXC_BUILD_NON_GPIO_PIN(22, 2, 30, 2),
+ MX31_PIN_KEY_COL2 = _MXC_BUILD_NON_GPIO_PIN(22, 1, 30, 1),
+ MX31_PIN_KEY_COL3 = _MXC_BUILD_NON_GPIO_PIN(22, 0, 30, 0),
+ MX31_PIN_KEY_ROW4 = _MXC_BUILD_GPIO_PIN(1, 18, 23, 3, 32, 1),
+ MX31_PIN_KEY_ROW5 = _MXC_BUILD_GPIO_PIN(1, 19, 23, 2, 32, 0),
+ MX31_PIN_KEY_ROW6 = _MXC_BUILD_GPIO_PIN(1, 20, 23, 1, 31, 2),
+ MX31_PIN_KEY_ROW7 = _MXC_BUILD_GPIO_PIN(1, 21, 23, 0, 31, 1),
+ MX31_PIN_KEY_ROW0 = _MXC_BUILD_NON_GPIO_PIN(24, 3, 33, 2),
+ MX31_PIN_KEY_ROW1 = _MXC_BUILD_NON_GPIO_PIN(24, 2, 33, 1),
+ MX31_PIN_KEY_ROW2 = _MXC_BUILD_NON_GPIO_PIN(24, 1, 33, 0),
+ MX31_PIN_KEY_ROW3 = _MXC_BUILD_NON_GPIO_PIN(24, 0, 32, 2),
+ MX31_PIN_TXD2 = _MXC_BUILD_GPIO_PIN(0, 28, 25, 3, 35, 0),
+ MX31_PIN_RTS2 = _MXC_BUILD_NON_GPIO_PIN(25, 2, 34, 2),
+ MX31_PIN_CTS2 = _MXC_BUILD_NON_GPIO_PIN(25, 1, 34, 1),
+ MX31_PIN_BATT_LINE = _MXC_BUILD_GPIO_PIN(1, 17, 25, 0, 34, 0),
+ MX31_PIN_RI_DTE1 = _MXC_BUILD_GPIO_PIN(1, 14, 26, 3, 36, 1),
+ MX31_PIN_DCD_DTE1 = _MXC_BUILD_GPIO_PIN(1, 15, 26, 2, 36, 0),
+ MX31_PIN_DTR_DCE2 = _MXC_BUILD_GPIO_PIN(1, 16, 26, 1, 35, 2),
+ MX31_PIN_RXD2 = _MXC_BUILD_GPIO_PIN(0, 27, 26, 0, 35, 1),
+ MX31_PIN_RI_DCE1 = _MXC_BUILD_GPIO_PIN(1, 10, 27, 3, 37, 2),
+ MX31_PIN_DCD_DCE1 = _MXC_BUILD_GPIO_PIN(1, 11, 27, 2, 37, 1),
+ MX31_PIN_DTR_DTE1 = _MXC_BUILD_GPIO_PIN(1, 12, 27, 1, 37, 0),
+ MX31_PIN_DSR_DTE1 = _MXC_BUILD_GPIO_PIN(1, 13, 27, 0, 36, 2),
+ MX31_PIN_RTS1 = _MXC_BUILD_GPIO_PIN(1, 6, 28, 3, 39, 0),
+ MX31_PIN_CTS1 = _MXC_BUILD_GPIO_PIN(1, 7, 28, 2, 38, 2),
+ MX31_PIN_DTR_DCE1 = _MXC_BUILD_GPIO_PIN(1, 8, 28, 1, 38, 1),
+ MX31_PIN_DSR_DCE1 = _MXC_BUILD_GPIO_PIN(1, 9, 28, 0, 38, 0),
+ MX31_PIN_CSPI2_SCLK = _MXC_BUILD_NON_GPIO_PIN(29, 3, 40, 1),
+ MX31_PIN_CSPI2_SPI_RDY = _MXC_BUILD_NON_GPIO_PIN(29, 2, 40, 0),
+ MX31_PIN_RXD1 = _MXC_BUILD_GPIO_PIN(1, 4, 29, 1, 39, 2),
+ MX31_PIN_TXD1 = _MXC_BUILD_GPIO_PIN(1, 5, 29, 0, 39, 1),
+ MX31_PIN_CSPI2_MISO = _MXC_BUILD_NON_GPIO_PIN(30, 3, 41, 2),
+ MX31_PIN_CSPI2_SS0 = _MXC_BUILD_NON_GPIO_PIN(30, 2, 41, 1),
+ MX31_PIN_CSPI2_SS1 = _MXC_BUILD_NON_GPIO_PIN(30, 1, 41, 0),
+ MX31_PIN_CSPI2_SS2 = _MXC_BUILD_NON_GPIO_PIN(30, 0, 40, 2),
+ MX31_PIN_CSPI1_SS2 = _MXC_BUILD_NON_GPIO_PIN(31, 3, 43, 0),
+ MX31_PIN_CSPI1_SCLK = _MXC_BUILD_NON_GPIO_PIN(31, 2, 42, 2),
+ MX31_PIN_CSPI1_SPI_RDY = _MXC_BUILD_NON_GPIO_PIN(31, 1, 42, 1),
+ MX31_PIN_CSPI2_MOSI = _MXC_BUILD_NON_GPIO_PIN(31, 0, 42, 0),
+ MX31_PIN_CSPI1_MOSI = _MXC_BUILD_NON_GPIO_PIN(32, 3, 44, 1),
+ MX31_PIN_CSPI1_MISO = _MXC_BUILD_NON_GPIO_PIN(32, 2, 44, 0),
+ MX31_PIN_CSPI1_SS0 = _MXC_BUILD_NON_GPIO_PIN(32, 1, 43, 2),
+ MX31_PIN_CSPI1_SS1 = _MXC_BUILD_NON_GPIO_PIN(32, 0, 43, 1),
+ MX31_PIN_STXD6 = _MXC_BUILD_GPIO_PIN(0, 23, 33, 3, 45, 2),
+ MX31_PIN_SRXD6 = _MXC_BUILD_GPIO_PIN(0, 24, 33, 2, 45, 1),
+ MX31_PIN_SCK6 = _MXC_BUILD_GPIO_PIN(0, 25, 33, 1, 45, 0),
+ MX31_PIN_SFS6 = _MXC_BUILD_GPIO_PIN(0, 26, 33, 0, 44, 2),
+ MX31_PIN_STXD5 = _MXC_BUILD_GPIO_PIN(0, 21, 34, 3, 47, 0),
+ MX31_PIN_SRXD5 = _MXC_BUILD_GPIO_PIN(0, 22, 34, 2, 46, 2),
+ MX31_PIN_SCK5 = _MXC_BUILD_NON_GPIO_PIN(34, 1, 46, 1),
+ MX31_PIN_SFS5 = _MXC_BUILD_NON_GPIO_PIN(34, 0, 46, 0),
+ MX31_PIN_STXD4 = _MXC_BUILD_GPIO_PIN(0, 19, 35, 3, 48, 1),
+ MX31_PIN_SRXD4 = _MXC_BUILD_GPIO_PIN(0, 20, 35, 2, 48, 0),
+ MX31_PIN_SCK4 = _MXC_BUILD_NON_GPIO_PIN(35, 1, 47, 2),
+ MX31_PIN_SFS4 = _MXC_BUILD_NON_GPIO_PIN(35, 0, 47, 1),
+ MX31_PIN_STXD3 = _MXC_BUILD_GPIO_PIN(0, 17, 36, 3, 49, 2),
+ MX31_PIN_SRXD3 = _MXC_BUILD_GPIO_PIN(0, 18, 36, 2, 49, 1),
+ MX31_PIN_SCK3 = _MXC_BUILD_NON_GPIO_PIN(36, 1, 49, 0),
+ MX31_PIN_SFS3 = _MXC_BUILD_NON_GPIO_PIN(36, 0, 48, 2),
+ MX31_PIN_CSI_HSYNC = _MXC_BUILD_GPIO_PIN(2, 18, 37, 3, 51, 0),
+ MX31_PIN_CSI_PIXCLK = _MXC_BUILD_GPIO_PIN(2, 19, 37, 2, 50, 2),
+ MX31_PIN_I2C_CLK = _MXC_BUILD_NON_GPIO_PIN(37, 1, 50, 1),
+ MX31_PIN_I2C_DAT = _MXC_BUILD_NON_GPIO_PIN(37, 0, 50, 0),
+ MX31_PIN_CSI_D14 = _MXC_BUILD_GPIO_PIN(2, 14, 38, 3, 52, 1),
+ MX31_PIN_CSI_D15 = _MXC_BUILD_GPIO_PIN(2, 15, 38, 2, 52, 0),
+ MX31_PIN_CSI_MCLK = _MXC_BUILD_GPIO_PIN(2, 16, 38, 1, 51, 2),
+ MX31_PIN_CSI_VSYNC = _MXC_BUILD_GPIO_PIN(2, 17, 38, 0, 51, 1),
+ MX31_PIN_CSI_D10 = _MXC_BUILD_GPIO_PIN(2, 10, 39, 3, 53, 2),
+ MX31_PIN_CSI_D11 = _MXC_BUILD_GPIO_PIN(2, 11, 39, 2, 53, 1),
+ MX31_PIN_CSI_D12 = _MXC_BUILD_GPIO_PIN(2, 12, 39, 1, 53, 0),
+ MX31_PIN_CSI_D13 = _MXC_BUILD_GPIO_PIN(2, 13, 39, 0, 52, 2),
+ MX31_PIN_CSI_D6 = _MXC_BUILD_GPIO_PIN(2, 6, 40, 3, 55, 0),
+ MX31_PIN_CSI_D7 = _MXC_BUILD_GPIO_PIN(2, 7, 40, 2, 54, 2),
+ MX31_PIN_CSI_D8 = _MXC_BUILD_GPIO_PIN(2, 8, 40, 1, 54, 1),
+ MX31_PIN_CSI_D9 = _MXC_BUILD_GPIO_PIN(2, 9, 40, 0, 54, 0),
+ MX31_PIN_M_REQUEST = _MXC_BUILD_NON_GPIO_PIN(41, 3, 56, 1),
+ MX31_PIN_M_GRANT = _MXC_BUILD_NON_GPIO_PIN(41, 2, 56, 0),
+ MX31_PIN_CSI_D4 = _MXC_BUILD_GPIO_PIN(2, 4, 41, 1, 55, 2),
+ MX31_PIN_CSI_D5 = _MXC_BUILD_GPIO_PIN(2, 5, 41, 0, 55, 1),
+ MX31_PIN_PC_RST = _MXC_BUILD_NON_GPIO_PIN(42, 3, 57, 2),
+ MX31_PIN_IOIS16 = _MXC_BUILD_NON_GPIO_PIN(42, 2, 57, 1),
+ MX31_PIN_PC_RW_B = _MXC_BUILD_NON_GPIO_PIN(42, 1, 57, 0),
+ MX31_PIN_PC_POE = _MXC_BUILD_NON_GPIO_PIN(42, 0, 56, 2),
+ MX31_PIN_PC_VS1 = _MXC_BUILD_NON_GPIO_PIN(43, 3, 59, 0),
+ MX31_PIN_PC_VS2 = _MXC_BUILD_NON_GPIO_PIN(43, 2, 58, 2),
+ MX31_PIN_PC_BVD1 = _MXC_BUILD_NON_GPIO_PIN(43, 1, 58, 1),
+ MX31_PIN_PC_BVD2 = _MXC_BUILD_NON_GPIO_PIN(43, 0, 58, 0),
+ MX31_PIN_PC_CD2_B = _MXC_BUILD_NON_GPIO_PIN(44, 3, 60, 1),
+ MX31_PIN_PC_WAIT_B = _MXC_BUILD_NON_GPIO_PIN(44, 2, 60, 0),
+ MX31_PIN_PC_READY = _MXC_BUILD_NON_GPIO_PIN(44, 1, 59, 2),
+ MX31_PIN_PC_PWRON = _MXC_BUILD_NON_GPIO_PIN(44, 0, 59, 1),
+ MX31_PIN_D2 = _MXC_BUILD_NON_GPIO_PIN(45, 3, 61, 2),
+ MX31_PIN_D1 = _MXC_BUILD_NON_GPIO_PIN(45, 2, 61, 1),
+ MX31_PIN_D0 = _MXC_BUILD_NON_GPIO_PIN(45, 1, 61, 0),
+ MX31_PIN_PC_CD1_B = _MXC_BUILD_NON_GPIO_PIN(45, 0, 60, 2),
+ MX31_PIN_D6 = _MXC_BUILD_NON_GPIO_PIN(46, 3, 63, 0),
+ MX31_PIN_D5 = _MXC_BUILD_NON_GPIO_PIN(46, 2, 62, 2),
+ MX31_PIN_D4 = _MXC_BUILD_NON_GPIO_PIN(46, 1, 62, 1),
+ MX31_PIN_D3 = _MXC_BUILD_NON_GPIO_PIN(46, 0, 62, 0),
+ MX31_PIN_D10 = _MXC_BUILD_NON_GPIO_PIN(47, 3, 64, 1),
+ MX31_PIN_D9 = _MXC_BUILD_NON_GPIO_PIN(47, 2, 64, 0),
+ MX31_PIN_D8 = _MXC_BUILD_NON_GPIO_PIN(47, 1, 63, 2),
+ MX31_PIN_D7 = _MXC_BUILD_NON_GPIO_PIN(47, 0, 63, 1),
+ MX31_PIN_D14 = _MXC_BUILD_NON_GPIO_PIN(48, 3, 65, 2),
+ MX31_PIN_D13 = _MXC_BUILD_NON_GPIO_PIN(48, 2, 65, 1),
+ MX31_PIN_D12 = _MXC_BUILD_NON_GPIO_PIN(48, 1, 65, 0),
+ MX31_PIN_D11 = _MXC_BUILD_NON_GPIO_PIN(48, 0, 64, 2),
+ MX31_PIN_NFWP_B = _MXC_BUILD_GPIO_PIN(0, 14, 49, 3, 67, 0),
+ MX31_PIN_NFCE_B = _MXC_BUILD_GPIO_PIN(0, 15, 49, 2, 66, 2),
+ MX31_PIN_NFRB = _MXC_BUILD_GPIO_PIN(0, 16, 49, 1, 66, 1),
+ MX31_PIN_D15 = _MXC_BUILD_NON_GPIO_PIN(49, 0, 66, 0),
+ MX31_PIN_NFWE_B = _MXC_BUILD_GPIO_PIN(0, 10, 50, 3, 68, 1),
+ MX31_PIN_NFRE_B = _MXC_BUILD_GPIO_PIN(0, 11, 50, 2, 68, 0),
+ MX31_PIN_NFALE = _MXC_BUILD_GPIO_PIN(0, 12, 50, 1, 67, 2),
+ MX31_PIN_NFCLE = _MXC_BUILD_GPIO_PIN(0, 13, 50, 0, 67, 1),
+ MX31_PIN_SDQS0 = _MXC_BUILD_NON_GPIO_PIN(51, 3, 69, 2),
+ MX31_PIN_SDQS1 = _MXC_BUILD_NON_GPIO_PIN(51, 2, 69, 1),
+ MX31_PIN_SDQS2 = _MXC_BUILD_NON_GPIO_PIN(51, 1, 69, 0),
+ MX31_PIN_SDQS3 = _MXC_BUILD_NON_GPIO_PIN(51, 0, 68, 2),
+ MX31_PIN_SDCKE0 = _MXC_BUILD_NON_GPIO_PIN(52, 3, 71, 0),
+ MX31_PIN_SDCKE1 = _MXC_BUILD_NON_GPIO_PIN(52, 2, 70, 2),
+ MX31_PIN_SDCLK = _MXC_BUILD_NON_GPIO_PIN(52, 1, 70, 1),
+ MX31_PIN_SDCLK_B = _MXC_BUILD_NON_GPIO_PIN(52, 0, 70, 0),
+ MX31_PIN_RW = _MXC_BUILD_NON_GPIO_PIN(53, 3, 72, 1),
+ MX31_PIN_RAS = _MXC_BUILD_NON_GPIO_PIN(53, 2, 72, 0),
+ MX31_PIN_CAS = _MXC_BUILD_NON_GPIO_PIN(53, 1, 71, 2),
+ MX31_PIN_SDWE = _MXC_BUILD_NON_GPIO_PIN(53, 0, 71, 1),
+ MX31_PIN_CS5 = _MXC_BUILD_NON_GPIO_PIN(54, 3, 73, 2),
+ MX31_PIN_ECB = _MXC_BUILD_NON_GPIO_PIN(54, 2, 73, 1),
+ MX31_PIN_LBA = _MXC_BUILD_NON_GPIO_PIN(54, 1, 73, 0),
+ MX31_PIN_BCLK = _MXC_BUILD_NON_GPIO_PIN(54, 0, 72, 2),
+ MX31_PIN_CS1 = _MXC_BUILD_NON_GPIO_PIN(55, 3, 75, 0),
+ MX31_PIN_CS2 = _MXC_BUILD_NON_GPIO_PIN(55, 2, 74, 2),
+ MX31_PIN_CS3 = _MXC_BUILD_NON_GPIO_PIN(55, 1, 74, 1),
+ MX31_PIN_CS4 = _MXC_BUILD_NON_GPIO_PIN(55, 0, 74, 0),
+ MX31_PIN_EB0 = _MXC_BUILD_NON_GPIO_PIN(56, 3, 76, 1),
+ MX31_PIN_EB1 = _MXC_BUILD_NON_GPIO_PIN(56, 2, 76, 0),
+ MX31_PIN_OE = _MXC_BUILD_NON_GPIO_PIN(56, 1, 75, 2),
+ MX31_PIN_CS0 = _MXC_BUILD_NON_GPIO_PIN(56, 0, 75, 1),
+ MX31_PIN_DQM0 = _MXC_BUILD_NON_GPIO_PIN(57, 3, 77, 2),
+ MX31_PIN_DQM1 = _MXC_BUILD_NON_GPIO_PIN(57, 2, 77, 1),
+ MX31_PIN_DQM2 = _MXC_BUILD_NON_GPIO_PIN(57, 1, 77, 0),
+ MX31_PIN_DQM3 = _MXC_BUILD_NON_GPIO_PIN(57, 0, 76, 2),
+ MX31_PIN_SD28 = _MXC_BUILD_NON_GPIO_PIN(58, 3, 79, 0),
+ MX31_PIN_SD29 = _MXC_BUILD_NON_GPIO_PIN(58, 2, 78, 2),
+ MX31_PIN_SD30 = _MXC_BUILD_NON_GPIO_PIN(58, 1, 78, 1),
+ MX31_PIN_SD31 = _MXC_BUILD_NON_GPIO_PIN(58, 0, 78, 0),
+ MX31_PIN_SD24 = _MXC_BUILD_NON_GPIO_PIN(59, 3, 80, 1),
+ MX31_PIN_SD25 = _MXC_BUILD_NON_GPIO_PIN(59, 2, 80, 0),
+ MX31_PIN_SD26 = _MXC_BUILD_NON_GPIO_PIN(59, 1, 79, 2),
+ MX31_PIN_SD27 = _MXC_BUILD_NON_GPIO_PIN(59, 0, 79, 1),
+ MX31_PIN_SD20 = _MXC_BUILD_NON_GPIO_PIN(60, 3, 81, 2),
+ MX31_PIN_SD21 = _MXC_BUILD_NON_GPIO_PIN(60, 2, 81, 1),
+ MX31_PIN_SD22 = _MXC_BUILD_NON_GPIO_PIN(60, 1, 81, 0),
+ MX31_PIN_SD23 = _MXC_BUILD_NON_GPIO_PIN(60, 0, 80, 2),
+ MX31_PIN_SD16 = _MXC_BUILD_NON_GPIO_PIN(61, 3, 83, 0),
+ MX31_PIN_SD17 = _MXC_BUILD_NON_GPIO_PIN(61, 2, 82, 2),
+ MX31_PIN_SD18 = _MXC_BUILD_NON_GPIO_PIN(61, 1, 82, 1),
+ MX31_PIN_SD19 = _MXC_BUILD_NON_GPIO_PIN(61, 0, 82, 0),
+ MX31_PIN_SD12 = _MXC_BUILD_NON_GPIO_PIN(62, 3, 84, 1),
+ MX31_PIN_SD13 = _MXC_BUILD_NON_GPIO_PIN(62, 2, 84, 0),
+ MX31_PIN_SD14 = _MXC_BUILD_NON_GPIO_PIN(62, 1, 83, 2),
+ MX31_PIN_SD15 = _MXC_BUILD_NON_GPIO_PIN(62, 0, 83, 1),
+ MX31_PIN_SD8 = _MXC_BUILD_NON_GPIO_PIN(63, 3, 85, 2),
+ MX31_PIN_SD9 = _MXC_BUILD_NON_GPIO_PIN(63, 2, 85, 1),
+ MX31_PIN_SD10 = _MXC_BUILD_NON_GPIO_PIN(63, 1, 85, 0),
+ MX31_PIN_SD11 = _MXC_BUILD_NON_GPIO_PIN(63, 0, 84, 2),
+ MX31_PIN_SD4 = _MXC_BUILD_NON_GPIO_PIN(64, 3, 87, 0),
+ MX31_PIN_SD5 = _MXC_BUILD_NON_GPIO_PIN(64, 2, 86, 2),
+ MX31_PIN_SD6 = _MXC_BUILD_NON_GPIO_PIN(64, 1, 86, 1),
+ MX31_PIN_SD7 = _MXC_BUILD_NON_GPIO_PIN(64, 0, 86, 0),
+ MX31_PIN_SD0 = _MXC_BUILD_NON_GPIO_PIN(65, 3, 88, 1),
+ MX31_PIN_SD1 = _MXC_BUILD_NON_GPIO_PIN(65, 2, 88, 0),
+ MX31_PIN_SD2 = _MXC_BUILD_NON_GPIO_PIN(65, 1, 87, 2),
+ MX31_PIN_SD3 = _MXC_BUILD_NON_GPIO_PIN(65, 0, 87, 1),
+ MX31_PIN_A24 = _MXC_BUILD_NON_GPIO_PIN(66, 3, 89, 2),
+ MX31_PIN_A25 = _MXC_BUILD_NON_GPIO_PIN(66, 2, 89, 1),
+ MX31_PIN_SDBA1 = _MXC_BUILD_NON_GPIO_PIN(66, 1, 89, 0),
+ MX31_PIN_SDBA0 = _MXC_BUILD_NON_GPIO_PIN(66, 0, 88, 2),
+ MX31_PIN_A20 = _MXC_BUILD_NON_GPIO_PIN(67, 3, 91, 0),
+ MX31_PIN_A21 = _MXC_BUILD_NON_GPIO_PIN(67, 2, 90, 2),
+ MX31_PIN_A22 = _MXC_BUILD_NON_GPIO_PIN(67, 1, 90, 1),
+ MX31_PIN_A23 = _MXC_BUILD_NON_GPIO_PIN(67, 0, 90, 0),
+ MX31_PIN_A16 = _MXC_BUILD_NON_GPIO_PIN(68, 3, 92, 1),
+ MX31_PIN_A17 = _MXC_BUILD_NON_GPIO_PIN(68, 2, 92, 0),
+ MX31_PIN_A18 = _MXC_BUILD_NON_GPIO_PIN(68, 1, 91, 2),
+ MX31_PIN_A19 = _MXC_BUILD_NON_GPIO_PIN(68, 0, 91, 1),
+ MX31_PIN_A12 = _MXC_BUILD_NON_GPIO_PIN(69, 3, 93, 2),
+ MX31_PIN_A13 = _MXC_BUILD_NON_GPIO_PIN(69, 2, 93, 1),
+ MX31_PIN_A14 = _MXC_BUILD_NON_GPIO_PIN(69, 1, 93, 0),
+ MX31_PIN_A15 = _MXC_BUILD_NON_GPIO_PIN(69, 0, 92, 2),
+ MX31_PIN_A9 = _MXC_BUILD_NON_GPIO_PIN(70, 3, 95, 0),
+ MX31_PIN_A10 = _MXC_BUILD_NON_GPIO_PIN(70, 2, 94, 2),
+ MX31_PIN_MA10 = _MXC_BUILD_NON_GPIO_PIN(70, 1, 94, 1),
+ MX31_PIN_A11 = _MXC_BUILD_NON_GPIO_PIN(70, 0, 94, 0),
+ MX31_PIN_A5 = _MXC_BUILD_NON_GPIO_PIN(71, 3, 96, 1),
+ MX31_PIN_A6 = _MXC_BUILD_NON_GPIO_PIN(71, 2, 96, 0),
+ MX31_PIN_A7 = _MXC_BUILD_NON_GPIO_PIN(71, 1, 95, 2),
+ MX31_PIN_A8 = _MXC_BUILD_NON_GPIO_PIN(71, 0, 95, 1),
+ MX31_PIN_A1 = _MXC_BUILD_NON_GPIO_PIN(72, 3, 97, 2),
+ MX31_PIN_A2 = _MXC_BUILD_NON_GPIO_PIN(72, 2, 97, 1),
+ MX31_PIN_A3 = _MXC_BUILD_NON_GPIO_PIN(72, 1, 97, 0),
+ MX31_PIN_A4 = _MXC_BUILD_NON_GPIO_PIN(72, 0, 96, 2),
+ MX31_PIN_DVFS1 = _MXC_BUILD_NON_GPIO_PIN(73, 3, 99, 0),
+ MX31_PIN_VPG0 = _MXC_BUILD_NON_GPIO_PIN(73, 2, 98, 2),
+ MX31_PIN_VPG1 = _MXC_BUILD_NON_GPIO_PIN(73, 1, 98, 1),
+ MX31_PIN_A0 = _MXC_BUILD_NON_GPIO_PIN(73, 0, 98, 0),
+ MX31_PIN_CKIL = _MXC_BUILD_NON_GPIO_PIN(74, 3, 100, 1),
+ MX31_PIN_POWER_FAIL = _MXC_BUILD_NON_GPIO_PIN(74, 2, 100, 0),
+ MX31_PIN_VSTBY = _MXC_BUILD_NON_GPIO_PIN(74, 1, 99, 2),
+ MX31_PIN_DVFS0 = _MXC_BUILD_NON_GPIO_PIN(74, 0, 99, 1),
+ MX31_PIN_BOOT_MODE1 = _MXC_BUILD_NON_GPIO_PIN(75, 3, 101, 2),
+ MX31_PIN_BOOT_MODE2 = _MXC_BUILD_NON_GPIO_PIN(75, 2, 101, 1),
+ MX31_PIN_BOOT_MODE3 = _MXC_BUILD_NON_GPIO_PIN(75, 1, 101, 0),
+ MX31_PIN_BOOT_MODE4 = _MXC_BUILD_NON_GPIO_PIN(75, 0, 100, 2),
+ MX31_PIN_RESET_IN_B = _MXC_BUILD_NON_GPIO_PIN(76, 3, 103, 0),
+ MX31_PIN_POR_B = _MXC_BUILD_NON_GPIO_PIN(76, 2, 102, 2),
+ MX31_PIN_CLKO = _MXC_BUILD_NON_GPIO_PIN(76, 1, 102, 1),
+ MX31_PIN_BOOT_MODE0 = _MXC_BUILD_NON_GPIO_PIN(76, 0, 102, 0),
+ MX31_PIN_STX0 = _MXC_BUILD_GPIO_PIN(1, 1, 77, 3, 104, 1),
+ MX31_PIN_SRX0 = _MXC_BUILD_GPIO_PIN(1, 2, 77, 2, 104, 0),
+ MX31_PIN_SIMPD0 = _MXC_BUILD_GPIO_PIN(1, 3, 77, 1, 103, 2),
+ MX31_PIN_CKIH = _MXC_BUILD_NON_GPIO_PIN(77, 0, 103, 1),
+ MX31_PIN_GPIO3_1 = _MXC_BUILD_GPIO_PIN(2, 1, 78, 3, 105, 2),
+ MX31_PIN_SCLK0 = _MXC_BUILD_GPIO_PIN(2, 2, 78, 2, 105, 1),
+ MX31_PIN_SRST0 = _MXC_BUILD_GPIO_PIN(2, 3, 78, 1, 105, 0),
+ MX31_PIN_SVEN0 = _MXC_BUILD_GPIO_PIN(1, 0, 78, 0, 104, 2),
+ MX31_PIN_GPIO1_4 = _MXC_BUILD_GPIO_PIN(0, 4, 79, 3, 107, 0),
+ MX31_PIN_GPIO1_5 = _MXC_BUILD_GPIO_PIN(0, 5, 79, 2, 106, 2),
+ MX31_PIN_GPIO1_6 = _MXC_BUILD_GPIO_PIN(0, 6, 79, 1, 106, 1),
+ MX31_PIN_GPIO3_0 = _MXC_BUILD_GPIO_PIN(2, 0, 79, 0, 106, 0),
+ MX31_PIN_GPIO1_0 = _MXC_BUILD_GPIO_PIN(0, 0, 80, 3, 108, 1),
+ MX31_PIN_GPIO1_1 = _MXC_BUILD_GPIO_PIN(0, 1, 80, 2, 108, 0),
+ MX31_PIN_GPIO1_2 = _MXC_BUILD_GPIO_PIN(0, 2, 80, 1, 107, 2),
+ MX31_PIN_GPIO1_3 = _MXC_BUILD_GPIO_PIN(0, 3, 80, 0, 107, 1),
+ MX31_PIN_CAPTURE = _MXC_BUILD_GPIO_PIN(0, 7, 81, 3, 109, 2),
+ MX31_PIN_COMPARE = _MXC_BUILD_GPIO_PIN(0, 8, 81, 2, 109, 1),
+ MX31_PIN_WATCHDOG_RST = _MXC_BUILD_NON_GPIO_PIN(81, 1, 109, 0),
+ MX31_PIN_PWMO = _MXC_BUILD_GPIO_PIN(0, 9, 81, 0, 108, 2),
+};
+
+#endif
+#endif
diff --git a/arch/arm/mach-mx3/mx31ads.c b/arch/arm/mach-mx3/mx31ads.c
index f902a7c37c31..cf16b719f4c9 100644
--- a/arch/arm/mach-mx3/mx31ads.c
+++ b/arch/arm/mach-mx3/mx31ads.c
@@ -1,7 +1,7 @@
/*
* Copyright (C) 2000 Deep Blue Solutions Ltd
* Copyright (C) 2002 Shane Nay (shane@minirl.com)
- * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2005-2008 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,31 +19,139 @@
*/
#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
#include <linux/init.h>
-#include <linux/clk.h>
#include <linux/serial_8250.h>
-#include <linux/irq.h>
+#include <linux/input.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/ata.h>
+#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE)
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/flash.h>
+#endif
#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/keypad.h>
#include <asm/mach/time.h>
-#include <asm/memory.h>
-#include <asm/mach/map.h>
#include <mach/common.h>
-#include <mach/board-mx31ads.h>
-#include <mach/imx-uart.h>
-#include <mach/iomux-mx3.h>
-
-#include "devices.h"
+#include <mach/memory.h>
+#include <mach/gpio.h>
+#include <mach/mmc.h>
+#include <mach/spba.h>
+#include "board-mx31ads.h"
+#include "crm_regs.h"
+#include "iomux.h"
/*!
- * @file mx31ads.c
+ * @file mach-mx3/mx31ads.c
*
* @brief This file contains the board-specific initialization routines.
*
- * @ingroup System
+ * @ingroup MSL_MX31
+ */
+
+extern void mx31ads_gpio_init(void) __init;
+
+static void mxc_nop_release(struct device *dev)
+{
+ /* Nothing */
+}
+
+#if defined(CONFIG_CS89x0) || defined(CONFIG_CS89x0_MODULE)
+/*! Null terminated portlist used to probe for the CS8900A device on ISA Bus
+ * Add 3 to reset the page window before probing (fixes eth probe when deployed
+ * using nand_boot)
+ */
+unsigned int netcard_portlist[] = { CS8900A_BASE_ADDRESS + 3, 0 };
+
+EXPORT_SYMBOL(netcard_portlist);
+/*!
+ * The CS8900A has 4 IRQ pins, which is software selectable, CS8900A interrupt
+ * pin 0 is used for interrupt generation.
*/
+unsigned int cs8900_irq_map[] = { CS8900AIRQ, 0, 0, 0 };
+
+EXPORT_SYMBOL(cs8900_irq_map);
+#endif
+
+#if defined(CONFIG_KEYBOARD_MXC) || defined(CONFIG_KEYBOARD_MXC_MODULE)
+
+/* Keypad keycodes for the EVB 8x8
+ * keypad. POWER and PTT keys don't generate
+ * any interrupts via this driver so they are
+ * not support. Change any keys as u like!
+ */
+static u16 keymapping[64] = {
+ KEY_SELECT, KEY_LEFT, KEY_DOWN, KEY_RIGHT,
+ KEY_UP, KEY_F12, KEY_END, KEY_BACK,
+ KEY_F1, KEY_SENDFILE, KEY_HOME, KEY_F6,
+ KEY_VOLUMEUP, KEY_F8, KEY_F9, KEY_F10,
+ KEY_3, KEY_2, KEY_1, KEY_4,
+ KEY_VOLUMEDOWN, KEY_7, KEY_5, KEY_6,
+ KEY_9, KEY_LEFTSHIFT, KEY_8, KEY_0,
+ KEY_KPASTERISK, KEY_RECORD, KEY_Q, KEY_W,
+ KEY_A, KEY_S, KEY_D, KEY_E,
+ KEY_F, KEY_R, KEY_T, KEY_Y,
+ KEY_TAB, KEY_F7, KEY_CAPSLOCK, KEY_Z,
+ KEY_X, KEY_C, KEY_V, KEY_G,
+ KEY_B, KEY_H, KEY_N, KEY_M,
+ KEY_J, KEY_K, KEY_U, KEY_I,
+ KEY_SPACE, KEY_F2, KEY_DOT, KEY_ENTER,
+ KEY_L, KEY_BACKSPACE, KEY_P, KEY_O,
+};
+
+static struct resource mxc_kpp_resources[] = {
+ [0] = {
+ .start = MXC_INT_KPP,
+ .end = MXC_INT_KPP,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct keypad_data evb_8_by_8_keypad = {
+ .rowmax = 8,
+ .colmax = 8,
+ .irq = MXC_INT_KPP,
+ .learning = 0,
+ .delay = 2,
+ .matrix = keymapping,
+};
+
+/* mxc keypad driver */
+static struct platform_device mxc_keypad_device = {
+ .name = "mxc_keypad",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mxc_kpp_resources),
+ .resource = mxc_kpp_resources,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &evb_8_by_8_keypad,
+ },
+};
+
+static void mxc_init_keypad(void)
+{
+ (void)platform_device_register(&mxc_keypad_device);
+}
+#else
+static inline void mxc_init_keypad(void)
+{
+}
+#endif
#if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE)
/*!
@@ -51,31 +159,30 @@
*/
static struct plat_serial8250_port serial_platform_data[] = {
{
- .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTA),
- .mapbase = (unsigned long)(CS4_BASE_ADDR + PBC_SC16C652_UARTA),
- .irq = EXPIO_INT_XUART_INTA,
- .uartclk = 14745600,
- .regshift = 0,
- .iotype = UPIO_MEM,
- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
- }, {
- .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTB),
- .mapbase = (unsigned long)(CS4_BASE_ADDR + PBC_SC16C652_UARTB),
- .irq = EXPIO_INT_XUART_INTB,
- .uartclk = 14745600,
- .regshift = 0,
- .iotype = UPIO_MEM,
- .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,
- },
+ .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTA),
+ .mapbase = (unsigned long)(CS4_BASE_ADDR + PBC_SC16C652_UARTA),
+ .irq = EXPIO_INT_XUART_INTA,
+ .uartclk = 14745600,
+ .regshift = 0,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,},
+ {
+ .membase = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTB),
+ .mapbase = (unsigned long)(CS4_BASE_ADDR + PBC_SC16C652_UARTB),
+ .irq = EXPIO_INT_XUART_INTB,
+ .uartclk = 14745600,
+ .regshift = 0,
+ .iotype = UPIO_MEM,
+ .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_AUTO_IRQ,},
{},
};
static struct platform_device serial_device = {
- .name = "serial8250",
- .id = 0,
- .dev = {
+ .name = "serial8250",
+ .id = 0,
+ .dev = {
.platform_data = serial_platform_data,
- },
+ },
};
static int __init mxc_init_extuart(void)
@@ -88,71 +195,380 @@ static inline int mxc_init_extuart(void)
return 0;
}
#endif
+/* MTD NOR flash */
+
+#if defined(CONFIG_MTD_MXC) || defined(CONFIG_MTD_MXC_MODULE)
+
+static struct mtd_partition mxc_nor_partitions[] = {
+ {
+ .name = "Bootloader",
+ .size = 512 * 1024,
+ .offset = 0x00000000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "nor.Kernel",
+ .size = 2 * 1024 * 1024,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = 0},
+ {
+ .name = "nor.userfs",
+ .size = 14 * 1024 * 1024,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = 0},
+ {
+ .name = "nor.rootfs",
+ .size = 12 * 1024 * 1024,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE},
+ {
+ .name = "FIS directory",
+ .size = 12 * 1024,
+ .offset = 0x01FE0000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "Redboot config",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0x01FFF000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+};
+
+static struct flash_platform_data mxc_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+ .parts = mxc_nor_partitions,
+ .nr_parts = ARRAY_SIZE(mxc_nor_partitions),
+};
+
+static struct resource mxc_flash_resource = {
+ .start = 0xa0000000,
+ .end = 0xa0000000 + 0x02000000 - 1,
+ .flags = IORESOURCE_MEM,
+
+};
+
+static struct platform_device mxc_nor_mtd_device = {
+ .name = "mxc_nor_flash",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &mxc_flash_resource,
+};
+
+static void mxc_init_nor_mtd(void)
+{
+ (void)platform_device_register(&mxc_nor_mtd_device);
+}
+#else
+static void mxc_init_nor_mtd(void)
+{
+}
+#endif
+
+/* MTD NAND flash */
+
+#if defined(CONFIG_MTD_NAND_MXC) || defined(CONFIG_MTD_NAND_MXC_MODULE) \
+ || defined(CONFIG_MTD_NAND_MXC_V2) || defined(CONFIG_MTD_NAND_MXC_V2_MODULE)
+
+static struct mtd_partition mxc_nand_partitions[4] = {
+ {
+ .name = "nand.bootloader",
+ .offset = 0,
+ .size = 1024 * 1024},
+ {
+ .name = "nand.kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 5 * 1024 * 1024},
+ {
+ .name = "nand.rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 22 * 1024 * 1024},
+ {
+ .name = "nand.userfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL},
+};
+
+static struct flash_platform_data mxc_nand_data = {
+ .parts = mxc_nand_partitions,
+ .nr_parts = ARRAY_SIZE(mxc_nand_partitions),
+ .width = 1,
+};
+
+static struct platform_device mxc_nand_mtd_device = {
+ .name = "mxc_nand_flash",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_nand_data,
+ },
+};
-#if defined(CONFIG_SERIAL_IMX) || defined(CONFIG_SERIAL_IMX_MODULE)
-static struct imxuart_platform_data uart_pdata = {
- .flags = IMXUART_HAVE_RTSCTS,
+static struct platform_device mxc_nandv2_mtd_device = {
+ .name = "mxc_nandv2_flash",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_nand_data,
+ },
};
-static inline void mxc_init_imx_uart(void)
+static void mxc_init_nand_mtd(void)
{
- mxc_iomux_mode(MX31_PIN_CTS1__CTS1);
- mxc_iomux_mode(MX31_PIN_RTS1__RTS1);
- mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
- mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
+ if (__raw_readl(MXC_CCM_RCSR) & MXC_CCM_RCSR_NF16B) {
+ mxc_nand_data.width = 2;
+ }
+ if (cpu_is_mx31()) {
+ (void)platform_device_register(&mxc_nand_mtd_device);
+ }
+ if (cpu_is_mx32()) {
+ (void)platform_device_register(&mxc_nandv2_mtd_device);
+ }
+}
+#else
+static inline void mxc_init_nand_mtd(void)
+{
+}
+#endif
- mxc_register_device(&mxc_uart_device0, &uart_pdata);
+static struct spi_board_info mxc_spi_board_info[] __initdata = {
+ {
+ .modalias = "pmic_spi",
+ .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+ .max_speed_hz = 4000000,
+ .bus_num = 2,
+ .chip_select = 0,
+ },
+};
+
+#if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE)
+static const char fb_default_mode[] = "Sharp-QVGA";
+
+/* mxc lcd driver */
+static struct platform_device mxc_fb_device = {
+ .name = "mxc_sdc_fb",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &fb_default_mode,
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+};
+
+static void mxc_init_fb(void)
+{
+ (void)platform_device_register(&mxc_fb_device);
}
-#else /* !SERIAL_IMX */
-static inline void mxc_init_imx_uart(void)
+#else
+static inline void mxc_init_fb(void)
{
}
-#endif /* !SERIAL_IMX */
+#endif
-static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc)
+#if defined(CONFIG_BACKLIGHT_MXC)
+static struct platform_device mxcbl_devices[] = {
+#if defined(CONFIG_BACKLIGHT_MXC_PMIC) || defined(CONFIG_BACKLIGHT_MXC_PMIC_MODULE)
+ {
+ .name = "mxc_pmic_bl",
+ .id = 0,
+ .dev = {
+ .platform_data = (void *)-1, /* DISP # for this backlight */
+ },
+ },
+ {
+ .name = "mxc_pmic_bl",
+ .id = 1,
+ .dev = {
+ .platform_data = (void *)0, /* DISP # for this backlight */
+ },
+ },
+#endif
+#if defined(CONFIG_BACKLIGHT_MXC_IPU) || defined(CONFIG_BACKLIGHT_MXC_IPU_MODULE)
+ {
+ .name = "mxc_ipu_bl",
+ .id = 0,
+ .dev = {
+ .platform_data = (void *)3, /* DISP # for this backlight */
+ },
+ },
+#endif
+};
+static inline void mxc_init_bl(void)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(mxcbl_devices); i++) {
+ platform_device_register(&mxcbl_devices[i]);
+ }
+}
+#else
+static inline void mxc_init_bl(void)
+{
+}
+#endif
+
+/*!
+ * Data structures and data for mt9v111 camera.
+ */
+static struct mxc_camera_platform_data camera_mt9v111_data = {
+ .mclk = 27000000,
+};
+
+/*!
+ * Data structures and data for ov2640 camera.
+ */
+static struct mxc_camera_platform_data camera_ov2640_data = {
+ .core_regulator = NULL,
+ .io_regulator = NULL,
+ .analog_regulator = NULL,
+ .gpo_regulator = NULL,
+ .mclk = 24000000,
+};
+
+/*!
+ * Info to register i2c devices.
+ */
+static struct i2c_board_info mxc_i2c_info[] __initdata = {
+ {
+ .type = "mt9v111",
+ .addr = 0x48,
+ .platform_data = (void *)&camera_mt9v111_data,
+ },
+ {
+ .type = "ov2640",
+ .addr = 0x30,
+ .platform_data = (void *)&camera_ov2640_data,
+ },
+};
+
+#if defined(CONFIG_MXC_FIR) || defined(CONFIG_MXC_FIR_MODULE)
+/*!
+ * Resource definition for the FIR
+ */
+static struct resource mxcir_resources[] = {
+ [0] = {
+ .start = UART2_BASE_ADDR,
+ .end = UART2_BASE_ADDR + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_UART2,
+ .end = MXC_INT_UART2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = FIRI_BASE_ADDR,
+ .end = FIRI_BASE_ADDR + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [3] = {
+ .start = MXC_INT_FIRI,
+ .end = MXC_INT_FIRI,
+ .flags = IORESOURCE_IRQ,
+ },
+ [4] = {
+ .start = MXC_INT_UART2,
+ .end = MXC_INT_UART2,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct mxc_ir_platform_data ir_data = {
+ .uart_ir_mux = 1,
+ .ir_rx_invert = MXC_IRDA_RX_INV,
+ .ir_tx_invert = MXC_IRDA_TX_INV,
+};
+
+/*! Device Definition for MXC FIR */
+static struct platform_device mxcir_device = {
+ .name = "mxcir",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &ir_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcir_resources),
+ .resource = mxcir_resources,
+};
+
+static inline void mxc_init_ir(void)
+{
+ ir_data.uart_clk = clk_get(NULL, "uart_clk.1");;
+ (void)platform_device_register(&mxcir_device);
+}
+#else
+static inline void mxc_init_ir(void)
+{
+}
+#endif
+
+static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc)
{
u32 imr_val;
u32 int_valid;
u32 expio_irq;
+ desc->chip->mask(irq); /* irq = gpio irq number */
+
imr_val = __raw_readw(PBC_INTMASK_SET_REG);
int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr_val;
+ if (unlikely(!int_valid)) {
+ printk(KERN_ERR "\nEXPIO: Spurious interrupt:0x%0x\n\n",
+ int_valid);
+ goto out;
+ }
+
expio_irq = MXC_EXP_IO_BASE;
for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
+ struct irq_desc *d;
if ((int_valid & 1) == 0)
continue;
-
- generic_handle_irq(expio_irq);
+ d = irq_desc + expio_irq;
+ if (unlikely(!(d->handle_irq))) {
+ printk(KERN_ERR "\nEXPIO irq: %d unhandeled\n",
+ expio_irq);
+ BUG(); /* oops */
+ }
+ d->handle_irq(expio_irq, d);
}
+
+ out:
+ desc->chip->ack(irq);
+ desc->chip->unmask(irq);
}
/*
* Disable an expio pin's interrupt by setting the bit in the imr.
- * @param irq an expio virtual irq number
+ * @param irq an expio virtual irq number
*/
static void expio_mask_irq(u32 irq)
{
u32 expio = MXC_IRQ_TO_EXPIO(irq);
/* mask the interrupt */
__raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG);
- __raw_readw(PBC_INTMASK_CLEAR_REG);
}
/*
* Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
- * @param irq an expanded io virtual irq number
+ * @param irq an expanded io virtual irq number
*/
static void expio_ack_irq(u32 irq)
{
u32 expio = MXC_IRQ_TO_EXPIO(irq);
/* clear the interrupt status */
__raw_writew(1 << expio, PBC_INTSTATUS_REG);
+ /* mask the interrupt */
+ expio_mask_irq(irq);
}
/*
* Enable a expio pin's interrupt by clearing the bit in the imr.
- * @param irq a expio virtual irq number
+ * @param irq a expio virtual irq number
*/
static void expio_unmask_irq(u32 irq)
{
@@ -167,16 +583,21 @@ static struct irq_chip expio_irq_chip = {
.unmask = expio_unmask_irq,
};
-static void __init mx31ads_init_expio(void)
+static int initialized = 0;
+
+static int __init _mxc_expio_init(void)
{
int i;
- printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n");
+ initialized = 1;
+ printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n");
/*
* Configure INT line as GPIO input
*/
- mxc_iomux_mode(IOMUX_MODE(MX31_PIN_GPIO1_4, IOMUX_CONFIG_GPIO));
+ mxc_request_iomux(MX31_PIN_GPIO1_4, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_set_gpio_direction(MX31_PIN_GPIO1_4, 1);
/* disable the interrupt and clear the status */
__raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG);
@@ -187,82 +608,426 @@ static void __init mx31ads_init_expio(void)
set_irq_handler(i, handle_level_irq);
set_irq_flags(i, IRQF_VALID);
}
- set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH);
- set_irq_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler);
+ set_irq_type(EXPIO_PARENT_INT, IRQF_TRIGGER_HIGH);
+ set_irq_chained_handler(EXPIO_PARENT_INT, mxc_expio_irq_handler);
+
+ return 0;
+}
+
+/*
+ * This may get called early from board specific init
+ */
+int mxc_expio_init(void)
+{
+ if (!initialized)
+ return _mxc_expio_init();
+ else
+ return 0;
}
+/* MMC device data */
+
+#if defined(CONFIG_MMC_MXC) || defined(CONFIG_MMC_MXC_MODULE)
+extern unsigned int sdhc_get_card_det_status(struct device *dev);
+extern int sdhc_init_card_det(int id);
+
+static struct mxc_mmc_platform_data mmc0_data = {
+ .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30,
+ .min_clk = 150000,
+ .max_clk = 25000000,
+ .card_inserted_state = 1,
+ .status = sdhc_get_card_det_status,
+ .power_mmc = "VMMC1",
+};
+static struct mxc_mmc_platform_data mmc1_data = {
+ .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30,
+ .min_clk = 150000,
+ .max_clk = 25000000,
+ .card_inserted_state = 1,
+ .status = sdhc_get_card_det_status,
+ .power_mmc = "VMMC2",
+};
+
/*!
- * This structure defines static mappings for the i.MX31ADS board.
+ * Resource definition for the SDHC1
*/
-static struct map_desc mx31ads_io_desc[] __initdata = {
- {
- .virtual = AIPS1_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
- .length = AIPS1_SIZE,
- .type = MT_DEVICE_NONSHARED
- }, {
- .virtual = SPBA0_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
- .length = SPBA0_SIZE,
- .type = MT_DEVICE_NONSHARED
- }, {
- .virtual = AIPS2_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
- .length = AIPS2_SIZE,
- .type = MT_DEVICE_NONSHARED
- }, {
- .virtual = CS4_BASE_ADDR_VIRT,
- .pfn = __phys_to_pfn(CS4_BASE_ADDR),
- .length = CS4_SIZE / 2,
- .type = MT_DEVICE
- },
+static struct resource mxcsdhc1_resources[] = {
+ [0] = {
+ .start = MMC_SDHC1_BASE_ADDR,
+ .end = MMC_SDHC1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_MMC_SDHC1,
+ .end = MXC_INT_MMC_SDHC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
};
/*!
- * Set up static virtual mappings.
+ * Resource definition for the SDHC2
*/
-void __init mx31ads_map_io(void)
+static struct resource mxcsdhc2_resources[] = {
+ [0] = {
+ .start = MMC_SDHC2_BASE_ADDR,
+ .end = MMC_SDHC2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_MMC_SDHC2,
+ .end = MXC_INT_MMC_SDHC2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Device Definition for MXC SDHC1 */
+static struct platform_device mxcsdhc1_device = {
+ .name = "mxcmci",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mmc0_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcsdhc1_resources),
+ .resource = mxcsdhc1_resources,
+};
+
+/*! Device Definition for MXC SDHC2 */
+static struct platform_device mxcsdhc2_device = {
+ .name = "mxcmci",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mmc1_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcsdhc2_resources),
+ .resource = mxcsdhc2_resources,
+};
+
+static inline void mxc_init_mmc(void)
+{
+ int cd_irq;
+
+ cd_irq = sdhc_init_card_det(0);
+ if (cd_irq) {
+ mxcsdhc1_device.resource[2].start = cd_irq;
+ mxcsdhc1_device.resource[2].end = cd_irq;
+ }
+
+ cd_irq = sdhc_init_card_det(1);
+ if (cd_irq) {
+ mxcsdhc2_device.resource[2].start = cd_irq;
+ mxcsdhc2_device.resource[2].end = cd_irq;
+ }
+
+ spba_take_ownership(SPBA_SDHC1, SPBA_MASTER_A | SPBA_MASTER_C);
+ (void)platform_device_register(&mxcsdhc1_device);
+ spba_take_ownership(SPBA_SDHC2, SPBA_MASTER_A | SPBA_MASTER_C);
+ (void)platform_device_register(&mxcsdhc2_device);
+}
+#else
+static inline void mxc_init_mmc(void)
+{
+}
+#endif
+
+/*!
+ * Board specific fixup function. It is called by \b setup_arch() in
+ * setup.c file very early on during kernel starts. It allows the user to
+ * statically fill in the proper values for the passed-in parameters. None of
+ * the parameters is used currently.
+ *
+ * @param desc pointer to \b struct \b machine_desc
+ * @param tags pointer to \b struct \b tag
+ * @param cmdline pointer to the command line
+ * @param mi pointer to \b struct \b meminfo
+ */
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
{
- mxc_map_io();
- iotable_init(mx31ads_io_desc, ARRAY_SIZE(mx31ads_io_desc));
+ mxc_cpu_init();
}
-void __init mx31ads_init_irq(void)
+#if (defined(CONFIG_MXC_PMIC_MC13783) || \
+ defined(CONFIG_MXC_PMIC_MC13783_MODULE)) \
+ && (defined(CONFIG_SND_MXC_PMIC) || defined(CONFIG_SND_MXC_PMIC_MODULE))
+extern void gpio_activate_audio_ports(void);
+
+static void __init mxc_init_pmic_audio(void)
+{
+ struct clk *ckih_clk;
+ struct clk *cko_clk;
+
+ /* Enable 26 mhz clock on CKO1 for PMIC audio */
+ ckih_clk = clk_get(NULL, "ckih");
+ cko_clk = clk_get(NULL, "cko1_clk");
+ if (IS_ERR(ckih_clk) || IS_ERR(cko_clk)) {
+ printk(KERN_ERR "Unable to set CKO1 output to CKIH\n");
+ } else {
+ clk_set_parent(cko_clk, ckih_clk);
+ clk_set_rate(cko_clk, clk_get_rate(ckih_clk));
+ clk_enable(cko_clk);
+ }
+ clk_put(ckih_clk);
+ clk_put(cko_clk);
+
+ gpio_activate_audio_ports();
+}
+#else
+static void __inline mxc_init_pmic_audio(void)
{
- mxc_init_irq();
- mx31ads_init_expio();
}
+#endif
+
+/* IDE device data */
+#if defined(CONFIG_BLK_DEV_IDE_MXC) || defined(CONFIG_BLK_DEV_IDE_MXC_MODULE)
+
+/*! Platform Data for MXC IDE */
+static struct mxc_ide_platform_data mxc_ide_data = {
+ .power_drive = NULL,
+ .power_io = NULL,
+};
+
+static struct platform_device mxc_ide_device = {
+ .name = "mxc_ide",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_ide_data,
+ },
+};
+
+static inline void mxc_init_ide(void)
+{
+ if (platform_device_register(&mxc_ide_device) < 0)
+ printk(KERN_ERR "Error: Registering the ide.\n");
+}
+#else
+static inline void mxc_init_ide(void)
+{
+}
+#endif
+
+#if defined(CONFIG_PATA_FSL) || defined(CONFIG_PATA_FSL_MODULE)
+extern void gpio_ata_active(void);
+extern void gpio_ata_inactive(void);
+
+static int ata_init(struct platform_device *pdev)
+{
+ /* Configure the pins */
+ gpio_ata_active();
+
+ return 0;
+}
+
+static void ata_exit(void)
+{
+ /* Free the pins */
+ gpio_ata_inactive();
+}
+
+static struct fsl_ata_platform_data ata_data = {
+ .udma_mask = ATA_UDMA3, /* board can handle up to UDMA3 */
+ .mwdma_mask = ATA_MWDMA2,
+ .pio_mask = ATA_PIO4,
+ .fifo_alarm = MXC_IDE_DMA_WATERMARK / 2,
+ .max_sg = MXC_IDE_DMA_BD_NR,
+ .init = ata_init,
+ .exit = ata_exit,
+ .core_reg = NULL, /*"LDO2", */
+ .io_reg = NULL, /*"LDO3", */
+};
+
+static struct resource pata_fsl_resources[] = {
+ [0] = { /* I/O */
+ .start = ATA_BASE_ADDR + 0x00,
+ .end = ATA_BASE_ADDR + 0xD8,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = { /* IRQ */
+ .start = MXC_INT_ATA,
+ .end = MXC_INT_ATA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pata_fsl_device = {
+ .name = "pata_fsl",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pata_fsl_resources),
+ .resource = pata_fsl_resources,
+ .dev = {
+ .platform_data = &ata_data,
+ .coherent_dma_mask = ~0,
+ },
+};
+
+static void __init mxc_init_pata(void)
+{
+ (void)platform_device_register(&pata_fsl_device);
+}
+#else /* CONFIG_PATA_FSL */
+static void __init mxc_init_pata(void)
+{
+}
+#endif /* CONFIG_PATA_FSL */
/*!
* Board specific initialization.
*/
static void __init mxc_board_init(void)
{
+ mxc_cpu_common_init();
+ early_console_setup(saved_command_line);
+ mxc_init_devices();
+ mxc_init_pmic_audio();
+ mxc_gpio_init();
+ mx31ads_gpio_init();
+ mxc_expio_init();
+ mxc_init_keypad();
mxc_init_extuart();
- mxc_init_imx_uart();
+ mxc_init_nor_mtd();
+ mxc_init_nand_mtd();
+
+ i2c_register_board_info(0, mxc_i2c_info, ARRAY_SIZE(mxc_i2c_info));
+ spi_register_board_info(mxc_spi_board_info,
+ ARRAY_SIZE(mxc_spi_board_info));
+
+ mxc_init_fb();
+ mxc_init_bl();
+ mxc_init_ir();
+ mxc_init_mmc();
+ mxc_init_ide();
+ mxc_init_pata();
}
+unsigned long board_get_ckih_rate(void)
+{
+}
static void __init mx31ads_timer_init(void)
{
- mxc_clocks_init(26000000);
- mxc_timer_init("ipg_clk.0");
+ unsigned long ckih = 26000000;
+
+ if ((__raw_readw(PBC_BASE_ADDRESS + PBC_BSTAT) &
+ CKIH_27MHZ_BIT_SET) != 0) {
+ ckih = 27000000;
+ }
+
+ mxc_clocks_init(32768, 0, ckih, 0);
+ mxc_timer_init("gpt_clk");
}
-struct sys_timer mx31ads_timer = {
+static struct sys_timer mx31ads_timer = {
.init = mx31ads_timer_init,
};
+
+#define PLL_PCTL_REG(pd, mfd, mfi, mfn) \
+ ((((pd) - 1) << 26) + (((mfd) - 1) << 16) + ((mfi) << 10) + mfn)
+
+/* For 26MHz input clock */
+#define PLL_532MHZ PLL_PCTL_REG(1, 13, 10, 3)
+#define PLL_399MHZ PLL_PCTL_REG(1, 52, 7, 35)
+#define PLL_133MHZ PLL_PCTL_REG(2, 26, 5, 3)
+
+/* For 27MHz input clock */
+#define PLL_532_8MHZ PLL_PCTL_REG(1, 15, 9, 13)
+#define PLL_399_6MHZ PLL_PCTL_REG(1, 18, 7, 7)
+#define PLL_133_2MHZ PLL_PCTL_REG(3, 5, 7, 2)
+
+#define PDR0_REG(mcu, max, hsp, ipg, nfc) \
+ (MXC_CCM_PDR0_MCU_DIV_##mcu | MXC_CCM_PDR0_MAX_DIV_##max | \
+ MXC_CCM_PDR0_HSP_DIV_##hsp | MXC_CCM_PDR0_IPG_DIV_##ipg | \
+ MXC_CCM_PDR0_NFC_DIV_##nfc)
+
+/* working point(wp): 0 - 133MHz; 1 - 266MHz; 2 - 399MHz; 3 - 532MHz */
+/* 26MHz input clock table */
+static struct cpu_wp cpu_wp_26[] = {
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 133000000,
+ .pdr0_reg = PDR0_REG(4, 4, 4, 2, 6),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 266000000,
+ .pdr0_reg = PDR0_REG(2, 4, 4, 2, 6),},
+ {
+ .pll_reg = PLL_399MHZ,
+ .pll_rate = 399000000,
+ .cpu_rate = 399000000,
+ .pdr0_reg = PDR0_REG(1, 3, 3, 2, 6),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 532000000,
+ .pdr0_reg = PDR0_REG(1, 4, 4, 2, 6),},
+};
+
+/* 27MHz input clock table */
+static struct cpu_wp cpu_wp_27[] = {
+ {
+ .pll_reg = PLL_532_8MHZ,
+ .pll_rate = 532800000,
+ .cpu_rate = 133200000,
+ .pdr0_reg = PDR0_REG(4, 4, 4, 2, 6),},
+ {
+ .pll_reg = PLL_532_8MHZ,
+ .pll_rate = 532800000,
+ .cpu_rate = 266400000,
+ .pdr0_reg = PDR0_REG(2, 4, 4, 2, 6),},
+ {
+ .pll_reg = PLL_399_6MHZ,
+ .pll_rate = 399600000,
+ .cpu_rate = 399600000,
+ .pdr0_reg = PDR0_REG(1, 3, 3, 2, 6),},
+ {
+ .pll_reg = PLL_532_8MHZ,
+ .pll_rate = 532800000,
+ .cpu_rate = 532800000,
+ .pdr0_reg = PDR0_REG(1, 4, 4, 2, 6),},
+};
+
+struct cpu_wp *get_cpu_wp(int *wp)
+{
+ *wp = 4;
+ if ((__raw_readw(PBC_BASE_ADDRESS + PBC_BSTAT) &
+ CKIH_27MHZ_BIT_SET) != 0) {
+ return cpu_wp_27;
+ } else {
+ return cpu_wp_26;
+ }
+}
+
/*
* The following uses standard kernel macros defined in arch.h in order to
* initialize __mach_desc_MX31ADS data structure.
*/
-MACHINE_START(MX31ADS, "Freescale MX31ADS")
+/* *INDENT-OFF* */
+MACHINE_START(MX31ADS, "Freescale MX31/MX32 ADS")
/* Maintainer: Freescale Semiconductor, Inc. */
- .phys_io = AIPS1_BASE_ADDR,
- .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
- .boot_params = PHYS_OFFSET + 0x100,
- .map_io = mx31ads_map_io,
- .init_irq = mx31ads_init_irq,
- .init_machine = mxc_board_init,
- .timer = &mx31ads_timer,
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ .phys_io = CS4_BASE_ADDR,
+ .io_pg_offst = ((CS4_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+#else
+ .phys_io = AIPS1_BASE_ADDR,
+ .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+#endif
+ .boot_params = PHYS_OFFSET + 0x100,
+ .fixup = fixup_mxc_board,
+ .map_io = mxc_map_io,
+ .init_irq = mxc_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &mx31ads_timer,
MACHINE_END
diff --git a/arch/arm/mach-mx3/mx31ads_gpio.c b/arch/arm/mach-mx3/mx31ads_gpio.c
new file mode 100644
index 000000000000..f4425673d9d9
--- /dev/null
+++ b/arch/arm/mach-mx3/mx31ads_gpio.c
@@ -0,0 +1,1561 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include "board-mx31ads.h"
+#include "iomux.h"
+
+/*!
+ * @file mach-mx3/mx31ads_gpio.c
+ *
+ * @brief This file contains all the GPIO setup functions for the board.
+ *
+ * @ingroup GPIO_MX31
+ */
+
+void gpio_activate_audio_ports(void);
+
+/*!
+ * This system-wise GPIO function initializes the pins during system startup.
+ * All the statically linked device drivers should put the proper GPIO initialization
+ * code inside this function. It is called by \b fixup_mx31ads() during
+ * system startup. This function is board specific.
+ */
+void mx31ads_gpio_init(void)
+{
+ /* config CS4 */
+ mxc_request_iomux(MX31_PIN_CS4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+
+ /*Connect DAM ports 4 & 5 to enable audio I/O */
+ gpio_activate_audio_ports();
+}
+
+/*!
+ * Setup GPIO for a UART port to be active
+ *
+ * @param port a UART port
+ * @param no_irda indicates if the port is used for SIR
+ */
+void gpio_uart_active(int port, int no_irda)
+{
+ unsigned int pbc_bctrl1_clr = 0, pbc_bctrl2_set = 0, pbc_bctrl2_clr = 0;
+ /*
+ * Configure the IOMUX control registers for the UART signals
+ */
+ switch (port) {
+ /* UART 1 IOMUX Configs */
+ case 0:
+ mxc_request_iomux(MX31_PIN_RXD1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_TXD1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_RTS1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CTS1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_DTR_DCE1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_DSR_DCE1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_RI_DCE1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_DCD_DCE1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+
+ /* Enable the transceiver */
+ pbc_bctrl1_clr |= PBC_BCTRL1_UENCE;
+ pbc_bctrl2_set |= PBC_BCTRL2_USELC;
+ break;
+ /* UART 2 IOMUX Configs */
+ case 1:
+ mxc_request_iomux(MX31_PIN_TXD2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_RXD2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+
+ if (no_irda == 1) {
+ mxc_request_iomux(MX31_PIN_RTS2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CTS2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_DTR_DCE2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ pbc_bctrl1_clr |= PBC_BCTRL1_UENCE;
+ pbc_bctrl2_clr |= PBC_BCTRL2_USELC;
+ } else {
+ pbc_bctrl1_clr |= PBC_BCTRL1_IREN;
+ pbc_bctrl2_clr |= PBC_BCTRL2_IRDA_MOD;
+ }
+ break;
+ /* UART 3 IOMUX Configs */
+ case 2:
+ mxc_request_iomux(MX31_PIN_CSPI3_MOSI, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_CSPI3_MISO, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_CSPI3_SCLK, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_CSPI3_SPI_RDY, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+
+ pbc_bctrl1_clr |= PBC_BCTRL1_UENB;
+ pbc_bctrl2_clr |= PBC_BCTRL2_USELB;
+ break;
+ /* UART 4 IOMUX Configs */
+ case 3:
+ mxc_request_iomux(MX31_PIN_ATA_CS0, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_ATA_CS1, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_ATA_DIOR, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_ATA_DIOW, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+
+ pbc_bctrl1_clr |= PBC_BCTRL1_UENB;
+ pbc_bctrl2_set |= PBC_BCTRL2_USELB;
+ break;
+ /* UART 5 IOMUX Configs */
+ case 4:
+ mxc_request_iomux(MX31_PIN_PC_VS2, OUTPUTCONFIG_ALT2,
+ INPUTCONFIG_ALT2);
+ mxc_request_iomux(MX31_PIN_PC_RST, OUTPUTCONFIG_ALT2,
+ INPUTCONFIG_ALT2);
+ mxc_request_iomux(MX31_PIN_PC_BVD1, OUTPUTCONFIG_ALT2,
+ INPUTCONFIG_ALT2);
+ mxc_request_iomux(MX31_PIN_PC_BVD2, OUTPUTCONFIG_ALT2,
+ INPUTCONFIG_ALT2);
+
+ pbc_bctrl1_clr |= PBC_BCTRL1_UENA;
+ pbc_bctrl2_set |= PBC_BCTRL2_USELA;
+ break;
+ default:
+ break;
+ }
+
+ __raw_writew(pbc_bctrl1_clr, PBC_BASE_ADDRESS + PBC_BCTRL1_CLEAR);
+ __raw_writew(pbc_bctrl2_set, PBC_BASE_ADDRESS + PBC_BCTRL2_SET);
+ __raw_writew(pbc_bctrl2_clr, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR);
+ /*
+ * TODO: Configure the Pad registers for the UART pins
+ */
+}
+
+/*!
+ * Setup GPIO for a UART port to be inactive
+ *
+ * @param port a UART port
+ * @param no_irda indicates if the port is used for SIR
+ */
+void gpio_uart_inactive(int port, int no_irda)
+{
+ unsigned int pbc_bctrl1_set = 0;
+
+ switch (port) {
+ case 0:
+ mxc_request_gpio(MX31_PIN_RXD1);
+ mxc_request_gpio(MX31_PIN_TXD1);
+ mxc_request_gpio(MX31_PIN_RTS1);
+ mxc_request_gpio(MX31_PIN_CTS1);
+ mxc_request_gpio(MX31_PIN_DTR_DCE1);
+ mxc_request_gpio(MX31_PIN_DSR_DCE1);
+ mxc_request_gpio(MX31_PIN_RI_DCE1);
+ mxc_request_gpio(MX31_PIN_DCD_DCE1);
+
+ mxc_free_iomux(MX31_PIN_RXD1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_TXD1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_RTS1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_CTS1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_DTR_DCE1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_DSR_DCE1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_RI_DCE1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_DCD_DCE1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+
+ pbc_bctrl1_set |= PBC_BCTRL1_UENCE;
+ break;
+ case 1:
+ mxc_request_gpio(MX31_PIN_TXD2);
+ mxc_request_gpio(MX31_PIN_RXD2);
+
+ mxc_free_iomux(MX31_PIN_TXD2, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_RXD2, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+
+ if (no_irda == 1) {
+ mxc_request_gpio(MX31_PIN_DTR_DCE2);
+ mxc_free_iomux(MX31_PIN_DTR_DCE2, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+
+ pbc_bctrl1_set |= PBC_BCTRL1_UENCE;
+ } else {
+ pbc_bctrl1_set |= PBC_BCTRL1_IREN;
+ }
+ break;
+ case 2:
+ pbc_bctrl1_set |= PBC_BCTRL1_UENB;
+ break;
+ case 3:
+ mxc_request_gpio(MX31_PIN_ATA_CS0);
+ mxc_request_gpio(MX31_PIN_ATA_CS1);
+ mxc_request_gpio(MX31_PIN_ATA_DIOR);
+ mxc_request_gpio(MX31_PIN_ATA_DIOW);
+
+ mxc_free_iomux(MX31_PIN_ATA_CS0, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_ATA_CS1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_ATA_DIOR, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_ATA_DIOW, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+
+ pbc_bctrl1_set |= PBC_BCTRL1_UENB;
+ break;
+ case 4:
+ pbc_bctrl1_set |= PBC_BCTRL1_UENA;
+ break;
+ default:
+ break;
+ }
+ __raw_writew(pbc_bctrl1_set, PBC_BASE_ADDRESS + PBC_BCTRL1_SET);
+}
+
+/*!
+ * Configure the IOMUX GPR register to receive shared SDMA UART events
+ *
+ * @param port a UART port
+ */
+void config_uartdma_event(int port)
+{
+ switch (port) {
+ case 1:
+ /* Configure to receive UART 2 SDMA events */
+ mxc_iomux_set_gpr(MUX_PGP_FIRI, false);
+ break;
+ case 2:
+ /* Configure to receive UART 3 SDMA events */
+ mxc_iomux_set_gpr(MUX_CSPI1_UART3, true);
+ break;
+ case 4:
+ /* Configure to receive UART 5 SDMA events */
+ mxc_iomux_set_gpr(MUX_CSPI3_UART5_SEL, true);
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_uart_active);
+EXPORT_SYMBOL(gpio_uart_inactive);
+EXPORT_SYMBOL(config_uartdma_event);
+
+/*!
+ * Setup GPIO for Keypad to be active
+ *
+ */
+void gpio_keypad_active(void)
+{
+ /*
+ * Configure the IOMUX control register for keypad signals.
+ */
+ mxc_request_iomux(MX31_PIN_KEY_COL0, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_COL1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_COL2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_COL3, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_COL4, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_COL5, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_COL6, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_COL7, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_ROW0, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_ROW1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_ROW2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_ROW3, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_ROW4, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_ROW5, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_ROW6, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_ROW7, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+}
+
+EXPORT_SYMBOL(gpio_keypad_active);
+
+/*!
+ * Setup GPIO for Keypad to be inactive
+ *
+ */
+void gpio_keypad_inactive(void)
+{
+ mxc_request_iomux(MX31_PIN_KEY_COL4, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_request_iomux(MX31_PIN_KEY_COL5, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_request_iomux(MX31_PIN_KEY_COL6, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_request_iomux(MX31_PIN_KEY_COL7, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+
+ mxc_request_iomux(MX31_PIN_KEY_ROW4, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_request_iomux(MX31_PIN_KEY_ROW5, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_request_iomux(MX31_PIN_KEY_ROW6, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_request_iomux(MX31_PIN_KEY_ROW7, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+}
+
+EXPORT_SYMBOL(gpio_keypad_inactive);
+
+void gpio_power_key_active(void)
+{
+}
+EXPORT_SYMBOL(gpio_power_key_active);
+
+/*!
+ * Setup GPIO for a CSPI device to be active
+ *
+ * @param cspi_mod an CSPI device
+ */
+void gpio_spi_active(int cspi_mod)
+{
+ switch (cspi_mod) {
+ case 0:
+ /* SPI1 */
+ mxc_request_iomux(MX31_PIN_CSPI1_MISO, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI1_MOSI, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI1_SCLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI1_SPI_RDY, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI1_SS0, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI1_SS1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI1_SS2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ break;
+ case 1:
+ /* SPI2 */
+ mxc_request_iomux(MX31_PIN_CSPI2_MISO, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_MOSI, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SPI_RDY, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SS0, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SS1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ break;
+ case 2:
+ /* SPI3 */
+ /*
+ mxc_request_iomux(MX31_PIN_CSPI2_MISO, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_MOSI, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SPI_RDY, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SS0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SS1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ */
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * Setup 1-Wire to be active
+ */
+void gpio_owire_active(void)
+{
+ /*
+ * Configure the IOMUX control register for 1-wire signals.
+ */
+ iomux_config_mux(MX31_PIN_BATT_LINE, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ iomux_config_pad(MX31_PIN_BATT_LINE, PAD_CTL_LOOPBACK);
+}
+
+/*!
+ * Setup 1-Wire to be active
+ */
+void gpio_owire_inactive(void)
+{
+ /*
+ * Configure the IOMUX control register for 1-wire signals.
+ */
+ iomux_config_mux(MX31_PIN_BATT_LINE, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+}
+
+EXPORT_SYMBOL(gpio_owire_active);
+EXPORT_SYMBOL(gpio_owire_inactive);
+
+/*!
+ * Setup GPIO for a CSPI device to be inactive
+ *
+ * @param cspi_mod a CSPI device
+ */
+void gpio_spi_inactive(int cspi_mod)
+{
+ /* Do nothing as CSPI pins doesn't have/support GPIO mode */
+}
+
+/*!
+ * Setup GPIO for an I2C device to be active
+ *
+ * @param i2c_num an I2C device
+ */
+void gpio_i2c_active(int i2c_num)
+{
+ switch (i2c_num) {
+ case 0:
+ mxc_request_iomux(MX31_PIN_I2C_CLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_I2C_DAT, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ break;
+ case 1:
+ mxc_request_iomux(MX31_PIN_CSPI2_MOSI, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_CSPI2_MISO, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ break;
+ case 2:
+ mxc_request_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ break;
+ default:
+ break;
+ }
+
+}
+
+/*!
+ * Setup GPIO for an I2C device to be inactive
+ *
+ * @param i2c_num an I2C device
+ */
+void gpio_i2c_inactive(int i2c_num)
+{
+ switch (i2c_num) {
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ mxc_request_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_ALT1);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * This function configures the IOMux block for PMIC standard operations.
+ *
+ */
+void gpio_pmic_active(void)
+{
+ mxc_request_iomux(MX31_PIN_GPIO1_3, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_set_gpio_direction(MX31_PIN_GPIO1_3, 1);
+// mxc_set_gpio_edge_ctrl(MX31_PIN_GPIO1_3, GPIO_INT_RISE_EDGE);
+}
+
+EXPORT_SYMBOL(gpio_pmic_active);
+
+/*!
+ * This function activates DAM ports 4 & 5 to enable
+ * audio I/O. Thsi function is called from mx31ads_gpio_init
+ * function, which is board-specific.
+ */
+void gpio_activate_audio_ports(void)
+{
+ /* config Audio ports (4 & 5) */
+ mxc_request_iomux(MX31_PIN_SCK4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SRXD4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_STXD4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SFS4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SCK5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SRXD5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_STXD5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SFS5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+}
+
+/*!
+ * Setup GPIO for SDHC to be active
+ *
+ * @param module SDHC module number
+ */
+void gpio_sdhc_active(int module)
+{
+ switch (module) {
+ case 0:
+ mxc_request_iomux(MX31_PIN_SD1_CLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SD1_CMD, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SD1_DATA0, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SD1_DATA1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SD1_DATA2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SD1_DATA3, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+
+ mxc_iomux_set_pad(MX31_PIN_SD1_CLK,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_SD1_CMD,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA0,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA1,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA2,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA3,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ break;
+ case 1:
+ mxc_request_iomux(MX31_PIN_PC_CD2_B, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_PC_CD1_B, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_PC_WAIT_B, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_PC_READY, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_PC_VS1, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_PC_PWRON, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_sdhc_active);
+
+/*!
+ * Setup GPIO for SDHC1 to be inactive
+ *
+ * @param module SDHC module number
+ */
+void gpio_sdhc_inactive(int module)
+{
+ switch (module) {
+ case 0:
+ mxc_request_iomux(MX31_PIN_SD1_CLK, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_SD1_CMD, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_SD1_DATA0, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_SD1_DATA1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_SD1_DATA2, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_SD1_DATA3, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+
+ mxc_iomux_set_pad(MX31_PIN_SD1_CLK,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX31_PIN_SD1_CMD,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA0,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA1,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA2,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA3,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ break;
+ case 1:
+ /* TODO:what are the pins for SDHC2? */
+ mxc_request_iomux(MX31_PIN_PC_CD2_B, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_PC_CD1_B, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_PC_WAIT_B, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_PC_READY, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_PC_VS1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_PC_PWRON, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_sdhc_inactive);
+
+/*
+ * Probe for the card. If present the GPIO data would be set.
+ */
+int sdhc_get_card_det_status(struct device *dev)
+{
+ if (to_platform_device(dev)->id == 0) {
+ return mxc_get_gpio_datain(MX31_PIN_GPIO1_1);
+ } else {
+ return mxc_get_gpio_datain(MX31_PIN_GPIO1_2);
+ }
+}
+
+EXPORT_SYMBOL(sdhc_get_card_det_status);
+
+/*
+ * Return the card detect pin.
+ */
+int sdhc_init_card_det(int id)
+{
+ if (id == 0) {
+ iomux_config_mux(MX31_PIN_GPIO1_1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ return IOMUX_TO_IRQ(MX31_PIN_GPIO1_1);
+ } else {
+ iomux_config_mux(MX31_PIN_GPIO1_2, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ return IOMUX_TO_IRQ(MX31_PIN_GPIO1_2);
+
+ }
+}
+
+EXPORT_SYMBOL(sdhc_init_card_det);
+
+/*!
+ * Setup GPIO for LCD to be active
+ *
+ */
+void gpio_lcd_active(void)
+{
+ u16 temp;
+
+ mxc_request_iomux(MX31_PIN_LD0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD8, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD9, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD10, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD11, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD12, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD13, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD14, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD15, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD16, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // LD16
+ mxc_request_iomux(MX31_PIN_LD17, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // LD17
+ mxc_request_iomux(MX31_PIN_VSYNC3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // VSYNC
+ mxc_request_iomux(MX31_PIN_HSYNC, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // HSYNC
+ mxc_request_iomux(MX31_PIN_FPSHIFT, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // CLK
+ mxc_request_iomux(MX31_PIN_DRDY0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // DRDY
+ mxc_request_iomux(MX31_PIN_D3_REV, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // REV
+ mxc_request_iomux(MX31_PIN_CONTRAST, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // CONTR
+ mxc_request_iomux(MX31_PIN_D3_SPL, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // SPL
+ mxc_request_iomux(MX31_PIN_D3_CLS, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // CLS
+
+ temp = PBC_BCTRL1_LCDON;
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL1_SET);
+}
+
+/*!
+ * Setup GPIO for LCD to be inactive
+ *
+ */
+void gpio_lcd_inactive(void)
+{
+ u16 pbc_bctrl1_set = 0;
+
+ pbc_bctrl1_set = (u16) PBC_BCTRL1_LCDON;
+ __raw_writew(pbc_bctrl1_set, PBC_BASE_ADDRESS + PBC_BCTRL1_SET + 2);
+}
+
+/*!
+ * Setup pins for SLCD to be active
+ *
+ */
+void slcd_gpio_config(void)
+{
+ u16 temp;
+
+ /* Reset smart lcd */
+ temp = PBC_BCTRL2_LDC_RST0;
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR);
+ msleep(2);
+ /* Bring out of reset */
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL2_SET);
+ msleep(2);
+
+ mxc_request_iomux(MX31_PIN_LD0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD8, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD9, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD10, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD11, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD12, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD13, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD14, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD15, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD16, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD17, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+
+ mxc_request_iomux(MX31_PIN_READ, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); /* read */
+ mxc_request_iomux(MX31_PIN_WRITE, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); /* write */
+ mxc_request_iomux(MX31_PIN_PAR_RS, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); /* RS */
+ mxc_request_iomux(MX31_PIN_LCS0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); /* chip select */
+
+ /* Enable smart lcd interface */
+ temp = PBC_BCTRL2_LDCIO_EN;
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR);
+}
+
+/*!
+ * Switch to the specified sensor - MX31 ADS has two
+ *
+ */
+void gpio_sensor_select(int sensor)
+{
+ u16 temp;
+
+ switch (sensor) {
+ case 0:
+#ifdef CONFIG_MXC_CAMERA_MC521DA
+ temp = 0x100;
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL1_SET);
+#else
+ temp = PBC_BCTRL1_SENSOR2_ON;
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL1_CLEAR);
+ temp = PBC_BCTRL1_SENSOR1_ON;
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL1_SET);
+#endif
+ break;
+ case 1:
+ temp = PBC_BCTRL1_SENSOR1_ON;
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL1_CLEAR);
+ temp = PBC_BCTRL1_SENSOR2_ON;
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL1_SET);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * Setup GPIO for sensor to be active
+ *
+ */
+void gpio_sensor_active(void)
+{
+ gpio_sensor_select(0);
+
+ /*
+ * Configure the iomuxen for the CSI.
+ */
+
+ mxc_request_iomux(MX31_PIN_CSI_D4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D8, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D9, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D10, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D11, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D12, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D13, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D14, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D15, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_HSYNC, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_MCLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_PIXCLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_VSYNC, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+
+#ifdef CONFIG_MXC_IPU_CAMERA_16BIT
+ /*
+ * The other 4 data bits are multiplexed on MX31.
+ */
+ mxc_request_iomux(MX31_PIN_ATA_CS0, OUTPUTCONFIG_ALT2,
+ INPUTCONFIG_ALT2);
+ mxc_request_iomux(MX31_PIN_ATA_CS1, OUTPUTCONFIG_ALT2,
+ INPUTCONFIG_ALT2);
+ mxc_request_iomux(MX31_PIN_ATA_DIOR, OUTPUTCONFIG_ALT2,
+ INPUTCONFIG_ALT2);
+ mxc_request_iomux(MX31_PIN_ATA_DIOW, OUTPUTCONFIG_ALT2,
+ INPUTCONFIG_ALT2);
+#endif
+
+ /*
+ * Now enable the CSI buffers
+ */
+
+ __raw_writew(PBC_BCTRL2_CSI_EN, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR);
+
+#ifdef CONFIG_MXC_IPU_CAMERA_16BIT
+ /*
+ * Enable the other buffer for the additional 4 data bits.
+ */
+ __raw_writew(PBC_BCTRL4_CSI_MSB_EN,
+ PBC_BASE_ADDRESS + PBC_BCTRL4_CLEAR);
+#endif
+}
+
+EXPORT_SYMBOL(gpio_sensor_active);
+
+void gpio_sensor_reset(bool flag)
+{
+ u16 temp;
+
+ if (flag) {
+ temp = 0x200;
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL1_CLEAR);
+ } else {
+ temp = 0x200;
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL1_SET);
+ }
+}
+
+EXPORT_SYMBOL(gpio_sensor_reset);
+
+/*!
+ * Setup GPIO for sensor to be inactive
+ *
+ */
+void gpio_sensor_inactive(void)
+{
+ mxc_free_iomux(MX31_PIN_CSI_D4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D8, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D9, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D10, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D11, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D12, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D13, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D14, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D15, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_HSYNC, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_MCLK, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_PIXCLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_VSYNC, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+}
+
+EXPORT_SYMBOL(gpio_sensor_inactive);
+
+/*!
+ * Setup GPIO for ATA interface
+ *
+ */
+void gpio_ata_active(void)
+{
+ /*
+ * Configure the GPR for ATA group B signals
+ */
+ __raw_writew(PBC_BCTRL2_ATA_SEL, PBC_BASE_ADDRESS + PBC_BCTRL2_SET);
+ __raw_writew(PBC_BCTRL2_ATA_EN, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR);
+
+ mxc_iomux_set_gpr(MUX_PGP_ATA_7 | MUX_PGP_ATA_6 | MUX_PGP_ATA_2 |
+ MUX_PGP_ATA_1, true);
+
+ /*
+ * Configure the IOMUX for ATA group B signals
+ */
+
+ mxc_request_iomux(MX31_PIN_CSPI1_MOSI, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D0
+ mxc_request_iomux(MX31_PIN_CSPI1_MISO, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D1
+ mxc_request_iomux(MX31_PIN_CSPI1_SS0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D2
+ mxc_request_iomux(MX31_PIN_CSPI1_SS1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D3
+ mxc_request_iomux(MX31_PIN_CSPI1_SS2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D4
+ mxc_request_iomux(MX31_PIN_CSPI1_SCLK, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D5
+ mxc_request_iomux(MX31_PIN_CSPI1_SPI_RDY, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D6
+ mxc_request_iomux(MX31_PIN_STXD3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D7
+ mxc_request_iomux(MX31_PIN_SRXD3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D8
+ mxc_request_iomux(MX31_PIN_SCK3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D9
+ mxc_request_iomux(MX31_PIN_SFS3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D10
+ mxc_request_iomux(MX31_PIN_STXD6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D11
+ mxc_request_iomux(MX31_PIN_SRXD6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D12
+ mxc_request_iomux(MX31_PIN_SCK6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D13
+ mxc_request_iomux(MX31_PIN_CAPTURE, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D14
+ mxc_request_iomux(MX31_PIN_COMPARE, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D15
+
+ mxc_request_iomux(MX31_PIN_USBH2_STP, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_DMARQ_B
+ mxc_request_iomux(MX31_PIN_USBH2_CLK, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_INTRQ_B
+ mxc_request_iomux(MX31_PIN_USBH2_NXT, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_DA0
+ mxc_request_iomux(MX31_PIN_USBH2_DATA0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_DA1
+ mxc_request_iomux(MX31_PIN_USBH2_DATA1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_DA2
+ mxc_request_iomux(MX31_PIN_USBH2_DIR, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_BUFFER_DIR
+
+ /* These ATA pins are common to Group A and Group B */
+
+ mxc_request_iomux(MX31_PIN_ATA_CS0, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_ATA_CS1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_ATA_DIOR, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_ATA_DIOW, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_ATA_DMACK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_ATA_RESET_B, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_PWMO, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+
+ /* Need fast slew rate for UDMA mode */
+
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 0
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 1
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 2
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 3
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 4
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 5
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 6
+ mxc_iomux_set_pad(MX31_PIN_STXD3, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 7
+ mxc_iomux_set_pad(MX31_PIN_SRXD3, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 8
+ mxc_iomux_set_pad(MX31_PIN_SCK3, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 9
+ mxc_iomux_set_pad(MX31_PIN_SFS3, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 10
+ mxc_iomux_set_pad(MX31_PIN_STXD6, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 11
+ mxc_iomux_set_pad(MX31_PIN_SRXD6, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 12
+ mxc_iomux_set_pad(MX31_PIN_SCK6, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 13
+ mxc_iomux_set_pad(MX31_PIN_CAPTURE, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 14
+ mxc_iomux_set_pad(MX31_PIN_COMPARE, PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE); // data 12
+
+ /*
+ * Turn off default pullups on high asserted control signals.
+ * These are pulled down externally, so it will just waste
+ * power and create voltage divider action to pull them up
+ * on chip.
+ */
+ mxc_iomux_set_pad(MX31_PIN_USBH2_STP, PAD_CTL_PKE_NONE); // ATA_DMARQ
+ mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, PAD_CTL_PKE_NONE); // ATA_INTRQ
+}
+
+EXPORT_SYMBOL(gpio_ata_active);
+
+/*!
+ * Restore ATA interface pins to reset values
+ *
+ */
+void gpio_ata_inactive(void)
+{
+ __raw_writew(PBC_BCTRL2_ATA_EN, PBC_BASE_ADDRESS + PBC_BCTRL2_SET);
+ /*
+ * Turn off ATA group B signals
+ */
+ mxc_request_iomux(MX31_PIN_STXD3, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D7
+ mxc_request_iomux(MX31_PIN_SRXD3, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D8
+ mxc_request_iomux(MX31_PIN_STXD6, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D11
+ mxc_request_iomux(MX31_PIN_SRXD6, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D12
+ mxc_request_iomux(MX31_PIN_SCK6, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D13
+ mxc_request_iomux(MX31_PIN_CAPTURE, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D14
+ mxc_request_iomux(MX31_PIN_COMPARE, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D15
+
+ /* These ATA pins are common to Group A and Group B */
+
+ mxc_request_iomux(MX31_PIN_ATA_CS0, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_ATA_CS1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_ATA_DIOR, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_ATA_DIOW, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_ATA_DMACK, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_ATA_RESET_B, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+
+ /* Needed fast slew rate for UDMA mode */
+
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 0
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 1
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 2
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 3
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 4
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 5
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 6
+ mxc_iomux_set_pad(MX31_PIN_STXD3, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 7
+ mxc_iomux_set_pad(MX31_PIN_SRXD3, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 8
+ mxc_iomux_set_pad(MX31_PIN_SCK3, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 9
+ mxc_iomux_set_pad(MX31_PIN_SFS3, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 10
+ mxc_iomux_set_pad(MX31_PIN_STXD3, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 11
+ mxc_iomux_set_pad(MX31_PIN_SRXD6, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 12
+ mxc_iomux_set_pad(MX31_PIN_SCK6, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 13
+ mxc_iomux_set_pad(MX31_PIN_CAPTURE, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 14
+ mxc_iomux_set_pad(MX31_PIN_COMPARE, PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE); // data 12
+}
+
+EXPORT_SYMBOL(gpio_ata_inactive);
+
+/*!
+ * Setup EDIO/IOMUX for external UART.
+ *
+ * @param port UART port
+ * @param irq Interrupt line to allocate
+ * @param handler Function to be called when the IRQ occurs
+ * @param irq_flags Interrupt type flags
+ * @param devname An ascii name for the claiming device
+ * @param dev_id A cookie passed back to the handler function
+ * @return Returns 0 if the interrupt was successfully requested,
+ * otherwise returns an error code.
+ */
+int extuart_intr_setup(unsigned int port, unsigned int irq,
+ irqreturn_t(*handler) (int, void *),
+ unsigned long irq_flags, const char *devname,
+ void *dev_id)
+{
+ return 0;
+}
+
+/*!
+ * Get the EDIO interrupt, clear if set.
+ *
+ * @param port UART port
+ */
+void extuart_intr_clear(unsigned int port)
+{
+}
+
+/*!
+ * Do IOMUX configs required to put the
+ * pin back in low power mode.
+ *
+ * @param port UART port
+ * @param irq Interrupt line to free
+ * @param dev_id Device identity to free
+ * @return Returns 0 if the interrupt was successfully freed,
+ * otherwise returns an error code.
+ */
+int extuart_intr_cleanup(unsigned int port, unsigned int irq, void *dev_id)
+{
+ return 0;
+}
+
+/* *INDENT-OFF* */
+/*
+ * USB Host 1
+ * pins conflict with SPI1, ATA, UART3
+ */
+int gpio_usbh1_active(void)
+{
+ if (mxc_request_iomux(MX31_PIN_CSPI1_MOSI, /* USBH1_RXDM */
+ OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) ||
+ mxc_request_iomux(MX31_PIN_CSPI1_MISO, /* USBH1_RXDP */
+ OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) ||
+ mxc_request_iomux(MX31_PIN_CSPI1_SS0, /* USBH1_TXDM */
+ OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) ||
+ mxc_request_iomux(MX31_PIN_CSPI1_SS1, /* USBH1_TXDP */
+ OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) ||
+ mxc_request_iomux(MX31_PIN_CSPI1_SS2, /* USBH1_RCV */
+ OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) ||
+ mxc_request_iomux(MX31_PIN_CSPI1_SCLK, /* USBH1_OEB (_TXOE) */
+ OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) ||
+ mxc_request_iomux(MX31_PIN_CSPI1_SPI_RDY, /* USBH1_FS */
+ OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1)) {
+ return -EINVAL;
+ }
+
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, /* USBH1_RXDM */
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, /* USBH1_RXDP */
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, /* USBH1_TXDM */
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, /* USBH1_TXDP */
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, /* USBH1_RCV */
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, /* USBH1_OEB (_TXOE) */
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, /* USBH1_FS */
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+
+ mxc_iomux_set_gpr(MUX_PGP_USB_SUSPEND, true);
+
+ __raw_writew(PBC_BCTRL3_FSH_EN, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR); /* enable FSH */
+ __raw_writew(PBC_BCTRL3_FSH_SEL, PBC_BASE_ADDRESS + PBC_BCTRL3_SET); /* Group B */
+ __raw_writew(PBC_BCTRL3_FSH_MOD, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR); /* single ended */
+ __raw_writew(PBC_BCTRL3_FSH_VBUS_EN, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR); /* enable FSH VBUS */
+
+ return 0;
+}
+
+EXPORT_SYMBOL(gpio_usbh1_active);
+
+void gpio_usbh1_inactive(void)
+{
+ /* Do nothing as pins don't have/support GPIO mode */
+
+}
+
+EXPORT_SYMBOL(gpio_usbh1_inactive);
+
+/*
+ * USB Host 2
+ * pins conflict with UART5, PCMCIA
+ */
+int gpio_usbh2_active(void)
+{
+ if (mxc_request_iomux(MX31_PIN_USBH2_CLK,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBH2_DIR,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBH2_NXT,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBH2_STP,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBH2_DATA0,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBH2_DATA1,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_PC_VS2, /* USBH2_DATA2 */
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) ||
+ mxc_request_iomux(MX31_PIN_PC_BVD1, /* USBH2_DATA3 */
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) ||
+ mxc_request_iomux(MX31_PIN_PC_BVD2, /* USBH2_DATA4 */
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) ||
+ mxc_request_iomux(MX31_PIN_PC_RST, /* USBH2_DATA5 */
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) ||
+ mxc_request_iomux(MX31_PIN_IOIS16, /* USBH2_DATA6 */
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) ||
+ mxc_request_iomux(MX31_PIN_PC_RW_B, /* USBH2_DATA7 */
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) ||
+ mxc_request_iomux(MX31_PIN_NFWE_B,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) ||
+ mxc_request_iomux(MX31_PIN_NFRE_B,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) ||
+ mxc_request_iomux(MX31_PIN_NFALE,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) ||
+ mxc_request_iomux(MX31_PIN_NFCLE,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) ||
+ mxc_request_iomux(MX31_PIN_NFWP_B,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE) ||
+ mxc_request_iomux(MX31_PIN_NFCE_B,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE)) {
+ return -EINVAL;
+ }
+
+#define H2_PAD_CFG (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST | PAD_CTL_HYS_CMOS | PAD_CTL_ODE_CMOS | PAD_CTL_100K_PU)
+ mxc_iomux_set_pad(MX31_PIN_USBH2_CLK, H2_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DIR, H2_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_NXT, H2_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_STP, H2_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0, H2_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1, H2_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SRXD6, H2_PAD_CFG); /* USBH2_DATA2 */
+ mxc_iomux_set_pad(MX31_PIN_STXD6, H2_PAD_CFG); /* USBH2_DATA3 */
+ mxc_iomux_set_pad(MX31_PIN_SFS3, H2_PAD_CFG); /* USBH2_DATA4 */
+ mxc_iomux_set_pad(MX31_PIN_SCK3, H2_PAD_CFG); /* USBH2_DATA5 */
+ mxc_iomux_set_pad(MX31_PIN_SRXD3, H2_PAD_CFG); /* USBH2_DATA6 */
+ mxc_iomux_set_pad(MX31_PIN_STXD3, H2_PAD_CFG); /* USBH2_DATA7 */
+#undef H2_PAD_CFG
+
+ mxc_iomux_set_gpr(MUX_PGP_UH2, true);
+
+ __raw_writew(PBC_BCTRL3_HSH_SEL, PBC_BASE_ADDRESS + PBC_BCTRL3_SET); /* enable HSH select */
+ __raw_writew(PBC_BCTRL3_HSH_EN, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR); /* enable HSH */
+
+ return 0;
+}
+
+EXPORT_SYMBOL(gpio_usbh2_active);
+
+void gpio_usbh2_inactive(void)
+{
+ iomux_config_gpr(MUX_PGP_UH2, false);
+
+ iomux_config_pad(MX31_PIN_USBH2_CLK,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ iomux_config_pad(MX31_PIN_USBH2_DIR,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ iomux_config_pad(MX31_PIN_USBH2_NXT,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ iomux_config_pad(MX31_PIN_USBH2_STP,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ iomux_config_pad(MX31_PIN_USBH2_DATA0,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ iomux_config_pad(MX31_PIN_USBH2_DATA1,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ iomux_config_pad(MX31_PIN_SRXD6, /* USBH2_DATA2 */
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ iomux_config_pad(MX31_PIN_STXD6, /* USBH2_DATA3 */
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ iomux_config_pad(MX31_PIN_SFS3, /* USBH2_DATA4 */
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ iomux_config_pad(MX31_PIN_SCK3, /* USBH2_DATA5 */
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ iomux_config_pad(MX31_PIN_SRXD3, /* USBH2_DATA6 */
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ iomux_config_pad(MX31_PIN_STXD3, /* USBH2_DATA7 */
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+
+ mxc_free_iomux(MX31_PIN_NFWE_B,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_NFRE_B,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_NFALE,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_NFCLE,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_NFWP_B,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_NFCE_B,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+
+ __raw_writew(PBC_BCTRL3_HSH_SEL, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR);
+ __raw_writew(PBC_BCTRL3_HSH_EN, PBC_BASE_ADDRESS + PBC_BCTRL3_SET);
+}
+
+EXPORT_SYMBOL(gpio_usbh2_inactive);
+
+/*
+ * USB OTG HS port
+ */
+int gpio_usbotg_hs_active(void)
+{
+ if (mxc_request_iomux(MX31_PIN_USBOTG_DATA0,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA1,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA2,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA3,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA4,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA5,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA6,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA7,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_CLK,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DIR,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_NXT,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_STP,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC)) {
+ return -EINVAL;
+ }
+
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_STP,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+
+ /* enable OTG/HS */
+ __raw_writew(PBC_BCTRL3_OTG_HS_EN, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR);
+ /* disable OTG/FS */
+ __raw_writew(PBC_BCTRL3_OTG_FS_EN, PBC_BASE_ADDRESS + PBC_BCTRL3_SET);
+ return 0;
+}
+
+EXPORT_SYMBOL(gpio_usbotg_hs_active);
+
+void gpio_usbotg_hs_inactive(void)
+{
+ /* Do nothing as pins doesn't have/support GPIO mode */
+
+}
+
+EXPORT_SYMBOL(gpio_usbotg_hs_inactive);
+
+/*
+ * USB OTG FS port
+ */
+int gpio_usbotg_fs_active(void)
+{
+ if (mxc_request_iomux(MX31_PIN_USBOTG_DATA0,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA1,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA2,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA3,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA4,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA5,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA6,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA7,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_CLK,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DIR,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_NXT,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_STP,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USB_PWR,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC)) {
+ return -EINVAL;
+ }
+
+ /* disable OTG/HS */
+ __raw_writew(PBC_BCTRL3_OTG_HS_EN, PBC_BASE_ADDRESS + PBC_BCTRL3_SET);
+ /* enable OTG/FS */
+ __raw_writew(PBC_BCTRL3_OTG_FS_EN, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR);
+
+#if defined(CONFIG_MC13783_MXC)
+ /* Select PMIC transceiver */
+ __raw_writew(PBC_BCTRL3_OTG_FS_SEL, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR);
+#endif
+ return 0;
+
+}
+
+EXPORT_SYMBOL(gpio_usbotg_fs_active);
+
+void gpio_usbotg_fs_inactive(void)
+{
+ /* Do nothing as pins doesn't have/support GPIO mode */
+
+}
+
+EXPORT_SYMBOL(gpio_usbotg_fs_inactive);
+/* *INDENT-ON* */
+
+/*!
+ * Setup GPIO for PCMCIA interface
+ *
+ */
+void gpio_pcmcia_active(void)
+{
+ u16 temp;
+
+ mxc_request_iomux(MX31_PIN_SDBA0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SDBA1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+
+ iomux_config_mux(MX31_PIN_LBA, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ iomux_config_mux(MX31_PIN_RW, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ iomux_config_mux(MX31_PIN_EB0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ iomux_config_mux(MX31_PIN_EB1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ iomux_config_mux(MX31_PIN_OE, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+
+ iomux_config_mux(MX31_PIN_IOIS16, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ iomux_config_mux(MX31_PIN_PC_BVD1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ iomux_config_mux(MX31_PIN_PC_BVD2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ iomux_config_mux(MX31_PIN_PC_CD1_B, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ iomux_config_mux(MX31_PIN_PC_CD2_B, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ iomux_config_mux(MX31_PIN_PC_POE, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ iomux_config_mux(MX31_PIN_PC_PWRON, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ iomux_config_mux(MX31_PIN_PC_READY, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ iomux_config_mux(MX31_PIN_PC_RST, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ iomux_config_mux(MX31_PIN_PC_RW_B, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ iomux_config_mux(MX31_PIN_PC_VS1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ iomux_config_mux(MX31_PIN_PC_VS2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ iomux_config_mux(MX31_PIN_PC_WAIT_B, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+
+ /* PCMCIA VPP, VCC Enable, 1 = power on */
+ temp = PBC_BCTRL2_VPP_EN | PBC_BCTRL2_VCC_EN;
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL2_SET);
+
+ /* Set up Card2 Select pin for PCMCIA, 0 = PCMCIA & SD2 */
+ temp = PBC_BCTRL3_CARD2_SEL;
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL3_CLEAR);
+
+ /* PCMCIA Enable, 0 = enable */
+ temp = PBC_BCTRL4_PCMCIA_EN;
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL4_CLEAR);
+ mdelay(1);
+}
+
+EXPORT_SYMBOL(gpio_pcmcia_active);
+
+/*!
+ * Setup GPIO for pcmcia to be inactive
+ */
+void gpio_pcmcia_inactive(void)
+{
+ u16 temp;
+
+ /* PCMCIA Enable, 0 = enable */
+ temp = PBC_BCTRL4_PCMCIA_EN;
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL4_SET);
+
+ /* Set up Card2 Select pin for PCMCIA, 0 = PCMCIA & SD2 */
+ temp = PBC_BCTRL3_CARD2_SEL;
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL3_SET);
+
+ /* PCMCIA VPP, VCC Enable, 1 = power on */
+ temp = PBC_BCTRL2_VPP_EN | PBC_BCTRL2_VCC_EN;
+ __raw_writew(temp, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR);
+}
+
+EXPORT_SYMBOL(gpio_pcmcia_inactive);
+/*!
+ * Setup IR to be used by UART and FIRI
+ */
+void gpio_firi_init(void)
+{
+ gpio_uart_active(1, 0);
+}
+
+EXPORT_SYMBOL(gpio_firi_init);
+
+/*!
+ * Setup IR to be used by UART
+ */
+void gpio_firi_inactive(void)
+{
+ unsigned int pbc_bctrl2_set = 0, pbc_bctrl2_clr = 0;
+
+ iomux_config_gpr(MUX_PGP_FIRI, false);
+ mxc_request_iomux(MX31_PIN_TXD2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_RXD2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+
+ pbc_bctrl2_set |= PBC_BCTRL2_IRDA_MOD;
+ __raw_writew(pbc_bctrl2_set, PBC_BASE_ADDRESS + PBC_BCTRL2_SET);
+
+ pbc_bctrl2_clr |= PBC_BCTRL2_IRDA_MOD;
+ __raw_writew(pbc_bctrl2_clr, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR);
+}
+
+EXPORT_SYMBOL(gpio_firi_inactive);
+
+/*!
+ * Setup IR to be used by FIRI
+ */
+void gpio_firi_active(void *fir_cong_reg_base, unsigned int tpp_mask)
+{
+ unsigned int pbc_bctrl2_set = 0, pbc_bctrl2_clr = 0;
+ unsigned int cr;
+
+ iomux_config_gpr(MUX_PGP_FIRI, true);
+
+ cr = readl(fir_cong_reg_base);
+ cr &= ~tpp_mask;
+ writel(cr, fir_cong_reg_base);
+
+ pbc_bctrl2_clr |= PBC_BCTRL2_IRDA_MOD;
+ __raw_writew(pbc_bctrl2_clr, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR);
+
+ pbc_bctrl2_set |= PBC_BCTRL2_IRDA_MOD;
+ __raw_writew(pbc_bctrl2_set, PBC_BASE_ADDRESS + PBC_BCTRL2_SET);
+
+ cr = readl(fir_cong_reg_base);
+ cr |= tpp_mask;
+ writel(cr, fir_cong_reg_base);
+
+ __raw_writew(pbc_bctrl2_clr, PBC_BASE_ADDRESS + PBC_BCTRL2_CLEAR);
+
+ cr = readl(fir_cong_reg_base);
+ cr &= ~tpp_mask;
+ writel(cr, fir_cong_reg_base);
+}
+
+EXPORT_SYMBOL(gpio_firi_active);
diff --git a/arch/arm/mach-mx3/mx3_3stack.c b/arch/arm/mach-mx3/mx3_3stack.c
new file mode 100644
index 000000000000..55b88527b015
--- /dev/null
+++ b/arch/arm/mach-mx3/mx3_3stack.c
@@ -0,0 +1,1085 @@
+/*
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright (C) 2002 Shane Nay (shane@minirl.com)
+ * Copyright 2005-2009 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
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/i2c.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/regulator/regulator-platform.h>
+#include <linux/regulator/regulator.h>
+#include <linux/ata.h>
+#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE)
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/flash.h>
+#endif
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/keypad.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+#include <mach/hardware.h>
+#include <mach/memory.h>
+#include <mach/gpio.h>
+#include <mach/mmc.h>
+#include <mach/spba.h>
+#include <mach/pmic_power.h>
+
+#include "board-mx3_3stack.h"
+#include "crm_regs.h"
+#include "iomux.h"
+/*!
+ * @file mach-mx3/mx3_3stack.c
+ *
+ * @brief This file contains the board specific initialization routines.
+ *
+ * @ingroup MSL_MX31
+ */
+
+extern void mxc_map_io(void);
+extern void mxc_init_irq(void);
+extern void mxc_cpu_init(void) __init;
+extern void mxc_cpu_common_init(void);
+extern void __init early_console_setup(char *);
+extern int mxc_init_devices(void);
+
+static void mxc_nop_release(struct device *dev)
+{
+ /* Nothing */
+}
+
+#if defined(CONFIG_KEYBOARD_MXC) || defined(CONFIG_KEYBOARD_MXC_MODULE)
+static u16 keymapping[12] = {
+ KEY_UP, KEY_DOWN, 0, 0,
+ KEY_RIGHT, KEY_LEFT, KEY_ENTER, 0,
+ KEY_F6, KEY_F8, KEY_F9, KEY_F10,
+};
+
+static struct resource mxc_kpp_resources[] = {
+ [0] = {
+ .start = MXC_INT_KPP,
+ .end = MXC_INT_KPP,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct keypad_data keypad_plat_data = {
+ .rowmax = 3,
+ .colmax = 4,
+ .irq = MXC_INT_KPP,
+ .learning = 0,
+ .delay = 2,
+ .matrix = keymapping,
+};
+
+/* mxc keypad driver */
+static struct platform_device mxc_keypad_device = {
+ .name = "mxc_keypad",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mxc_kpp_resources),
+ .resource = mxc_kpp_resources,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &keypad_plat_data,
+ },
+};
+
+static void mxc_init_keypad(void)
+{
+ (void)platform_device_register(&mxc_keypad_device);
+}
+#else
+static inline void mxc_init_keypad(void)
+{
+}
+#endif
+
+/* MTD NAND flash */
+#if defined(CONFIG_MTD_NAND_MXC) || defined(CONFIG_MTD_NAND_MXC_MODULE) \
+ || defined(CONFIG_MTD_NAND_MXC_V2) || defined(CONFIG_MTD_NAND_MXC_V2_MODULE)
+
+static struct mtd_partition mxc_nand_partitions[] = {
+ {
+ .name = "nand.bootloader",
+ .offset = 0,
+ .size = 1024 * 1024},
+ {
+ .name = "nand.kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 5 * 1024 * 1024},
+ {
+ .name = "nand.rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 96 * 1024 * 1024},
+ {
+ .name = "nand.configure",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024},
+ {
+ .name = "nand.userfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL},
+};
+
+static struct flash_platform_data mxc_nand_data = {
+ .parts = mxc_nand_partitions,
+ .nr_parts = ARRAY_SIZE(mxc_nand_partitions),
+ .width = 1,
+};
+
+static struct platform_device mxc_nand_mtd_device = {
+ .name = "mxc_nand_flash",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_nand_data,
+ },
+};
+
+static struct platform_device mxc_nandv2_mtd_device = {
+ .name = "mxc_nandv2_flash",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_nand_data,
+ },
+};
+
+static void mxc_init_nand_mtd(void)
+{
+ if (__raw_readl(MXC_CCM_RCSR) & MXC_CCM_RCSR_NF16B) {
+ mxc_nand_data.width = 2;
+ }
+ if (cpu_is_mx31()) {
+ (void)platform_device_register(&mxc_nand_mtd_device);
+ }
+ if (cpu_is_mx32()) {
+ (void)platform_device_register(&mxc_nandv2_mtd_device);
+ }
+}
+#else
+static inline void mxc_init_nand_mtd(void)
+{
+}
+#endif
+
+static void lcd_reset(void)
+{
+ /* ensure that LCDIO(1.8V) has been turn on */
+ /* active reset line GPIO */
+ mxc_request_iomux(MX31_PIN_LCS1, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_set_gpio_dataout(MX31_PIN_LCS1, 0);
+ mxc_set_gpio_direction(MX31_PIN_LCS1, 0);
+ /* do reset */
+ msleep(10); /* tRES >= 100us */
+ mxc_set_gpio_dataout(MX31_PIN_LCS1, 1);
+ msleep(60);
+#ifdef CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL
+ mxc_set_gpio_dataout(MX31_PIN_LCS1, 0);
+#endif
+}
+
+static struct mxc_lcd_platform_data lcd_data = {
+ .io_reg = "VGEN",
+#ifdef CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL
+ .core_reg = "GPO1",
+#else
+ .core_reg = "VMMC1",
+#endif
+ .reset = lcd_reset,
+};
+
+static struct mxc_camera_platform_data camera_data = {
+ .core_regulator = "VVIB",
+ .io_regulator = "VMMC1",
+ .analog_regulator = "SW2B_NORMAL",
+ .gpo_regulator = "GPO3",
+ .mclk = 27000000,
+};
+
+struct mxc_tvout_platform_data tvout_data = {
+ .io_reg = "VGEN",
+ .core_reg = "GPO3",
+ .analog_reg = "GPO1",
+ .detect_line = MX31_PIN_BATT_LINE,
+};
+
+void si4702_reset(void)
+{
+ mxc_set_gpio_dataout(MX31_PIN_SRST0, 0);
+ msleep(100);
+ mxc_set_gpio_dataout(MX31_PIN_SRST0, 1);
+ msleep(100);
+}
+
+void si4702_clock_ctl(int flag)
+{
+ mxc_set_gpio_dataout(MX31_PIN_SIMPD0, flag);
+}
+
+static void si4702_gpio_get(void)
+{
+ /* reset pin */
+ mxc_request_iomux(MX31_PIN_SRST0, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_set_gpio_direction(MX31_PIN_SRST0, 0);
+
+ mxc_request_iomux(MX31_PIN_SIMPD0, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_set_gpio_direction(MX31_PIN_SIMPD0, 0);
+}
+
+static void si4702_gpio_put(void)
+{
+ mxc_free_iomux(MX31_PIN_SRST0, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_SIMPD0, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+}
+
+static struct mxc_fm_platform_data si4702_data = {
+ .reg_vio = "GPO3",
+ .reg_vdd = "VMMC1",
+ .gpio_get = si4702_gpio_get,
+ .gpio_put = si4702_gpio_put,
+ .reset = si4702_reset,
+ .clock_ctl = si4702_clock_ctl,
+};
+
+/* setup GPIO for mma7450 */
+static void gpio_mma7450_get(void)
+{
+ mxc_request_iomux(MX31_PIN_STX0, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO);
+ mxc_iomux_set_pad(MX31_PIN_STX0, PAD_CTL_PKE_NONE);
+ mxc_set_gpio_direction(MX31_PIN_STX0, 1);
+
+ mxc_request_iomux(MX31_PIN_SRX0, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO);
+ mxc_iomux_set_pad(MX31_PIN_SRX0, PAD_CTL_PKE_NONE);
+ mxc_set_gpio_direction(MX31_PIN_SRX0, 1);
+}
+
+static void gpio_mma7450_put(void)
+{
+ mxc_free_iomux(MX31_PIN_STX0, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_SRX0, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO);
+}
+
+static struct mxc_mma7450_platform_data mma7450_data = {
+ .reg_dvdd_io = "GPO3",
+ .reg_avdd = "VMMC1",
+ .gpio_pin_get = gpio_mma7450_get,
+ .gpio_pin_put = gpio_mma7450_put,
+ .int1 = IOMUX_TO_IRQ(MX31_PIN_STX0),
+ .int2 = IOMUX_TO_IRQ(MX31_PIN_SRX0),
+};
+
+static struct i2c_board_info mxc_i2c_board_info[] __initdata = {
+ {
+ .type = "ov2640",
+ .addr = 0x30,
+ .platform_data = (void *)&camera_data,},
+ {
+ .type = "ch7024",
+ .addr = 0x76,
+ .platform_data = (void *)&tvout_data,
+ .irq = IOMUX_TO_IRQ(MX31_PIN_BATT_LINE),},
+ {
+ .type = "si4702",
+ .addr = 0x10,
+ .platform_data = (void *)&si4702_data,
+ },
+ {
+ .type = "mma7450",
+ .addr = 0x1d,
+ .platform_data = (void *)&mma7450_data,
+ },
+};
+
+static struct spi_board_info mxc_spi_board_info[] __initdata = {
+ {
+ .modalias = "pmic_spi",
+ .irq = IOMUX_TO_IRQ(MX31_PIN_GPIO1_3),
+ .max_speed_hz = 4000000,
+ .bus_num = 2,
+ .platform_data = (void *)IOMUX_TO_IRQ(MX31_PIN_GPIO1_2),
+ .chip_select = 2,},
+ {
+ .modalias = "lcd_spi",
+ .platform_data = (void *)&lcd_data,
+ .max_speed_hz = 5000000,
+ .bus_num = 1,
+ .chip_select = 2,},
+};
+
+/*lan9217 device*/
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+static struct resource smsc911x_resources[] = {
+ {
+ .start = LAN9217_BASE_ADDR,
+ .end = LAN9217_BASE_ADDR + 0x100,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = LAN9217_IRQ,
+ .end = LAN9217_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+static struct platform_device smsc_lan9217_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+};
+static void mxc_init_enet(void)
+{
+ (void)platform_device_register(&smsc_lan9217_device);
+}
+#else
+static inline void mxc_init_enet(void)
+{
+}
+#endif
+
+#if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE)
+static const char fb_default_mode[] = "Epson-VGA";
+
+/* mxc lcd driver */
+static struct platform_device mxc_fb_device = {
+ .name = "mxc_sdc_fb",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &fb_default_mode,
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+};
+
+static struct platform_device mxc_fb_wvga_device = {
+ .name = "lcd_claa",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &lcd_data,
+ },
+};
+
+static void mxc_init_fb(void)
+{
+ (void)platform_device_register(&mxc_fb_device);
+ (void)platform_device_register(&mxc_fb_wvga_device);
+}
+#else
+static inline void mxc_init_fb(void)
+{
+}
+#endif
+
+#if defined(CONFIG_BACKLIGHT_MXC)
+static struct platform_device mxcbl_devices[] = {
+#if defined(CONFIG_BACKLIGHT_MXC_IPU) || defined(CONFIG_BACKLIGHT_MXC_IPU_MODULE)
+ {
+ .name = "mxc_ipu_bl",
+ .id = 0,
+ .dev = {
+ .platform_data = (void *)3, /* DISP # for this backlight */
+ },
+ },
+#endif
+};
+static inline void mxc_init_bl(void)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(mxcbl_devices); i++) {
+ platform_device_register(&mxcbl_devices[i]);
+ }
+}
+#else
+static inline void mxc_init_bl(void)
+{
+}
+#endif
+
+#if defined(CONFIG_FB_MXC_TVOUT_CH7024) || \
+ defined(CONFIG_FB_MXC_TVOUT_CH7024_MODULE)
+static int mxc_init_ch7024(void)
+{
+ /* request gpio for phone jack detect */
+ mxc_request_iomux(MX31_PIN_BATT_LINE, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_iomux_set_pad(MX31_PIN_BATT_LINE, PAD_CTL_PKE_NONE);
+ mxc_set_gpio_direction(MX31_PIN_BATT_LINE, 1);
+
+ return 0;
+}
+#else
+static inline int mxc_init_ch7024(void)
+{
+ return 0;
+}
+#endif
+
+static u32 brd_io;
+
+static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 imr_val;
+ u32 int_valid;
+ u32 expio_irq;
+
+ desc->chip->mask(irq); /* irq = gpio irq number */
+
+ imr_val = __raw_readw(brd_io + INTR_MASK_REG);
+ int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val;
+
+ if (unlikely(!int_valid)) {
+ goto out;
+ }
+
+ expio_irq = MXC_EXP_IO_BASE;
+ for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
+ struct irq_desc *d;
+ if ((int_valid & 1) == 0)
+ continue;
+ d = irq_desc + expio_irq;
+ if (unlikely(!(d->handle_irq))) {
+ printk(KERN_ERR "\nEXPIO irq: %d unhandled\n",
+ expio_irq);
+ BUG(); /* oops */
+ }
+ d->handle_irq(expio_irq, d);
+ }
+
+ out:
+ desc->chip->ack(irq);
+ desc->chip->unmask(irq);
+}
+
+/*
+ * Disable an expio pin's interrupt by setting the bit in the imr.
+ * @param irq an expio virtual irq number
+ */
+static void expio_mask_irq(u32 irq)
+{
+ u16 reg;
+ u32 expio = MXC_IRQ_TO_EXPIO(irq);
+ /* mask the interrupt */
+ reg = __raw_readw(brd_io + INTR_MASK_REG);
+ reg |= (1 << expio);
+ __raw_writew(reg, brd_io + INTR_MASK_REG);
+}
+
+/*
+ * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
+ * @param irq an expanded io virtual irq number
+ */
+static void expio_ack_irq(u32 irq)
+{
+ u32 expio = MXC_IRQ_TO_EXPIO(irq);
+ /* clear the interrupt status */
+ __raw_writew(1 << expio, brd_io + INTR_RESET_REG);
+ __raw_writew(0, brd_io + INTR_RESET_REG);
+ /* mask the interrupt */
+ expio_mask_irq(irq);
+}
+
+/*
+ * Enable a expio pin's interrupt by clearing the bit in the imr.
+ * @param irq a expio virtual irq number
+ */
+static void expio_unmask_irq(u32 irq)
+{
+ u16 reg;
+ u32 expio = MXC_IRQ_TO_EXPIO(irq);
+ /* unmask the interrupt */
+ reg = __raw_readw(brd_io + INTR_MASK_REG);
+ reg &= ~(1 << expio);
+ __raw_writew(reg, brd_io + INTR_MASK_REG);
+}
+
+static struct irq_chip expio_irq_chip = {
+ .ack = expio_ack_irq,
+ .mask = expio_mask_irq,
+ .unmask = expio_unmask_irq,
+};
+
+static int __init mxc_expio_init(void)
+{
+ int i;
+
+ brd_io = (u32) ioremap(BOARD_IO_ADDR, SZ_4K);
+ if (brd_io == 0)
+ return -ENOMEM;
+
+ if ((__raw_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) ||
+ (__raw_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) ||
+ (__raw_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) {
+ iounmap((void *)brd_io);
+ brd_io = 0;
+ return -ENODEV;
+ }
+
+ pr_info("3-Stack Debug board detected, rev = 0x%04X\n",
+ readw(brd_io + CPLD_CODE_VER_REG));
+
+ /*
+ * Configure INT line as GPIO input
+ */
+ mxc_request_iomux(MX31_PIN_GPIO1_1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_set_gpio_direction(MX31_PIN_GPIO1_1, 1);
+
+ /* disable the interrupt and clear the status */
+ __raw_writew(0, brd_io + INTR_MASK_REG);
+ __raw_writew(0xFFFF, brd_io + INTR_RESET_REG);
+ __raw_writew(0, brd_io + INTR_RESET_REG);
+ __raw_writew(0x1F, brd_io + INTR_MASK_REG);
+ for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
+ i++) {
+ set_irq_chip(i, &expio_irq_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+ set_irq_type(EXPIO_PARENT_INT, IRQF_TRIGGER_LOW);
+ set_irq_chained_handler(EXPIO_PARENT_INT, mxc_expio_irq_handler);
+
+ return 0;
+}
+
+static int __init mxc_init_regulator(void)
+{
+ int err;
+ struct regulator *gpo1;
+ struct regulator *gpo2;
+ struct regulator *gpo3;
+ struct regulator *gpo4;
+
+ gpo1 = regulator_get(NULL, "GPO1");
+ gpo2 = regulator_get(NULL, "GPO2");
+ gpo3 = regulator_get(NULL, "GPO3");
+ gpo4 = regulator_get(NULL, "GPO4");
+
+ err = regulator_set_platform_source(gpo2, gpo1);
+ if (err)
+ printk(KERN_ERR "Unable to set GPO1 be the parent of GPO2\n");
+
+ err = regulator_set_platform_source(gpo3, gpo1);
+ if (err)
+ printk(KERN_ERR "Unable to set GPO1 be the parent of GPO3\n");
+
+ err = regulator_set_platform_source(gpo4, gpo1);
+ if (err)
+ printk(KERN_ERR "Unable to set GPO1 be the parent of GPO4\n");
+
+ return 0;
+}
+
+module_init(mxc_init_regulator);
+
+#if (defined(CONFIG_MXC_PMIC_MC13783) || \
+ defined(CONFIG_MXC_PMIC_MC13783_MODULE)) \
+ && (defined(CONFIG_SND_MXC_PMIC) || defined(CONFIG_SND_MXC_PMIC_MODULE))
+static void __init mxc_init_pmic_audio(void)
+{
+ struct clk *ckih_clk;
+ struct clk *cko_clk;
+
+ /* Enable 26 mhz clock on CKO1 for PMIC audio */
+ ckih_clk = clk_get(NULL, "ckih");
+ cko_clk = clk_get(NULL, "cko1_clk");
+ if (IS_ERR(ckih_clk) || IS_ERR(cko_clk)) {
+ printk(KERN_ERR "Unable to set CKO1 output to CKIH\n");
+ } else {
+ clk_set_parent(cko_clk, ckih_clk);
+ clk_set_rate(cko_clk, clk_get_rate(ckih_clk));
+ clk_enable(cko_clk);
+ }
+ clk_put(ckih_clk);
+ clk_put(cko_clk);
+
+ /* config Audio ports (4 & 5) */
+ mxc_request_iomux(MX31_PIN_SCK4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SRXD4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_STXD4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SFS4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SCK5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SRXD5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_STXD5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SFS5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+}
+#else
+static void __inline mxc_init_pmic_audio(void)
+{
+}
+#endif
+
+/* MMC device data */
+
+#if defined(CONFIG_MMC_MXC) || defined(CONFIG_MMC_MXC_MODULE)
+static struct mxc_mmc_platform_data mmc0_data = {
+ .ocr_mask = MMC_VDD_32_33,
+ .min_clk = 150000,
+ .max_clk = 25000000,
+ .card_inserted_state = 0,
+ .status = sdhc_get_card_det_status,
+ .wp_status = sdhc_write_protect,
+ .power_mmc = "GPO1",
+};
+
+/*!
+ * Resource definition for the SDHC1
+ */
+static struct resource mxcsdhc1_resources[] = {
+ [0] = {
+ .start = MMC_SDHC1_BASE_ADDR,
+ .end = MMC_SDHC1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_MMC_SDHC1,
+ .end = MXC_INT_MMC_SDHC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mxc_mmc_platform_data mmc1_data = {
+ .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 |
+ MMC_VDD_31_32,
+ .min_clk = 150000,
+ .max_clk = 25000000,
+ .card_fixed = 1,
+ .card_inserted_state = 0,
+ .status = sdhc_get_card_det_status,
+ .power_mmc = "VMMC2",
+};
+
+/*!
+ * Resource definition for the SDHC1
+ */
+static struct resource mxcsdhc2_resources[] = {
+ [0] = {
+ .start = MMC_SDHC2_BASE_ADDR,
+ .end = MMC_SDHC2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_MMC_SDHC2,
+ .end = MXC_INT_MMC_SDHC2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Device Definition for MXC SDHC1 */
+static struct platform_device mxcsdhc1_device = {
+ .name = "mxcmci",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mmc0_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcsdhc1_resources),
+ .resource = mxcsdhc1_resources,
+};
+
+/*! Device Definition for MXC SDHC2 */
+static struct platform_device mxcsdhc2_device = {
+ .name = "mxcmci",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mmc1_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcsdhc2_resources),
+ .resource = mxcsdhc2_resources,
+};
+
+static inline void mxc_init_mmc(void)
+{
+ int cd_irq;
+
+ cd_irq = sdhc_init_card_det(0);
+ if (cd_irq) {
+ mxcsdhc1_device.resource[2].start = cd_irq;
+ mxcsdhc1_device.resource[2].end = cd_irq;
+ }
+
+ cd_irq = sdhc_init_card_det(1);
+ if (cd_irq) {
+ mxcsdhc2_device.resource[2].start = cd_irq;
+ mxcsdhc2_device.resource[2].end = cd_irq;
+ }
+
+ spba_take_ownership(SPBA_SDHC1, SPBA_MASTER_A | SPBA_MASTER_C);
+ (void)platform_device_register(&mxcsdhc1_device);
+
+ spba_take_ownership(SPBA_SDHC2, SPBA_MASTER_A | SPBA_MASTER_C);
+ (void)platform_device_register(&mxcsdhc2_device);
+}
+#else
+static inline void mxc_init_mmc(void)
+{
+}
+#endif
+
+/*!
+ * Board specific fixup function. It is called by \b setup_arch() in
+ * setup.c file very early on during kernel starts. It allows the user to
+ * statically fill in the proper values for the passed-in parameters. None of
+ * the parameters is used currently.
+ *
+ * @param desc pointer to \b struct \b machine_desc
+ * @param tags pointer to \b struct \b tag
+ * @param cmdline pointer to the command line
+ * @param mi pointer to \b struct \b meminfo
+ */
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ mxc_cpu_init();
+
+#ifdef CONFIG_DISCONTIGMEM
+ do {
+ int nid;
+ mi->nr_banks = MXC_NUMNODES;
+ for (nid = 0; nid < mi->nr_banks; nid++) {
+ SET_NODE(mi, nid);
+ }
+ } while (0);
+#endif
+}
+
+/* IDE device data */
+#if defined(CONFIG_BLK_DEV_IDE_MXC) || defined(CONFIG_BLK_DEV_IDE_MXC_MODULE)
+
+/*! Platform Data for MXC IDE */
+static struct mxc_ide_platform_data mxc_ide_data = {
+ .power_drive = "GPO2",
+ .power_io = "GPO3",
+};
+
+static struct platform_device mxc_ide_device = {
+ .name = "mxc_ide",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_ide_data,
+ },
+};
+
+static inline void mxc_init_ide(void)
+{
+ if (platform_device_register(&mxc_ide_device) < 0)
+ printk(KERN_ERR "Error: Registering the ide.\n");
+}
+#else
+static inline void mxc_init_ide(void)
+{
+}
+#endif
+
+#if defined(CONFIG_PATA_FSL) || defined(CONFIG_PATA_FSL_MODULE)
+extern void gpio_ata_active(void);
+extern void gpio_ata_inactive(void);
+
+static int ata_init(struct platform_device *pdev)
+{
+ /* Configure the pins */
+ gpio_ata_active();
+
+ return 0;
+}
+
+static void ata_exit(void)
+{
+ /* Free the pins */
+ gpio_ata_inactive();
+}
+
+static struct fsl_ata_platform_data ata_data = {
+ .udma_mask = ATA_UDMA3, /* board can handle up to UDMA3 */
+ .mwdma_mask = ATA_MWDMA2,
+ .pio_mask = ATA_PIO4,
+ .fifo_alarm = MXC_IDE_DMA_WATERMARK / 2,
+ .max_sg = MXC_IDE_DMA_BD_NR,
+ .init = ata_init,
+ .exit = ata_exit,
+ .core_reg = "GPO2", /*"LDO2", */
+ .io_reg = "GPO3", /*"LDO3", */
+};
+
+static struct resource pata_fsl_resources[] = {
+ [0] = { /* I/O */
+ .start = ATA_BASE_ADDR + 0x00,
+ .end = ATA_BASE_ADDR + 0xD8,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = { /* IRQ */
+ .start = MXC_INT_ATA,
+ .end = MXC_INT_ATA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pata_fsl_device = {
+ .name = "pata_fsl",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pata_fsl_resources),
+ .resource = pata_fsl_resources,
+ .dev = {
+ .platform_data = &ata_data,
+ .coherent_dma_mask = ~0,
+ },
+};
+
+static void __init mxc_init_pata(void)
+{
+ (void)platform_device_register(&pata_fsl_device);
+}
+#else /* CONFIG_PATA_FSL */
+static void __init mxc_init_pata(void)
+{
+}
+#endif /* CONFIG_PATA_FSL */
+
+static void bt_reset(void)
+{
+ mxc_set_gpio_dataout(MX31_PIN_DCD_DCE1, 1);
+}
+
+static struct mxc_bt_platform_data mxc_bt_data = {
+ .bt_vdd = "VMMC2",
+ .bt_vdd_parent = "GPO1",
+ .bt_vusb = NULL,
+ .bt_vusb_parent = "GPO3",
+ .bt_reset = bt_reset,
+};
+
+static struct platform_device mxc_bt_device = {
+ .name = "mxc_bt",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_bt_data,
+ },
+};
+
+static void mxc_init_bluetooth(void)
+{
+ (void)platform_device_register(&mxc_bt_device);
+}
+
+static void mxc_unifi_hardreset(void)
+{
+ mxc_set_gpio_dataout(MX31_PIN_DCD_DCE1, 0);
+ msleep(100);
+ mxc_set_gpio_dataout(MX31_PIN_DCD_DCE1, 1);
+}
+
+static struct mxc_unifi_platform_data unifi_data = {
+ .hardreset = mxc_unifi_hardreset,
+
+ /* GPO3 -> enables SW2B 1.8V out - this becomes 1V8 on personality
+ * board, then 1V8_EXT, then BT_VUSB
+ */
+ .reg_gpo1 = "GPO3",
+
+ /* GPO4 -> WiFi_PWEN, but this signal is not used on current boards */
+ .reg_gpo2 = "GPO4",
+
+ .reg_1v5_ana_bb = "VRF1", /* VRF1 -> WL_1V5ANA and WL_1V5BB */
+ .reg_vdd_vpa = "VMMC2", /* VMMC2 -> WL_VDD and WL_VPA */
+ .reg_1v5_dd = "VRF2", /* VRF2 -> WL_1V5DD */
+
+ .host_id = 1,
+};
+
+struct mxc_unifi_platform_data *get_unifi_plat_data(void)
+{
+ return &unifi_data;
+}
+
+EXPORT_SYMBOL(get_unifi_plat_data);
+
+#if defined(CONFIG_GPS_IOCTRL) || defined(CONFIG_GPS_IOCTRL_MODULE)
+static struct mxc_gps_platform_data gps_data = {
+ .core_reg = "GPO3",
+ .analog_reg = "GPO1",
+};
+
+static struct platform_device mxc_gps_device = {
+ .name = "gps_ioctrl",
+ .id = -1,
+ .dev = {
+ .platform_data = &gps_data,
+ },
+};
+
+static void __init mxc_init_gps(void)
+{
+ (void)platform_device_register(&mxc_gps_device);
+}
+#else
+static void __init mxc_init_gps(void)
+{
+}
+#endif
+
+static void __init mx3_3stack_timer_init(void)
+{
+ mxc_clocks_init(32768, 0, 26000000, 0);
+ mxc_timer_init("gpt_clk");
+}
+
+static struct sys_timer mxc_timer = {
+ .init = mx3_3stack_timer_init,
+};
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ /* config CS5 for debug board */
+ mxc_request_iomux(MX31_PIN_CS5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+
+ mxc_cpu_common_init();
+ mxc_gpio_init();
+ early_console_setup(saved_command_line);
+ mxc_init_devices();
+
+ /*Pull down MX31_PIN_USB_BYP to reset USB3317 */
+ mxc_request_iomux(MX31_PIN_USB_BYP, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_set_gpio_direction(MX31_PIN_USB_BYP, 0);
+ mxc_set_gpio_dataout(MX31_PIN_USB_BYP, 0);
+ mxc_free_iomux(MX31_PIN_USB_BYP, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+
+ /* Reset BT/WiFi chip */
+ mxc_request_iomux(MX31_PIN_DCD_DCE1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_set_gpio_direction(MX31_PIN_DCD_DCE1, 0);
+ mxc_set_gpio_dataout(MX31_PIN_DCD_DCE1, 0);
+
+ mxc_init_pmic_audio();
+ mxc_expio_init();
+ mxc_init_keypad();
+ mxc_init_enet();
+ mxc_init_nand_mtd();
+ mxc_init_ch7024();
+
+ i2c_register_board_info(0, mxc_i2c_board_info,
+ ARRAY_SIZE(mxc_i2c_board_info));
+ spi_register_board_info(mxc_spi_board_info,
+ ARRAY_SIZE(mxc_spi_board_info));
+
+ mxc_init_fb();
+ mxc_init_bl();
+ mxc_init_mmc();
+ mxc_init_ide();
+ mxc_init_pata();
+ mxc_init_bluetooth();
+ mxc_init_gps();
+}
+
+#define PLL_PCTL_REG(pd, mfd, mfi, mfn) \
+ ((((pd) - 1) << 26) + (((mfd) - 1) << 16) + ((mfi) << 10) + mfn)
+
+/* For 26MHz input clock */
+#define PLL_532MHZ PLL_PCTL_REG(1, 13, 10, 3)
+#define PLL_399MHZ PLL_PCTL_REG(1, 52, 7, 35)
+#define PLL_133MHZ PLL_PCTL_REG(2, 26, 5, 3)
+
+#define PDR0_REG(mcu, max, hsp, ipg, nfc) \
+ (MXC_CCM_PDR0_MCU_DIV_##mcu | MXC_CCM_PDR0_MAX_DIV_##max | \
+ MXC_CCM_PDR0_HSP_DIV_##hsp | MXC_CCM_PDR0_IPG_DIV_##ipg | \
+ MXC_CCM_PDR0_NFC_DIV_##nfc)
+
+/* working point(wp): 0 - 133MHz; 1 - 266MHz; 2 - 399MHz; 3 - 532MHz */
+/* 26MHz input clock table */
+static struct cpu_wp cpu_wp_26[] = {
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 133000000,
+ .pdr0_reg = PDR0_REG(4, 4, 4, 2, 6),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 266000000,
+ .pdr0_reg = PDR0_REG(2, 4, 4, 2, 6),},
+ {
+ .pll_reg = PLL_399MHZ,
+ .pll_rate = 399000000,
+ .cpu_rate = 399000000,
+ .pdr0_reg = PDR0_REG(1, 3, 3, 2, 6),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 532000000,
+ .pdr0_reg = PDR0_REG(1, 4, 4, 2, 6),},
+};
+
+struct cpu_wp *get_cpu_wp(int *wp)
+{
+ *wp = 4;
+ return cpu_wp_26;
+}
+
+/*
+ * The following uses standard kernel macros define in arch.h in order to
+ * initialize __mach_desc_MX3_3STACK data structure.
+ */
+/* *INDENT-OFF* */
+MACHINE_START(MX31_3DS, "Freescale MX31/MX32 3-Stack Board")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .phys_io = AIPS1_BASE_ADDR,
+ .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = PHYS_OFFSET + 0x100,
+ .fixup = fixup_mxc_board,
+ .map_io = mxc_map_io,
+ .init_irq = mxc_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &mxc_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx3/mx3_3stack_gpio.c b/arch/arm/mach-mx3/mx3_3stack_gpio.c
new file mode 100644
index 000000000000..44f55c148716
--- /dev/null
+++ b/arch/arm/mach-mx3/mx3_3stack_gpio.c
@@ -0,0 +1,1298 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/irq.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <mach/pmic_adc.h>
+#include "board-mx3_3stack.h"
+#include "iomux.h"
+
+/*!
+ * @file mach-mx3/mx3_3stack_gpio.c
+ *
+ * @brief This file contains all the GPIO setup functions for the board.
+ *
+ * @ingroup GPIO_MX31
+ */
+
+/*!
+ * Setup GPIO for a UART port to be active
+ *
+ * @param port a UART port
+ * @param no_irda indicates if the port is used for SIR
+ */
+void gpio_uart_active(int port, int no_irda)
+{
+ /*
+ * Configure the IOMUX control registers for the UART signals
+ */
+ switch (port) {
+ /* UART 1 IOMUX Configs */
+ case 0:
+ mxc_request_iomux(MX31_PIN_RXD1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_TXD1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_RTS1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CTS1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ break;
+ /* UART 2 IOMUX Configs */
+ case 1:
+ mxc_request_iomux(MX31_PIN_TXD2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_RXD2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+
+ mxc_request_iomux(MX31_PIN_RTS2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CTS2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ break;
+ /* UART 3 IOMUX Configs */
+ case 2:
+ mxc_request_iomux(MX31_PIN_CSPI3_MOSI, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_CSPI3_MISO, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_CSPI3_SCLK, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_CSPI3_SPI_RDY, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * TODO: Configure the Pad registers for the UART pins
+ */
+}
+
+/*!
+ * Setup GPIO for a UART port to be inactive
+ *
+ * @param port a UART port
+ * @param no_irda indicates if the port is used for SIR
+ */
+void gpio_uart_inactive(int port, int no_irda)
+{
+ switch (port) {
+ case 0:
+ mxc_request_gpio(MX31_PIN_RXD1);
+ mxc_request_gpio(MX31_PIN_TXD1);
+ mxc_request_gpio(MX31_PIN_RTS1);
+ mxc_request_gpio(MX31_PIN_CTS1);
+
+ mxc_free_iomux(MX31_PIN_RXD1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_TXD1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_RTS1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_CTS1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ break;
+ case 1:
+ mxc_request_gpio(MX31_PIN_TXD2);
+ mxc_request_gpio(MX31_PIN_RXD2);
+
+ mxc_free_iomux(MX31_PIN_TXD2, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_RXD2, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_RTS2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CTS2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * Configure the IOMUX GPR register to receive shared SDMA UART events
+ *
+ * @param port a UART port
+ */
+void config_uartdma_event(int port)
+{
+ switch (port) {
+ case 1:
+ /* Configure to receive UART 2 SDMA events */
+ mxc_iomux_set_gpr(MUX_PGP_FIRI, false);
+ break;
+ case 2:
+ /* Configure to receive UART 3 SDMA events */
+ mxc_iomux_set_gpr(MUX_CSPI1_UART3, true);
+ break;
+ case 4:
+ /* Configure to receive UART 5 SDMA events */
+ mxc_iomux_set_gpr(MUX_CSPI3_UART5_SEL, true);
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_uart_active);
+EXPORT_SYMBOL(gpio_uart_inactive);
+EXPORT_SYMBOL(config_uartdma_event);
+
+/*!
+ * Setup GPIO for Keypad to be active
+ *
+ */
+void gpio_keypad_active(void)
+{
+ /*
+ * Configure the IOMUX control register for keypad signals.
+ */
+ mxc_request_iomux(MX31_PIN_KEY_COL0, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_COL1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_COL2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_COL3, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_ROW0, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_ROW1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_KEY_ROW2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+}
+
+EXPORT_SYMBOL(gpio_keypad_active);
+
+/*!
+ * Setup GPIO for Keypad to be inactive
+ *
+ */
+void gpio_keypad_inactive(void)
+{
+ mxc_request_gpio(MX31_PIN_KEY_COL0);
+ mxc_request_gpio(MX31_PIN_KEY_COL1);
+ mxc_request_gpio(MX31_PIN_KEY_COL2);
+ mxc_request_gpio(MX31_PIN_KEY_COL3);
+ mxc_request_gpio(MX31_PIN_KEY_ROW0);
+ mxc_request_gpio(MX31_PIN_KEY_ROW1);
+ mxc_request_gpio(MX31_PIN_KEY_ROW2);
+
+ mxc_free_iomux(MX31_PIN_KEY_COL0, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_KEY_COL1, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_KEY_COL2, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_KEY_COL3, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_KEY_ROW0, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_KEY_ROW1, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_KEY_ROW2, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO);
+}
+
+EXPORT_SYMBOL(gpio_keypad_inactive);
+
+void gpio_power_key_active(void)
+{
+ mxc_request_iomux(MX31_PIN_GPIO1_2, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_set_gpio_direction(MX31_PIN_GPIO1_2, 1);
+ mxc_iomux_set_pad(MX31_PIN_GPIO1_2, PAD_CTL_PKE_NONE);
+}
+
+EXPORT_SYMBOL(gpio_power_key_active);
+
+/*!
+ * Setup GPIO for a CSPI device to be active
+ *
+ * @param cspi_mod an CSPI device
+ */
+void gpio_spi_active(int cspi_mod)
+{
+ switch (cspi_mod) {
+ case 0:
+ /* SPI1 */
+ /* setup GPR for CSPI BB */
+ iomux_config_gpr(MUX_PGP_CSPI_BB, true);
+ /* CSPI1 clock and RDY use full UART ALT1 mode */
+ mxc_request_iomux(MX31_PIN_DSR_DCE1, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_RI_DCE1, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ break;
+ case 1:
+ /* SPI2 */
+ mxc_request_iomux(MX31_PIN_CSPI2_MISO, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_MOSI, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SPI_RDY, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SS0, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ break;
+ case 2:
+ /* SPI3 */
+ /*
+ mxc_request_iomux(MX31_PIN_CSPI2_MISO, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_MOSI, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SPI_RDY, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SS0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SS1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ */
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * Setup 1-Wire to be active
+ */
+void gpio_owire_active(void)
+{
+ /*
+ * Configure the IOMUX control register for 1-wire signals.
+ */
+ iomux_config_mux(MX31_PIN_BATT_LINE, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ iomux_config_pad(MX31_PIN_BATT_LINE, PAD_CTL_LOOPBACK);
+}
+
+/*!
+ * Setup 1-Wire to be active
+ */
+void gpio_owire_inactive(void)
+{
+ /*
+ * Configure the IOMUX control register for 1-wire signals.
+ */
+ iomux_config_mux(MX31_PIN_BATT_LINE, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+}
+
+EXPORT_SYMBOL(gpio_owire_active);
+EXPORT_SYMBOL(gpio_owire_inactive);
+
+/*!
+ * Setup GPIO for a CSPI device to be inactive
+ *
+ * @param cspi_mod a CSPI device
+ */
+void gpio_spi_inactive(int cspi_mod)
+{
+ switch (cspi_mod) {
+ case 0:
+ /* SPI1 */
+ /* setup GPR for CSPI BB */
+ iomux_config_gpr(MUX_PGP_CSPI_BB, false);
+ /* CSPI1 clock and RDY use full UART ALT1 mode */
+ mxc_free_iomux(MX31_PIN_DSR_DCE1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_RI_DCE1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ break;
+ case 1:
+ /* SPI2 */
+ mxc_free_iomux(MX31_PIN_CSPI2_MISO, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSPI2_MOSI, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSPI2_SPI_RDY, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSPI2_SS0, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ break;
+ case 2:
+ /* SPI3 */
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * Setup GPIO for an I2C device to be active
+ *
+ * @param i2c_num an I2C device
+ */
+void gpio_i2c_active(int i2c_num)
+{
+ switch (i2c_num) {
+ case 0:
+ mxc_request_iomux(MX31_PIN_I2C_CLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_I2C_DAT, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ break;
+ case 1:
+ mxc_request_iomux(MX31_PIN_CSPI2_MOSI, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_CSPI2_MISO, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ break;
+ case 2:
+ mxc_request_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ break;
+ default:
+ break;
+ }
+
+}
+
+/*!
+ * Setup GPIO for an I2C device to be inactive
+ *
+ * @param i2c_num an I2C device
+ */
+void gpio_i2c_inactive(int i2c_num)
+{
+ switch (i2c_num) {
+ case 0:
+ mxc_free_iomux(MX31_PIN_I2C_CLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_I2C_DAT, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ break;
+ case 1:
+ mxc_free_iomux(MX31_PIN_CSPI2_MOSI, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_ALT1);
+ mxc_free_iomux(MX31_PIN_CSPI2_MISO, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_ALT1);
+ break;
+ case 2:
+ mxc_request_iomux(MX31_PIN_CSPI2_SS2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_CSPI2_SCLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_ALT1);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * This function configures the IOMux block for PMIC standard operations.
+ *
+ */
+void gpio_pmic_active(void)
+{
+ mxc_request_iomux(MX31_PIN_GPIO1_3, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_set_gpio_direction(MX31_PIN_GPIO1_3, 1);
+}
+
+EXPORT_SYMBOL(gpio_pmic_active);
+
+/*!
+ * Setup GPIO for SDHC to be active
+ *
+ * @param module SDHC module number
+ */
+void gpio_sdhc_active(int module)
+{
+ switch (module) {
+ case 0:
+ mxc_request_iomux(MX31_PIN_SD1_CLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SD1_CMD, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SD1_DATA0, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SD1_DATA1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SD1_DATA2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_SD1_DATA3, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+
+ mxc_iomux_set_pad(MX31_PIN_SD1_CLK,
+ (PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST
+ | PAD_CTL_100K_PU));
+ mxc_iomux_set_pad(MX31_PIN_SD1_CMD,
+ (PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST
+ | PAD_CTL_100K_PU));
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA0,
+ (PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST
+ | PAD_CTL_100K_PU));
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA1,
+ (PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST
+ | PAD_CTL_100K_PU));
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA2,
+ (PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST
+ | PAD_CTL_100K_PU));
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA3,
+ (PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST
+ | PAD_CTL_100K_PU));
+
+ /*
+ * Active the Buffer Enable Pin only if there is
+ * a card in slot.
+ * To fix the card voltage issue caused by
+ * bi-directional chip TXB0108 on 3Stack
+ */
+ if (mxc_get_gpio_datain(MX31_PIN_GPIO3_1))
+ mxc_set_gpio_dataout(MX31_PIN_GPIO3_0, 0);
+ else
+ mxc_set_gpio_dataout(MX31_PIN_GPIO3_0, 1);
+ break;
+ case 1:
+ mxc_request_iomux(MX31_PIN_PC_CD2_B, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_PC_CD1_B, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_PC_WAIT_B, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_PC_READY, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_PC_VS1, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ mxc_request_iomux(MX31_PIN_PC_PWRON, OUTPUTCONFIG_ALT1,
+ INPUTCONFIG_ALT1);
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_sdhc_active);
+
+/*!
+ * Setup GPIO for SDHC1 to be inactive
+ *
+ * @param module SDHC module number
+ */
+void gpio_sdhc_inactive(int module)
+{
+ switch (module) {
+ case 0:
+ mxc_free_iomux(MX31_PIN_SD1_CLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_SD1_CMD, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_SD1_DATA0, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_SD1_DATA1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_SD1_DATA2, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_SD1_DATA3, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+
+ mxc_iomux_set_pad(MX31_PIN_SD1_CLK,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX31_PIN_SD1_CMD,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA0,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA1,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA2,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX31_PIN_SD1_DATA3,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+
+ /* Buffer Enable Pin of SD, Active HI */
+ mxc_set_gpio_dataout(MX31_PIN_GPIO3_0, 0);
+ break;
+ case 1:
+ /* TODO:what are the pins for SDHC2? */
+ mxc_free_iomux(MX31_PIN_PC_CD2_B, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_PC_CD1_B, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_PC_WAIT_B, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_PC_READY, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_PC_VS1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_PC_PWRON, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_NONE);
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_sdhc_inactive);
+
+/*
+ * Probe for the card. If present the GPIO data would be set.
+ */
+unsigned int sdhc_get_card_det_status(struct device *dev)
+{
+ int ret;
+
+ if (to_platform_device(dev)->id == 0) {
+ ret = mxc_get_gpio_datain(MX31_PIN_GPIO3_1);
+ /*
+ * Active the Buffer Enable Pin only if there is
+ * a card in slot.
+ * To fix the card voltage issue caused by
+ * bi-directional chip TXB0108 on 3Stack
+ */
+ if (ret)
+ mxc_set_gpio_dataout(MX31_PIN_GPIO3_0, 0);
+ else
+ mxc_set_gpio_dataout(MX31_PIN_GPIO3_0, 1);
+ return ret;
+ } else
+ return mxc_get_gpio_datain(MX31_PIN_GPIO1_2);
+}
+
+EXPORT_SYMBOL(sdhc_get_card_det_status);
+
+/*
+ * Return the card detect pin.
+ */
+int sdhc_init_card_det(int id)
+{
+ if (id == 0) {
+ /* Buffer Enable Pin, Active HI */
+ mxc_request_iomux(MX31_PIN_GPIO3_0, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_set_gpio_direction(MX31_PIN_GPIO3_0, 0);
+ mxc_set_gpio_dataout(MX31_PIN_GPIO3_0, 0);
+
+ /* CD Pin */
+ mxc_request_iomux(MX31_PIN_GPIO3_1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_iomux_set_pad(MX31_PIN_GPIO3_1, PAD_CTL_PKE_NONE);
+ mxc_set_gpio_direction(MX31_PIN_GPIO3_1, 1);
+ return IOMUX_TO_IRQ(MX31_PIN_GPIO3_1);
+ } else {
+ iomux_config_mux(MX31_PIN_GPIO1_2, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ return IOMUX_TO_IRQ(MX31_PIN_GPIO1_2);
+
+ }
+}
+
+EXPORT_SYMBOL(sdhc_init_card_det);
+
+/*!
+ * Get SD1_WP ADIN7 of ATLAS pin value to detect write protection
+ */
+int sdhc_write_protect(struct device *dev)
+{
+ unsigned short rc = 0;
+
+ pmic_adc_convert(GEN_PURPOSE_AD7, &rc);
+ if (rc > 0)
+ return 1;
+ else
+ return 0;
+}
+
+EXPORT_SYMBOL(sdhc_write_protect);
+
+/*!
+ * Setup GPIO for LCD to be active
+ *
+ */
+void gpio_lcd_active(void)
+{
+
+ mxc_request_iomux(MX31_PIN_LD0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD8, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD9, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD10, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD11, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD12, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD13, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD14, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD15, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_LD16, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // LD16
+ mxc_request_iomux(MX31_PIN_LD17, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // LD17
+ mxc_request_iomux(MX31_PIN_VSYNC3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // VSYNC
+ mxc_request_iomux(MX31_PIN_HSYNC, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // HSYNC
+ mxc_request_iomux(MX31_PIN_FPSHIFT, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // CLK
+ mxc_request_iomux(MX31_PIN_CONTRAST, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // CONTR
+
+#ifdef CONFIG_FB_MXC_CLAA_WVGA_SYNC_PANEL
+ mxc_request_iomux(MX31_PIN_DRDY0,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); /* DRDY */
+ mxc_request_iomux(MX31_PIN_D3_REV,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); /* REV */
+ mxc_request_iomux(MX31_PIN_D3_SPL,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); /* SPL */
+ mxc_request_iomux(MX31_PIN_D3_CLS,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); /* CLS */
+#else
+ /* ensure that LCDIO(1.8V) has been turn on */
+ /* active reset line GPIO */
+ mxc_request_iomux(MX31_PIN_LCS1, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_set_gpio_direction(MX31_PIN_LCS1, 0);
+ /* do reset */
+ mdelay(10); /* tRES >= 100us */
+ mxc_set_gpio_dataout(MX31_PIN_LCS1, 1);
+
+ /* enable data */
+ mxc_request_iomux(MX31_PIN_SER_RS, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_set_gpio_direction(MX31_PIN_SER_RS, 0);
+ mxc_set_gpio_dataout(MX31_PIN_SER_RS, 1);
+#endif
+}
+
+/*!
+ * Setup GPIO for LCD to be inactive
+ *
+ */
+void gpio_lcd_inactive(void)
+{
+ mxc_set_gpio_dataout(MX31_PIN_SER_RS, 0);
+}
+
+/*!
+ * Switch to the specified sensor - MX31 ADS has two
+ *
+ */
+void gpio_sensor_select(int sensor)
+{
+}
+
+/*!
+ * Setup GPIO for sensor to be active
+ *
+ */
+void gpio_sensor_active(void)
+{
+ gpio_sensor_select(0);
+
+ /*
+ * Configure the iomuxen for the CSI.
+ */
+
+ mxc_request_iomux(MX31_PIN_CSI_D5, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_set_gpio_direction(MX31_PIN_CSI_D5, 0);
+ mxc_set_gpio_dataout(MX31_PIN_CSI_D5, 0);
+
+ mxc_request_iomux(MX31_PIN_CSI_D6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D8, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D9, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D10, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D11, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D12, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D13, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D14, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_D15, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_HSYNC, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_MCLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_PIXCLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_CSI_VSYNC, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+
+ if (mxc_request_iomux(MX31_PIN_A23, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE)
+ == 0) {
+ printk(KERN_ERR "%s:REGEN set request gpio ok\n", __func__);
+ } else {
+ printk(KERN_ERR "%s:REGEN set error, request gpio error\n",
+ __func__);
+ return;
+ }
+ mxc_set_gpio_direction(MX31_PIN_SD_D_IO, 0);
+ mxc_set_gpio_dataout(MX31_PIN_SD_D_IO, 1);
+}
+
+EXPORT_SYMBOL(gpio_sensor_active);
+
+void gpio_sensor_reset(bool flag)
+{
+}
+
+EXPORT_SYMBOL(gpio_sensor_reset);
+
+/*!
+ * Setup GPIO for sensor to be inactive
+ *
+ */
+void gpio_sensor_inactive(void)
+{
+ mxc_free_iomux(MX31_PIN_CSI_D5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D8, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D9, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D10, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D11, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D12, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D13, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D14, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_D15, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_HSYNC, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_MCLK, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_PIXCLK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_free_iomux(MX31_PIN_CSI_VSYNC, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+}
+
+EXPORT_SYMBOL(gpio_sensor_inactive);
+
+/*!
+ * Setup GPIO for ATA interface
+ *
+ */
+void gpio_ata_active(void)
+{
+ /*
+ * Configure the GPR for ATA group B signals
+ */
+ mxc_iomux_set_gpr(MUX_PGP_ATA_8 | MUX_PGP_ATA_5 | MUX_PGP_ATA_4 |
+ MUX_PGP_ATA_3 | MUX_PGP_ATA_2, false);
+
+ mxc_iomux_set_gpr(MUX_PGP_ATA_9 | MUX_PGP_ATA_7 | MUX_PGP_ATA_6 |
+ MUX_PGP_ATA_1, true);
+
+ /*
+ * Configure the IOMUX for ATA group B signals
+ */
+
+ mxc_request_iomux(MX31_PIN_CSPI1_MOSI, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D0
+ mxc_request_iomux(MX31_PIN_CSPI1_MISO, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D1
+ mxc_request_iomux(MX31_PIN_CSPI1_SS0, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D2
+ mxc_request_iomux(MX31_PIN_CSPI1_SS1, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D3
+ mxc_request_iomux(MX31_PIN_CSPI1_SS2, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D4
+ mxc_request_iomux(MX31_PIN_CSPI1_SCLK, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D5
+ mxc_request_iomux(MX31_PIN_CSPI1_SPI_RDY, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D6
+ mxc_request_iomux(MX31_PIN_STXD3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D7
+ mxc_request_iomux(MX31_PIN_SRXD3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D8
+ mxc_request_iomux(MX31_PIN_SCK3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D9
+ mxc_request_iomux(MX31_PIN_SFS3, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D10
+ mxc_request_iomux(MX31_PIN_STXD6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D11
+ mxc_request_iomux(MX31_PIN_SRXD6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D12
+ mxc_request_iomux(MX31_PIN_SCK6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D13
+ mxc_request_iomux(MX31_PIN_CAPTURE, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D14
+ mxc_request_iomux(MX31_PIN_COMPARE, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_D15
+
+ /* Config the multiplex pin of ATA interface DIR, DA0-2, INTRQ, DMARQ */
+ mxc_request_iomux(MX31_PIN_KEY_COL4, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_DMARQ_B
+ mxc_request_iomux(MX31_PIN_KEY_ROW6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_INTRQ_B
+ mxc_request_iomux(MX31_PIN_KEY_COL5, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_DA0
+ mxc_request_iomux(MX31_PIN_KEY_COL6, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_DA1
+ mxc_request_iomux(MX31_PIN_KEY_COL7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_DA2
+ mxc_request_iomux(MX31_PIN_KEY_ROW7, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC); // ATA_BUFFER_DIR
+
+ /* HDD_ENABLE_B(H:Disable,L:Enable) */
+ mxc_request_iomux(MX31_PIN_CSI_D4, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO); // HDD_ENABLE_B
+ mxc_set_gpio_direction(MX31_PIN_CSI_D4, 0);
+ mdelay(10);
+ mxc_set_gpio_dataout(MX31_PIN_CSI_D4, 0);
+ mdelay(10);
+
+ /* These ATA pins are common to Group A and Group B */
+
+ mxc_request_iomux(MX31_PIN_ATA_CS0, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_ATA_CS1, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_ATA_DIOR, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_ATA_DIOW, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_ATA_DMACK, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_ATA_RESET_B, OUTPUTCONFIG_FUNC,
+ INPUTCONFIG_FUNC);
+ mxc_request_iomux(MX31_PIN_PWMO, OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC);
+
+ /* Need fast slew rate for UDMA mode */
+
+#define ATA_DAT_PAD_CFG (PAD_CTL_SRE_FAST | PAD_CTL_PKE_NONE | PAD_CTL_100K_PU)
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, ATA_DAT_PAD_CFG); // data 0
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, ATA_DAT_PAD_CFG); // data 1
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, ATA_DAT_PAD_CFG); // data 2
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, ATA_DAT_PAD_CFG); // data 3
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, ATA_DAT_PAD_CFG); // data 4
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, ATA_DAT_PAD_CFG); // data 5
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, ATA_DAT_PAD_CFG); // data 6
+ mxc_iomux_set_pad(MX31_PIN_STXD3, ATA_DAT_PAD_CFG); // data 7
+ mxc_iomux_set_pad(MX31_PIN_SRXD3, ATA_DAT_PAD_CFG); // data 8
+ mxc_iomux_set_pad(MX31_PIN_SCK3, ATA_DAT_PAD_CFG); // data 9
+ mxc_iomux_set_pad(MX31_PIN_SFS3, ATA_DAT_PAD_CFG); // data 10
+ mxc_iomux_set_pad(MX31_PIN_STXD6, ATA_DAT_PAD_CFG); // data 11
+ mxc_iomux_set_pad(MX31_PIN_SRXD6, ATA_DAT_PAD_CFG); // data 12
+ mxc_iomux_set_pad(MX31_PIN_SCK6, ATA_DAT_PAD_CFG); // data 13
+ mxc_iomux_set_pad(MX31_PIN_CAPTURE, ATA_DAT_PAD_CFG); // data 14
+ mxc_iomux_set_pad(MX31_PIN_COMPARE, ATA_DAT_PAD_CFG); // data 15
+#undef ATA_DAT_PAD_CFG
+
+#define ATA_CTL_PAD_CFG (PAD_CTL_SRE_SLOW | PAD_CTL_PKE_NONE)
+ mxc_iomux_set_pad(MX31_PIN_KEY_COL4, ATA_CTL_PAD_CFG); // ATA_DMARQ);
+ mxc_iomux_set_pad(MX31_PIN_KEY_ROW6, ATA_CTL_PAD_CFG); // ATA_INTRQ);
+ mxc_iomux_set_pad(MX31_PIN_KEY_COL5, ATA_CTL_PAD_CFG); //
+ mxc_iomux_set_pad(MX31_PIN_KEY_COL6, ATA_CTL_PAD_CFG); //
+ mxc_iomux_set_pad(MX31_PIN_KEY_COL7, ATA_CTL_PAD_CFG); //
+ mxc_iomux_set_pad(MX31_PIN_KEY_ROW7, ATA_CTL_PAD_CFG); //
+
+ mxc_iomux_set_pad(MX31_PIN_ATA_CS0, ATA_CTL_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_ATA_CS1, ATA_CTL_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_ATA_DIOR, ATA_CTL_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_ATA_DIOW, ATA_CTL_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_ATA_DMACK, ATA_CTL_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_ATA_RESET_B, ATA_CTL_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_PWMO, ATA_CTL_PAD_CFG);
+#undef ATA_CTL_PAD_CFG
+}
+
+EXPORT_SYMBOL(gpio_ata_active);
+
+/*!
+ * Restore ATA interface pins to reset values
+ *
+ */
+void gpio_ata_inactive(void)
+{
+ /*
+ * Turn off ATA group B signals
+ */
+ mxc_request_iomux(MX31_PIN_CSPI1_MOSI, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D0
+ mxc_request_iomux(MX31_PIN_CSPI1_MISO, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D1
+ mxc_request_iomux(MX31_PIN_CSPI1_SS0, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D2
+ mxc_request_iomux(MX31_PIN_CSPI1_SS1, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D3
+ mxc_request_iomux(MX31_PIN_CSPI1_SS2, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D4
+ mxc_request_iomux(MX31_PIN_CSPI1_SCLK, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D5
+ mxc_request_iomux(MX31_PIN_CSPI1_SPI_RDY, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D6
+ mxc_request_iomux(MX31_PIN_STXD3, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D7
+ mxc_request_iomux(MX31_PIN_SRXD3, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D8
+ mxc_request_iomux(MX31_PIN_SCK3, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D9
+ mxc_request_iomux(MX31_PIN_SFS3, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D10
+ mxc_request_iomux(MX31_PIN_STXD6, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D11
+ mxc_request_iomux(MX31_PIN_SRXD6, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D12
+ mxc_request_iomux(MX31_PIN_SCK6, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D13
+ mxc_request_iomux(MX31_PIN_CAPTURE, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D14
+ mxc_request_iomux(MX31_PIN_COMPARE, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_D15
+
+ /* Config the multiplex pin of ATA interface DIR, DA0-2, INTRQ, DMARQ */
+ mxc_request_iomux(MX31_PIN_KEY_COL4, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_DMARQ_B
+ mxc_request_iomux(MX31_PIN_KEY_ROW6, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_INTRQ_B
+ mxc_request_iomux(MX31_PIN_KEY_COL5, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_DA0
+ mxc_request_iomux(MX31_PIN_KEY_COL6, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_DA1
+ mxc_request_iomux(MX31_PIN_KEY_COL7, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_DA2
+ mxc_request_iomux(MX31_PIN_KEY_ROW7, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE); // ATA_BUFFER_DIR
+
+ /* HDD_BUFF_EN (H:A->B, L:B->A) and HDD_ENABLE_B(H:Disable,L:Enable) */
+ mxc_free_iomux(MX31_PIN_CSI_D4, OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO);
+
+ /* These ATA pins are common to Group A and Group B */
+
+ mxc_request_iomux(MX31_PIN_ATA_CS0, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_ATA_CS1, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_ATA_DIOR, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_ATA_DIOW, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_ATA_DMACK, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_ATA_RESET_B, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_request_iomux(MX31_PIN_PWMO, OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+
+ /* Needed fast slew rate for UDMA mode */
+
+#define ATA_DAT_PAD_CFG (PAD_CTL_SRE_SLOW | PAD_CTL_DRV_NORMAL | PAD_CTL_PKE_NONE)
+ mxc_iomux_set_pad(MX31_PIN_KEY_COL4, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_KEY_ROW6, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_KEY_COL5, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_KEY_COL6, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_KEY_COL7, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_KEY_ROW7, ATA_DAT_PAD_CFG);
+
+ mxc_iomux_set_pad(MX31_PIN_ATA_CS0, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_ATA_CS1, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_ATA_DIOR, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_ATA_DIOW, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_ATA_DMACK, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_ATA_RESET_B, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_PWMO, ATA_DAT_PAD_CFG);
+
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_MISO, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_MOSI, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS0, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS1, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SS2, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SCLK, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CSPI1_SPI_RDY, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_STXD3, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SRXD3, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SCK3, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SFS3, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_STXD6, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SRXD6, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_SCK6, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_CAPTURE, ATA_DAT_PAD_CFG);
+ mxc_iomux_set_pad(MX31_PIN_COMPARE, ATA_DAT_PAD_CFG);
+#undef ATA_DAT_PAD_CFG
+}
+
+EXPORT_SYMBOL(gpio_ata_inactive);
+
+/* *INDENT-OFF* */
+/*
+ * USB Host 1
+ * pins conflict with SPI1, ATA, UART3
+ */
+int gpio_usbh1_active(void)
+{
+ return 0;
+}
+
+EXPORT_SYMBOL(gpio_usbh1_active);
+
+void gpio_usbh1_inactive(void)
+{
+ /* Do nothing as pins don't have/support GPIO mode */
+
+}
+
+EXPORT_SYMBOL(gpio_usbh1_inactive);
+
+/*
+ * USB Host 2
+ * pins conflict with UART5, PCMCIA
+ */
+int gpio_usbh2_active(void)
+{
+ if (mxc_request_iomux(MX31_PIN_USBH2_CLK,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBH2_DIR,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBH2_NXT,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBH2_STP,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBH2_DATA0,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBH2_DATA1,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_PC_VS2, /* USBH2_DATA2 */
+ OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) ||
+ mxc_request_iomux(MX31_PIN_PC_BVD1, /* USBH2_DATA3 */
+ OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) ||
+ mxc_request_iomux(MX31_PIN_PC_BVD2, /* USBH2_DATA4 */
+ OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) ||
+ mxc_request_iomux(MX31_PIN_PC_RST, /* USBH2_DATA5 */
+ OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) ||
+ mxc_request_iomux(MX31_PIN_IOIS16, /* USBH2_DATA6 */
+ OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1) ||
+ mxc_request_iomux(MX31_PIN_PC_RW_B, /* USBH2_DATA7 */
+ OUTPUTCONFIG_ALT1, INPUTCONFIG_ALT1)) {
+ return -EINVAL;
+ }
+ mxc_iomux_set_pad(MX31_PIN_USBH2_CLK,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST |
+ PAD_CTL_PKE_NONE));
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DIR,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBH2_NXT,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBH2_STP,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_PC_VS2,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_PC_BVD1,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_PC_BVD2,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_PC_RST,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_IOIS16,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_PC_RW_B,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+
+ mxc_request_iomux(MX31_PIN_USB_BYP, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_NONE);
+ mxc_set_gpio_direction(MX31_PIN_USB_BYP, 0);
+ mxc_set_gpio_dataout(MX31_PIN_USB_BYP, 0);
+ mdelay(1);
+ mxc_set_gpio_dataout(MX31_PIN_USB_BYP, 1);
+ return 0;
+}
+
+EXPORT_SYMBOL(gpio_usbh2_active);
+
+void gpio_usbh2_inactive(void)
+{
+ mxc_iomux_set_pad(MX31_PIN_USBH2_CLK,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DIR,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBH2_NXT,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBH2_STP,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA0,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBH2_DATA1,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_PC_VS2,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_PC_BVD1,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_PC_BVD2,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_PC_RST,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_IOIS16,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_PC_RW_B,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_FAST));
+
+ mxc_free_iomux(MX31_PIN_USBH2_CLK,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_USBH2_DIR,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_USBH2_NXT,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_USBH2_STP,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_USBH2_DATA0,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_USBH2_DATA1,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+
+ mxc_free_iomux(MX31_PIN_PC_VS2, /* USBH2_DATA2 */
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_PC_BVD1, /* USBH2_DATA3 */
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_PC_BVD2, /* USBH2_DATA4 */
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_PC_RST, /* USBH2_DATA5 */
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_IOIS16, /* USBH2_DATA6 */
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+ mxc_free_iomux(MX31_PIN_PC_RW_B, /* USBH2_DATA7 */
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+
+ mxc_free_iomux(MX31_PIN_USB_BYP, /* USBH2 PHY reset */
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_NONE);
+}
+
+EXPORT_SYMBOL(gpio_usbh2_inactive);
+
+/*
+ * USB OTG HS port
+ */
+int gpio_usbotg_hs_active(void)
+{
+ if (mxc_request_iomux(MX31_PIN_USBOTG_DATA0,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA1,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA2,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA3,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA4,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA5,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA6,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA7,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_CLK,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DIR,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_NXT,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_STP,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC)) {
+ return -EINVAL;
+ }
+
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA0,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA1,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA2,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA3,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA4,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA5,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA6,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DATA7,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_CLK,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_DIR,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_NXT,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+ mxc_iomux_set_pad(MX31_PIN_USBOTG_STP,
+ (PAD_CTL_DRV_MAX | PAD_CTL_SRE_FAST));
+
+ /* reset transceiver */
+ mxc_request_iomux(MX31_PIN_USB_PWR, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+ mxc_set_gpio_direction(MX31_PIN_USB_PWR, 0);
+ mxc_set_gpio_dataout(MX31_PIN_USB_PWR, 0);
+ mdelay(1);
+ mxc_set_gpio_dataout(MX31_PIN_USB_PWR, 1);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(gpio_usbotg_hs_active);
+
+void gpio_usbotg_hs_inactive(void)
+{
+ mxc_free_iomux(MX31_PIN_USB_PWR, OUTPUTCONFIG_GPIO,
+ INPUTCONFIG_GPIO);
+}
+
+EXPORT_SYMBOL(gpio_usbotg_hs_inactive);
+
+/*!
+ * USB OTG FS port
+ */
+int gpio_usbotg_fs_active(void)
+{
+ if (mxc_request_iomux(MX31_PIN_USBOTG_DATA0,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA1,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA2,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA3,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA4,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA5,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA6,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DATA7,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_CLK,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_DIR,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_NXT,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USBOTG_STP,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC) ||
+ mxc_request_iomux(MX31_PIN_USB_PWR,
+ OUTPUTCONFIG_FUNC, INPUTCONFIG_FUNC))
+ return -EINVAL;
+ return 0;
+}
+
+EXPORT_SYMBOL(gpio_usbotg_fs_active);
+
+void gpio_usbotg_fs_inactive(void)
+{
+ /* Do nothing as pins doesn't have/support GPIO mode */
+
+}
+
+EXPORT_SYMBOL(gpio_usbotg_fs_inactive);
+
+/*!
+ * GPS GPIO
+ */
+void gpio_gps_active(void)
+{
+ /* POWER_EN */
+ mxc_request_iomux(MX31_PIN_SCLK0,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO);
+ mxc_set_gpio_direction(MX31_PIN_SCLK0, 0);
+ /* Reset Pin */
+ mxc_request_iomux(MX31_PIN_DCD_DTE1,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO);
+ mxc_set_gpio_direction(MX31_PIN_DCD_DTE1, 0);
+
+ mxc_set_gpio_dataout(MX31_PIN_SCLK0, 0);
+ mxc_set_gpio_dataout(MX31_PIN_DCD_DTE1, 0);
+
+ msleep(5);
+ mxc_set_gpio_dataout(MX31_PIN_DCD_DTE1, 1);
+ msleep(5);
+}
+
+EXPORT_SYMBOL(gpio_gps_active);
+
+int gpio_gps_access(int para)
+{
+ iomux_pin_name_t pin;
+ pin = (para & 0x1) ? MX31_PIN_SCLK0 : MX31_PIN_DCD_DTE1;
+
+ if (para & 0x4) /* Read GPIO */
+ return mxc_get_gpio_datain(pin);
+ else if (para & 0x2) /* Write GPIO */
+ mxc_set_gpio_dataout(pin, 1);
+ else
+ mxc_set_gpio_dataout(pin, 0);
+ return 0;
+}
+
+EXPORT_SYMBOL(gpio_gps_access);
+
+void gpio_gps_inactive(void)
+{
+ mxc_free_iomux(MX31_PIN_DCD_DTE1,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO);
+ mxc_free_iomux(MX31_PIN_SCLK0,
+ OUTPUTCONFIG_GPIO, INPUTCONFIG_GPIO);
+}
+
+EXPORT_SYMBOL(gpio_gps_inactive);
diff --git a/arch/arm/mach-mx3/mxc_pm.c b/arch/arm/mach-mx3/mxc_pm.c
new file mode 100644
index 000000000000..fc0aa6820dd7
--- /dev/null
+++ b/arch/arm/mach-mx3/mxc_pm.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup DPM_MX31 Power Management
+ * @ingroup MSL_MX31
+ */
+/*!
+ * @file mach-mx3/mxc_pm.c
+ *
+ * @brief This file provides all the kernel level and user level API
+ * definitions for the CRM_MCU and DPLL in mx3.
+ *
+ * @ingroup DPM_MX31
+ */
+
+/*
+ * Include Files
+ */
+#include <linux/module.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+#include <mach/hardware.h>
+#include <mach/system.h>
+#include <mach/mxc_pm.h>
+#include <asm/cacheflush.h>
+#include <asm/irq.h>
+#include <mach/common.h>
+#include <asm/hardware/cache-l2x0.h>
+
+#include "crm_regs.h"
+
+/* Local defines */
+#define FREQ_COMP_TOLERANCE 200 /* tolerance percentage times 100 */
+#define MCU_PLL_MAX_FREQ 600000000 /* Maximum frequency MCU PLL clock */
+#define MCU_PLL_MIN_FREQ 160000000 /* Minimum frequency MCU PLL clock */
+#define NFC_MAX_FREQ 20000000 /* Maximum frequency NFC clock */
+#define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */
+
+static struct clk *mcu_pll_clk;
+static struct clk *cpu_clk;
+static struct clk *ahb_clk;
+static struct clk *ipg_clk;
+
+/*!
+ * Spinlock to protect CRM register accesses
+ */
+static DEFINE_SPINLOCK(mxc_crm_lock);
+
+/*!
+ * This function is called to modify the contents of a CCM_MCU register
+ *
+ * @param reg_offset the CCM_MCU register that will read
+ * @param mask the mask to be used to clear the bits that are to be modified
+ * @param data the data that should be written to the register
+ */
+void mxc_ccm_modify_reg(void *reg_offset, unsigned int mask,
+ unsigned int data)
+{
+ unsigned long flags;
+ unsigned long reg;
+
+ spin_lock_irqsave(&mxc_crm_lock, flags);
+ reg = __raw_readl(reg_offset);
+ reg = (reg & (~mask)) | data;
+ __raw_writel(reg, reg_offset);
+ spin_unlock_irqrestore(&mxc_crm_lock, flags);
+}
+
+/*!
+ * Compare two frequences using allowable tolerance
+ *
+ * The MX3 PLL can generate many frequencies. This function
+ * compares the generated frequency to the requested frequency
+ * and determines it they are within and acceptable tolerance.
+ *
+ * @param freq1 desired frequency
+ * @param freq2 generated frequency
+ *
+ * @return Returns 0 is frequencies are within talerance
+ * and non-zero is they are not.
+ */
+static int freq_equal(unsigned long freq1, unsigned long freq2)
+{
+ if (freq1 > freq2) {
+ return (freq1 - freq2) <= (freq1 / FREQ_COMP_TOLERANCE);
+ }
+ return (freq2 - freq1) <= (freq1 / FREQ_COMP_TOLERANCE);
+}
+
+/*!
+ * Calculate new MCU clock dividers for the PDR0 regiser.
+ *
+ * @param mcu_main_clk PLL output frequency (Hz)
+ * @param arm_freq desired ARM frequency (Hz)
+ * @param max_freq desired MAX frequency (Hz)
+ * @param ip_freq desired IP frequency (Hz)
+ * @param mask were to return PDR0 mask
+ * @param value were to return PDR0 value
+ *
+ * @return Returns 0 on success or
+ * Returns non zero if error
+ * PLL_LESS_ARM_ERR if pll frequency is less than
+ * desired core frequency
+ * FREQ_OUT_OF_RANGE if desided frequencies ar not
+ * possible with the current mcu pll frequency.
+ */
+static int
+cal_pdr0_value(unsigned long mcu_main_clk,
+ long arm_freq,
+ long max_freq,
+ long ip_freq, unsigned long *mask, unsigned long *value)
+{
+ unsigned long arm_div; /* ARM core clock divider */
+ unsigned long max_div; /* MAX clock divider */
+ unsigned long ipg_div; /* IPG clock divider */
+ unsigned long nfc_div; /* NFC (Nand Flash Controller) clock divider */
+ unsigned long hsp_div; /* HSP clock divider */
+
+ if (arm_freq > mcu_main_clk) {
+ return -PLL_LESS_ARM_ERR;
+ }
+
+ arm_div = mcu_main_clk / arm_freq;
+ if ((arm_div == 0) || !freq_equal(arm_freq, mcu_main_clk / arm_div)) {
+ return FREQ_OUT_OF_RANGE;
+ }
+ max_div = mcu_main_clk / max_freq;
+ if ((max_div == 0) || !freq_equal(max_freq, mcu_main_clk / max_div)) {
+ return FREQ_OUT_OF_RANGE;
+ }
+ hsp_div = max_div;
+
+ ipg_div = max_freq / ip_freq;
+ if ((ipg_div == 0) || !freq_equal(ip_freq, max_freq / ipg_div)) {
+ return FREQ_OUT_OF_RANGE;
+ }
+
+ nfc_div = ((max_freq - 1000000) / NFC_MAX_FREQ) + 1;
+
+ /* All of the divider values have been calculated.
+ * Now change the hardware register. */
+
+ *mask = MXC_CCM_PDR0_HSP_PODF_MASK |
+ MXC_CCM_PDR0_NFC_PODF_MASK |
+ MXC_CCM_PDR0_IPG_PODF_MASK |
+ MXC_CCM_PDR0_MAX_PODF_MASK | MXC_CCM_PDR0_MCU_PODF_MASK;
+
+ *value = ((hsp_div - 1) << MXC_CCM_PDR0_HSP_PODF_OFFSET) |
+ ((nfc_div - 1) << MXC_CCM_PDR0_NFC_PODF_OFFSET) |
+ ((ipg_div - 1) << MXC_CCM_PDR0_IPG_PODF_OFFSET) |
+ ((max_div - 1) << MXC_CCM_PDR0_MAX_PODF_OFFSET) |
+ ((arm_div - 1) << MXC_CCM_PDR0_MCU_PODF_OFFSET);
+
+ return 0;
+}
+
+/*!
+ * Integer clock scaling
+ *
+ * Change main arm clock frequencies without changing the PLL.
+ * The integer dividers are changed to produce the desired
+ * frequencies. The number of valid frequency are limited and
+ * are determined by the current MCU PLL frequency
+ *
+ * @param arm_freq desired ARM frequency (Hz)
+ * @param max_freq desired MAX frequency (Hz)
+ * @param ip_freq desired IP frequency (Hz)
+ *
+ * @return Returns 0 on success or
+ * Returns non zero if error
+ * PLL_LESS_ARM_ERR if pll frequency is less than
+ * desired core frequency
+ * FREQ_OUT_OF_RANGE if desided frequencies ar not
+ * possible with the current mcu pll frequency.
+ */
+int mxc_pm_intscale(long arm_freq, long max_freq, long ip_freq)
+{
+ unsigned long mcu_main_clk; /* mcu clock domain main clock */
+ unsigned long mask;
+ unsigned long value;
+ int ret_value;
+
+ printk(KERN_INFO "arm_freq=%ld, max_freq=%ld, ip_freq=%ld\n",
+ arm_freq, max_freq, ip_freq);
+ //print_frequencies(); /* debug */
+
+ mcu_main_clk = clk_get_rate(mcu_pll_clk);
+ ret_value = cal_pdr0_value(mcu_main_clk, arm_freq, max_freq, ip_freq,
+ &mask, &value);
+ if ((arm_freq != clk_round_rate(cpu_clk, arm_freq)) ||
+ (max_freq != clk_round_rate(ahb_clk, max_freq)) ||
+ (ip_freq != clk_round_rate(ipg_clk, ip_freq))) {
+ return -EINVAL;
+ }
+
+ if ((max_freq != clk_get_rate(ahb_clk)) ||
+ (ip_freq != clk_get_rate(ipg_clk))) {
+ return -EINVAL;
+ }
+
+ if (arm_freq != clk_get_rate(cpu_clk)) {
+ ret_value = clk_set_rate(cpu_clk, arm_freq);
+ }
+ return ret_value;
+}
+
+/*!
+ * PLL clock scaling
+ *
+ * Change MCU PLL frequency and adjust derived clocks. Integer
+ * dividers are used generate the derived clocks so changed to produce
+ * the desired the valid frequencies are limited by the desired ARM
+ * frequency.
+ *
+ * The clock source for the MCU is set to the MCU PLL.
+ *
+ * @param arm_freq desired ARM frequency (Hz)
+ * @param max_freq desired MAX frequency (Hz)
+ * @param ip_freq desired IP frequency (Hz)
+ *
+ * @return Returns 0 on success or
+ * Returns non zero if error
+ * PLL_LESS_ARM_ERR if pll frequency is less than
+ * desired core frequency
+ * FREQ_OUT_OF_RANGE if desided frequencies ar not
+ * possible with the current mcu pll frequency.
+ */
+int mxc_pm_pllscale(long arm_freq, long max_freq, long ip_freq)
+{
+ signed long pll_freq = 0; /* target pll frequency */
+ unsigned long old_pll;
+ unsigned long mask;
+ unsigned long value;
+ int ret_value;
+
+ printk(KERN_INFO "arm_freq=%ld, max_freq=%ld, ip_freq=%ld\n",
+ arm_freq, max_freq, ip_freq);
+ //print_frequencies();
+
+ do {
+ pll_freq += arm_freq;
+ if ((pll_freq > MCU_PLL_MAX_FREQ) || (pll_freq / 8 > arm_freq)) {
+ return FREQ_OUT_OF_RANGE;
+ }
+ if (pll_freq < MCU_PLL_MIN_FREQ) {
+ ret_value = 111;
+ } else {
+ ret_value =
+ cal_pdr0_value(pll_freq, arm_freq, max_freq,
+ ip_freq, &mask, &value);
+ }
+ } while (ret_value != 0);
+
+ old_pll = clk_get_rate(mcu_pll_clk);
+ if (pll_freq > old_pll) {
+ /* if pll freq is increasing then change dividers first */
+ mxc_ccm_modify_reg(MXC_CCM_PDR0, mask, value);
+ ret_value = clk_set_rate(mcu_pll_clk, pll_freq);
+ } else {
+ /* if pll freq is decreasing then change pll first */
+ ret_value = clk_set_rate(mcu_pll_clk, pll_freq);
+ mxc_ccm_modify_reg(MXC_CCM_PDR0, mask, value);
+ }
+ //print_frequencies();
+ return ret_value;
+}
+
+/*!
+ * Implementing steps required to transition to low-power modes
+ *
+ * @param mode The desired low-power mode. Possible values are,
+ * WAIT_MODE, DOZE_MODE, STOP_MODE or DSM_MODE
+ *
+ */
+void mxc_pm_lowpower(int mode)
+{
+ unsigned int lpm;
+ int enable_flag;
+ unsigned long reg;
+
+ local_irq_disable();
+ enable_flag = 0;
+
+ switch (mode) {
+ case STOP_MODE:
+ /* State Retention mode */
+ lpm = 2;
+ /* Disable timer interrupt */
+ disable_irq(MXC_INT_GPT);
+ enable_flag = 1;
+
+ /* Enable Well Bias and set VSTBY
+ * VSTBY pin will be asserted during SR mode. This asks the
+ * PM IC to set the core voltage to the standby voltage
+ * Must clear the MXC_CCM_CCMR_SBYCS bit as well */
+ mxc_ccm_modify_reg(MXC_CCM_CCMR,
+ MXC_CCM_CCMR_WBEN | MXC_CCM_CCMR_VSTBY |
+ MXC_CCM_CCMR_SBYCS,
+ MXC_CCM_CCMR_WBEN | MXC_CCM_CCMR_VSTBY |
+ MXC_CCM_CCMR_SBYCS);
+
+ mxc_ccm_modify_reg(MXC_CCM_CCMR,
+ MXC_CCM_CCMR_LPM_MASK,
+ lpm << MXC_CCM_CCMR_LPM_OFFSET);
+ cpu_do_idle();
+ break;
+
+ case DSM_MODE:
+ /* Deep Sleep Mode */
+ lpm = 3;
+ /* Disable timer interrupt */
+ disable_irq(MXC_INT_GPT);
+ enable_flag = 1;
+ /* Enabled Well Bias
+ * SBYCS = 0, MCU clock source is disabled*/
+ mxc_ccm_modify_reg(MXC_CCM_CCMR,
+ MXC_CCM_CCMR_WBEN | MXC_CCM_CCMR_VSTBY |
+ MXC_CCM_CCMR_SBYCS | MXC_CCM_CCMR_LPM_MASK,
+ MXC_CCM_CCMR_WBEN | MXC_CCM_CCMR_VSTBY |
+ MXC_CCM_CCMR_SBYCS |
+ (lpm << MXC_CCM_CCMR_LPM_OFFSET));
+
+ reg = __raw_readl(MXC_CCM_WIMR);
+ reg &= ~(1 << 18);
+ __raw_writel(reg, MXC_CCM_WIMR);
+
+ flush_cache_all();
+ l2x0_disable();
+
+ mxc_pm_arch_entry(IO_ADDRESS(NFC_BASE_ADDR), 2048);
+ printk(KERN_INFO "Resume from DSM\n");
+
+ l2x0_enable();
+ mxc_init_irq();
+
+ break;
+ default:
+ case WAIT_MODE:
+ /* Wait is the default mode used when idle. */
+ reg = __raw_readl(MXC_CCM_CCMR);
+ reg &= ~MXC_CCM_CCMR_LPM_MASK;
+ __raw_writel(reg, MXC_CCM_CCMR);
+ break;
+ }
+
+ if (enable_flag) {
+ /* Enable timer interrupt */
+ enable_irq(MXC_INT_GPT);
+ }
+ local_irq_enable();
+}
+
+#ifdef CONFIG_MXC_DVFS
+/*!
+ * Changes MCU frequencies using dvfs.
+ *
+ * @param armfreq desired ARM frequency in Hz
+ * @param ahbfreq desired AHB frequency in Hz
+ * @param ipfreq desired IP frequency in Hz
+ *
+ * @return Returns 0 on success, non-zero on error
+ */
+int mxc_pm_dvfs(unsigned long armfreq, long ahbfreq, long ipfreq)
+{
+ int ret_value;
+ int i;
+
+ if (ahbfreq != 133000000) {
+ return FREQ_OUT_OF_RANGE;
+ }
+ if (ipfreq != 66500000) {
+ return FREQ_OUT_OF_RANGE;
+ }
+ ret_value = FREQ_OUT_OF_RANGE;
+ for (i = 0; i < dvfs_states_tbl->num_of_states; i++) {
+ if (dvfs_states_tbl->freqs[i] == armfreq) {
+ ret_value = dvfs_set_state(i);
+ break;
+ }
+ }
+
+ return ret_value;
+}
+#endif /* CONFIG_MXC_DVFS */
+
+/*!
+ * This function is used to load the module.
+ *
+ * @return Returns an Integer on success
+ */
+static int __init mxc_pm_init_module(void)
+{
+ printk(KERN_INFO "Low-Level PM Driver module loaded\n");
+
+ mcu_pll_clk = clk_get(NULL, "mcu_pll");
+ cpu_clk = clk_get(NULL, "cpu_clk");
+ ahb_clk = clk_get(NULL, "ahb_clk");
+ ipg_clk = clk_get(NULL, "ipg_clk");
+ return 0;
+}
+
+/*!
+ * This function is used to unload the module
+ */
+static void __exit mxc_pm_cleanup_module(void)
+{
+ clk_put(mcu_pll_clk);
+ clk_put(cpu_clk);
+ clk_put(ahb_clk);
+ clk_put(ipg_clk);
+ printk(KERN_INFO "Low-Level PM Driver module Unloaded\n");
+}
+
+module_init(mxc_pm_init_module);
+module_exit(mxc_pm_cleanup_module);
+
+EXPORT_SYMBOL(mxc_pm_intscale);
+EXPORT_SYMBOL(mxc_pm_pllscale);
+EXPORT_SYMBOL(mxc_pm_lowpower);
+#ifdef CONFIG_MXC_DVFS
+EXPORT_SYMBOL(mxc_pm_dvfs);
+#endif
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MX3 Low-level Power Management Driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-mx3/pm.c b/arch/arm/mach-mx3/pm.c
new file mode 100644
index 000000000000..532b70012cdd
--- /dev/null
+++ b/arch/arm/mach-mx3/pm.c
@@ -0,0 +1,113 @@
+/*
+ * linux/arch/arm/mach-mx3/pm.c
+ *
+ * MX3 Power Management Routines
+ *
+ * Original code for the SA11x0:
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * Modified for the PXA250 by Nicolas Pitre:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * Modified for the OMAP1510 by David Singleton:
+ * Copyright (c) 2002 Monta Vista Software, Inc.
+ *
+ * Cleanup 2004 for OMAP1510/1610 by Dirk Behme <dirk.behme@de.bosch.com>
+ *
+ * Modified for the MX31
+ * Copyright 2005-2009 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 SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * 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.,
+ * 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/suspend.h>
+#include <linux/regulator/regulator-platform.h>
+#include <mach/mxc_pm.h>
+
+/*
+ * TODO: whatta save?
+ */
+
+static int mx31_suspend_enter(suspend_state_t state)
+{
+ printk(KERN_INFO "Hi, from mx31_pm_enter\n");
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ mxc_pm_lowpower(DSM_MODE);
+ break;
+ case PM_SUSPEND_STANDBY:
+ mxc_pm_lowpower(STOP_MODE);
+ break;
+ default:
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int mx31_suspend_prepare(void)
+{
+ struct regulator *reg_core;
+ reg_core = regulator_get(NULL, "SW1A_STBY");
+ if (reg_core == NULL || IS_ERR(reg_core)) {
+ printk(KERN_ERR "Get regulator SW1A_STBY fail\n");
+ return -1;
+ }
+ regulator_set_voltage(reg_core, 1250000);
+ regulator_set_mode(reg_core, REGULATOR_MODE_STANDBY);
+ regulator_put(reg_core, NULL);
+
+ return 0;
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+static void mx31_suspend_finish(void)
+{
+ return;
+}
+
+static int mx31_pm_valid(suspend_state_t state)
+{
+ return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX);
+}
+
+struct platform_suspend_ops mx31_suspend_ops = {
+ .valid = mx31_pm_valid,
+ .prepare = mx31_suspend_prepare,
+ .enter = mx31_suspend_enter,
+ .finish = mx31_suspend_finish,
+};
+
+static int __init mx31_pm_init(void)
+{
+ printk(KERN_INFO "Power Management for Freescale MX31\n");
+ suspend_set_ops(&mx31_suspend_ops);
+
+ return 0;
+}
+
+late_initcall(mx31_pm_init);
diff --git a/arch/arm/mach-mx3/sdma_script_code.h b/arch/arm/mach-mx3/sdma_script_code.h
new file mode 100644
index 000000000000..627b896f91a1
--- /dev/null
+++ b/arch/arm/mach-mx3/sdma_script_code.h
@@ -0,0 +1,581 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __SDMA_SCRIPT_CODE_H__
+#define __SDMA_SCRIPT_CODE_H__
+
+/*!
+* Following define start address of start script
+*/
+#define start_ADDR 0
+/*!
+* Following define size of start script
+*/
+#define start_SIZE 21
+
+/*!
+* Following define start address of core script
+*/
+#define core_ADDR 80
+/*!
+* Following define size of core script
+*/
+#define core_SIZE 152
+
+/*!
+* Following define start address of common script
+*/
+#define common_ADDR 232
+/*!
+* Following define size of common script
+*/
+#define common_SIZE 191
+
+/*!
+* Following define start address of burst_copy script
+*/
+#define burst_copy_ADDR 423
+/*!
+* Following define size of burst_copy script
+*/
+#define burst_copy_SIZE 87
+
+/*!
+* Following define start address of dsp_2_burst script
+*/
+#define dsp_2_burst_ADDR 510
+/*!
+* Following define size of dsp_2_burst script
+*/
+#define dsp_2_burst_SIZE 24
+
+/*!
+* Following define start address of burst_2_dsp script
+*/
+#define burst_2_dsp_ADDR 534
+/*!
+* Following define size of burst_2_dsp script
+*/
+#define burst_2_dsp_SIZE 24
+
+/*!
+* Following define start address of dsp_copy script
+*/
+#define dsp_copy_ADDR 558
+/*!
+* Following define size of dsp_copy script
+*/
+#define dsp_copy_SIZE 86
+
+/*!
+* Following define start address of mcu_2_mcu script
+*/
+#define mcu_2_mcu_ADDR 644
+/*!
+* Following define size of mcu_2_mcu script
+*/
+#define mcu_2_mcu_SIZE 79
+
+/*!
+* Following define start address of mcu_2_per script
+*/
+#define mcu_2_per_ADDR 723
+/*!
+* Following define size of mcu_2_per script
+*/
+#define mcu_2_per_SIZE 88
+
+/*!
+* Following define start address of test script
+*/
+#define test_ADDR 811
+/*!
+* Following define size of test script
+*/
+#define test_SIZE 63
+
+/*!
+* Following define start address of mcu_2_dsp script
+*/
+#define mcu_2_dsp_ADDR 874
+/*!
+* Following define size of mcu_2_dsp script
+*/
+#define mcu_2_dsp_SIZE 30
+
+/*!
+* Following define start address of mcu_2_dsp_2buf script
+*/
+#define mcu_2_dsp_2buf_ADDR 904
+/*!
+* Following define size of mcu_2_dsp_2buf script
+*/
+#define mcu_2_dsp_2buf_SIZE 113
+
+/*!
+* Following define start address of dsp_2_mcu script
+*/
+#define dsp_2_mcu_ADDR 1017
+/*!
+* Following define size of dsp_2_mcu script
+*/
+#define dsp_2_mcu_SIZE 30
+
+/*!
+* Following define start address of dsp_2_mcu_2buf script
+*/
+#define dsp_2_mcu_2buf_ADDR 1047
+/*!
+* Following define size of dsp_2_mcu_2buf script
+*/
+#define dsp_2_mcu_2buf_SIZE 113
+
+/*!
+* Following define start address of dsp_2_dsp script
+*/
+#define dsp_2_dsp_ADDR 1160
+/*!
+* Following define size of dsp_2_dsp script
+*/
+#define dsp_2_dsp_SIZE 64
+
+/*!
+* Following define start address of per_2_mcu script
+*/
+#define per_2_mcu_ADDR 1224
+/*!
+* Following define size of per_2_mcu script
+*/
+#define per_2_mcu_SIZE 121
+
+/*!
+* Following define start address of dsp_2_per_2buf script
+*/
+#define dsp_2_per_2buf_ADDR 1345
+/*!
+* Following define size of dsp_2_per_2buf script
+*/
+#define dsp_2_per_2buf_SIZE 164
+
+/*!
+* Following define start address of per_2_dsp_2buf script
+*/
+#define per_2_dsp_2buf_ADDR 1509
+/*!
+* Following define size of per_2_dsp_2buf script
+*/
+#define per_2_dsp_2buf_SIZE 168
+
+/*!
+* Following define start address of per_2_per script
+*/
+#define per_2_per_ADDR 1677
+/*!
+* Following define size of per_2_per script
+*/
+#define per_2_per_SIZE 67
+
+/*!
+* Following define start address of error_dsp script
+*/
+#define error_dsp_ADDR 1744
+/*!
+* Following define size of error_dsp script
+*/
+#define error_dsp_SIZE 34
+
+/*!
+* Following define start address of ap_2_ap script
+*/
+#define ap_2_ap_ADDR 6144
+/*!
+* Following define size of ap_2_ap script
+*/
+#define ap_2_ap_SIZE 294
+
+/*!
+* Following define start address of app_2_mcu script
+*/
+#define app_2_mcu_ADDR 6438
+/*!
+* Following define size of app_2_mcu script
+*/
+#define app_2_mcu_SIZE 101
+
+/*!
+* Following define start address of ata_2_mcu script
+*/
+#define ata_2_mcu_ADDR 6539
+/*!
+* Following define size of ata_2_mcu script
+*/
+#define ata_2_mcu_SIZE 110
+
+/*!
+* Following define start address of dptc_dvfs script
+*/
+#define dptc_dvfs_ADDR 6649
+/*!
+* Following define size of dptc_dvfs script
+*/
+#define dptc_dvfs_SIZE 274
+
+/*!
+* Following define start address of error script
+*/
+#define error_ADDR 6923
+/*!
+* Following define size of error script
+*/
+#define error_SIZE 73
+
+/*!
+* Following define start address of firi_2_mcu script
+*/
+#define firi_2_mcu_ADDR 6996
+/*!
+* Following define size of firi_2_mcu script
+*/
+#define firi_2_mcu_SIZE 114
+
+/*!
+* Following define start address of mcu_2_app script
+*/
+#define mcu_2_app_ADDR 7110
+/*!
+* Following define size of mcu_2_app script
+*/
+#define mcu_2_app_SIZE 127
+
+/*!
+* Following define start address of mcu_2_ata script
+*/
+#define mcu_2_ata_ADDR 7237
+/*!
+* Following define size of mcu_2_ata script
+*/
+#define mcu_2_ata_SIZE 87
+
+/*!
+* Following define start address of mcu_2_firi script
+*/
+#define mcu_2_firi_ADDR 7324
+/*!
+* Following define size of mcu_2_firi script
+*/
+#define mcu_2_firi_SIZE 77
+
+/*!
+* Following define start address of mcu_2_mshc script
+*/
+#define mcu_2_mshc_ADDR 7401
+/*!
+* Following define size of mcu_2_mshc script
+*/
+#define mcu_2_mshc_SIZE 48
+
+/*!
+* Following define start address of mcu_2_shp script
+*/
+#define mcu_2_shp_ADDR 7449
+/*!
+* Following define size of mcu_2_shp script
+*/
+#define mcu_2_shp_SIZE 123
+
+/*!
+* Following define start address of mshc_2_mcu script
+*/
+#define mshc_2_mcu_ADDR 7572
+/*!
+* Following define size of mshc_2_mcu script
+*/
+#define mshc_2_mcu_SIZE 60
+
+/*!
+* Following define start address of shp_2_mcu script
+*/
+#define shp_2_mcu_ADDR 7632
+/*!
+* Following define size of shp_2_mcu script
+*/
+#define shp_2_mcu_SIZE 101
+
+/*!
+* Following define start address of uart_2_mcu script
+*/
+#define uart_2_mcu_ADDR 7733
+/*!
+* Following define size of uart_2_mcu script
+*/
+#define uart_2_mcu_SIZE 105
+
+/*!
+* Following define start address of uartsh_2_mcu script
+*/
+#define uartsh_2_mcu_ADDR 7838
+/*!
+* Following define size of uartsh_2_mcu script
+*/
+#define uartsh_2_mcu_SIZE 98
+
+/*!
+* Following define the start address of sdma ram
+*/
+
+#define RAM_CODE_START_ADDR 6144
+/*!
+* Following define the size of sdma ram
+*/
+#define RAM_CODE_SIZE 1792
+
+/*!
+* This function returns buffer that holds the image of SDMA RAM.
+* This is required to start on a 4-byte aligned boundary on some platforms
+* for SDMA to work properly.
+*
+* @return pointer to buffer that holds the image of SDMA RAM
+*/
+
+__attribute__ ((__aligned__(4)))
+#ifndef CONFIG_XIP_KERNEL
+const
+#endif
+static short sdma_code[] = {
+ 0xc0ec, 0x7d59, 0x0970, 0x0111, 0x5111, 0x5ad1, 0x5bd9, 0xc0fe,
+ 0x5ce1, 0x7d02, 0x0200, 0x9806, 0x08ff, 0x0011, 0x28ff, 0x00bc,
+ 0x05df, 0x7d4b, 0x06df, 0x7d2f, 0x6dc5, 0x6ed5, 0x5ef1, 0x0288,
+ 0xd81a, 0x9854, 0x0b04, 0x00d3, 0x7d20, 0x06a5, 0x3e03, 0x3d03,
+ 0x03a5, 0x3b03, 0x008b, 0x058b, 0x7802, 0x63d8, 0x0000, 0x7e72,
+ 0x63ff, 0x7e70, 0x02a5, 0x008a, 0x4e00, 0x7d01, 0x983d, 0x6dcf,
+ 0x6edf, 0x0015, 0x0015, 0x7802, 0x63d8, 0x0000, 0x7e63, 0x63ff,
+ 0x7e61, 0x3a03, 0x008a, 0x6dcd, 0x6edd, 0x7801, 0x63d8, 0x7e5a,
+ 0x63ff, 0x7e58, 0x0006, 0x6dc5, 0x6e07, 0x5ef1, 0x0288, 0xd8f7,
+ 0x7e02, 0x7f04, 0x9854, 0x0007, 0x68cc, 0x6b28, 0x54e1, 0x0089,
+ 0xdb13, 0x0188, 0x5ce1, 0x9854, 0x52d1, 0x53d9, 0x54e1, 0xc10d,
+ 0x7dad, 0x0200, 0x9800, 0x0200, 0x9800, 0x06df, 0x7d06, 0x6d23,
+ 0x6ed5, 0x5ef1, 0x0288, 0xd8cd, 0x9854, 0x5ef1, 0x6e07, 0x6d03,
+ 0x0b04, 0x00d3, 0x7d59, 0x06a5, 0x3e03, 0x3d03, 0x4d00, 0x7d09,
+ 0x03a5, 0x00a3, 0x0588, 0x008b, 0xd8c9, 0x7ed8, 0x620c, 0x7ed6,
+ 0x008d, 0x4e00, 0x7c25, 0x0a20, 0x00da, 0x7c22, 0x6503, 0x3d1f,
+ 0x02a5, 0x00a2, 0x0215, 0x0215, 0x6a18, 0x6a28, 0x7fc7, 0x0a20,
+ 0x0b08, 0x00da, 0x7c06, 0x6b18, 0x6b28, 0x7fc0, 0x0000, 0x2020,
+ 0x9889, 0x0688, 0x0015, 0x0015, 0x6818, 0x6828, 0x7fb7, 0x98c2,
+ 0x0007, 0x6a0c, 0x54e1, 0x0089, 0xdb0f, 0x0188, 0x5ce1, 0x9854,
+ 0x0b04, 0x00d3, 0x7d21, 0x0389, 0x1b12, 0x048b, 0x0688, 0x0015,
+ 0x0015, 0x0588, 0x038c, 0x0a08, 0x05da, 0x008d, 0x7c01, 0x008a,
+ 0x05a0, 0x7803, 0x620b, 0x5a03, 0x1b01, 0x7e98, 0x008b, 0x00a4,
+ 0x038c, 0x7803, 0x5203, 0x6a0b, 0x1b01, 0x6a28, 0x7f8f, 0x0000,
+ 0x4d00, 0x7ce8, 0x008e, 0x3803, 0xd8c9, 0x7e88, 0x620c, 0x7e86,
+ 0x9854, 0x7802, 0x6209, 0x6a29, 0x0006, 0x3e03, 0x4e00, 0x7d11,
+ 0x0b04, 0x03a6, 0x02db, 0x7d01, 0x038a, 0x02a3, 0x048a, 0x008b,
+ 0x7802, 0x6329, 0x6bc8, 0x7ebc, 0x63c8, 0x7ebc, 0x008c, 0x4800,
+ 0x7d15, 0x0488, 0x0015, 0x0015, 0x6edf, 0x7803, 0x632b, 0x6bc8,
+ 0x0000, 0x7eae, 0x63c8, 0x7eae, 0x008c, 0x3803, 0x6edd, 0x7803,
+ 0x6329, 0x6bc8, 0x0000, 0x7ea4, 0x63c8, 0x7ea4, 0x0006, 0x3d03,
+ 0x4d00, 0x7d0e, 0x0b04, 0x03a5, 0x02db, 0x7d01, 0x038a, 0x02a3,
+ 0x048a, 0x008b, 0x7802, 0x63c8, 0x6b09, 0x7e1e, 0x7f1e, 0x008c,
+ 0x0488, 0x0015, 0x0015, 0x6dcf, 0x0288, 0x008a, 0x0d08, 0x02dd,
+ 0x7c01, 0x008d, 0x7802, 0x63c8, 0x6b0b, 0x7e0e, 0x6b28, 0x7f0d,
+ 0x0000, 0x02dd, 0x7c02, 0x2208, 0x990d, 0x008c, 0x3803, 0x65c0,
+ 0x6dc5, 0x7802, 0x63c8, 0x6b09, 0x6b28, 0x0006, 0x0870, 0x0011,
+ 0x5010, 0xc0ec, 0x7d5e, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8,
+ 0x7d02, 0x0200, 0x992c, 0x6ec3, 0x6d07, 0x5df0, 0x0dff, 0x0511,
+ 0x1dff, 0x05bc, 0x4d00, 0x7d44, 0x0b70, 0x0311, 0x522b, 0x5313,
+ 0x02b9, 0x4a00, 0x7c04, 0x6a28, 0x7f3a, 0x0400, 0x993c, 0x008f,
+ 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x0a03, 0x0212, 0x02bc, 0x0210,
+ 0x4a00, 0x7d1c, 0x4a02, 0x7d20, 0x4a01, 0x7d23, 0x0b70, 0x0311,
+ 0x53eb, 0x62c8, 0x7e24, 0x0360, 0x7d02, 0x0210, 0x0212, 0x6a09,
+ 0x7f1e, 0x0212, 0x6a09, 0x7f1b, 0x0212, 0x6a09, 0x7f18, 0x2003,
+ 0x4800, 0x7cef, 0x0b70, 0x0311, 0x5313, 0x997d, 0x0015, 0x0015,
+ 0x7802, 0x62c8, 0x6a0b, 0x997c, 0x0015, 0x7802, 0x62c8, 0x6a0a,
+ 0x997c, 0x7802, 0x62c8, 0x6a09, 0x7c02, 0x0000, 0x993a, 0xdb13,
+ 0x6a28, 0x7ffd, 0x008b, 0x52c3, 0x53cb, 0xc10d, 0x7da5, 0x0200,
+ 0x992c, 0x0200, 0x9929, 0xc19d, 0xc0ec, 0x7d69, 0x0c70, 0x0411,
+ 0x5414, 0x5ac4, 0x028c, 0x58da, 0x5efa, 0xc0fe, 0x56fa, 0x7d02,
+ 0x0200, 0x9994, 0x6d07, 0x5bca, 0x5cd2, 0x0bff, 0x0311, 0x1bff,
+ 0x04bb, 0x0415, 0x53da, 0x4c00, 0x7d47, 0x0a70, 0x0211, 0x552a,
+ 0x5212, 0x008d, 0x00bb, 0x4800, 0x7c07, 0x05b9, 0x4d00, 0x7c13,
+ 0x6928, 0x7f2d, 0x0400, 0x99a5, 0x008f, 0x0015, 0x04d8, 0x7d01,
+ 0x008c, 0x04a0, 0x0015, 0x7802, 0x55c6, 0x6d0b, 0x7e29, 0x6d28,
+ 0x7f1e, 0x0000, 0x99a3, 0x1e20, 0x5506, 0x2620, 0x008d, 0x0560,
+ 0x7c08, 0x065f, 0x55c6, 0x063f, 0x7e1b, 0x6d0a, 0x7f10, 0x4c00,
+ 0x7d1b, 0x04d8, 0x7d02, 0x008c, 0x0020, 0x04a0, 0x0015, 0x7802,
+ 0x55c6, 0x6d0b, 0x7e0d, 0x6d28, 0x7f02, 0x0000, 0x99ec, 0x0007,
+ 0x680c, 0x6d0c, 0x6507, 0x6d07, 0x6d2b, 0x6d28, 0x0007, 0x680c,
+ 0x0007, 0x54d2, 0x0454, 0x99ef, 0x6928, 0x7ff1, 0x54d2, 0x008a,
+ 0x52c0, 0x53c8, 0xc10d, 0x0288, 0x7d9f, 0x0200, 0x9994, 0x0200,
+ 0x998c, 0xc0ec, 0x7d72, 0x0800, 0x0970, 0x0111, 0x5111, 0x5ac1,
+ 0x5bc9, 0x028e, 0xc0fe, 0x068a, 0x7c6a, 0x5dd9, 0x5ce1, 0x0bff,
+ 0x0311, 0x1bff, 0x03bc, 0x5bd1, 0x1a5c, 0x6ac3, 0x63c8, 0x0363,
+ 0x7c05, 0x036f, 0x7d27, 0x0374, 0x7c7a, 0x9a71, 0xdb04, 0x3c06,
+ 0x4c00, 0x7df7, 0x028f, 0x1a04, 0x6a23, 0x620b, 0x6f23, 0x301f,
+ 0x00aa, 0x0462, 0x7c04, 0x4a00, 0x7d0b, 0x2001, 0x9a30, 0x048a,
+ 0x620b, 0x2201, 0x1c01, 0x1801, 0x02dc, 0x7d02, 0x301f, 0x00aa,
+ 0x048f, 0x1c04, 0x6c07, 0x0488, 0x3c1f, 0x6c2b, 0x0045, 0x028e,
+ 0x1a5c, 0x9a11, 0x058f, 0x1d0c, 0x6d23, 0x650b, 0x007d, 0x7c01,
+ 0x1d08, 0x007c, 0x7c01, 0x1d04, 0x6d23, 0x650b, 0x0488, 0x3c1f,
+ 0x0417, 0x0417, 0x0417, 0x0417, 0x059c, 0x6d23, 0x028e, 0x1a34,
+ 0x6ad7, 0x0488, 0x0804, 0x7802, 0x650b, 0x6dc8, 0x008c, 0x1a28,
+ 0x6ad7, 0x63c8, 0x034c, 0x6bc8, 0x54d1, 0x4c00, 0x7d06, 0x0065,
+ 0x7c02, 0x0101, 0x0025, 0x0400, 0x9a0d, 0x52c1, 0x53c9, 0x54e1,
+ 0x0453, 0xc10d, 0x7d95, 0x0200, 0x9a00, 0x0200, 0x99f9, 0x0200,
+ 0x9a00, 0x55d9, 0x6d07, 0x54d1, 0x058a, 0x2508, 0x6dc7, 0x0373,
+ 0x7c03, 0x65c8, 0x6d0b, 0x2408, 0x0372, 0x7c04, 0x65c8, 0x6d0b,
+ 0x2408, 0x9a86, 0x6cce, 0x65c8, 0x6d0a, 0x2404, 0x6d28, 0x6507,
+ 0x5dd9, 0x5cd1, 0x6ad7, 0x6ae3, 0x63c8, 0x0334, 0x6bc8, 0x0370,
+ 0x7ca9, 0x0c60, 0x0411, 0x04bb, 0x4c00, 0x7da4, 0x0410, 0x1c30,
+ 0x0410, 0x04bb, 0x046d, 0x7d0a, 0x047d, 0x7c03, 0x047c, 0x7c01,
+ 0x9a3a, 0x003b, 0x003a, 0x0039, 0x0058, 0x9ab5, 0x047d, 0x7d03,
+ 0x047c, 0x7d01, 0x9a3a, 0x005b, 0xdaf9, 0x1d18, 0x6d23, 0x650b,
+ 0x0510, 0x003a, 0x0039, 0x0038, 0x00ad, 0xdb04, 0x0c30, 0x0410,
+ 0x04bb, 0x003c, 0x003d, 0x00ac, 0xdaf9, 0x007b, 0x7c04, 0x003d,
+ 0x003c, 0x1d0c, 0x9ad6, 0x048f, 0x1c14, 0x6c23, 0x640b, 0x4401,
+ 0x7d04, 0x005d, 0x005c, 0x1d0c, 0x9ad6, 0x0310, 0x3b30, 0x4b30,
+ 0x7d01, 0x1b10, 0x0310, 0x003d, 0x003c, 0x00ab, 0x6ad7, 0x63c8,
+ 0x6d23, 0x650b, 0x0560, 0x7d03, 0x005e, 0xdaed, 0x9a3a, 0x003e,
+ 0x0c80, 0x0410, 0x0394, 0xdaed, 0x640b, 0x037f, 0x7d02, 0x1a14,
+ 0x9aea, 0x1a0c, 0x6ad7, 0x6cc8, 0x9a3a, 0x0c7f, 0x0410, 0x03b4,
+ 0x04b8, 0x03ac, 0x640b, 0x6bc8, 0x028e, 0x1a04, 0x6ad7, 0x6cc8,
+ 0x0006, 0x058f, 0x1d08, 0x6d23, 0x650b, 0x007d, 0x7c01, 0x1d38,
+ 0x007c, 0x7c01, 0x1d1c, 0x0006, 0x048b, 0x042c, 0x0454, 0x042b,
+ 0x6ad7, 0x6cc8, 0x0006, 0x0007, 0x684c, 0x6144, 0x9b1c, 0x0007,
+ 0x68cc, 0x61d0, 0x9b1c, 0x0007, 0x680c, 0x680c, 0x6107, 0x6907,
+ 0x692b, 0x6928, 0x0007, 0x680c, 0x0d70, 0x0511, 0x5515, 0x55f5,
+ 0x01a5, 0x0dff, 0x0512, 0x1dff, 0x0512, 0x04bd, 0x0499, 0x0454,
+ 0x0006, 0x08ff, 0x0011, 0x28ff, 0x0006, 0x038c, 0x0eff, 0x0611,
+ 0x2eff, 0x03b6, 0x0006, 0x53d6, 0x0398, 0x5bd6, 0x53ee, 0x0398,
+ 0x5bee, 0x0006, 0x52de, 0x53e6, 0x54ee, 0x0498, 0x0454, 0x0006,
+ 0x50f6, 0x52c6, 0x53ce, 0x54d6, 0x0498, 0x0454, 0x0006, 0x6207,
+ 0x0b70, 0x0311, 0x5013, 0x55f0, 0x02a5, 0x0bff, 0x0312, 0x1bff,
+ 0x0312, 0x04bb, 0x049a, 0x0006, 0x1e10, 0x0870, 0x0011, 0x5010,
+ 0xc0ec, 0x7d39, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02,
+ 0x0200, 0x9b5b, 0x6d07, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc,
+ 0x4d00, 0x7d17, 0x6ec3, 0x62c8, 0x7e28, 0x0264, 0x7d08, 0x0b70,
+ 0x0311, 0x522b, 0x02b9, 0x4a00, 0x7c18, 0x0400, 0x9b6a, 0x0212,
+ 0x3aff, 0x008a, 0x05d8, 0x7d01, 0x008d, 0x0a10, 0x6ed3, 0x6ac8,
+ 0xdba5, 0x6a28, 0x7f17, 0x0b70, 0x0311, 0x5013, 0xdbbd, 0x52c0,
+ 0x53c8, 0xc10d, 0x7dd0, 0x0200, 0x9b5b, 0x008f, 0x00d5, 0x7d01,
+ 0x008d, 0xdba5, 0x9b68, 0x0200, 0x9b58, 0x0007, 0x68cc, 0x6a28,
+ 0x7f01, 0x9ba3, 0x0007, 0x6a0c, 0x6a0c, 0x6207, 0x6a07, 0x6a2b,
+ 0x6a28, 0x0007, 0x680c, 0x0454, 0x9b81, 0x05a0, 0x1e08, 0x6ec3,
+ 0x0388, 0x3b03, 0x0015, 0x0015, 0x7802, 0x62c8, 0x6a0b, 0x7ee5,
+ 0x6a28, 0x7fe8, 0x0000, 0x6ec1, 0x008b, 0x7802, 0x62c8, 0x6a09,
+ 0x7edc, 0x6a28, 0x7fdf, 0x2608, 0x0006, 0x55f0, 0x6207, 0x02a5,
+ 0x0dff, 0x0511, 0x1dff, 0x04b5, 0x049a, 0x0006, 0x0870, 0x0011,
+ 0x5010, 0xc0ec, 0x7d78, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8,
+ 0x7d02, 0x0200, 0x9bcc, 0x6d03, 0x6ed3, 0x0dff, 0x0511, 0x1dff,
+ 0x05bc, 0x5df8, 0x4d00, 0x7d5e, 0x0b70, 0x0311, 0x522b, 0x5313,
+ 0x02b9, 0x4a00, 0x7c04, 0x62ff, 0x7e3f, 0x0400, 0x9bdc, 0x008f,
+ 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5ddb, 0x0d03, 0x0512, 0x05bc,
+ 0x0510, 0x5dd3, 0x4d00, 0x7d27, 0x4d02, 0x7d20, 0x4d01, 0x7d1a,
+ 0x0b70, 0x0311, 0x53eb, 0x0360, 0x7d05, 0x6509, 0x7e25, 0x620a,
+ 0x7e23, 0x9c06, 0x620a, 0x7e20, 0x6509, 0x7e1e, 0x0512, 0x0512,
+ 0x02ad, 0x6ac8, 0x7f19, 0x2003, 0x4800, 0x7ced, 0x0b70, 0x0311,
+ 0x5313, 0x9c21, 0x7802, 0x6209, 0x6ac8, 0x9c20, 0x0015, 0x7802,
+ 0x620a, 0x6ac8, 0x9c20, 0x0015, 0x0015, 0x7802, 0x620b, 0x6ac8,
+ 0x7c03, 0x0000, 0x55db, 0x9bda, 0x0007, 0x68cc, 0x680c, 0x55d3,
+ 0x4d00, 0x7d03, 0x4d02, 0x7d02, 0x9c2f, 0x0017, 0x0017, 0x55db,
+ 0x009d, 0x55fb, 0x05a0, 0x08ff, 0x0011, 0x18ff, 0x0010, 0x04b8,
+ 0x04ad, 0x0454, 0x62ff, 0x7ee8, 0x008b, 0x52c0, 0x53c8, 0xc10d,
+ 0x7d8b, 0x0200, 0x9bcc, 0x0200, 0x9bc9, 0xc19d, 0xc0ec, 0x7d52,
+ 0x0c70, 0x0411, 0x5414, 0x5ac4, 0x028c, 0x58da, 0x5efa, 0xc0fe,
+ 0x56fa, 0x7d02, 0x0200, 0x9c4e, 0x6d03, 0x5bca, 0x5cd2, 0x0bff,
+ 0x0311, 0x1bff, 0x04bb, 0x0415, 0x53da, 0x0a70, 0x0211, 0x4c00,
+ 0x7d28, 0x552a, 0x05bb, 0x4d00, 0x7c02, 0x0400, 0x9c61, 0x4c01,
+ 0x7d0f, 0x008f, 0x0015, 0x04d8, 0x7d01, 0x008c, 0x0020, 0x04a0,
+ 0x0015, 0x7802, 0x650b, 0x5d06, 0x0000, 0x7e0c, 0x7f0d, 0x9c5f,
+ 0x650a, 0x7e08, 0x008d, 0x0011, 0x0010, 0x05a8, 0x065f, 0x5d06,
+ 0x063f, 0x7f02, 0x0007, 0x680c, 0x0007, 0x5012, 0x54d0, 0x0454,
+ 0x9c8b, 0x5012, 0x54d0, 0x0473, 0x7c06, 0x552a, 0x05b9, 0x4d00,
+ 0x7c02, 0x0400, 0x9c8d, 0x52c0, 0x53c8, 0xc10d, 0x0288, 0x7db6,
+ 0x0200, 0x9c4e, 0x0200, 0x9c46, 0x0870, 0x0011, 0x5010, 0xc0ec,
+ 0x7d46, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200,
+ 0x9ca2, 0x0b70, 0x0311, 0x6ed3, 0x6d03, 0x0dff, 0x0511, 0x1dff,
+ 0x05bc, 0x4d00, 0x7d2b, 0x522b, 0x02b9, 0x4a00, 0x7c04, 0x62c8,
+ 0x7e1f, 0x0400, 0x9cb3, 0x008f, 0x00d5, 0x7d01, 0x008d, 0x05a0,
+ 0x0060, 0x7c05, 0x6edd, 0x6209, 0x7e16, 0x6ac8, 0x7f11, 0x0015,
+ 0x0060, 0x7c05, 0x6ede, 0x620a, 0x7e0e, 0x6ac8, 0x7f09, 0x6edf,
+ 0x0015, 0x7802, 0x620b, 0x6ac8, 0x0000, 0x7e05, 0x7f01, 0x9cb1,
+ 0x0007, 0x68cc, 0x9cdd, 0x0007, 0x6a0c, 0x0454, 0x62c8, 0x7ef8,
+ 0x5013, 0x52c0, 0x53c8, 0xc10d, 0x7dbd, 0x0200, 0x9ca2, 0x0200,
+ 0x9c9f, 0xc19d, 0x0870, 0x0011, 0xc0ec, 0x7d29, 0x5010, 0x5ac0,
+ 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, 0x9cf0, 0x0870, 0x0011,
+ 0x6d03, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d12, 0x5228,
+ 0x02b9, 0x4a00, 0x7c02, 0x0400, 0x9cff, 0x620b, 0x7e06, 0x5a06,
+ 0x7f06, 0x0000, 0x2504, 0x7d05, 0x9cff, 0x0007, 0x680c, 0x0007,
+ 0x0454, 0x5010, 0x52c0, 0xc10d, 0x7ddb, 0x0200, 0x9cf0, 0x0200,
+ 0x9cec, 0xc19d, 0x0870, 0x0011, 0xc0ec, 0x7d74, 0x5010, 0x5ac0,
+ 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, 0x9d20, 0x6d03,
+ 0x0d03, 0x0512, 0x05bc, 0x0510, 0x5dd0, 0x0dff, 0x0511, 0x1dff,
+ 0x05bc, 0x5df8, 0x4d00, 0x7d57, 0x0a70, 0x0211, 0x532a, 0x5212,
+ 0x03b9, 0x4b00, 0x7c02, 0x0400, 0x9d34, 0x008f, 0x05d8, 0x7d01,
+ 0x008d, 0x05a0, 0x5dda, 0x55d2, 0x4d00, 0x7d27, 0x4d02, 0x7d20,
+ 0x4d01, 0x7d1a, 0x0a70, 0x0211, 0x52ea, 0x0260, 0x7d05, 0x6509,
+ 0x7e25, 0x630a, 0x7e23, 0x9d58, 0x630a, 0x7e20, 0x6509, 0x7e1e,
+ 0x0512, 0x0512, 0x03ad, 0x5b06, 0x7f19, 0x2003, 0x4800, 0x7ced,
+ 0x0a70, 0x0211, 0x5212, 0x9d73, 0x7802, 0x6309, 0x5b06, 0x9d72,
+ 0x0015, 0x7802, 0x630a, 0x5b06, 0x9d72, 0x0015, 0x0015, 0x7802,
+ 0x630b, 0x5b06, 0x7c03, 0x55da, 0x0000, 0x9d32, 0x0007, 0x680c,
+ 0x55d2, 0x4d00, 0x7d03, 0x4d02, 0x7d02, 0x9d80, 0x0017, 0x0017,
+ 0x55da, 0x009d, 0x55fa, 0x05a0, 0x08ff, 0x0011, 0x18ff, 0x0010,
+ 0x04b8, 0x04ad, 0x0454, 0x008a, 0x52c0, 0x53c8, 0xc10d, 0x7d90,
+ 0x0200, 0x9d20, 0x0200, 0x9d1c, 0xc19d, 0x0870, 0x0011, 0xc0ec,
+ 0x7d35, 0x5010, 0x5ac0, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200,
+ 0x9d9b, 0x0870, 0x0011, 0x6d07, 0x0dff, 0x0511, 0x1dff, 0x05bc,
+ 0x4d00, 0x7d1c, 0x5228, 0x02b9, 0x4a00, 0x7c04, 0x6928, 0x7f0b,
+ 0x0400, 0x9daa, 0x5206, 0x7e10, 0x6a0b, 0x6928, 0x7f04, 0x0000,
+ 0x2504, 0x7d0c, 0x9daa, 0x0007, 0x680c, 0x680c, 0x6207, 0x6a07,
+ 0x6a2b, 0x6a28, 0x0007, 0x680c, 0x0007, 0x0454, 0x6928, 0x7ff3,
+ 0x5010, 0x52c0, 0xc10d, 0x7dcf, 0x0200, 0x9d9b, 0x0200, 0x9d97,
+ 0xc19d, 0x0870, 0x0011, 0xc0ec, 0x7d5e, 0x5010, 0x5ac0, 0x5bc8,
+ 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, 0x9dd7, 0x6d07, 0x5df0,
+ 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d44, 0x0a70, 0x0211,
+ 0x532a, 0x5212, 0x03b9, 0x4b00, 0x7c04, 0x6a28, 0x7f3a, 0x0400,
+ 0x9de6, 0x008f, 0x05d8, 0x7d01, 0x008d, 0x05a0, 0x0b03, 0x0312,
+ 0x03bc, 0x0310, 0x4b00, 0x7d1c, 0x4b02, 0x7d20, 0x4b01, 0x7d23,
+ 0x0a70, 0x0211, 0x52ea, 0x5306, 0x7e24, 0x0260, 0x7d02, 0x0310,
+ 0x0312, 0x6b09, 0x7f1e, 0x0312, 0x6b09, 0x7f1b, 0x0312, 0x6b09,
+ 0x7f18, 0x2003, 0x4800, 0x7cef, 0x0a70, 0x0211, 0x5212, 0x9e27,
+ 0x0015, 0x0015, 0x7802, 0x5306, 0x6b0b, 0x9e26, 0x0015, 0x7802,
+ 0x5306, 0x6b0a, 0x9e26, 0x7802, 0x5306, 0x6b09, 0x7c02, 0x0000,
+ 0x9de4, 0xdb13, 0x6928, 0x7ffd, 0x008a, 0x52c0, 0x53c8, 0xc10d,
+ 0x7da6, 0x0200, 0x9dd7, 0x0200, 0x9dd3, 0x0870, 0x0011, 0x5010,
+ 0xc0ec, 0x7d5b, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02,
+ 0x0200, 0x9e3b, 0x0b70, 0x0311, 0x6ec3, 0x6d07, 0x5df0, 0x0dff,
+ 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d3d, 0x522b, 0x02b9, 0x4a00,
+ 0x7c04, 0x6a28, 0x7f33, 0x0400, 0x9e4d, 0x028e, 0x1a94, 0x6ac3,
+ 0x62c8, 0x0269, 0x7d1b, 0x1e94, 0x6ec3, 0x6ed3, 0x62c8, 0x0248,
+ 0x6ac8, 0x2694, 0x6ec3, 0x62c8, 0x026e, 0x7d31, 0x6a09, 0x7f1e,
+ 0x2501, 0x4d00, 0x7d1f, 0x028e, 0x1a98, 0x6ac3, 0x62c8, 0x6ec3,
+ 0x0260, 0x7df1, 0x6a28, 0x7f12, 0xdb47, 0x9e8c, 0x6ee3, 0x008f,
+ 0x2001, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x62c8, 0x026e, 0x7d17,
+ 0x6a09, 0x7f04, 0x2001, 0x7cf9, 0x0000, 0x9e4b, 0x0289, 0xdb13,
+ 0x018a, 0x9e9b, 0x6a28, 0x7ffa, 0x0b70, 0x0311, 0x5013, 0x52c0,
+ 0x53c8, 0xc10d, 0x7da8, 0x0200, 0x9e3b, 0x0200, 0x9e38, 0x6a28,
+ 0x7fed, 0xdb47, 0x9e9b, 0x0458, 0x0454, 0x9e8c, 0xc19d, 0x0870,
+ 0x0011, 0xc0ec, 0x7d54, 0x5010, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe,
+ 0x56f8, 0x7d02, 0x0200, 0x9ea5, 0x0b70, 0x0311, 0x6d07, 0x5df0,
+ 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d36, 0x522b, 0x02b9,
+ 0x4a00, 0x7c04, 0x6928, 0x7f2c, 0x0400, 0x9eb6, 0x028e, 0x1a94,
+ 0x5202, 0x0269, 0x7d16, 0x1e94, 0x5206, 0x0248, 0x5a06, 0x2694,
+ 0x5206, 0x026e, 0x7d2e, 0x6a09, 0x7f1b, 0x2501, 0x4d00, 0x7d1c,
+ 0x028e, 0x1a98, 0x5202, 0x0260, 0x7df3, 0x6a28, 0x7f11, 0xdb47,
+ 0x9eee, 0x008f, 0x2001, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5206,
+ 0x026e, 0x7d17, 0x6a09, 0x7f04, 0x2001, 0x7cf9, 0x0000, 0x9eb4,
+ 0x0289, 0xdb13, 0x018a, 0x9efd, 0x6928, 0x7ffa, 0x0b70, 0x0311,
+ 0x5013, 0x52c0, 0x53c8, 0xc10d, 0x7db0, 0x0200, 0x9ea5, 0x0200,
+ 0x9ea1, 0x6a28, 0x7fed, 0xdb47, 0x9efd, 0x0458, 0x0454, 0x9eee,
+ 0x9eee
+};
+#endif
diff --git a/arch/arm/mach-mx3/sdma_script_code_pass2.h b/arch/arm/mach-mx3/sdma_script_code_pass2.h
new file mode 100644
index 000000000000..85de716c45f9
--- /dev/null
+++ b/arch/arm/mach-mx3/sdma_script_code_pass2.h
@@ -0,0 +1,434 @@
+/*
+ * Copyright 2004-2008 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 */
+
+/*!
+ * @file sdma_script_code.h
+ * @brief This file contains functions of SDMA scripts code initialization
+ *
+ * The file was generated automatically. Based on sdma scripts library.
+ *
+ * @ingroup SDMA
+ */
+/*******************************************************************************
+
+ SDMA RELEASE LABEL: "SS15_MX31"
+
+*******************************************************************************/
+
+#ifndef __SDMA_SCRIPT_CODE_PASS2_H__
+#define __SDMA_SCRIPT_CODE_PASS2_H__
+
+/*!
+* SDMA ROM scripts start addresses and sizes
+*/
+
+#define start_ADDR_2 0
+#define start_SIZE_2 20
+
+#define core_ADDR_2 80
+#define core_SIZE_2 152
+
+#define common_ADDR_2 232
+#define common_SIZE_2 191
+
+#define ap_2_ap_ADDR_2 423
+#define ap_2_ap_SIZE_2 294
+
+#define bp_2_bp_ADDR_2 717
+#define bp_2_bp_SIZE_2 112
+
+#define ap_2_bp_ADDR_2 829
+#define ap_2_bp_SIZE_2 200
+
+#define bp_2_ap_ADDR_2 1029
+#define bp_2_ap_SIZE_2 223
+
+#define app_2_mcu_ADDR_2 1252
+#define app_2_mcu_SIZE_2 101
+
+#define mcu_2_app_ADDR_2 1353
+#define mcu_2_app_SIZE_2 127
+
+#define uart_2_mcu_ADDR_2 1480
+#define uart_2_mcu_SIZE_2 105
+
+#define uartsh_2_mcu_ADDR_2 1585
+#define uartsh_2_mcu_SIZE_2 98
+
+#define mcu_2_shp_ADDR_2 1683
+#define mcu_2_shp_SIZE_2 123
+
+#define shp_2_mcu_ADDR_2 1806
+#define shp_2_mcu_SIZE_2 101
+
+#define error_ADDR_2 1907
+#define error_SIZE_2 73
+
+#define test_ADDR_2 1980
+#define test_SIZE_2 63
+
+#define signature_ADDR_2 1023
+#define signature_SIZE_2 1
+
+/*!
+* SDMA RAM scripts start addresses and sizes
+*/
+
+#define ap_2_ap_fixed_addr_ADDR_2 6144
+#define ap_2_ap_fixed_addr_SIZE_2 68
+
+#define app_2_mcu_patched_ADDR_2 6212
+#define app_2_mcu_patched_SIZE_2 104
+
+#undef app_2_mcu_ADDR_2
+#undef app_2_mcu_SIZE_2
+
+/*mapping the app_2_mcu start address to the patched(RAM)script start address*/
+#define app_2_mcu_ADDR_2 app_2_mcu_patched_ADDR_2
+#define app_2_mcu_SIZE_2 app_2_mcu_patched_SIZE_2
+
+#define app_2_per_ADDR_2 6316
+#define app_2_per_SIZE_2 105
+
+#define ata_2_mcu_ADDR_2 6421
+#define ata_2_mcu_SIZE_2 110
+
+#define firi_2_mcu_ADDR_2 6531
+#define firi_2_mcu_SIZE_2 114
+
+#define loop_DMAs_fixed_addr_ADDR_2 6645
+#define loop_DMAs_fixed_addr_SIZE_2 90
+
+#define mcu_2_app_patched_ADDR_2 6735
+#define mcu_2_app_patched_SIZE_2 129
+
+#undef mcu_2_app_ADDR_2
+#undef mcu_2_app_SIZE_2
+
+/*mapping the mcu_2_app start address to the patched(RAM)script start address*/
+#define mcu_2_app_ADDR_2 mcu_2_app_patched_ADDR_2
+#define mcu_2_app_SIZE_2 mcu_2_app_patched_SIZE_2
+
+#define mcu_2_ata_ADDR_2 6864
+#define mcu_2_ata_SIZE_2 87
+
+#define mcu_2_firi_ADDR_2 6951
+#define mcu_2_firi_SIZE_2 77
+
+#define mcu_2_mshc_ADDR_2 7028
+#define mcu_2_mshc_SIZE_2 48
+
+#define mcu_2_shp_patched_ADDR_2 7076
+#define mcu_2_shp_patched_SIZE_2 125
+
+#undef mcu_2_shp_ADDR_2
+#undef mcu_2_shp_SIZE_2
+
+/*mapping the mcu_2_shp start address to the patched(RAM)script start address*/
+#define mcu_2_shp_ADDR_2 mcu_2_shp_patched_ADDR_2
+#define mcu_2_shp_SIZE_2 mcu_2_shp_patched_SIZE_2
+
+#define mshc_2_mcu_ADDR_2 7201
+#define mshc_2_mcu_SIZE_2 60
+
+#define per_2_app_ADDR_2 7261
+#define per_2_app_SIZE_2 131
+
+#define per_2_shp_ADDR_2 7392
+#define per_2_shp_SIZE_2 131
+
+#define shp_2_mcu_patched_ADDR_2 7523
+#define shp_2_mcu_patched_SIZE_2 104
+
+#undef shp_2_mcu_ADDR_2
+#undef shp_2_mcu_SIZE_2
+
+/*mapping the shp_2_mcu start address to the patched(RAM)script start address*/
+#define shp_2_mcu_ADDR_2 shp_2_mcu_patched_ADDR_2
+#define shp_2_mcu_SIZE_2 shp_2_mcu_patched_SIZE_2
+
+#define shp_2_per_ADDR_2 7627
+#define shp_2_per_SIZE_2 109
+
+#define uart_2_mcu_patched_ADDR_2 7736
+#define uart_2_mcu_patched_SIZE_2 106
+
+#undef uart_2_mcu_ADDR_2
+#undef uart_2_mcu_SIZE_2
+
+/*mapping the uart_2_mcu start address to the patched(RAM)script start address*/
+#define uart_2_mcu_ADDR_2 uart_2_mcu_patched_ADDR_2
+#define uart_2_mcu_SIZE_2 uart_2_mcu_patched_SIZE_2
+
+#define uartsh_2_mcu_patched_ADDR_2 7842
+#define uartsh_2_mcu_patched_SIZE_2 99
+
+#undef uartsh_2_mcu_ADDR_2
+#undef uartsh_2_mcu_SIZE_2
+
+/*
+ * mapping the uartsh_2_mcu start address to the patched(RAM)script
+ * start address
+ */
+#define uartsh_2_mcu_ADDR_2 uartsh_2_mcu_patched_ADDR_2
+#define uartsh_2_mcu_SIZE_2 uartsh_2_mcu_patched_SIZE_2
+
+/*!
+* SDMA RAM image start address and size
+*/
+
+#define RAM_CODE_START_ADDR_2 6144
+#define RAM_CODE_SIZE_2 1797
+
+/*!
+* Buffer that holds the SDMA RAM image
+*/
+
+__attribute__ ((__aligned__(4)))
+#ifndef CONFIG_XIP_KERNEL
+const
+#endif
+static const short sdma_code_2[] = {
+ 0x0970, 0x0111, 0x5111, 0x5ef9, 0xc0ec, 0x7d23, 0x5ad1, 0x5bd9,
+ 0xc0fe, 0x7c1f, 0x5ce1, 0x5de9, 0x5ef1, 0x08ff, 0x0011, 0x28ff,
+ 0x00bc, 0x048e, 0x56f9, 0x0660, 0x7d05, 0x0661, 0x7c2b, 0x6c07,
+ 0x6d13, 0x9821, 0x0661, 0x7d26, 0x6c17, 0x6d03, 0x028d, 0x058c,
+ 0x048a, 0xd9f5, 0x7e08, 0x7f07, 0x54e1, 0x52d1, 0x53d9, 0xc10d,
+ 0x7dde, 0x0200, 0x9804, 0x0660, 0x7d03, 0x6007, 0x52f1, 0x9832,
+ 0x6003, 0x52e9, 0x00a2, 0x0007, 0x6a0c, 0x6a0c, 0x6207, 0x6a07,
+ 0x6a2b, 0x6a28, 0x0007, 0x6a0c, 0x54e1, 0xc795, 0x048b, 0x0498,
+ 0x0454, 0x9825, 0x0800, 0x983c, 0x0870, 0x0011, 0x5010, 0xc0ec,
+ 0x7d61, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200,
+ 0x984a, 0x6ec3, 0x6d07, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc,
+ 0x4d00, 0x7d45, 0x0b70, 0x0311, 0x522b, 0x5313, 0x02b9, 0x4a00,
+ 0x7c04, 0x6a28, 0x7f3b, 0x0400, 0x985a, 0x008f, 0x00d5, 0x7d01,
+ 0x008d, 0x05a0, 0x0a03, 0x0212, 0x02bc, 0x0210, 0x4a00, 0x7d1c,
+ 0x4a02, 0x7d20, 0x4a01, 0x7d23, 0x0b70, 0x0311, 0x53eb, 0x62c8,
+ 0x7e25, 0x0360, 0x7d02, 0x0210, 0x0212, 0x6a09, 0x7f1f, 0x0212,
+ 0x6a09, 0x7f1c, 0x0212, 0x6a09, 0x7f19, 0x2003, 0x4800, 0x7cef,
+ 0x0b70, 0x0311, 0x5313, 0x989b, 0x0015, 0x0015, 0x7802, 0x62c8,
+ 0x6a0b, 0x989a, 0x0015, 0x7802, 0x62c8, 0x6a0a, 0x989a, 0x7802,
+ 0x62c8, 0x6a09, 0x7c03, 0x6a28, 0x0000, 0x9858, 0xc77b, 0x6a28,
+ 0x7ffd, 0x0870, 0x0011, 0x5010, 0x52c0, 0x53c8, 0xc10d, 0x7da2,
+ 0x0200, 0x984a, 0x0200, 0x9847, 0x0870, 0x0011, 0x5010, 0xc0ec,
+ 0x7d62, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200,
+ 0x98b2, 0x6ec3, 0x6dd7, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc,
+ 0x4d00, 0x7d46, 0x0b70, 0x0311, 0x522b, 0x5313, 0x02b9, 0x4a00,
+ 0x7c04, 0x62ff, 0x7e3c, 0x0400, 0x98c2, 0x008f, 0x00d5, 0x7d01,
+ 0x008d, 0x05a0, 0x0a03, 0x0212, 0x02bc, 0x0210, 0x4a00, 0x7d28,
+ 0x4a02, 0x7d20, 0x4a01, 0x7d19, 0x6ddd, 0x0b70, 0x0311, 0x53eb,
+ 0x62c8, 0x7e25, 0x0360, 0x7d02, 0x0210, 0x0212, 0x6ac8, 0x7f1f,
+ 0x0212, 0x6ac8, 0x7f1c, 0x0212, 0x6ac8, 0x7f19, 0x2003, 0x4800,
+ 0x7cef, 0x0b70, 0x0311, 0x5313, 0x9905, 0x6ddd, 0x7802, 0x62c8,
+ 0x6ac8, 0x9904, 0x6dde, 0x0015, 0x7802, 0x62c8, 0x6ac8, 0x9904,
+ 0x0015, 0x0015, 0x7801, 0x62d8, 0x7c02, 0x0000, 0x98c0, 0xc777,
+ 0x62ff, 0x7efd, 0x0870, 0x0011, 0x5010, 0x52c0, 0x53c8, 0xc10d,
+ 0x7da1, 0x0200, 0x98b2, 0x0200, 0x98af, 0xc19d, 0xc0ec, 0x7d69,
+ 0x0c70, 0x0411, 0x5414, 0x5ac4, 0x028c, 0x58da, 0x5efa, 0xc0fe,
+ 0x56fa, 0x7d02, 0x0200, 0x991e, 0x6d07, 0x5bca, 0x5cd2, 0x0bff,
+ 0x0311, 0x1bff, 0x04bb, 0x0415, 0x53da, 0x4c00, 0x7d47, 0x0a70,
+ 0x0211, 0x552a, 0x5212, 0x008d, 0x00bb, 0x4800, 0x7c07, 0x05b9,
+ 0x4d00, 0x7c13, 0x6928, 0x7f2d, 0x0400, 0x992f, 0x008f, 0x0015,
+ 0x04d8, 0x7d01, 0x008c, 0x04a0, 0x0015, 0x7802, 0x55c6, 0x6d0b,
+ 0x7e29, 0x6d28, 0x7f1e, 0x0000, 0x992d, 0x1e20, 0x5506, 0x2620,
+ 0x008d, 0x0560, 0x7c08, 0x065f, 0x55c6, 0x063f, 0x7e1b, 0x6d0a,
+ 0x7f10, 0x4c00, 0x7d1b, 0x04d8, 0x7d02, 0x008c, 0x0020, 0x04a0,
+ 0x0015, 0x7802, 0x55c6, 0x6d0b, 0x7e0d, 0x6d28, 0x7f02, 0x0000,
+ 0x9976, 0x0007, 0x680c, 0x6d0c, 0x6507, 0x6d07, 0x6d2b, 0x6d28,
+ 0x0007, 0x680c, 0x0007, 0x54d2, 0x0454, 0x9979, 0x6928, 0x7ff1,
+ 0x54d2, 0x008a, 0x52c0, 0x53c8, 0xc10d, 0x0288, 0x7d9f, 0x0200,
+ 0x991e, 0x0200, 0x9916, 0x1e10, 0x0870, 0x0011, 0x5010, 0xc0ec,
+ 0x7d39, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200,
+ 0x998a, 0x6d07, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00,
+ 0x7d17, 0x6ec3, 0x62c8, 0x7e28, 0x0264, 0x7d08, 0x0b70, 0x0311,
+ 0x522b, 0x02b9, 0x4a00, 0x7c18, 0x0400, 0x9999, 0x0212, 0x3aff,
+ 0x008a, 0x05d8, 0x7d01, 0x008d, 0x0a10, 0x6ed3, 0x6ac8, 0xd9d4,
+ 0x6a28, 0x7f17, 0x0b70, 0x0311, 0x5013, 0xd9ec, 0x52c0, 0x53c8,
+ 0xc10d, 0x7dd0, 0x0200, 0x998a, 0x008f, 0x00d5, 0x7d01, 0x008d,
+ 0xd9d4, 0x9997, 0x0200, 0x9987, 0x0007, 0x68cc, 0x6a28, 0x7f01,
+ 0x99d2, 0x0007, 0x6a0c, 0x6a0c, 0x6207, 0x6a07, 0x6a2b, 0x6a28,
+ 0x0007, 0x680c, 0x0454, 0x99b0, 0x05a0, 0x1e08, 0x6ec3, 0x0388,
+ 0x3b03, 0x0015, 0x0015, 0x7802, 0x62c8, 0x6a0b, 0x7ee5, 0x6a28,
+ 0x7fe8, 0x0000, 0x6ec1, 0x008b, 0x7802, 0x62c8, 0x6a09, 0x7edc,
+ 0x6a28, 0x7fdf, 0x2608, 0x0006, 0x55f0, 0x6207, 0x02a5, 0x0dff,
+ 0x0511, 0x1dff, 0x04b5, 0x049a, 0x0006, 0x0388, 0x028d, 0x3a03,
+ 0x4a00, 0x7c33, 0x028c, 0x3a03, 0x4a00, 0x7d0c, 0x0804, 0x00a2,
+ 0x00db, 0x7d24, 0x03a0, 0x0498, 0x7802, 0x6209, 0x6a29, 0x7e24,
+ 0x620c, 0x7e22, 0x0804, 0x03d0, 0x7d19, 0x0820, 0x028c, 0x3a1f,
+ 0x00a2, 0x03d0, 0x7c02, 0x008b, 0x3003, 0x03a0, 0x0015, 0x0015,
+ 0x6818, 0x7e12, 0x6828, 0x7f10, 0x0000, 0x0820, 0x03d8, 0x7df5,
+ 0x0804, 0x03d0, 0x7d03, 0x008b, 0x3003, 0x9a15, 0x008b, 0x7802,
+ 0x6209, 0x6a29, 0x7e01, 0x620c, 0x0006, 0x0804, 0x03d0, 0x7df6,
+ 0x048b, 0x3403, 0x03a4, 0x0415, 0x0415, 0x0d0f, 0x0511, 0x1df0,
+ 0x0808, 0x04d0, 0x7c01, 0x008c, 0x58c1, 0x04a0, 0x7803, 0x620b,
+ 0x5a05, 0x1d01, 0x7ee9, 0x50c1, 0x05a0, 0x7803, 0x5205, 0x6a0b,
+ 0x1d01, 0x6a28, 0x7fe1, 0x0000, 0x4c00, 0x7ce7, 0x9a26, 0x0870,
+ 0x0011, 0x5010, 0xc0ec, 0x7d7a, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe,
+ 0x56f8, 0x7d02, 0x0200, 0x9a55, 0x6d03, 0x6ed3, 0x0dff, 0x0511,
+ 0x1dff, 0x05bc, 0x5df8, 0x4d00, 0x7d5e, 0x0b70, 0x0311, 0x522b,
+ 0x5313, 0x02b9, 0x4a00, 0x7c04, 0x62ff, 0x7e3f, 0x0400, 0x9a65,
+ 0x008f, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5ddb, 0x0d03, 0x0512,
+ 0x05bc, 0x0510, 0x5dd3, 0x4d00, 0x7d27, 0x4d02, 0x7d20, 0x4d01,
+ 0x7d1a, 0x0b70, 0x0311, 0x53eb, 0x0360, 0x7d05, 0x6509, 0x7e25,
+ 0x620a, 0x7e23, 0x9a8f, 0x620a, 0x7e20, 0x6509, 0x7e1e, 0x0512,
+ 0x0512, 0x02ad, 0x6ac8, 0x7f19, 0x2003, 0x4800, 0x7ced, 0x0b70,
+ 0x0311, 0x5313, 0x9aaa, 0x7802, 0x6209, 0x6ac8, 0x9aa9, 0x0015,
+ 0x7802, 0x620a, 0x6ac8, 0x9aa9, 0x0015, 0x0015, 0x7802, 0x620b,
+ 0x6ac8, 0x7c03, 0x0000, 0x55db, 0x9a63, 0x0007, 0x68cc, 0x680c,
+ 0x55d3, 0x4d00, 0x7d03, 0x4d02, 0x7d02, 0x9ab8, 0x0017, 0x0017,
+ 0x55db, 0x009d, 0x55fb, 0x05a0, 0x08ff, 0x0011, 0x18ff, 0x0010,
+ 0x04b8, 0x04ad, 0x0454, 0x62ff, 0x7ee8, 0x0870, 0x0011, 0x5010,
+ 0x52c0, 0x53c8, 0xc10d, 0x7d89, 0x0200, 0x9a55, 0x0200, 0x9a52,
+ 0xc19d, 0xc0ec, 0x7d52, 0x0c70, 0x0411, 0x5414, 0x5ac4, 0x028c,
+ 0x58da, 0x5efa, 0xc0fe, 0x56fa, 0x7d02, 0x0200, 0x9ad9, 0x6d03,
+ 0x5bca, 0x5cd2, 0x0bff, 0x0311, 0x1bff, 0x04bb, 0x0415, 0x53da,
+ 0x0a70, 0x0211, 0x4c00, 0x7d28, 0x552a, 0x05bb, 0x4d00, 0x7c02,
+ 0x0400, 0x9aec, 0x4c01, 0x7d0f, 0x008f, 0x0015, 0x04d8, 0x7d01,
+ 0x008c, 0x0020, 0x04a0, 0x0015, 0x7802, 0x650b, 0x5d06, 0x0000,
+ 0x7e0c, 0x7f0d, 0x9aea, 0x650a, 0x7e08, 0x008d, 0x0011, 0x0010,
+ 0x05a8, 0x065f, 0x5d06, 0x063f, 0x7f02, 0x0007, 0x680c, 0x0007,
+ 0x5012, 0x54d0, 0x0454, 0x9b16, 0x5012, 0x54d0, 0x0473, 0x7c06,
+ 0x552a, 0x05b9, 0x4d00, 0x7c02, 0x0400, 0x9b18, 0x52c0, 0x53c8,
+ 0xc10d, 0x0288, 0x7db6, 0x0200, 0x9ad9, 0x0200, 0x9ad1, 0x0870,
+ 0x0011, 0x5010, 0xc0ec, 0x7d46, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe,
+ 0x56f8, 0x7d02, 0x0200, 0x9b2d, 0x0b70, 0x0311, 0x6ed3, 0x6d03,
+ 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d2b, 0x522b, 0x02b9,
+ 0x4a00, 0x7c04, 0x62c8, 0x7e1f, 0x0400, 0x9b3e, 0x008f, 0x00d5,
+ 0x7d01, 0x008d, 0x05a0, 0x0060, 0x7c05, 0x6edd, 0x6209, 0x7e16,
+ 0x6ac8, 0x7f11, 0x0015, 0x0060, 0x7c05, 0x6ede, 0x620a, 0x7e0e,
+ 0x6ac8, 0x7f09, 0x6edf, 0x0015, 0x7802, 0x620b, 0x6ac8, 0x0000,
+ 0x7e05, 0x7f01, 0x9b3c, 0x0007, 0x68cc, 0x9b68, 0x0007, 0x6a0c,
+ 0x0454, 0x62c8, 0x7ef8, 0x5013, 0x52c0, 0x53c8, 0xc10d, 0x7dbd,
+ 0x0200, 0x9b2d, 0x0200, 0x9b2a, 0xc19d, 0x0870, 0x0011, 0xc0ec,
+ 0x7d29, 0x5010, 0x5ac0, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200,
+ 0x9b7b, 0x0870, 0x0011, 0x6d03, 0x0dff, 0x0511, 0x1dff, 0x05bc,
+ 0x4d00, 0x7d12, 0x5228, 0x02b9, 0x4a00, 0x7c02, 0x0400, 0x9b8a,
+ 0x620b, 0x7e06, 0x5a06, 0x7f06, 0x0000, 0x2504, 0x7d05, 0x9b8a,
+ 0x0007, 0x680c, 0x0007, 0x0454, 0x5010, 0x52c0, 0xc10d, 0x7ddb,
+ 0x0200, 0x9b7b, 0x0200, 0x9b77, 0xc19d, 0x0870, 0x0011, 0xc0ec,
+ 0x7d76, 0x5010, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02,
+ 0x0200, 0x9bab, 0x6d03, 0x0d03, 0x0512, 0x05bc, 0x0510, 0x5dd0,
+ 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x5df8, 0x4d00, 0x7d57, 0x0a70,
+ 0x0211, 0x532a, 0x5212, 0x03b9, 0x4b00, 0x7c02, 0x0400, 0x9bbf,
+ 0x008f, 0x05d8, 0x7d01, 0x008d, 0x05a0, 0x5dda, 0x55d2, 0x4d00,
+ 0x7d27, 0x4d02, 0x7d20, 0x4d01, 0x7d1a, 0x0a70, 0x0211, 0x52ea,
+ 0x0260, 0x7d05, 0x6509, 0x7e25, 0x630a, 0x7e23, 0x9be3, 0x630a,
+ 0x7e20, 0x6509, 0x7e1e, 0x0512, 0x0512, 0x03ad, 0x5b06, 0x7f19,
+ 0x2003, 0x4800, 0x7ced, 0x0a70, 0x0211, 0x5212, 0x9bfe, 0x7802,
+ 0x6309, 0x5b06, 0x9bfd, 0x0015, 0x7802, 0x630a, 0x5b06, 0x9bfd,
+ 0x0015, 0x0015, 0x7802, 0x630b, 0x5b06, 0x7c03, 0x55da, 0x0000,
+ 0x9bbd, 0x0007, 0x680c, 0x55d2, 0x4d00, 0x7d03, 0x4d02, 0x7d02,
+ 0x9c0b, 0x0017, 0x0017, 0x55da, 0x009d, 0x55fa, 0x05a0, 0x08ff,
+ 0x0011, 0x18ff, 0x0010, 0x04b8, 0x04ad, 0x0454, 0x0870, 0x0011,
+ 0x5010, 0x52c0, 0x53c8, 0xc10d, 0x7d8e, 0x0200, 0x9bab, 0x0200,
+ 0x9ba7, 0xc19d, 0x0870, 0x0011, 0xc0ec, 0x7d35, 0x5010, 0x5ac0,
+ 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, 0x9c28, 0x0870, 0x0011,
+ 0x6d07, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d1c, 0x5228,
+ 0x02b9, 0x4a00, 0x7c04, 0x6928, 0x7f0b, 0x0400, 0x9c37, 0x5206,
+ 0x7e10, 0x6a0b, 0x6928, 0x7f04, 0x0000, 0x2504, 0x7d0c, 0x9c37,
+ 0x0007, 0x680c, 0x680c, 0x6207, 0x6a07, 0x6a2b, 0x6a28, 0x0007,
+ 0x680c, 0x0007, 0x0454, 0x6928, 0x7ff3, 0x5010, 0x52c0, 0xc10d,
+ 0x7dcf, 0x0200, 0x9c28, 0x0200, 0x9c24, 0x0870, 0x0011, 0x5010,
+ 0xc0ec, 0x7d7c, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02,
+ 0x0200, 0x9c63, 0x6ed3, 0x6dc5, 0x0dff, 0x0511, 0x1dff, 0x05bc,
+ 0x5df8, 0x4d00, 0x7d60, 0x0b70, 0x0311, 0x522b, 0x5313, 0x02b9,
+ 0x4a00, 0x7c02, 0x0400, 0x9c73, 0x008f, 0x00d5, 0x7d01, 0x008d,
+ 0x05a0, 0x5ddb, 0x0d03, 0x0512, 0x05bc, 0x0510, 0x5dd3, 0x4d00,
+ 0x7d2c, 0x4d02, 0x7d24, 0x4d01, 0x7d1e, 0x59e3, 0x0b70, 0x0311,
+ 0x53eb, 0x61c8, 0x7e2b, 0x62c8, 0x7e29, 0x65c8, 0x7e27, 0x0360,
+ 0x7d03, 0x0112, 0x0112, 0x9c9e, 0x0512, 0x0512, 0x0211, 0x02a9,
+ 0x02ad, 0x6ac8, 0x7f1b, 0x2003, 0x4800, 0x7ceb, 0x0b70, 0x0311,
+ 0x5313, 0x51e3, 0x9cbb, 0x7802, 0x62c8, 0x6ac8, 0x9cba, 0x6dce,
+ 0x0015, 0x7802, 0x62c8, 0x6ac8, 0x9cba, 0x6dcf, 0x0015, 0x0015,
+ 0x7801, 0x62d8, 0x7c03, 0x0000, 0x55db, 0x9c71, 0x0007, 0x68ff,
+ 0x55d3, 0x4d00, 0x7d03, 0x4d02, 0x7d02, 0x9cc8, 0x0017, 0x0017,
+ 0x55db, 0x009d, 0x55fb, 0x05a0, 0x08ff, 0x0011, 0x18ff, 0x0010,
+ 0x04b8, 0x04ad, 0x0454, 0x62c8, 0x7ee9, 0x0870, 0x0011, 0x5010,
+ 0x52c0, 0x53c8, 0xc10d, 0x7d87, 0x0200, 0x9c63, 0x0200, 0x9c60,
+ 0xc19d, 0x0870, 0x0011, 0xc0ec, 0x7d7c, 0x5010, 0x5ac0, 0x5bc8,
+ 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, 0x9ce7, 0x6dc5, 0x0d03,
+ 0x0512, 0x05bc, 0x0510, 0x5dd0, 0x0dff, 0x0511, 0x1dff, 0x05bc,
+ 0x5df8, 0x4d00, 0x7d5d, 0x0a70, 0x0211, 0x532a, 0x5212, 0x03b9,
+ 0x4b00, 0x7c02, 0x0400, 0x9cfb, 0x008f, 0x05d8, 0x7d01, 0x008d,
+ 0x05a0, 0x5dda, 0x55d2, 0x4d00, 0x7d2c, 0x4d02, 0x7d24, 0x4d01,
+ 0x7d1e, 0x59e2, 0x0a70, 0x0211, 0x52ea, 0x61c8, 0x7e2c, 0x63c8,
+ 0x7e2a, 0x65c8, 0x7e28, 0x0260, 0x7d03, 0x0112, 0x0112, 0x9d22,
+ 0x0512, 0x0512, 0x0311, 0x03a9, 0x03ad, 0x5b06, 0x7f1c, 0x2003,
+ 0x4800, 0x7ceb, 0x0a70, 0x0211, 0x5212, 0x51e2, 0x9d40, 0x7802,
+ 0x63c8, 0x5b06, 0x9d3f, 0x6dce, 0x0015, 0x7802, 0x63c8, 0x5b06,
+ 0x9d3f, 0x6dcf, 0x0015, 0x0015, 0x7802, 0x63c8, 0x5b06, 0x7c03,
+ 0x55da, 0x0000, 0x9cf9, 0x0007, 0x68ff, 0x55d2, 0x4d00, 0x7d03,
+ 0x4d02, 0x7d02, 0x9d4d, 0x0017, 0x0017, 0x55da, 0x009d, 0x55fa,
+ 0x05a0, 0x08ff, 0x0011, 0x18ff, 0x0010, 0x04b8, 0x04ad, 0x0454,
+ 0x0870, 0x0011, 0x5010, 0x52c0, 0x53c8, 0xc10d, 0x7d88, 0x0200,
+ 0x9ce7, 0x0200, 0x9ce3, 0xc19d, 0x0870, 0x0011, 0xc0ec, 0x7d61,
+ 0x5010, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200,
+ 0x9d6a, 0x6d07, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00,
+ 0x7d45, 0x0a70, 0x0211, 0x532a, 0x5212, 0x03b9, 0x4b00, 0x7c04,
+ 0x6a28, 0x7f3b, 0x0400, 0x9d79, 0x008f, 0x05d8, 0x7d01, 0x008d,
+ 0x05a0, 0x0b03, 0x0312, 0x03bc, 0x0310, 0x4b00, 0x7d1c, 0x4b02,
+ 0x7d20, 0x4b01, 0x7d23, 0x0a70, 0x0211, 0x52ea, 0x5306, 0x7e25,
+ 0x0260, 0x7d02, 0x0310, 0x0312, 0x6b09, 0x7f1f, 0x0312, 0x6b09,
+ 0x7f1c, 0x0312, 0x6b09, 0x7f19, 0x2003, 0x4800, 0x7cef, 0x0a70,
+ 0x0211, 0x5212, 0x9dba, 0x0015, 0x0015, 0x7802, 0x5306, 0x6b0b,
+ 0x9db9, 0x0015, 0x7802, 0x5306, 0x6b0a, 0x9db9, 0x7802, 0x5306,
+ 0x6b09, 0x7c03, 0x6b28, 0x0000, 0x9d77, 0xc77b, 0x6928, 0x7ffd,
+ 0x0870, 0x0011, 0x5010, 0x52c0, 0x53c8, 0xc10d, 0x7da3, 0x0200,
+ 0x9d6a, 0x0200, 0x9d66, 0xc19d, 0x0870, 0x0011, 0xc0ec, 0x7d60,
+ 0x5010, 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200,
+ 0x9dd2, 0x6dd7, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00,
+ 0x7d46, 0x0a70, 0x0211, 0x532a, 0x5212, 0x03b9, 0x4b00, 0x7c02,
+ 0x0400, 0x9de1, 0x008f, 0x05d8, 0x7d01, 0x008d, 0x05a0, 0x0b03,
+ 0x0312, 0x03bc, 0x0310, 0x4b00, 0x7d28, 0x4b02, 0x7d20, 0x4b01,
+ 0x7d19, 0x6ddd, 0x0a70, 0x0211, 0x52ea, 0x5306, 0x7e27, 0x0260,
+ 0x7d02, 0x0310, 0x0312, 0x6bc8, 0x7f21, 0x0312, 0x6bc8, 0x7f1e,
+ 0x0312, 0x6bc8, 0x7f1b, 0x2003, 0x4800, 0x7cef, 0x0a70, 0x0211,
+ 0x5212, 0x9e23, 0x6ddd, 0x7802, 0x5306, 0x6bc8, 0x9e22, 0x6dde,
+ 0x0015, 0x7802, 0x5306, 0x6bc8, 0x9e22, 0x0015, 0x0015, 0x7802,
+ 0x5306, 0x6bc8, 0x7c03, 0x0000, 0xde32, 0x9ddf, 0xc777, 0x0870,
+ 0x0011, 0x5010, 0x52c0, 0x53c8, 0xc10d, 0x7da4, 0x0200, 0x9dd2,
+ 0x0200, 0x9dce, 0x63ff, 0x0368, 0x7d02, 0x0369, 0x7def, 0x0006,
+ 0x0870, 0x0011, 0x5010, 0xc0ec, 0x7d5c, 0x5ac0, 0x5bc8, 0x5ef8,
+ 0xc0fe, 0x56f8, 0x7d02, 0x0200, 0x9e3e, 0x0b70, 0x0311, 0x6ec3,
+ 0x6d07, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d3e,
+ 0x522b, 0x02b9, 0x4a00, 0x7c04, 0x6a28, 0x7f34, 0x0400, 0x9e50,
+ 0x028e, 0x1a94, 0x6ac3, 0x62c8, 0x0269, 0x7d1b, 0x1e94, 0x6ec3,
+ 0x6ed3, 0x62c8, 0x0248, 0x6ac8, 0x2694, 0x6ec3, 0x62c8, 0x026e,
+ 0x7d32, 0x6a09, 0x7f1f, 0x2501, 0x4d00, 0x7d20, 0x028e, 0x1a98,
+ 0x6ac3, 0x62c8, 0x6ec3, 0x0260, 0x7df1, 0x6a28, 0x7f13, 0xc7af,
+ 0x9e90, 0x6ee3, 0x008f, 0x2001, 0x00d5, 0x7d01, 0x008d, 0x05a0,
+ 0x62c8, 0x026e, 0x7d18, 0x6a09, 0x7f05, 0x2001, 0x7cf9, 0x6a28,
+ 0x0000, 0x9e4e, 0x0289, 0xc77b, 0x018a, 0x9e9f, 0x6a28, 0x7ffa,
+ 0x0b70, 0x0311, 0x5013, 0x52c0, 0x53c8, 0xc10d, 0x7da7, 0x0200,
+ 0x9e3e, 0x0200, 0x9e3b, 0x6a28, 0x7fed, 0xc7af, 0x9e9f, 0x0458,
+ 0x0454, 0x9e90, 0xc19d, 0x0870, 0x0011, 0xc0ec, 0x7d55, 0x5010,
+ 0x5ac0, 0x5bc8, 0x5ef8, 0xc0fe, 0x56f8, 0x7d02, 0x0200, 0x9ea9,
+ 0x0b70, 0x0311, 0x6d07, 0x5df0, 0x0dff, 0x0511, 0x1dff, 0x05bc,
+ 0x4d00, 0x7d37, 0x522b, 0x02b9, 0x4a00, 0x7c04, 0x6928, 0x7f2d,
+ 0x0400, 0x9eba, 0x028e, 0x1a94, 0x5202, 0x0269, 0x7d16, 0x1e94,
+ 0x5206, 0x0248, 0x5a06, 0x2694, 0x5206, 0x026e, 0x7d2f, 0x6a09,
+ 0x7f1c, 0x2501, 0x4d00, 0x7d1d, 0x028e, 0x1a98, 0x5202, 0x0260,
+ 0x7df3, 0x6a28, 0x7f12, 0xc7af, 0x9ef3, 0x008f, 0x2001, 0x00d5,
+ 0x7d01, 0x008d, 0x05a0, 0x5206, 0x026e, 0x7d18, 0x6a09, 0x7f05,
+ 0x2001, 0x7cf9, 0x6a28, 0x0000, 0x9eb8, 0x0289, 0xc77b, 0x018a,
+ 0x9f02, 0x6928, 0x7ffa, 0x0b70, 0x0311, 0x5013, 0x52c0, 0x53c8,
+ 0xc10d, 0x7daf, 0x0200, 0x9ea9, 0x0200, 0x9ea5, 0x6a28, 0x7fed,
+ 0xc7af, 0x9f02, 0x0458, 0x0454, 0x9ef3
+};
+#endif
diff --git a/arch/arm/mach-mx3/serial.c b/arch/arm/mach-mx3/serial.c
new file mode 100644
index 000000000000..fca1b5b8a38f
--- /dev/null
+++ b/arch/arm/mach-mx3/serial.c
@@ -0,0 +1,267 @@
+/*
+ * Copyright 2006-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/*!
+ * @file mach-mx3/serial.c
+ *
+ * @brief This file contains the UART initiliazation.
+ *
+ * @ingroup MSL_MX31
+ */
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <mach/hardware.h>
+#include <mach/mxc_uart.h>
+#include <mach/spba.h>
+#include "serial.h"
+#include "board-mx31ads.h"
+#include "board-mx3_3stack.h"
+
+#if defined(CONFIG_SERIAL_MXC) || defined(CONFIG_SERIAL_MXC_MODULE)
+
+/*!
+ * This is an array where each element holds information about a UART port,
+ * like base address of the UART, interrupt numbers etc. This structure is
+ * passed to the serial_core.c file. Based on which UART is used, the core file
+ * passes back the appropriate port structure as an argument to the control
+ * functions.
+ */
+static uart_mxc_port mxc_ports[MXC_UART_NR] = {
+ [0] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART1_BASE_ADDR),
+ .mapbase = UART1_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART1_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 0,
+ },
+ .ints_muxed = UART1_MUX_INTS,
+ .irqs = {UART1_INT2, UART1_INT3},
+ .mode = UART1_MODE,
+ .ir_mode = UART1_IR,
+ .enabled = UART1_ENABLED,
+ .hardware_flow = UART1_HW_FLOW,
+ .cts_threshold = UART1_UCR4_CTSTL,
+ .dma_enabled = UART1_DMA_ENABLE,
+ .dma_rxbuf_size = UART1_DMA_RXBUFSIZE,
+ .rx_threshold = UART1_UFCR_RXTL,
+ .tx_threshold = UART1_UFCR_TXTL,
+ .shared = UART1_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART1_TX,
+ .dma_rx_id = MXC_DMA_UART1_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ .ir_tx_inv = MXC_IRDA_TX_INV,
+ .ir_rx_inv = MXC_IRDA_RX_INV,
+ },
+ [1] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART2_BASE_ADDR),
+ .mapbase = UART2_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART2_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 1,
+ },
+ .ints_muxed = UART2_MUX_INTS,
+ .irqs = {UART2_INT2, UART2_INT3},
+ .mode = UART2_MODE,
+ .ir_mode = UART2_IR,
+ .enabled = UART2_ENABLED,
+ .hardware_flow = UART2_HW_FLOW,
+ .cts_threshold = UART2_UCR4_CTSTL,
+ .dma_enabled = UART2_DMA_ENABLE,
+ .dma_rxbuf_size = UART2_DMA_RXBUFSIZE,
+ .rx_threshold = UART2_UFCR_RXTL,
+ .tx_threshold = UART2_UFCR_TXTL,
+ .shared = UART2_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART2_TX,
+ .dma_rx_id = MXC_DMA_UART2_RX,
+ .rxd_mux = MXC_UART_IR_RXDMUX,
+ .ir_tx_inv = MXC_IRDA_TX_INV,
+ .ir_rx_inv = MXC_IRDA_RX_INV,
+ },
+#if UART3_ENABLED == 1
+ [2] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART3_BASE_ADDR),
+ .mapbase = UART3_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART3_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 2,
+ },
+ .ints_muxed = UART3_MUX_INTS,
+ .irqs = {UART3_INT2, UART3_INT3},
+ .mode = UART3_MODE,
+ .ir_mode = UART3_IR,
+ .enabled = UART3_ENABLED,
+ .hardware_flow = UART3_HW_FLOW,
+ .cts_threshold = UART3_UCR4_CTSTL,
+ .dma_enabled = UART3_DMA_ENABLE,
+ .dma_rxbuf_size = UART3_DMA_RXBUFSIZE,
+ .rx_threshold = UART3_UFCR_RXTL,
+ .tx_threshold = UART3_UFCR_TXTL,
+ .shared = UART3_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART3_TX,
+ .dma_rx_id = MXC_DMA_UART3_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ .ir_tx_inv = MXC_IRDA_TX_INV,
+ .ir_rx_inv = MXC_IRDA_RX_INV,
+ },
+#endif
+#if UART4_ENABLED == 1
+ [3] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART4_BASE_ADDR),
+ .mapbase = UART4_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART4_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 3,
+ },
+ .ints_muxed = UART4_MUX_INTS,
+ .irqs = {UART4_INT2, UART4_INT3},
+ .mode = UART4_MODE,
+ .ir_mode = UART4_IR,
+ .enabled = UART4_ENABLED,
+ .hardware_flow = UART4_HW_FLOW,
+ .cts_threshold = UART4_UCR4_CTSTL,
+ .dma_enabled = UART4_DMA_ENABLE,
+ .dma_rxbuf_size = UART4_DMA_RXBUFSIZE,
+ .rx_threshold = UART4_UFCR_RXTL,
+ .tx_threshold = UART4_UFCR_TXTL,
+ .shared = UART4_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART4_TX,
+ .dma_rx_id = MXC_DMA_UART4_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ .ir_tx_inv = MXC_IRDA_TX_INV,
+ .ir_rx_inv = MXC_IRDA_RX_INV,
+ },
+#endif
+#if UART5_ENABLED == 1
+ [4] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART5_BASE_ADDR),
+ .mapbase = UART5_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART5_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 4,
+ },
+ .ints_muxed = UART5_MUX_INTS,
+ .irqs = {UART5_INT2, UART5_INT3},
+ .mode = UART5_MODE,
+ .ir_mode = UART5_IR,
+ .enabled = UART5_ENABLED,
+ .hardware_flow = UART5_HW_FLOW,
+ .cts_threshold = UART5_UCR4_CTSTL,
+ .dma_enabled = UART5_DMA_ENABLE,
+ .dma_rxbuf_size = UART5_DMA_RXBUFSIZE,
+ .rx_threshold = UART5_UFCR_RXTL,
+ .tx_threshold = UART5_UFCR_TXTL,
+ .shared = UART5_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART5_TX,
+ .dma_rx_id = MXC_DMA_UART5_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ .ir_tx_inv = MXC_IRDA_TX_INV,
+ .ir_rx_inv = MXC_IRDA_RX_INV,
+ },
+#endif
+};
+
+static struct platform_device mxc_uart_device1 = {
+ .name = "mxcintuart",
+ .id = 0,
+ .dev = {
+ .platform_data = &mxc_ports[0],
+ },
+};
+
+static struct platform_device mxc_uart_device2 = {
+ .name = "mxcintuart",
+ .id = 1,
+ .dev = {
+ .platform_data = &mxc_ports[1],
+ },
+};
+
+#if UART3_ENABLED == 1
+static struct platform_device mxc_uart_device3 = {
+ .name = "mxcintuart",
+ .id = 2,
+ .dev = {
+ .platform_data = &mxc_ports[2],
+ },
+};
+#endif
+
+#if UART4_ENABLED == 1
+static struct platform_device mxc_uart_device4 = {
+ .name = "mxcintuart",
+ .id = 3,
+ .dev = {
+ .platform_data = &mxc_ports[3],
+ },
+};
+#endif
+
+#if UART5_ENABLED == 1
+static struct platform_device mxc_uart_device5 = {
+ .name = "mxcintuart",
+ .id = 4,
+ .dev = {
+ .platform_data = &mxc_ports[4],
+ },
+};
+#endif
+
+static int __init mxc_init_uart(void)
+{
+ /* Register all the MXC UART platform device structures */
+ platform_device_register(&mxc_uart_device1);
+ platform_device_register(&mxc_uart_device2);
+
+ /* Grab ownership of shared UARTs 3 and 4, only when enabled */
+#if UART3_ENABLED == 1
+#if UART3_DMA_ENABLE == 1
+ spba_take_ownership(UART3_SHARED_PERI, (SPBA_MASTER_A | SPBA_MASTER_C));
+#else
+ spba_take_ownership(UART3_SHARED_PERI, SPBA_MASTER_A);
+#endif /* UART3_DMA_ENABLE */
+ platform_device_register(&mxc_uart_device3);
+#endif /* UART3_ENABLED */
+
+#if UART4_ENABLED == 1
+ platform_device_register(&mxc_uart_device4);
+#endif /* UART4_ENABLED */
+
+#if UART5_ENABLED == 1
+ platform_device_register(&mxc_uart_device5);
+#endif /* UART5_ENABLED */
+ return 0;
+}
+
+#else
+static int __init mxc_init_uart(void)
+{
+ return 0;
+}
+#endif
+
+arch_initcall(mxc_init_uart);
diff --git a/arch/arm/mach-mx3/serial.h b/arch/arm/mach-mx3/serial.h
new file mode 100644
index 000000000000..03cce3bf5f24
--- /dev/null
+++ b/arch/arm/mach-mx3/serial.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ARCH_ARM_MACH_MX3_SERIAL_H__
+#define __ARCH_ARM_MACH_MX3_SERIAL_H__
+
+/*!
+ * @file mach-mx3/serial.h
+ *
+ * @ingroup MSL_MX31
+ */
+#include <mach/mxc_uart.h>
+
+/* UART 1 configuration */
+/*!
+ * This option allows to choose either an interrupt-driven software controlled
+ * hardware flow control (set this option to 0) or hardware-driven hardware
+ * flow control (set this option to 1).
+ */
+/* UART used as wakeup source */
+#define UART1_HW_FLOW 0
+/*!
+ * This specifies the threshold at which the CTS pin is deasserted by the
+ * RXFIFO. Set this value in Decimal to anything from 0 to 32 for
+ * hardware-driven hardware flow control. Read the HW spec while specifying
+ * this value. When using interrupt-driven software controlled hardware
+ * flow control set this option to -1.
+ */
+#define UART1_UCR4_CTSTL 16
+/*!
+ * This is option to enable (set this option to 1) or disable DMA data transfer
+ */
+#define UART1_DMA_ENABLE 0
+/*!
+ * Specify the size of the DMA receive buffer. The minimum buffer size is 512
+ * bytes. The buffer size should be a multiple of 256.
+ */
+#define UART1_DMA_RXBUFSIZE 1024
+/*!
+ * Specify the MXC UART's Receive Trigger Level. This controls the threshold at
+ * which a maskable interrupt is generated by the RxFIFO. Set this value in
+ * Decimal to anything from 0 to 32. Read the HW spec while specifying this
+ * value.
+ */
+#define UART1_UFCR_RXTL 16
+/*!
+ * Specify the MXC UART's Transmit Trigger Level. This controls the threshold at
+ * which a maskable interrupt is generated by the TxFIFO. Set this value in
+ * Decimal to anything from 0 to 32. Read the HW spec while specifying this
+ * value.
+ */
+#define UART1_UFCR_TXTL 16
+/* UART 2 configuration */
+#define UART2_HW_FLOW 0
+#define UART2_UCR4_CTSTL -1
+#define UART2_DMA_ENABLE 0
+#define UART2_DMA_RXBUFSIZE 512
+#define UART2_UFCR_RXTL 16
+#define UART2_UFCR_TXTL 16
+/* UART 3 configuration */
+#define UART3_HW_FLOW 1
+#define UART3_UCR4_CTSTL 16
+#define UART3_DMA_ENABLE 1
+#define UART3_DMA_RXBUFSIZE 1024
+#define UART3_UFCR_RXTL 16
+#define UART3_UFCR_TXTL 16
+/* UART 4 configuration */
+#define UART4_HW_FLOW 1
+#define UART4_UCR4_CTSTL 16
+#define UART4_DMA_ENABLE 0
+#define UART4_DMA_RXBUFSIZE 512
+#define UART4_UFCR_RXTL 16
+#define UART4_UFCR_TXTL 16
+/* UART 5 configuration */
+#define UART5_HW_FLOW 1
+#define UART5_UCR4_CTSTL 16
+#define UART5_DMA_ENABLE 0
+#define UART5_DMA_RXBUFSIZE 512
+#define UART5_UFCR_RXTL 16
+#define UART5_UFCR_TXTL 16
+/*
+ * UART Chip level Configuration that a user may not have to edit. These
+ * configuration vary depending on how the UART module is integrated with
+ * the ARM core
+ */
+/*
+ * Is the MUXED interrupt output sent to the ARM core
+ */
+#define INTS_NOTMUXED 0
+#define INTS_MUXED 1
+/* UART 1 configuration */
+/*!
+ * This define specifies whether the muxed ANDed interrupt line or the
+ * individual interrupts from the UART port is integrated with the ARM core.
+ * There exists a define like this for each UART port. Valid values that can
+ * be used are \b INTS_NOTMUXED or \b INTS_MUXED.
+ */
+#define UART1_MUX_INTS INTS_MUXED
+/*!
+ * This define specifies the transmitter interrupt number or the interrupt
+ * number of the ANDed interrupt in case the interrupts are muxed. There exists
+ * a define like this for each UART port.
+ */
+#define UART1_INT1 MXC_INT_UART1
+/*!
+ * This define specifies the receiver interrupt number. If the interrupts of
+ * the UART are muxed, then we specify here a dummy value -1. There exists a
+ * define like this for each UART port.
+ */
+#define UART1_INT2 -1
+/*!
+ * This specifies the master interrupt number. If the interrupts of the UART
+ * are muxed, then we specify here a dummy value of -1. There exists a define
+ * like this for each UART port.
+ */
+#define UART1_INT3 -1
+/*!
+ * This specifies if the UART is a shared peripheral. It holds the shared
+ * peripheral number if it is shared or -1 if it is not shared. There exists
+ * a define like this for each UART port.
+ */
+#define UART1_SHARED_PERI -1
+/* UART 2 configuration */
+#define UART2_MUX_INTS INTS_MUXED
+#define UART2_INT1 MXC_INT_UART2
+#define UART2_INT2 -1
+#define UART2_INT3 -1
+#define UART2_SHARED_PERI -1
+/* UART 3 configuration */
+#define UART3_MUX_INTS INTS_MUXED
+#define UART3_INT1 MXC_INT_UART3
+#define UART3_INT2 -1
+#define UART3_INT3 -1
+#define UART3_SHARED_PERI SPBA_UART3
+/* UART 4 configuration */
+#define UART4_MUX_INTS INTS_MUXED
+#define UART4_INT1 MXC_INT_UART4
+#define UART4_INT2 -1
+#define UART4_INT3 -1
+#define UART4_SHARED_PERI -1
+/* UART 5 configuration */
+#define UART5_MUX_INTS INTS_MUXED
+#define UART5_INT1 MXC_INT_UART5
+#define UART5_INT2 -1
+#define UART5_INT3 -1
+#define UART5_SHARED_PERI -1
+
+#endif /* __ARCH_ARM_MACH_MX3_SERIAL_H__ */
diff --git a/arch/arm/mach-mx3/system.c b/arch/arm/mach-mx3/system.c
new file mode 100644
index 000000000000..932bf99322d9
--- /dev/null
+++ b/arch/arm/mach-mx3/system.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2004-2009 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
+ */
+
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+#include <mach/clock.h>
+#include "crm_regs.h"
+
+/*!
+ * @defgroup MSL_MX31 i.MX31 Machine Specific Layer (MSL)
+ */
+
+/*!
+ * @file mach-mx3/system.c
+ * @brief This file contains idle and reset functions.
+ *
+ * @ingroup MSL_MX31
+ */
+
+static int clks_initialized = 0;
+static struct clk *sdma_clk, *mbx_clk, *ipu_clk, *mpeg_clk, *vpu_clk, *usb_clk,
+ *rtic_clk, *nfc_clk, *emi_clk;
+
+extern int mxc_jtag_enabled;
+
+/*!
+ * This function puts the CPU into idle mode. It is called by default_idle()
+ * in process.c file.
+ */
+void arch_idle(void)
+{
+ int emi_gated_off = 0;
+
+ /*
+ * This should do all the clock switching
+ * and wait for interrupt tricks.
+ */
+ if (!mxc_jtag_enabled) {
+ if (clks_initialized == 0) {
+ clks_initialized = 1;
+ sdma_clk = clk_get(NULL, "sdma_ahb_clk");
+ ipu_clk = clk_get(NULL, "ipu_clk");
+ if (cpu_is_mx31()) {
+ mpeg_clk = clk_get(NULL, "mpeg4_clk");
+ mbx_clk = clk_get(NULL, "mbx_clk");
+ } else {
+ vpu_clk = clk_get(NULL, "vpu_clk");
+ }
+ usb_clk = clk_get(NULL, "usb_ahb_clk");
+ rtic_clk = clk_get(NULL, "rtic_clk");
+ nfc_clk = clk_get(NULL, "nfc_clk");
+ emi_clk = clk_get(NULL, "emi_clk");
+ }
+
+ if ((clk_get_usecount(sdma_clk) == 0)
+ && (clk_get_usecount(ipu_clk) <= 1)
+ && (clk_get_usecount(usb_clk) == 0)
+ && (clk_get_usecount(rtic_clk) == 0)
+ && (clk_get_usecount(mpeg_clk) == 0)
+ && (clk_get_usecount(mbx_clk) == 0)
+ && (clk_get_usecount(nfc_clk) == 0)
+ && (clk_get_usecount(vpu_clk) == 0)) {
+ emi_gated_off = 1;
+ clk_disable(emi_clk);
+ }
+
+ cpu_do_idle();
+ if (emi_gated_off == 1) {
+ clk_enable(emi_clk);
+ }
+ }
+}
+
+/*
+ * This function resets the system. It is called by machine_restart().
+ *
+ * @param mode indicates different kinds of resets
+ */
+void arch_reset(char mode)
+{
+ /* Assert SRS signal */
+ mxc_wd_reset();
+}
diff --git a/arch/arm/mach-mx3/usb.h b/arch/arm/mach-mx3/usb.h
new file mode 100644
index 000000000000..d272195f2bc0
--- /dev/null
+++ b/arch/arm/mach-mx3/usb.h
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2005-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+
+extern int usbotg_init(struct platform_device *pdev);
+extern void usbotg_uninit(struct fsl_usb2_platform_data *pdata);
+extern int gpio_usbotg_fs_active(void);
+extern void gpio_usbotg_fs_inactive(void);
+extern int gpio_usbotg_hs_active(void);
+extern void gpio_usbotg_hs_inactive(void);
+extern struct platform_device *host_pdev_register(struct resource *res,
+ int n_res, struct fsl_usb2_platform_data *config);
+
+extern int fsl_usb_host_init(struct platform_device *pdev);
+extern void fsl_usb_host_uninit(struct fsl_usb2_platform_data *pdata);
+extern int gpio_usbh1_active(void);
+extern void gpio_usbh1_inactive(void);
+extern int gpio_usbh2_active(void);
+extern void gpio_usbh2_inactive(void);
+
+/*
+ * Determine which platform_data struct to use for the DR controller,
+ * based on which transceiver is configured.
+ * PDATA is a pointer to it.
+ */
+#if defined(CONFIG_ISP1504_MXC)
+static struct fsl_usb2_platform_data __maybe_unused dr_1504_config;
+#define PDATA (&dr_1504_config)
+#elif defined(CONFIG_ISP1301_MXC)
+static struct fsl_usb2_platform_data __maybe_unused dr_1301_config;
+#define PDATA (&dr_1301_config)
+#elif defined(CONFIG_MC13783_MXC)
+static struct fsl_usb2_platform_data __maybe_unused dr_13783_config;
+#define PDATA (&dr_13783_config)
+#endif
+
+
+/*
+ * Used to set pdata->operating_mode before registering the platform_device.
+ * If OTG is configured, the controller operates in OTG mode,
+ * otherwise it's either host or device.
+ */
+#ifdef CONFIG_USB_OTG
+#define DR_UDC_MODE FSL_USB2_DR_OTG
+#define DR_HOST_MODE FSL_USB2_DR_OTG
+#else
+#define DR_UDC_MODE FSL_USB2_DR_DEVICE
+#define DR_HOST_MODE FSL_USB2_DR_HOST
+#endif
+
+
+#ifdef CONFIG_USB_EHCI_ARC_OTG
+static inline void dr_register_host(struct resource *r, int rs)
+{
+ PDATA->operating_mode = DR_HOST_MODE;
+ host_pdev_register(r, rs, PDATA);
+}
+#else
+static inline void dr_register_host(struct resource *r, int rs)
+{
+}
+#endif
+
+#ifdef CONFIG_USB_GADGET_ARC
+static struct platform_device dr_udc_device;
+
+static inline void dr_register_udc(void)
+{
+ PDATA->operating_mode = DR_UDC_MODE;
+ dr_udc_device.dev.platform_data = PDATA;
+
+ if (platform_device_register(&dr_udc_device))
+ printk(KERN_ERR "usb: can't register DR gadget\n");
+ else
+ printk(KERN_INFO "usb: DR gadget (%s) registered\n",
+ PDATA->transceiver);
+}
+#else
+static inline void dr_register_udc(void)
+{
+}
+#endif
+
+#ifdef CONFIG_USB_OTG
+static struct platform_device dr_otg_device;
+
+/*
+ * set the proper operating_mode and
+ * platform_data pointer, then register the
+ * device.
+ */
+static inline void dr_register_otg(void)
+{
+ PDATA->operating_mode = FSL_USB2_DR_OTG;
+ dr_otg_device.dev.platform_data = PDATA;
+
+ if (platform_device_register(&dr_otg_device))
+ printk(KERN_ERR "usb: can't register otg device\n");
+ else
+ printk(KERN_INFO "usb: DR OTG registered\n");
+}
+#else
+static inline void dr_register_otg(void)
+{
+}
+#endif
diff --git a/arch/arm/mach-mx3/usb_dr.c b/arch/arm/mach-mx3/usb_dr.c
new file mode 100644
index 000000000000..b745428dce87
--- /dev/null
+++ b/arch/arm/mach-mx3/usb_dr.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <mach/arc_otg.h>
+#include "usb.h"
+
+/*
+ * platform data structs
+ * - Which one to use is determined by CONFIG options in usb.h
+ * - operating_mode plugged at run time
+ */
+static struct fsl_usb2_platform_data __maybe_unused dr_13783_config = {
+ .name = "DR",
+ .platform_init = usbotg_init,
+ .platform_uninit = usbotg_uninit,
+ .phy_mode = FSL_USB2_PHY_SERIAL,
+ .power_budget = 500, /* 500 mA max power */
+ .gpio_usb_active = gpio_usbotg_fs_active,
+ .gpio_usb_inactive = gpio_usbotg_fs_inactive,
+ .transceiver = "mc13783",
+};
+
+static struct fsl_usb2_platform_data __maybe_unused dr_1301_config = {
+ .name = "DR",
+ .platform_init = usbotg_init,
+ .platform_uninit = usbotg_uninit,
+ .phy_mode = FSL_USB2_PHY_SERIAL,
+ .power_budget = 150, /* 150 mA max power */
+ .gpio_usb_active = gpio_usbotg_fs_active,
+ .gpio_usb_inactive = gpio_usbotg_fs_inactive,
+ .transceiver = "isp1301",
+};
+
+static struct fsl_usb2_platform_data __maybe_unused dr_1504_config = {
+ .name = "DR",
+ .platform_init = usbotg_init,
+ .platform_uninit = usbotg_uninit,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+ .power_budget = 150, /* 150 mA max power */
+ .gpio_usb_active = gpio_usbotg_hs_active,
+ .gpio_usb_inactive = gpio_usbotg_hs_inactive,
+ .transceiver = "isp1504",
+};
+
+
+/*
+ * resources
+ */
+static struct resource otg_resources[] = {
+ [0] = {
+ .start = (u32)(USB_OTGREGS_BASE),
+ .end = (u32)(USB_OTGREGS_BASE + 0x1ff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_USB3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+static u64 dr_udc_dmamask = ~(u32) 0;
+static void dr_udc_release(struct device *dev)
+{
+}
+
+static u64 dr_otg_dmamask = ~(u32) 0;
+static void dr_otg_release(struct device *dev)
+{
+}
+
+/*
+ * platform device structs
+ * dev.platform_data field plugged at run time
+ */
+static struct platform_device __maybe_unused dr_udc_device = {
+ .name = "fsl-usb2-udc",
+ .id = -1,
+ .dev = {
+ .release = dr_udc_release,
+ .dma_mask = &dr_udc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .resource = otg_resources,
+ .num_resources = ARRAY_SIZE(otg_resources),
+};
+
+static struct platform_device __maybe_unused dr_otg_device = {
+ .name = "fsl-usb2-otg",
+ .id = -1,
+ .dev = {
+ .release = dr_otg_release,
+ .dma_mask = &dr_otg_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .resource = otg_resources,
+ .num_resources = ARRAY_SIZE(otg_resources),
+};
+
+static int __init usb_dr_init(void)
+{
+ pr_debug("%s: \n", __func__);
+
+ dr_register_otg();
+ dr_register_host(otg_resources, ARRAY_SIZE(otg_resources));
+ dr_register_udc();
+
+ return 0;
+}
+
+module_init(usb_dr_init);
diff --git a/arch/arm/mach-mx3/usb_h1.c b/arch/arm/mach-mx3/usb_h1.c
new file mode 100644
index 000000000000..5c6c9c59fb3b
--- /dev/null
+++ b/arch/arm/mach-mx3/usb_h1.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <mach/arc_otg.h>
+#include "usb.h"
+
+static struct fsl_usb2_platform_data usbh1_config = {
+ .name = "Host 1",
+ .platform_init = fsl_usb_host_init,
+ .platform_uninit = fsl_usb_host_uninit,
+ .operating_mode = FSL_USB2_MPH_HOST,
+ .phy_mode = FSL_USB2_PHY_SERIAL,
+ .power_budget = 500, /* 500 mA max power */
+ .gpio_usb_active = gpio_usbh1_active,
+ .gpio_usb_inactive = gpio_usbh1_inactive,
+ .transceiver = "serial",
+};
+
+static struct resource usbh1_resources[] = {
+ [0] = {
+ .start = (u32) (USB_H1REGS_BASE),
+ .end = (u32) (USB_H1REGS_BASE + 0x1ff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_USB1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static int __init usbh1_init(void)
+{
+ pr_debug("%s: \n", __func__);
+
+ host_pdev_register(usbh1_resources, ARRAY_SIZE(usbh1_resources),
+ &usbh1_config);
+ return 0;
+}
+module_init(usbh1_init);
diff --git a/arch/arm/mach-mx3/usb_h2.c b/arch/arm/mach-mx3/usb_h2.c
new file mode 100644
index 000000000000..c5689d5ab2a5
--- /dev/null
+++ b/arch/arm/mach-mx3/usb_h2.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/usb/fsl_xcvr.h>
+#include <linux/regulator/regulator.h>
+#include <mach/arc_otg.h>
+#include "usb.h"
+
+static struct fsl_usb2_platform_data usbh2_config = {
+ .name = "Host 2",
+ .platform_init = fsl_usb_host_init,
+ .platform_uninit = fsl_usb_host_uninit,
+ .operating_mode = FSL_USB2_MPH_HOST,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+ .power_budget = 500, /* 500 mA max power */
+ .gpio_usb_active = gpio_usbh2_active,
+ .gpio_usb_inactive = gpio_usbh2_inactive,
+ .transceiver = "isp1504",
+};
+
+static struct resource usbh2_resources[] = {
+ [0] = {
+ .start = (u32) (USB_H2REGS_BASE),
+ .end = (u32) (USB_H2REGS_BASE + 0x1ff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_USB2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+void usbh2_get_xcvr_power(struct device *dev)
+{
+ struct regulator *usbh2_regux;
+
+ usbh2_regux = regulator_get(dev, "GPO1");
+ regulator_enable(usbh2_regux);
+ ((struct fsl_usb2_platform_data *)dev->platform_data)->
+ xcvr_pwr->regu1 = usbh2_regux;
+
+ usbh2_regux = regulator_get(dev, "GPO3");
+ regulator_enable(usbh2_regux);
+ ((struct fsl_usb2_platform_data *)dev->platform_data)->
+ xcvr_pwr->regu2 = usbh2_regux;
+}
+EXPORT_SYMBOL(usbh2_get_xcvr_power);
+
+void usbh2_put_xcvr_power(struct device *dev)
+{
+ struct regulator *usbh2_regux;
+
+ usbh2_regux = ((struct fsl_usb2_platform_data *)dev->
+ platform_data)->xcvr_pwr->regu2;
+ regulator_disable(usbh2_regux);
+ regulator_put(usbh2_regux, dev);
+
+ usbh2_regux = ((struct fsl_usb2_platform_data *)dev->
+ platform_data)->xcvr_pwr->regu1;
+ regulator_disable(usbh2_regux);
+ regulator_put(usbh2_regux, dev);
+}
+EXPORT_SYMBOL(usbh2_put_xcvr_power);
+
+
+static int __init usbh2_init(void)
+{
+ pr_debug("%s: \n", __func__);
+
+ host_pdev_register(usbh2_resources, ARRAY_SIZE(usbh2_resources),
+ &usbh2_config);
+ return 0;
+}
+module_init(usbh2_init);
diff --git a/arch/arm/mach-mx35/Kconfig b/arch/arm/mach-mx35/Kconfig
new file mode 100644
index 000000000000..78a2dae58500
--- /dev/null
+++ b/arch/arm/mach-mx35/Kconfig
@@ -0,0 +1,106 @@
+menu "MX35 Options"
+ depends on ARCH_MX35
+
+config MX35_OPTIONS
+ bool
+ default y
+ select CPU_V6
+ select ARM_ERRATA_364296
+ select ARM_ERRATA_411920
+ select CACHE_L2X0
+ select OUTER_CACHE
+ select USB_ARCH_HAS_EHCI
+ select ARCH_HAS_EVTMON
+
+config MACH_MX35_3DS
+ bool "Support MX35 3STACK platforms"
+ default y
+ select MXC_PSEUDO_IRQS if MXC_PMIC_MC9SDZ60
+ help
+ Include support for MX35 3STACK platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX35EVB
+ bool "Support MX35EVB platforms"
+ default n
+ help
+ Include support for MX35EVB platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MX35_DOZE_DURING_IDLE
+ bool "Enter Doze mode during idle"
+ help
+ Turning on this option will put the CPU into Doze mode during idle.
+ The default is to enter Wait mode during idle. Doze mode during
+ idle will save additional power over Wait mode.
+
+config MXC_SDMA_API
+ bool "Use SDMA API"
+ default y
+ help
+ This selects the Freescale MXC SDMA API.
+ If unsure, say N.
+
+menu "SDMA options"
+ depends on MXC_SDMA_API
+
+config SDMA_IRAM
+ bool "Use Internal RAM for SDMA transfer"
+ default n
+ help
+ Support Internal RAM as SDMA buffer or control structures
+
+config SDMA_IRAM_SIZE
+ hex "Reserved bytes of IRAM for SDMA (0x800-0x1000)"
+ range 0x800 0x1000
+ depends on SDMA_IRAM
+ default "0x1000"
+ help
+ Set the size of IRAM for SDMA. It must be a multiple of 512bytes.
+endmenu
+
+config ARCH_MXC_HAS_NFC_V2
+ bool "MXC NFC Hardware Version 2"
+ depends on ARCH_MX35
+ default y
+ help
+ This selects the Freescale MXC Nand Flash Controller Hardware Version 3
+ If unsure, say N.
+
+config ARCH_MXC_HAS_NFC_V2_1
+ bool "MXC NFC Hardware Version 2.1"
+ depends on ARCH_MXC_HAS_NFC_V2
+ default y
+ help
+ This selects the Freescale MXC Nand Flash Controller Hardware Version 2.1
+ If unsure, say N.
+
+menu "Device options"
+
+config I2C_MXC_SELECT1
+ bool "Enable I2C1 module"
+ default y
+ depends on I2C_MXC
+ help
+ Enable MX35 I2C1 module.
+
+config I2C_MXC_SELECT2
+ bool "Enable I2C2 module"
+ default n
+ depends on I2C_MXC
+ help
+ Enable MX35 I2C2 module.
+
+config I2C_MXC_SELECT3
+ bool "Enable I2C3 module"
+ default n
+ depends on I2C_MXC
+ help
+ Enable MX35 I2C3 module.
+
+endmenu
+
+config MXC_PSEUDO_IRQS
+ bool
+
+endmenu
diff --git a/arch/arm/mach-mx35/Makefile b/arch/arm/mach-mx35/Makefile
new file mode 100644
index 000000000000..0eb7df59c476
--- /dev/null
+++ b/arch/arm/mach-mx35/Makefile
@@ -0,0 +1,20 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := system.o iomux.o cpu.o mm.o clock.o devices.o serial.o
+obj-$(CONFIG_MXC_SDMA_API) += dma.o
+obj-$(CONFIG_MACH_MX35_3DS) += mx35_3stack.o mx35_3stack_gpio.o mx35_3stack_cpld.o dvfs.o
+obj-$(CONFIG_MACH_MX35EVB) += mx35evb.o mx35evb_cpld.o mx35evb_gpio.o
+
+obj-$(CONFIG_MXC_PSEUDO_IRQS) += mx35_3stack_irq.o
+obj-$(CONFIG_PM) += pm.o
+
+obj-$(CONFIG_USB_EHCI_ARC_H2) += usb_h2.o
+
+ifneq ($(strip $(CONFIG_USB_GADGET_ARC) $(CONFIG_USB_EHCI_ARC_OTG)),)
+ obj-y += usb_dr.o
+endif
+
diff --git a/arch/arm/mach-mx35/Makefile.boot b/arch/arm/mach-mx35/Makefile.boot
new file mode 100644
index 000000000000..198d92d5e463
--- /dev/null
+++ b/arch/arm/mach-mx35/Makefile.boot
@@ -0,0 +1,9 @@
+ifeq ($(CONFIG_MACH_MX35EVB), y)
+ zreladdr-y := 0x90008000
+params_phys-y := 0x90000100
+initrd_phys-y := 0x90800000
+else
+ zreladdr-y := 0x80008000
+params_phys-y := 0x80000100
+initrd_phys-y := 0x80800000
+endif
diff --git a/arch/arm/mach-mx35/board-mx35_3stack.h b/arch/arm/mach-mx35/board-mx35_3stack.h
new file mode 100644
index 000000000000..ee7d13902122
--- /dev/null
+++ b/arch/arm/mach-mx35/board-mx35_3stack.h
@@ -0,0 +1,199 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX35_3STACK_H__
+#define __ASM_ARCH_MXC_BOARD_MX35_3STACK_H__
+
+#ifdef CONFIG_MACH_MX35_3DS
+
+/*!
+ * @defgroup BRDCFG_MX35 Board Configuration Options
+ * @ingroup MSL_MX35
+ */
+
+/*!
+ * @file mach-mx35/board-mx35_3stack.h
+ *
+ * @brief This file contains all the board level configuration options.
+ *
+ * It currently hold the options defined for MX35 3STACK Platform.
+ *
+ * @ingroup BRDCFG_MX35
+ */
+
+/*
+ * Include Files
+ */
+#include <mach/mxc_uart.h>
+
+/*!
+ * @name MXC UART EVB board level configurations
+ */
+/*! @{ */
+/*!
+ * Specifies if the Irda transmit path is inverting
+ */
+#define MXC_IRDA_TX_INV 0
+/*!
+ * Specifies if the Irda receive path is inverting
+ */
+#define MXC_IRDA_RX_INV 0
+
+/* UART 1 configuration */
+/*!
+ * This define specifies if the UART port is configured to be in DTE or
+ * DCE mode. There exists a define like this for each UART port. Valid
+ * values that can be used are \b MODE_DTE or \b MODE_DCE.
+ */
+#define UART1_MODE MODE_DCE
+/*!
+ * This define specifies if the UART is to be used for IRDA. There exists a
+ * define like this for each UART port. Valid values that can be used are
+ * \b IRDA or \b NO_IRDA.
+ */
+#define UART1_IR NO_IRDA
+/*!
+ * This define is used to enable or disable a particular UART port. If
+ * disabled, the UART will not be registered in the file system and the user
+ * will not be able to access it. There exists a define like this for each UART
+ * port. Specify a value of 1 to enable the UART and 0 to disable it.
+ */
+#define UART1_ENABLED 1
+/*! @} */
+/* UART 2 configuration */
+#define UART2_MODE MODE_DTE
+#define UART2_IR NO_IRDA
+#define UART2_ENABLED 1
+
+/* UART 3 configuration */
+#define UART3_MODE MODE_DTE
+#define UART3_IR NO_IRDA
+#define UART3_ENABLED 1
+
+#define MXC_LL_UART_PADDR UART1_BASE_ADDR
+#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
+
+#define MXC_PSEUDO_PARENT MXC_INT_RESV0
+
+enum {
+ MCU_INT_HEADPHONE = 0,
+ MCU_INT_GPS,
+ MCU_INT_SD1_CD,
+ MCU_INT_SD1_WP,
+ MCU_INT_SD2_CD,
+ MCU_INT_SD2_WP,
+ MCU_INT_POWER_KEY,
+ MCU_INT_RTC,
+ MCU_INT_TS_ADC,
+ MCU_INT_TS_CALIBRATE,
+ MCU_INT_KEYPAD,
+};
+
+#define MXC_PSEUDO_IRQ_HEADPHONE (MXC_PSEUDO_IO_BASE + MCU_INT_HEADPHONE)
+#define MXC_PSEUDO_IRQ_GPS (MXC_PSEUDO_IO_BASE + MCU_INT_GPS)
+#define MXC_PSEUDO_IRQ_SD1_CD (MXC_PSEUDO_IO_BASE + MCU_INT_SD1_CD)
+#define MXC_PSEUDO_IRQ_SD1_WP (MXC_PSEUDO_IO_BASE + MCU_INT_SD1_WP)
+#define MXC_PSEUDO_IRQ_SD2_CD (MXC_PSEUDO_IO_BASE + MCU_INT_SD2_CD)
+#define MXC_PSEUDO_IRQ_SD2_WP (MXC_PSEUDO_IO_BASE + MCU_INT_SD2_WP)
+#define MXC_PSEUDO_IRQ_POWER_KEY (MXC_PSEUDO_IO_BASE + MCU_INT_POWER_KEY)
+#define MXC_PSEUDO_IRQ_KEYPAD (MXC_PSEUDO_IO_BASE + MCU_INT_KEYPAD)
+#define MXC_PSEUDO_IRQ_RTC (MXC_PSEUDO_IO_BASE + MCU_INT_RTC)
+#define MXC_PSEUDO_IRQ_TS_ADC (MXC_PSEUDO_IO_BASE + MCU_INT_TS_ADC)
+
+/*!
+ * @name debug board parameters
+ */
+/*! @{ */
+/*!
+ * Base address of debug board
+ */
+#define DEBUG_BASE_ADDRESS CS5_BASE_ADDR
+
+/* External ethernet LAN9217 base address */
+#define LAN9217_BASE_ADDR DEBUG_BASE_ADDRESS
+
+/* External UART */
+#define UARTA_BASE_ADDR (DEBUG_BASE_ADDRESS + 0x08000)
+#define UARTB_BASE_ADDR (DEBUG_BASE_ADDRESS + 0x10000)
+
+#define BOARD_IO_ADDR (DEBUG_BASE_ADDRESS + 0x20000)
+
+/* LED switchs */
+#define LED_SWITCH_REG 0x00
+/* buttons */
+#define SWITCH_BUTTON_REG 0x08
+/* status, interrupt */
+#define INTR_STATUS_REG 0x10
+#define INTR_RESET_REG 0x20
+/*CPLD configuration*/
+#define CONFIG1_REG 0x28
+#define CONFIG2_REG 0x30
+/*interrupt mask */
+#define INTR_MASK_REG 0x38
+
+/* magic word for debug CPLD */
+#define MAGIC_NUMBER1_REG 0x40
+#define MAGIC_NUMBER2_REG 0x48
+/* CPLD code version */
+#define CPLD_CODE_VER_REG 0x50
+/* magic word for debug CPLD */
+#define MAGIC3_NUMBER3_REG 0x58
+/* module reset register*/
+#define CONTROL_REG 0x60
+/* CPU ID and Personality ID*/
+#define IDENT_REG 0x68
+
+/* For interrupts like xuart, enet etc */
+#define EXPIO_PARENT_INT MX35_PIN_GPIO1_1
+
+#define EXPIO_INT_ENET_INT (MXC_EXP_IO_BASE + 0)
+#define EXPIO_INT_XUARTA_INT (MXC_EXP_IO_BASE + 1)
+#define EXPIO_INT_XUARTB_INT (MXC_EXP_IO_BASE + 2)
+#define EXPIO_INT_BUTTONA_INT (MXC_EXP_IO_BASE + 3)
+#define EXPIO_INT_BUTTONB_INT (MXC_EXP_IO_BASE + 4)
+
+/*! This is System IRQ used by LAN9217 for interrupt generation taken
+ * from platform.h
+ */
+#define LAN9217_IRQ EXPIO_INT_ENET_INT
+
+/*! This is base virtual address of debug board*/
+extern unsigned int mx35_3stack_board_io;
+
+#define MXC_BD_LED1 (1)
+#define MXC_BD_LED2 (1 << 1)
+#define MXC_BD_LED3 (1 << 2)
+#define MXC_BD_LED4 (1 << 3)
+#define MXC_BD_LED5 (1 << 4)
+#define MXC_BD_LED6 (1 << 5)
+#define MXC_BD_LED7 (1 << 6)
+#define MXC_BD_LED8 (1 << 7)
+#define MXC_BD_LED_ON(led)
+#define MXC_BD_LED_OFF(led)
+
+/*! @} */
+
+#define AHB_FREQ 133000000
+#define IPG_FREQ 66500000
+
+extern void mx35_3stack_gpio_init(void) __init;
+extern void gpio_tsc_active(void);
+extern void gpio_tsc_inactive(void);
+extern unsigned int sdhc_get_card_det_status(struct device *dev);
+extern int sdhc_write_protect(struct device *dev);
+extern void gpio_can_active(int id);
+extern void gpio_can_inactive(int id);
+extern struct flexcan_platform_data flexcan_data[];
+
+#endif /* CONFIG_MACH_MX35_3DS */
+#endif /* __ASM_ARCH_MXC_BOARD_MX35_3STACK_H__ */
diff --git a/arch/arm/mach-mx35/board-mx35evb.h b/arch/arm/mach-mx35/board-mx35evb.h
new file mode 100644
index 000000000000..3eb124c1b1ff
--- /dev/null
+++ b/arch/arm/mach-mx35/board-mx35evb.h
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX35EVB_H__
+#define __ASM_ARCH_MXC_BOARD_MX35EVB_H__
+
+#ifdef CONFIG_MACH_MX35EVB
+/*!
+ * @defgroup BRDCFG_MX35 Board Configuration Options
+ * @ingroup MSL_MX35
+ */
+
+/*!
+ * @file mach-mx35/board-mx35evb.h
+ *
+ * @brief This file contains all the board level configuration options.
+ *
+ * It currently hold the options defined for MX35 EVB Platform.
+ *
+ * @ingroup BRDCFG_MX35
+ */
+
+/*
+ * Include Files
+ */
+#include <mach/mxc_uart.h>
+
+/*!
+ * @name MXC UART EVB board level configurations
+ */
+/*! @{ */
+/*!
+ * Specifies if the Irda transmit path is inverting
+ */
+#define MXC_IRDA_TX_INV 0
+/*!
+ * Specifies if the Irda receive path is inverting
+ */
+#define MXC_IRDA_RX_INV 0
+
+/* UART 1 configuration */
+/*!
+ * This define specifies if the UART port is configured to be in DTE or
+ * DCE mode. There exists a define like this for each UART port. Valid
+ * values that can be used are \b MODE_DTE or \b MODE_DCE.
+ */
+#define UART1_MODE MODE_DCE
+/*!
+ * This define specifies if the UART is to be used for IRDA. There exists a
+ * define like this for each UART port. Valid values that can be used are
+ * \b IRDA or \b NO_IRDA.
+ */
+#define UART1_IR NO_IRDA
+/*!
+ * This define is used to enable or disable a particular UART port. If
+ * disabled, the UART will not be registered in the file system and the user
+ * will not be able to access it. There exists a define like this for each UART
+ * port. Specify a value of 1 to enable the UART and 0 to disable it.
+ */
+#define UART1_ENABLED 1
+/*! @} */
+/* UART 2 configuration */
+#define UART2_MODE MODE_DCE
+#define UART2_IR NO_IRDA
+#define UART2_ENABLED 1
+
+/* UART 3 configuration */
+#define UART3_MODE MODE_DTE
+#define UART3_IR NO_IRDA
+#define UART3_ENABLED 1
+
+#define MXC_LL_UART_PADDR UART1_BASE_ADDR
+#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
+
+/*!
+ * @name PBC Controller parameters
+ */
+/*!
+ * Base address of PBC controller
+ */
+/*! @{ */
+#define PBC_BASE_ADDRESS CS4_BASE_ADDR
+
+#define PBC_VERSION 0x0000
+#define PBC_BCTRL1_SET 0x0008
+#define PBC_BCTRL1_CLR 0x000C
+#define PBC_BCTRL2_SET 0x0010
+#define PBC_BCTRL2_CLR 0x0014
+#define PBC_IMR1_SET 0x0018
+#define PBC_IMR1_CLR 0x001C
+#define PBC_IMR2_SET 0x0020
+#define PBC_IMR2_CLR 0x0024
+#define PBC_BSTAT1 0x0028
+#define PBC_ISR 0x002C
+
+#define ENET_BASE_ADDRESS (PBC_BASE_ADDRESS + 0x20000)
+
+/*! Definitions in Board Control Register 1 */
+#define PBC_BCTRL1_ENET_RESET_B (1)
+#define PBC_BCTRL1_FEC_RESET_B (1<<2)
+
+/*! @} */
+
+#define EXPIO_PARENT_INT_0 IOMUX_TO_IRQ(MX35_PIN_GPIO1_0)
+#define EXPIO_PARENT_INT_1 IOMUX_TO_IRQ(MX35_PIN_GPIO1_1)
+
+#define EXPIO_PARENT_INT EXPIO_PARENT_INT_1
+#define EXPIO_PARENT_INT_PIN MX35_PIN_GPIO1_1
+
+#define EXPIO_INT_FEC (EXPIO_PARENT_INT + 0)
+#define EXPIO_INT_ENET (EXPIO_PARENT_INT + 1)
+
+extern unsigned int mx35evb_board_io;
+
+#define MXC_BD_LED1 (1)
+#define MXC_BD_LED2 (1 << 1)
+#define MXC_BD_LED3 (1 << 2)
+#define MXC_BD_LED4 (1 << 3)
+#define MXC_BD_LED_ON(led) \
+ __raw_writew(led, mx35evb_bard_io + PBC_BCTRL2_SET)
+#define MXC_BD_LED_OFF(led) \
+ __raw_writew(led, mx35evb_bard_io + PBC_BCTRL2_CLR)
+
+#define AHB_FREQ 133000000
+#define IPG_FREQ 66500000
+/*!
+ * Specifies if the MXC Write Protectect function is suppport or not.
+ */
+#define MXC_MMC_WRITE_PROTECT 1
+
+extern void mx35evb_gpio_init(void) __init;
+
+#endif /* CONFIG_MACH_MX35EVB */
+#endif /* __ASM_ARCH_MXC_BOARD_MX35EVB_H__ */
diff --git a/arch/arm/mach-mx35/clock.c b/arch/arm/mach-mx35/clock.c
new file mode 100644
index 000000000000..e2095f2d1c88
--- /dev/null
+++ b/arch/arm/mach-mx35/clock.c
@@ -0,0 +1,1849 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <mach/clock.h>
+#include <asm/div64.h>
+
+#include "crm_regs.h"
+
+#define PRE_DIV_MIN_FREQ 10000000 /* Minimum Frequency after Predivider */
+#define PROPAGATE_RATE_DIS 2
+
+struct timer_list dptcen_timer;
+static int cpu_curr_wp;
+static struct cpu_wp *cpu_wp_tbl;
+static int cpu_wp_nr;
+static int cpu_wp_offset;
+
+static struct clk mcu_pll_clk;
+static struct clk peri_pll_clk;
+static struct clk ipg_clk;
+static struct clk ckih_clk;
+static struct clk ckie_clk;
+static struct clk ahb_clk;
+static struct clk cpu_clk;
+
+#define CLK_CODE(arm, ahb, sel) (((arm) << 16) + ((ahb) << 8) + (sel))
+#define CLK_CODE_ARM(c) (((c) >> 16) & 0xFF)
+#define CLK_CODE_AHB(c) (((c) >> 8) & 0xFF)
+#define CLK_CODE_PATH(c) ((c) & 0xFF)
+
+static int __get_arm_div(unsigned long pdr0, int *fi, int *fd);
+
+static int g_clk_mux_auto[8] = {
+ CLK_CODE(1, 3, 0), CLK_CODE(1, 2, 1), CLK_CODE(2, 1, 1), -1,
+ CLK_CODE(1, 6, 0), CLK_CODE(1, 4, 1), CLK_CODE(2, 2, 1), -1,
+};
+
+static int g_clk_mux_consumer[16] = {
+ CLK_CODE(1, 4, 0), CLK_CODE(1, 3, 1), CLK_CODE(2, 2, 0), -1,
+ -1, -1, CLK_CODE(4, 1, 0), CLK_CODE(1, 5, 0),
+ CLK_CODE(1, 8, 0), CLK_CODE(1, 6, 1), CLK_CODE(2, 4, 0), -1,
+ -1, -1, CLK_CODE(4, 2, 0), -1,
+};
+
+static int g_hsp_div_table[3][16] = {
+ {4, 3, 2, -1, -1, -1, 1, 5, 4, 3, 2, -1, -1, -1, 1, -1},
+ {-1, -1, -1, -1, -1, -1, -1, -1, 8, 6, 4, -1, -1, -1, 2, -1},
+ {3, -1, -1, -1, -1, -1, -1, -1, 3, -1, -1, -1, -1, -1, -1, -1},
+};
+
+static void __calc_dividers(u32 div, u32 *pre, u32 *post, u32 base)
+{
+ u32 min_pre, temp_pre, old_err, err;
+ min_pre = (div - 1) / base + 1;
+ old_err = 8;
+ for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
+ if (div > (temp_pre * base))
+ break;
+ if (div < (temp_pre * temp_pre))
+ continue;
+ err = div % temp_pre;
+ if (err == 0) {
+ *pre = temp_pre;
+ break;
+ }
+ err = temp_pre - err;
+ if (err < old_err) {
+ old_err = err;
+ *pre = temp_pre;
+ }
+ }
+ *post = (div + *pre - 1) / *pre;
+}
+
+static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post)
+{
+ if (div >= 512) {
+ *pre = 8;
+ *post = 64;
+ } else if (div >= 64) {
+ __calc_dividers(div, pre, post, 64);
+ } else if (div <= 8) {
+ *pre = div;
+ *post = 1;
+ } else {
+ *pre = 1;
+ *post = div;
+ }
+}
+
+static void __calc_two_dividers(u32 div, u32 *pre, u32 *post)
+{
+ if (div >= 64) {
+ *pre = *post = 8;
+ } else if (div > 8) {
+ __calc_dividers(div, pre, post, 8);
+ } else {
+ *pre = 1;
+ *post = div;
+ }
+}
+
+static unsigned long _clk_per_post_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 pre, post;
+ u32 div = clk->parent->rate / rate;
+ if (clk->parent->rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ return clk->parent->rate / (pre * post);
+}
+
+static unsigned long _clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 pre, post;
+ u32 div = clk->parent->rate / rate;
+ if (clk->parent->rate % rate)
+ div++;
+
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ __calc_two_dividers(div, &pre, &post);
+ return clk->parent->rate / (pre * post);
+ } else
+ return clk->parent->rate / div;
+}
+
+static int __switch_cpu_wp(struct clk *clk, unsigned long rate)
+{
+ int i;
+ if (cpu_wp_tbl[cpu_curr_wp].cpu_rate < rate) {
+ for (i = cpu_curr_wp + 2; i < cpu_wp_nr; i += 2) {
+ if (rate == cpu_wp_tbl[i].cpu_rate)
+ goto found;
+ }
+ return -EINVAL;
+ } else {
+ for (i = cpu_curr_wp - 2; i >= 0; i -= 2) {
+ if (rate == cpu_wp_tbl[i].cpu_rate)
+ goto found;
+ }
+ return -EINVAL;
+ }
+ found:
+ __raw_writel(cpu_wp_tbl[i].pdr0_reg, MXC_CCM_PDR0);
+
+ if (cpu_wp_tbl[i].pll_rate != cpu_wp_tbl[cpu_curr_wp].pll_rate)
+ clk_set_rate(clk->parent, cpu_wp_tbl[i].pll_rate);
+ cpu_curr_wp = i;
+ clk->rate = rate;
+ return 0;
+}
+
+static int __switch_cpu_rate(struct clk *clk, unsigned long rate)
+{
+ int prev;
+ unsigned long tmp;
+ int arm_div, fi, fd, start, end;
+ if (cpu_wp_tbl[cpu_curr_wp].cpu_rate < rate) {
+ start = cpu_curr_wp + 2;
+ end = cpu_wp_nr;
+ prev = cpu_curr_wp;
+ } else {
+ start = cpu_wp_offset + 2;
+ end = cpu_curr_wp;
+ prev = cpu_wp_offset;
+ }
+ while (start < end) {
+ arm_div = __get_arm_div(cpu_wp_tbl[start].pdr0_reg, &fi, &fd);
+ tmp = (mcu_pll_clk.rate * fi) / (arm_div * fd);
+ if (tmp == rate) {
+ prev = start;
+ break;
+ }
+ if (tmp < rate) {
+ if (prev < start)
+ prev = start;
+ } else {
+ break;
+ }
+ start += 2;
+ }
+ if (start >= end)
+ return -EINVAL;
+
+ if (prev == cpu_curr_wp)
+ return 0;
+
+ __raw_writel(cpu_wp_tbl[prev].pdr0_reg, MXC_CCM_PDR0);
+
+ cpu_curr_wp = prev;
+ clk->rate = rate;
+ return 0;
+}
+
+static int __get_arm_div(unsigned long pdr0, int *fi, int *fd)
+{
+ int *pclk_mux;
+ if ((pdr0 & MXC_CCM_PDR0_AUTO_CON)
+ || (cpu_is_mx35_rev(CHIP_REV_2_0) >= 1))
+ pclk_mux =
+ g_clk_mux_consumer +
+ ((pdr0 & MXC_CCM_PDR0_CON_MUX_DIV_MASK) >>
+ MXC_CCM_PDR0_CON_MUX_DIV_OFFSET);
+ else {
+ pclk_mux = g_clk_mux_auto +
+ ((pdr0 & MXC_CCM_PDR0_AUTO_MUX_DIV_MASK) >>
+ MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET);
+ }
+
+ if ((*pclk_mux) == -1) {
+ BUG();
+ return -EINVAL;
+ }
+
+ if (fi && fd) {
+ if (!CLK_CODE_PATH(*pclk_mux)) {
+ *fi = *fd = 1;
+ return CLK_CODE_ARM(*pclk_mux);
+ }
+ if ((pdr0 & MXC_CCM_PDR0_AUTO_CON)
+ || (cpu_is_mx35_rev(CHIP_REV_2_0) >= 1)) {
+ *fi = 3;
+ *fd = 4;
+ } else {
+ *fi = 2;
+ *fd = 3;
+ }
+ }
+ return CLK_CODE_ARM(*pclk_mux);
+}
+
+static int __get_ahb_div(unsigned long pdr0)
+{
+ int *pclk_mux;
+ if ((pdr0 & MXC_CCM_PDR0_AUTO_CON)
+ || (cpu_is_mx35_rev(CHIP_REV_2_0) >= 1)) {
+ pclk_mux =
+ g_clk_mux_consumer +
+ ((pdr0 & MXC_CCM_PDR0_CON_MUX_DIV_MASK) >>
+ MXC_CCM_PDR0_CON_MUX_DIV_OFFSET);
+ } else {
+ pclk_mux = g_clk_mux_auto +
+ ((pdr0 & MXC_CCM_PDR0_AUTO_MUX_DIV_MASK) >>
+ MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET);
+ }
+
+ if ((*pclk_mux) == -1) {
+ BUG();
+ return -EINVAL;
+ }
+ return CLK_CODE_AHB(*pclk_mux);
+}
+
+static void sync_cpu_wb(void)
+{
+ int i;
+ struct cpu_wp *p;
+ unsigned long reg = __raw_readl(MXC_CCM_PDR0);
+ if ((reg & MXC_CCM_PDR0_AUTO_CON)
+ || (cpu_is_mx35_rev(CHIP_REV_2_0) >= 1)) {
+ reg &= MXC_CCM_PDR0_CON_MUX_DIV_MASK;
+ } else {
+ reg &= MXC_CCM_PDR0_AUTO_MUX_DIV_MASK;
+ }
+ for (i = 0; i < cpu_wp_nr; i++) {
+ p = cpu_wp_tbl + cpu_curr_wp;
+ if (p->pdr0_reg == (reg & 0xF0E00))
+ break;
+ cpu_curr_wp = (cpu_curr_wp + 1) % cpu_wp_nr;
+ }
+ cpu_wp_offset = cpu_curr_wp & 1;
+}
+
+static int _clk_enable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg |= 3 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void _clk_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(3 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static void _clk_emi_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(3 << clk->enable_shift);
+ reg |= (1 << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static int _clk_asrc_enable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(MXC_CCM_COSR);
+ __raw_writel(reg | MXC_CCM_COSR_ASRC_AUDIO_EN, MXC_CCM_COSR);
+ return 0;
+}
+
+static void _clk_asrc_disable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(MXC_CCM_COSR);
+ __raw_writel(reg & (~MXC_CCM_COSR_ASRC_AUDIO_EN), MXC_CCM_COSR);
+}
+
+static int _clk_pll_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ signed long pd = 1; /* Pre-divider */
+ signed long mfi; /* Multiplication Factor (Integer part) */
+ signed long mfn; /* Multiplication Factor (Integer part) */
+ signed long mfd; /* Multiplication Factor (Denominator Part) */
+ signed long tmp;
+ u32 ref_freq = clk->parent->rate;
+
+ if ((clk == &mcu_pll_clk)
+ && (clk->parent->rate == cpu_wp_tbl[cpu_curr_wp].pll_rate)) {
+ __raw_writel(cpu_wp_tbl[cpu_curr_wp].pll_reg, MXC_CCM_MPCTL);
+ clk->rate = rate;
+ return 0;
+ }
+
+ while (((ref_freq / pd) * 10) > rate)
+ pd++;
+
+ if ((ref_freq / pd) < PRE_DIV_MIN_FREQ)
+ return -EINVAL;
+
+ /* the ref_freq/2 in the following is to round up */
+ mfi = (((rate / 2) * pd) + (ref_freq / 2)) / ref_freq;
+ if (mfi < 5 || mfi > 15)
+ return -EINVAL;
+
+ /* pick a mfd value that will work
+ * then solve for mfn */
+ mfd = ref_freq / 50000;
+
+ /*
+ * pll_freq * pd * mfd
+ * mfn = -------------------- - (mfi * mfd)
+ * 2 * ref_freq
+ */
+ /* the tmp/2 is for rounding */
+ tmp = ref_freq / 10000;
+ mfn =
+ ((((((rate / 2) + (tmp / 2)) / tmp) * pd) * mfd) / 10000) -
+ (mfi * mfd);
+
+ mfn = mfn & 0x3ff;
+ pd--;
+ mfd--;
+
+ /* Change the Pll value */
+ reg = (mfi << MXC_CCM_PCTL_MFI_OFFSET) |
+ (mfn << MXC_CCM_PCTL_MFN_OFFSET) |
+ (mfd << MXC_CCM_PCTL_MFD_OFFSET) | (pd << MXC_CCM_PCTL_PD_OFFSET);
+
+ if (clk == &mcu_pll_clk)
+ __raw_writel(reg, MXC_CCM_MPCTL);
+ else if (clk == &peri_pll_clk)
+ __raw_writel(reg, MXC_CCM_PPCTL);
+
+ clk->rate = rate;
+ return 0;
+}
+
+static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate)
+{
+ if ((rate < ahb_clk.rate) || (rate % ahb_clk.rate != 0)) {
+ printk(KERN_ERR "Wrong rate %lu in _clk_cpu_set_rate\n", rate);
+ return -EINVAL;
+ }
+
+ if (clk->rate == rate)
+ return 0;
+
+ if (clk->parent->rate == cpu_wp_tbl[cpu_curr_wp].pll_rate)
+ return __switch_cpu_wp(clk, rate);
+ return __switch_cpu_rate(clk, rate);
+}
+
+static void _clk_pll_recalc(struct clk *clk)
+{
+ long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+ unsigned long reg = 0;
+ s64 temp;
+
+ ref_clk = ckih_clk.rate;
+
+ if (clk == &mcu_pll_clk)
+ reg = __raw_readl(MXC_CCM_MPCTL);
+ else if (clk == &peri_pll_clk)
+ reg = __raw_readl(MXC_CCM_PPCTL);
+ else
+ BUG();
+
+ pdf = (reg & MXC_CCM_PCTL_PD_MASK) >> MXC_CCM_PCTL_PD_OFFSET;
+ mfd = (reg & MXC_CCM_PCTL_MFD_MASK) >> MXC_CCM_PCTL_MFD_OFFSET;
+ mfi = (reg & MXC_CCM_PCTL_MFI_MASK) >> MXC_CCM_PCTL_MFI_OFFSET;
+ mfi = (mfi <= 5) ? 5 : mfi;
+ mfn = mfn_abs = reg & MXC_CCM_PCTL_MFN_MASK;
+
+ if (mfn >= 0x200) {
+ mfn |= 0xFFFFFE00;
+ mfn_abs = -mfn;
+ }
+
+ ref_clk *= 2;
+ ref_clk /= pdf + 1;
+
+ temp = (u64) ref_clk * mfn_abs;
+ do_div(temp, mfd + 1);
+ if (mfn < 0)
+ temp = -temp;
+ temp = (ref_clk * mfi) + temp;
+
+ clk->rate = temp;
+}
+
+static int _clk_peri_pll_enable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(MXC_CCM_CCMR);
+ reg |= MXC_CCM_CCMR_UPE;
+ __raw_writel(reg, MXC_CCM_CCMR);
+
+ /* No lock bit on MX31, so using max time from spec */
+ udelay(80);
+
+ return 0;
+}
+
+static void _clk_peri_pll_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCMR);
+ reg &= ~MXC_CCM_CCMR_UPE;
+ __raw_writel(reg, MXC_CCM_CCMR);
+}
+
+#define PDR0(mask, off) ((__raw_readl(MXC_CCM_PDR0) & mask) >> off)
+#define PDR1(mask, off) ((__raw_readl(MXC_CCM_PDR1) & mask) >> off)
+#define PDR2(mask, off) ((__raw_readl(MXC_CCM_PDR2) & mask) >> off)
+#define PDR3(mask, off) ((__raw_readl(MXC_CCM_PDR3) & mask) >> off)
+#define PDR4(mask, off) ((__raw_readl(MXC_CCM_PDR4) & mask) >> off)
+
+static void _clk_cpu_recalc(struct clk *clk)
+{
+ unsigned long pdr0 = __raw_readl(MXC_CCM_PDR0);
+ int arm_div, fi, fd;
+ if (clk->parent->rate == cpu_wp_tbl[cpu_curr_wp].pll_rate) {
+ clk->rate = cpu_wp_tbl[cpu_curr_wp].cpu_rate;
+ } else {
+ arm_div = __get_arm_div(pdr0, &fi, &fd);
+ clk->rate = (clk->parent->rate * fi) / (arm_div * fd);
+ }
+}
+
+static void _clk_hclk_recalc(struct clk *clk)
+{
+ unsigned long ahb_div, pdr0 = __raw_readl(MXC_CCM_PDR0);
+ ahb_div = __get_ahb_div(pdr0);
+ clk->rate = clk->parent->rate / ahb_div;
+}
+
+static void _clk_ipg_recalc(struct clk *clk)
+{
+ clk->rate = clk->parent->rate / 2;
+}
+
+static void _clk_nfc_recalc(struct clk *clk)
+{
+ unsigned long nfc_pdf;
+
+ nfc_pdf = PDR4(MXC_CCM_PDR4_NFC_PODF_MASK,
+ MXC_CCM_PDR4_NFC_PODF_OFFSET);
+ clk->rate = clk->parent->rate / (nfc_pdf + 1);
+}
+
+static void _clk_hsp_recalc(struct clk *clk)
+{
+ int hsp_pdf;
+ unsigned long reg;
+ reg = __raw_readl(MXC_CCM_PDR0);
+
+ if ((reg & MXC_CCM_PDR0_AUTO_CON)
+ || (cpu_is_mx35_rev(CHIP_REV_2_0) >= 1)) {
+ hsp_pdf =
+ (reg & MXC_CCM_PDR0_HSP_PODF_MASK) >>
+ MXC_CCM_PDR0_HSP_PODF_OFFSET;
+ reg =
+ (reg & MXC_CCM_PDR0_CON_MUX_DIV_MASK) >>
+ MXC_CCM_PDR0_CON_MUX_DIV_OFFSET;
+ if (hsp_pdf < 3) {
+ hsp_pdf = g_hsp_div_table[hsp_pdf][reg];
+ if (hsp_pdf > 0)
+ clk->rate = clk->parent->rate / hsp_pdf;
+ }
+ } else {
+ clk->rate = clk->parent->rate;
+ }
+}
+
+static void _clk_mlb_recalc(struct clk *clk)
+{
+ clk->rate = clk->parent->rate * 2;
+}
+
+static void _clk_usb_recalc(struct clk *clk)
+{
+ unsigned long usb_podf, usb_prdf;
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ usb_podf = PDR4(MXC_CCM_PDR4_USB_PODF_MASK,
+ MXC_CCM_PDR4_USB_PODF_OFFSET);
+ usb_prdf = PDR4(MXC_CCM_PDR4_USB_PRDF_MASK,
+ MXC_CCM_PDR4_USB_PRDF_OFFSET);
+ clk->rate =
+ clk->parent->rate / ((usb_prdf + 1) * (usb_podf + 1));
+ } else {
+ usb_podf = PDR4(MXC_CCM_PDR4_USB_PODF_MASK_V2,
+ MXC_CCM_PDR4_USB_PODF_OFFSET);
+ clk->rate = clk->parent->rate / (usb_podf + 1);
+ }
+}
+
+static int _clk_usb_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 podf, prdf;
+
+ div = clk->parent->rate / rate;
+
+ if ((clk->parent->rate / div) != rate)
+ return -EINVAL;
+
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ __calc_two_dividers(div, &prdf, &podf);
+ reg = __raw_readl(MXC_CCM_PDR4) &
+ ~(MXC_CCM_PDR4_USB_PODF_MASK | MXC_CCM_PDR4_USB_PRDF_MASK);
+ reg |= (podf - 1) << MXC_CCM_PDR4_USB_PODF_OFFSET;
+ reg |= (prdf - 1) << MXC_CCM_PDR4_USB_PRDF_OFFSET;
+ } else {
+ podf = div - 1;
+ reg =
+ __raw_readl(MXC_CCM_PDR4) & ~MXC_CCM_PDR4_USB_PODF_MASK_V2;
+ reg |= (podf - 1) << MXC_CCM_PDR4_USB_PODF_OFFSET;
+ }
+ __raw_writel(reg, MXC_CCM_PDR4);
+ clk->rate = rate;
+ return 0;
+}
+
+static void _clk_csi_recalc(struct clk *clk)
+{
+ u32 podf, prdf;
+
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ prdf = PDR2(MXC_CCM_PDR2_CSI_PRDF_MASK,
+ MXC_CCM_PDR2_CSI_PRDF_OFFSET);
+ podf =
+ PDR2(MXC_CCM_PDR2_CSI_PODF_MASK,
+ MXC_CCM_PDR2_CSI_PODF_OFFSET);
+ clk->rate = clk->parent->rate / ((prdf + 1) * (podf + 1));
+ } else {
+ podf =
+ PDR2(MXC_CCM_PDR2_CSI_PODF_MASK_V2,
+ MXC_CCM_PDR2_CSI_PODF_OFFSET);
+ clk->rate = clk->parent->rate / (podf + 1);
+ }
+}
+
+static int _clk_csi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 prdf, podf;
+
+ div = clk->parent->rate / rate;
+
+ if ((clk->parent->rate / div) != rate)
+ return -EINVAL;
+
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ __calc_two_dividers(div, &prdf, &podf);
+ reg = __raw_readl(MXC_CCM_PDR2) &
+ ~(MXC_CCM_PDR2_CSI_PRDF_MASK | MXC_CCM_PDR2_CSI_PODF_MASK);
+ reg |= (podf - 1) << MXC_CCM_PDR2_CSI_PODF_OFFSET;
+ reg |= (prdf - 1) << MXC_CCM_PDR2_CSI_PRDF_OFFSET;
+ } else {
+ reg =
+ __raw_readl(MXC_CCM_PDR2) & ~MXC_CCM_PDR2_CSI_PODF_MASK_V2;
+ reg |= (div - 1) << MXC_CCM_PDR2_CSI_PODF_OFFSET;
+ }
+
+ /* Set CSI clock divider */
+ __raw_writel(reg, MXC_CCM_PDR2);
+ clk->rate = rate;
+ return 0;
+}
+
+static int _clk_csi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+ if (parent == &cpu_clk)
+ reg = __raw_readl(MXC_CCM_PDR2) | MXC_CCM_PDR2_CSI_M_U;
+ else if (parent == &peri_pll_clk)
+ reg = __raw_readl(MXC_CCM_PDR2) & (~MXC_CCM_PDR2_CSI_M_U);
+ else
+ return -EINVAL;
+ __raw_writel(reg, MXC_CCM_PDR2);
+ return 0;
+}
+
+static void _clk_per_recalc(struct clk *clk)
+{
+ u32 podf = 0, prdf = 0;
+
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ if (clk->parent == &cpu_clk) {
+ prdf = PDR4(MXC_CCM_PDR4_PER0_PRDF_MASK,
+ MXC_CCM_PDR4_PER0_PRDF_OFFSET);
+ podf = PDR4(MXC_CCM_PDR4_PER0_PODF_MASK,
+ MXC_CCM_PDR4_PER0_PODF_OFFSET);
+ } else {
+ podf = PDR0(MXC_CCM_PDR0_PER_PODF_MASK,
+ MXC_CCM_PDR0_PER_PODF_OFFSET);
+ }
+ clk->rate = clk->parent->rate / ((podf + 1) * (prdf + 1));
+ } else {
+ if (clk->parent == &ahb_clk)
+ podf = PDR0(MXC_CCM_PDR0_PER_PODF_MASK,
+ MXC_CCM_PDR0_PER_PODF_OFFSET);
+ else if (clk->parent == &cpu_clk) {
+ podf = PDR4(MXC_CCM_PDR4_PER0_PODF_MASK_V2,
+ MXC_CCM_PDR4_PER0_PODF_OFFSET);
+ }
+ clk->rate = clk->parent->rate / (podf + 1);
+ }
+}
+
+static void _clk_uart_per_recalc(struct clk *clk)
+{
+ unsigned long podf, prdf;
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ prdf = PDR4(MXC_CCM_PDR4_UART_PRDF_MASK,
+ MXC_CCM_PDR4_UART_PRDF_OFFSET);
+ podf = PDR4(MXC_CCM_PDR4_UART_PODF_MASK,
+ MXC_CCM_PDR4_UART_PODF_OFFSET);
+ clk->rate = clk->parent->rate / ((prdf + 1) * (podf + 1));
+ } else {
+ podf =
+ PDR4(MXC_CCM_PDR4_UART_PODF_MASK_V2,
+ MXC_CCM_PDR4_UART_PODF_OFFSET);
+ clk->rate = clk->parent->rate / (podf + 1);
+ }
+
+}
+
+static int _clk_uart_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 prdf, podf;
+
+ div = clk->parent->rate / rate;
+
+ if ((clk->parent->rate / div) != rate)
+ return -EINVAL;
+
+ /* Set UART clock divider */
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ __calc_two_dividers(div, &prdf, &podf);
+ reg = __raw_readl(MXC_CCM_PDR4) &
+ ~(MXC_CCM_PDR4_UART_PRDF_MASK |
+ MXC_CCM_PDR4_UART_PODF_MASK);
+ reg |= (podf - 1) << MXC_CCM_PDR4_UART_PODF_OFFSET;
+ reg |= (prdf - 1) << MXC_CCM_PDR4_UART_PRDF_OFFSET;
+ } else {
+ reg =
+ __raw_readl(MXC_CCM_PDR4) & ~MXC_CCM_PDR4_UART_PODF_MASK_V2;
+ reg |= (div - 1) << MXC_CCM_PDR4_UART_PODF_OFFSET;
+ }
+ __raw_writel(reg, MXC_CCM_PDR4);
+ clk->rate = rate;
+ return 0;
+}
+
+static void _clk_ssi_recalc(struct clk *clk)
+{
+ unsigned long ssi_pdf, ssi_prepdf;
+
+ if (clk->id == 1) {
+ ssi_pdf = PDR2(MXC_CCM_PDR2_SSI2_PODF_MASK,
+ MXC_CCM_PDR2_SSI2_PODF_OFFSET);
+ ssi_prepdf = PDR2(MXC_CCM_PDR2_SSI2_PRDF_MASK,
+ MXC_CCM_PDR2_SSI2_PRDF_OFFSET);
+ } else {
+ ssi_pdf = PDR2(MXC_CCM_PDR2_SSI1_PODF_MASK,
+ MXC_CCM_PDR2_SSI1_PODF_OFFSET);
+ ssi_prepdf = PDR2(MXC_CCM_PDR2_SSI1_PRDF_MASK,
+ MXC_CCM_PDR2_SSI1_PRDF_OFFSET);
+ }
+ clk->rate = clk->parent->rate / ((ssi_prepdf + 1) * (ssi_pdf + 1));
+}
+
+static int _clk_ssi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 pre, post;
+
+ div = clk->parent->rate / rate;
+
+ if ((clk->parent->rate / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ if (clk->id == 1) {
+ reg = __raw_readl(MXC_CCM_PDR2) &
+ ~(MXC_CCM_PDR2_SSI2_PRDF_MASK |
+ MXC_CCM_PDR2_SSI2_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_PDR2_SSI2_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_PDR2_SSI2_PRDF_OFFSET;
+ } else {
+ reg = __raw_readl(MXC_CCM_PDR2) &
+ ~(MXC_CCM_PDR2_SSI1_PRDF_MASK |
+ MXC_CCM_PDR2_SSI1_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_PDR2_SSI1_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_PDR2_SSI1_PRDF_OFFSET;
+ }
+ __raw_writel(reg, MXC_CCM_PDR2);
+
+ clk->rate = rate;
+ return 0;
+}
+
+static void _clk_mstick1_recalc(struct clk *clk)
+{
+ unsigned long prdf, podf;
+ prdf = PDR1(MXC_CCM_PDR1_MSHC_PRDF_MASK, MXC_CCM_PDR1_MSHC_PRDF_OFFSET);
+ podf = PDR1(MXC_CCM_PDR1_MSHC_PODF_MASK, MXC_CCM_PDR1_MSHC_PODF_OFFSET);
+ clk->rate = clk->parent->rate / ((prdf + 1) * (podf + 1));
+}
+
+static int _clk_mstick1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 pre, post;
+
+ div = clk->parent->rate / rate;
+
+ if ((clk->parent->rate / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_PDR1) &
+ ~(MXC_CCM_PDR1_MSHC_PRDF_MASK | MXC_CCM_PDR1_MSHC_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_PDR1_MSHC_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_PDR1_MSHC_PRDF_OFFSET;
+ __raw_writel(reg, MXC_CCM_PDR1);
+
+ clk->rate = rate;
+ return 0;
+}
+
+static int _clk_mstick1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+ if (parent == &cpu_clk)
+ reg = __raw_readl(MXC_CCM_PDR1) | MXC_CCM_PDR1_MSHC_M_U;
+ else if (parent == &peri_pll_clk)
+ reg = __raw_readl(MXC_CCM_PDR1) & (~MXC_CCM_PDR1_MSHC_M_U);
+ else
+ return -EINVAL;
+ __raw_writel(reg, MXC_CCM_PDR1);
+ return 0;
+}
+
+static void _clk_spdif_recalc(struct clk *clk)
+{
+ unsigned long prdf, podf;
+ prdf =
+ PDR3(MXC_CCM_PDR3_SPDIF_PRDF_MASK, MXC_CCM_PDR3_SPDIF_PRDF_OFFSET);
+ podf =
+ PDR3(MXC_CCM_PDR3_SPDIF_PODF_MASK, MXC_CCM_PDR3_SPDIF_PODF_OFFSET);
+ clk->rate = clk->parent->rate / ((prdf + 1) * (podf + 1));
+}
+
+static int _clk_spdif_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 pre, post;
+
+ div = clk->parent->rate / rate;
+
+ if ((clk->parent->rate / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ reg = __raw_readl(MXC_CCM_PDR3) &
+ ~(MXC_CCM_PDR3_SPDIF_PRDF_MASK | MXC_CCM_PDR3_SPDIF_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_PDR3_SPDIF_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_PDR3_SPDIF_PRDF_OFFSET;
+ __raw_writel(reg, MXC_CCM_PDR3);
+
+ clk->rate = rate;
+ return 0;
+}
+
+static int _clk_spdif_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+ if (parent == &cpu_clk)
+ reg = __raw_readl(MXC_CCM_PDR3) | MXC_CCM_PDR3_SPDIF_M_U;
+ else if (parent == &peri_pll_clk)
+ reg = __raw_readl(MXC_CCM_PDR3) & (~MXC_CCM_PDR3_SPDIF_M_U);
+ else
+ return -EINVAL;
+ __raw_writel(reg, MXC_CCM_PDR3);
+ return 0;
+}
+
+static void _clk_asrc_recalc(struct clk *clk)
+{
+ unsigned long div;
+ div = __raw_readl(MXC_CCM_COSR) & MXC_CCM_COSR_ASRC_AUDIO_PODF_MASK;
+ div = div >> MXC_CCM_COSR_ASRC_AUDIO_PODF_OFFSET;
+ clk->rate = clk->parent->rate / (div + 1);
+}
+
+static int _clk_asrc_set_rate(struct clk *clk, unsigned long rate)
+{
+ int div;
+ unsigned long reg;
+ if (clk->parent->rate % rate)
+ return -EINVAL;
+
+ div = clk->parent->rate / rate;
+ reg = __raw_readl(MXC_CCM_COSR) & (~MXC_CCM_COSR_ASRC_AUDIO_PODF_MASK);
+ reg |= (div - 1) << MXC_CCM_COSR_ASRC_AUDIO_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_COSR);
+ clk->rate = rate;
+ return 0;
+}
+
+static void _clk_sdhc_recalc(struct clk *clk)
+{
+ u32 podf = 0, prdf = 0;
+
+ switch (clk->id) {
+ case 0:
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ prdf = PDR3(MXC_CCM_PDR3_ESDHC1_PRDF_MASK,
+ MXC_CCM_PDR3_ESDHC1_PRDF_OFFSET);
+ podf = PDR3(MXC_CCM_PDR3_ESDHC1_PODF_MASK,
+ MXC_CCM_PDR3_ESDHC1_PODF_OFFSET);
+ } else
+ podf = PDR3(MXC_CCM_PDR3_ESDHC1_PODF_MASK_V2,
+ MXC_CCM_PDR3_ESDHC1_PODF_OFFSET);
+ break;
+ case 1:
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ prdf = PDR3(MXC_CCM_PDR3_ESDHC2_PRDF_MASK,
+ MXC_CCM_PDR3_ESDHC2_PRDF_OFFSET);
+ podf = PDR3(MXC_CCM_PDR3_ESDHC2_PODF_MASK,
+ MXC_CCM_PDR3_ESDHC2_PODF_OFFSET);
+ } else
+ podf = PDR3(MXC_CCM_PDR3_ESDHC2_PODF_MASK_V2,
+ MXC_CCM_PDR3_ESDHC2_PODF_OFFSET);
+ break;
+ case 2:
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ prdf = PDR3(MXC_CCM_PDR3_ESDHC3_PRDF_MASK,
+ MXC_CCM_PDR3_ESDHC3_PRDF_OFFSET);
+ podf = PDR3(MXC_CCM_PDR3_ESDHC3_PODF_MASK,
+ MXC_CCM_PDR3_ESDHC3_PODF_OFFSET);
+ } else
+ podf = PDR3(MXC_CCM_PDR3_ESDHC3_PODF_MASK_V2,
+ MXC_CCM_PDR3_ESDHC3_PODF_OFFSET);
+ break;
+ default:
+ return;
+ }
+ clk->rate = clk->parent->rate / ((podf + 1) * (prdf + 1));
+}
+
+static int _clk_sdhc_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 prdf, podf;
+
+ div = clk->parent->rate / rate;
+
+ if ((clk->parent->rate / div) != rate)
+ return -EINVAL;
+
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1)
+ __calc_pre_post_dividers(div, &prdf, &podf);
+
+ switch (clk->id) {
+ case 0:
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ reg = __raw_readl(MXC_CCM_PDR3) &
+ ~(MXC_CCM_PDR3_ESDHC1_PRDF_MASK |
+ MXC_CCM_PDR3_ESDHC1_PODF_MASK);
+ reg |= (podf - 1) << MXC_CCM_PDR3_ESDHC1_PODF_OFFSET;
+ reg |= (prdf - 1) << MXC_CCM_PDR3_ESDHC1_PRDF_OFFSET;
+ } else {
+ reg = __raw_readl(MXC_CCM_PDR3) &
+ ~MXC_CCM_PDR3_ESDHC1_PODF_MASK_V2;
+ reg |= (div - 1) << MXC_CCM_PDR3_ESDHC1_PODF_OFFSET;
+ }
+ break;
+ case 1:
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ reg = __raw_readl(MXC_CCM_PDR3) &
+ ~(MXC_CCM_PDR3_ESDHC2_PRDF_MASK |
+ MXC_CCM_PDR3_ESDHC2_PODF_MASK);
+ reg |= (podf - 1) << MXC_CCM_PDR3_ESDHC2_PODF_OFFSET;
+ reg |= (prdf - 1) << MXC_CCM_PDR3_ESDHC2_PRDF_OFFSET;
+ } else {
+ reg = __raw_readl(MXC_CCM_PDR3) &
+ ~MXC_CCM_PDR3_ESDHC2_PODF_MASK_V2;
+ reg |= (div - 1) << MXC_CCM_PDR3_ESDHC2_PODF_OFFSET;
+ }
+ break;
+ case 2:
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ reg = __raw_readl(MXC_CCM_PDR3) &
+ ~(MXC_CCM_PDR3_ESDHC3_PRDF_MASK |
+ MXC_CCM_PDR3_ESDHC3_PODF_MASK);
+ reg |= (podf - 1) << MXC_CCM_PDR3_ESDHC3_PODF_OFFSET;
+ reg |= (prdf - 1) << MXC_CCM_PDR3_ESDHC3_PRDF_OFFSET;
+ } else {
+ reg = __raw_readl(MXC_CCM_PDR3) &
+ ~MXC_CCM_PDR3_ESDHC3_PODF_MASK_V2;
+ reg |= (div - 1) << MXC_CCM_PDR3_ESDHC3_PODF_OFFSET;
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+ __raw_writel(reg, MXC_CCM_PDR3);
+
+ clk->rate = rate;
+ return 0;
+}
+
+static struct clk ckih_clk = {
+ .name = "ckih",
+ .rate = CKIH_CLK_FREQ,
+ .flags = RATE_FIXED,
+};
+
+static struct clk ckil_clk = {
+ .name = "ckil",
+ .rate = CKIL_CLK_FREQ,
+ .flags = RATE_FIXED,
+};
+
+static struct clk ckie_clk = {
+ .name = "ckie",
+ .rate = CKIE_CLK_FREQ,
+ .flags = RATE_FIXED,
+};
+
+static struct clk mcu_pll_clk = {
+ .name = "mcu_pll",
+ .parent = &ckih_clk,
+ .set_rate = _clk_pll_set_rate,
+ .recalc = _clk_pll_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk peri_pll_clk = {
+ .name = "peri_pll",
+ .parent = &ckih_clk,
+ .set_rate = _clk_pll_set_rate,
+ .recalc = _clk_pll_recalc,
+ .enable = _clk_peri_pll_enable,
+ .disable = _clk_peri_pll_disable,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk cpu_clk = {
+ .name = "cpu_clk",
+ .parent = &mcu_pll_clk,
+ .recalc = _clk_cpu_recalc,
+ .set_rate = _clk_cpu_set_rate,
+};
+
+static struct clk ahb_clk = {
+ .name = "ahb_clk",
+ .parent = &cpu_clk,
+ .recalc = _clk_hclk_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk ipg_clk = {
+ .name = "ipg_clk",
+ .parent = &ahb_clk,
+ .recalc = _clk_ipg_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk perclk_clk = {
+ .name = "perclk_clk",
+ .parent = &ahb_clk,
+ .recalc = _clk_per_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk uart_per_clk = {
+ .name = "uart_per_clk",
+ .parent = &peri_pll_clk,
+ .recalc = _clk_uart_per_recalc,
+ .round_rate = _clk_round_rate,
+ .set_rate = _clk_uart_set_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk asrc_clk[] = {
+ {
+ .name = "asrc_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR0,
+ .enable_shift = MXC_CCM_CGR0_ASRC_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "asrc_audio_clk",
+ .parent = &ckie_clk,
+ .recalc = _clk_asrc_recalc,
+ .round_rate = _clk_round_rate,
+ .set_rate = _clk_asrc_set_rate,
+ .enable = _clk_asrc_enable,
+ .disable = _clk_asrc_disable,},
+};
+
+static struct clk ata_clk = {
+ .name = "ata_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR0,
+ .enable_shift = MXC_CCM_CGR0_ATA_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk can_clk[] = {
+ {
+ .name = "can_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR0,
+ .enable_shift = MXC_CCM_CGR0_CAN1_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "can_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR0,
+ .enable_shift = MXC_CCM_CGR0_CAN2_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk cspi_clk[] = {
+ {
+ .name = "cspi_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR0,
+ .enable_shift = MXC_CCM_CGR0_CSPI1_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "cspi_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR0,
+ .enable_shift = MXC_CCM_CGR0_CSPI2_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk ect_clk = {
+ .name = "ect_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR0,
+ .enable_shift = MXC_CCM_CGR0_ECT_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk emi_clk = {
+ .name = "emi_clk",
+ .parent = &ahb_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR0,
+ .enable_shift = MXC_CCM_CGR0_EMI_OFFSET,
+ .disable = _clk_emi_disable,
+};
+
+static struct clk epit_clk[] = {
+ {
+ .name = "epit_clk",
+ .id = 0,
+ .parent = &perclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR0,
+ .enable_shift = MXC_CCM_CGR0_EPIT1_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "epit_clk",
+ .id = 1,
+ .parent = &perclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR0,
+ .enable_shift = MXC_CCM_CGR0_EPIT2_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk esai_clk = {
+ .name = "esai_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR0,
+ .enable_shift = MXC_CCM_CGR0_ESAI_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk sdhc_clk[] = {
+ {
+ .name = "sdhc_clk",
+ .id = 0,
+ .parent = &peri_pll_clk,
+ .recalc = _clk_sdhc_recalc,
+ .set_rate = _clk_sdhc_set_rate,
+ .round_rate = _clk_round_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR0,
+ .enable_shift = MXC_CCM_CGR0_ESDHC1_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "sdhc_clk",
+ .id = 1,
+ .parent = &peri_pll_clk,
+ .recalc = _clk_sdhc_recalc,
+ .set_rate = _clk_sdhc_set_rate,
+ .round_rate = _clk_round_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR0,
+ .enable_shift = MXC_CCM_CGR0_ESDHC2_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "sdhc_clk",
+ .id = 2,
+ .parent = &peri_pll_clk,
+ .recalc = _clk_sdhc_recalc,
+ .set_rate = _clk_sdhc_set_rate,
+ .round_rate = _clk_round_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR0,
+ .enable_shift = MXC_CCM_CGR0_ESDHC3_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk fec_clk = {
+ .name = "fec_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR1,
+ .enable_shift = MXC_CCM_CGR1_FEC_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk gpt_clk = {
+ .name = "gpt_clk",
+ .parent = &perclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR1,
+ .enable_shift = MXC_CCM_CGR1_GPT_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk i2c_clk[] = {
+ {
+ .name = "i2c_clk",
+ .id = 0,
+ .parent = &perclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR1,
+ .enable_shift = MXC_CCM_CGR1_I2C1_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "i2c_clk",
+ .id = 1,
+ .parent = &perclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR1,
+ .enable_shift = MXC_CCM_CGR1_I2C2_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "i2c_clk",
+ .id = 2,
+ .parent = &perclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR1,
+ .enable_shift = MXC_CCM_CGR1_I2C3_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk ipu_clk = {
+ .name = "ipu_clk",
+ .parent = &cpu_clk,
+ .recalc = _clk_hsp_recalc,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR1,
+ .enable_shift = MXC_CCM_CGR1_IPU_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk kpp_clk = {
+ .name = "kpp_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR1,
+ .enable_shift = MXC_CCM_CGR1_KPP_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk mlb_clk = {
+ .name = "mlb_clk",
+ .parent = &ahb_clk,
+ .recalc = _clk_mlb_recalc,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR1,
+ .enable_shift = MXC_CCM_CGR1_MLB_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk mstick_clk = {
+ .name = "mstick_clk",
+ .id = 0,
+ .parent = &peri_pll_clk,
+ .recalc = _clk_mstick1_recalc,
+ .set_rate = _clk_mstick1_set_rate,
+ .round_rate = _clk_per_post_round_rate,
+ .set_parent = _clk_mstick1_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR1,
+ .enable_shift = MXC_CCM_CGR1_MSHC_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk owire_clk = {
+ .name = "owire_clk",
+ .parent = &perclk_clk,
+ .enable_reg = MXC_CCM_CGR1,
+ .enable_shift = MXC_CCM_CGR1_OWIRE_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static struct clk pwm_clk = {
+ .name = "pwm_clk",
+ .parent = &perclk_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR1,
+ .enable_shift = MXC_CCM_CGR1_PWM_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk rng_clk = {
+ .name = "rng_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR1,
+ .enable_shift = MXC_CCM_CGR1_RNGC_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk rtc_clk = {
+ .name = "rtc_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR2,
+ .enable_shift = MXC_CCM_CGR2_RTC_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk rtic_clk = {
+ .name = "rtic_clk",
+ .parent = &ahb_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR2,
+ .enable_shift = MXC_CCM_CGR2_RTIC_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk scc_clk = {
+ .name = "scc_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR2,
+ .enable_shift = MXC_CCM_CGR2_SCC_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk sdma_clk[] = {
+ {
+ .name = "sdma_ahb_clk",
+ .parent = &ahb_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR2,
+ .enable_shift = MXC_CCM_CGR2_SDMA_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "sdma_ipg_clk",
+ .parent = &ipg_clk,}
+};
+
+static struct clk spba_clk = {
+ .name = "spba_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR2,
+ .enable_shift = MXC_CCM_CGR2_SPBA_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk spdif_clk[] = {
+ {
+ .name = "spdif_clk",
+ .parent = &peri_pll_clk,
+ .recalc = _clk_spdif_recalc,
+ .set_rate = _clk_spdif_set_rate,
+ .round_rate = _clk_per_post_round_rate,
+ .set_parent = _clk_spdif_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR2,
+ .enable_shift = MXC_CCM_CGR2_SPDIF_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "spdif_audio_clk",
+ .parent = &ckie_clk,},
+ {
+ .name = "spdif_ipg_clk",
+ .parent = &ipg_clk,},
+};
+
+static struct clk ssi_clk[] = {
+ {
+ .name = "ssi_clk",
+ .parent = &peri_pll_clk,
+ .recalc = _clk_ssi_recalc,
+ .set_rate = _clk_ssi_set_rate,
+ .round_rate = _clk_per_post_round_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR2,
+ .enable_shift = MXC_CCM_CGR2_SSI1_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "ssi_clk",
+ .id = 1,
+ .parent = &peri_pll_clk,
+ .recalc = _clk_ssi_recalc,
+ .set_rate = _clk_ssi_set_rate,
+ .round_rate = _clk_per_post_round_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR2,
+ .enable_shift = MXC_CCM_CGR2_SSI2_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk uart_clk[] = {
+ {
+ .name = "uart_clk",
+ .id = 0,
+ .parent = &uart_per_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR2,
+ .enable_shift = MXC_CCM_CGR2_UART1_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "uart_clk",
+ .id = 1,
+ .parent = &uart_per_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR2,
+ .enable_shift = MXC_CCM_CGR2_UART2_OFFSET,
+ .disable = _clk_disable,},
+ {
+ .name = "uart_clk",
+ .id = 2,
+ .parent = &uart_per_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR2,
+ .enable_shift = MXC_CCM_CGR2_UART3_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk usb_clk[] = {
+ {
+ .name = "usb_clk",
+ .parent = &peri_pll_clk,
+ .recalc = _clk_usb_recalc,
+ .round_rate = _clk_round_rate,
+ .set_rate = _clk_usb_set_rate,},
+ {
+ .name = "usb_ahb_clk",
+ .parent = &ahb_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR2,
+ .enable_shift = MXC_CCM_CGR2_USBOTG_OFFSET,
+ .disable = _clk_disable,},
+};
+
+static struct clk wdog_clk = {
+ .name = "wdog_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR2,
+ .enable_shift = MXC_CCM_CGR2_WDOG_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk csi_clk = {
+ .name = "csi_clk",
+ .parent = &peri_pll_clk,
+ .recalc = _clk_csi_recalc,
+ .round_rate = _clk_round_rate,
+ .set_rate = _clk_csi_set_rate,
+ .set_parent = _clk_csi_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR3,
+ .enable_shift = MXC_CCM_CGR3_CSI_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk iim_clk = {
+ .name = "iim_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CGR3,
+ .enable_shift = MXC_CCM_CGR3_IIM_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk nfc_clk = {
+ .name = "nfc_clk",
+ .parent = &ahb_clk,
+ .recalc = _clk_nfc_recalc,
+};
+
+static unsigned long _clk_cko1_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 div = 0, div1 = 1;
+
+ div = clk->parent->rate / rate;
+ if (clk->parent->rate % rate)
+ div++;
+
+ if (div > 64) {
+ div = (div + 1) >> 1;
+ div1++;
+ }
+
+ if (div > 128)
+ div = 64;
+ return clk->parent->rate / (div * div1);
+}
+
+static int _clk_cko1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div, div1 = 0;
+ u32 prdf, podf;
+
+ div = clk->parent->rate / rate;
+ if ((clk->parent->rate / div) != rate)
+ return -EINVAL;
+ if (div > 64) {
+ div1 = MXC_CCM_COSR_CLKOUTDIV_1;
+ div >>= 1;
+ } else {
+ div1 = 0;
+ }
+
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ __calc_two_dividers(div, &prdf, &podf);
+ reg = __raw_readl(MXC_CCM_COSR) &
+ ~(MXC_CCM_COSR_CLKOUT_PREDIV_MASK |
+ MXC_CCM_COSR_CLKOUT_PRODIV_MASK |
+ MXC_CCM_COSR_CLKOUTDIV_1);
+ reg |= ((prdf - 1) << MXC_CCM_COSR_CLKOUT_PREDIV_OFFSET)
+ | ((podf - 1) << MXC_CCM_COSR_CLKOUT_PRODIV_OFFSET)
+ | div1;
+ } else {
+ reg = __raw_readl(MXC_CCM_COSR) &
+ ~(MXC_CCM_COSR_CLKOUT_PRODIV_MASK_V2 |
+ MXC_CCM_COSR_CLKOUTDIV_1);
+ reg |= ((div - 1) << MXC_CCM_COSR_CLKOUT_PRODIV_OFFSET) | div1;
+ }
+ __raw_writel(reg, MXC_CCM_COSR);
+
+ return 0;
+}
+
+static void _clk_cko1_recalc(struct clk *clk)
+{
+ u32 prdf = 1;
+ u32 podf, div1;
+ u32 reg = __raw_readl(MXC_CCM_COSR);
+
+ div1 = 1 << ((reg & MXC_CCM_COSR_CLKOUTDIV_1) != 0);
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ prdf = (reg & MXC_CCM_COSR_CLKOUT_PREDIV_MASK) >>
+ MXC_CCM_COSR_CLKOUT_PREDIV_OFFSET;
+ podf = (reg & MXC_CCM_COSR_CLKOUT_PRODIV_MASK) >>
+ MXC_CCM_COSR_CLKOUT_PRODIV_OFFSET;
+ } else
+ podf = (reg & MXC_CCM_COSR_CLKOUT_PRODIV_MASK_V2) >>
+ MXC_CCM_COSR_CLKOUT_PRODIV_OFFSET;
+
+ clk->rate = clk->parent->rate / (div1 * (podf + 1) * (prdf + 1));
+}
+
+static int _clk_cko1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+ reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOSEL_MASK;
+
+ if (parent == &ckil_clk) {
+ reg &= ~MXC_CCM_COSR_CKIL_CKIH_MASK;
+ reg |= 0 << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ } else if (parent == &ckih_clk) {
+ reg |= 1 << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ } else if (parent == &ckie_clk)
+ reg |= 2 << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ else if (parent == &peri_pll_clk)
+ reg |= 6 << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ else if (parent == &cpu_clk)
+ reg |= 7 << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ else if (parent == &ahb_clk)
+ reg |= 8 << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ else if (parent == &ipg_clk)
+ reg |= 9 << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ else if (parent == &usb_clk[1])
+ reg |= 0xB << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ else if (parent == &sdhc_clk[1])
+ reg |= 0xC << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ else if (parent == &ssi_clk[1])
+ reg |= 0xD << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ else if (parent == &mlb_clk)
+ reg |= 0xE << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ else if (parent == &csi_clk)
+ reg |= 0x11 << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ else if (parent == &spdif_clk[0])
+ reg |= 0x12 << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ else if (parent == &uart_clk[0])
+ reg |= 0x13 << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ else if (parent == &asrc_clk[1])
+ reg |= 0x14 << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ else if ((parent == &nfc_clk) && (cpu_is_mx35_rev(CHIP_REV_2_0) >= 1))
+ reg |= 0x17 << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ else if ((parent == &ipu_clk) && (cpu_is_mx35_rev(CHIP_REV_2_0) >= 1))
+ reg |= 0x18 << MXC_CCM_COSR_CLKOSEL_OFFSET;
+ else
+ return -EINVAL;
+
+ __raw_writel(reg, MXC_CCM_COSR);
+ return 0;
+}
+
+static int _clk_cko1_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_COSR) | MXC_CCM_COSR_CLKOEN;
+ __raw_writel(reg, MXC_CCM_COSR);
+
+ return 0;
+}
+
+static void _clk_cko1_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_COSR) & ~MXC_CCM_COSR_CLKOEN;
+ __raw_writel(reg, MXC_CCM_COSR);
+}
+
+static struct clk cko1_clk = {
+ .name = "cko1_clk",
+ .recalc = _clk_cko1_recalc,
+ .set_rate = _clk_cko1_set_rate,
+ .round_rate = _clk_cko1_round_rate,
+ .set_parent = _clk_cko1_set_parent,
+ .enable = _clk_cko1_enable,
+ .disable = _clk_cko1_disable,
+};
+
+static struct clk *mxc_clks[] = {
+ &ckih_clk,
+ &ckil_clk,
+ &ckie_clk,
+ &mcu_pll_clk,
+ &peri_pll_clk,
+ &cpu_clk,
+ &ahb_clk,
+ &ipg_clk,
+ &perclk_clk,
+ &uart_per_clk,
+ &asrc_clk[0],
+ &asrc_clk[1],
+ &ata_clk,
+ &can_clk[0],
+ &can_clk[1],
+ &cspi_clk[0],
+ &cspi_clk[1],
+ &ect_clk,
+ &emi_clk,
+ &epit_clk[0],
+ &epit_clk[1],
+ &esai_clk,
+ &sdhc_clk[0],
+ &sdhc_clk[1],
+ &sdhc_clk[2],
+ &fec_clk,
+ &gpt_clk,
+ &i2c_clk[0],
+ &i2c_clk[1],
+ &i2c_clk[2],
+ &ipu_clk,
+ &kpp_clk,
+ &mlb_clk,
+ &mstick_clk,
+ &owire_clk,
+ &rng_clk,
+ &pwm_clk,
+ &rtc_clk,
+ &rtic_clk,
+ &scc_clk,
+ &sdma_clk[0],
+ &sdma_clk[1],
+ &spba_clk,
+ &spdif_clk[0],
+ &spdif_clk[1],
+ &spdif_clk[2],
+ &ssi_clk[0],
+ &ssi_clk[1],
+ &uart_clk[0],
+ &uart_clk[1],
+ &uart_clk[2],
+ &usb_clk[0],
+ &usb_clk[1],
+ &wdog_clk,
+ &csi_clk,
+ &iim_clk,
+ &nfc_clk,
+ &cko1_clk,
+};
+
+extern void propagate_rate(struct clk *tclk);
+
+static void mxc_clockout_scan(void)
+{
+ u32 reg = __raw_readl(MXC_CCM_COSR) & MXC_CCM_COSR_CLKOSEL_MASK;
+ reg >>= MXC_CCM_COSR_CLKOSEL_OFFSET;
+ switch (reg) {
+ case 0:
+ cko1_clk.parent = &ckil_clk;
+ break;
+ case 1:
+ cko1_clk.parent = &ckih_clk;
+ break;
+ case 2:
+ cko1_clk.parent = &ckie_clk;
+ break;
+ case 6:
+ cko1_clk.parent = &peri_pll_clk;
+ break;
+ case 7:
+ cko1_clk.parent = &cpu_clk;
+ break;
+ case 8:
+ cko1_clk.parent = &ahb_clk;
+ break;
+ case 9:
+ cko1_clk.parent = &ipg_clk;
+ break;
+ case 0xB:
+ cko1_clk.parent = &usb_clk[1];
+ break;
+ case 0xC:
+ cko1_clk.parent = &sdhc_clk[1];
+ break;
+ case 0xD:
+ cko1_clk.parent = &ssi_clk[1];
+ break;
+ case 0xE:
+ cko1_clk.parent = &mlb_clk;
+ break;
+ case 0x11:
+ cko1_clk.parent = &csi_clk;
+ break;
+ case 0x12:
+ cko1_clk.parent = &spdif_clk[0];
+ break;
+ case 0x13:
+ cko1_clk.parent = &uart_clk[0];
+ break;
+ case 0x14:
+ cko1_clk.parent = &asrc_clk[1];
+ break;
+ case 0x17:
+ cko1_clk.parent = &nfc_clk;
+ break;
+ case 0x18:
+ cko1_clk.parent = &ipu_clk;
+ break;
+ }
+}
+
+static void mxc_update_clocks(void)
+{
+ unsigned long reg;
+ reg = __raw_readl(MXC_CCM_PDR0);
+ if ((!(reg & MXC_CCM_PDR0_AUTO_CON))
+ && (cpu_is_mx35_rev(CHIP_REV_2_0) < 1))
+ ipu_clk.parent = &ahb_clk;
+
+ if (reg & MXC_CCM_PDR0_PER_SEL)
+ perclk_clk.parent = &cpu_clk;
+
+ reg = __raw_readl(MXC_CCM_PDR1);
+ if (reg & MXC_CCM_PDR1_MSHC_M_U)
+ mstick_clk.parent = &cpu_clk;
+
+ reg = __raw_readl(MXC_CCM_PDR2);
+ if (reg & MXC_CCM_PDR2_CSI_M_U)
+ csi_clk.parent = &cpu_clk;
+ if (reg & MXC_CCM_PDR2_SSI_M_U) {
+ ssi_clk[0].parent = &cpu_clk;
+ ssi_clk[1].parent = &cpu_clk;
+ }
+
+ reg = __raw_readl(MXC_CCM_PDR3);
+ if (reg & MXC_CCM_PDR3_SPDIF_M_U)
+ spdif_clk[0].parent = &cpu_clk;
+
+ if (reg & MXC_CCM_PDR3_UART_M_U)
+ uart_per_clk.parent = &cpu_clk;
+
+ if (reg & MXC_CCM_PDR3_ESDHC_M_U) {
+ sdhc_clk[0].parent = &cpu_clk;
+ sdhc_clk[1].parent = &cpu_clk;
+ sdhc_clk[2].parent = &cpu_clk;
+ }
+
+ reg = __raw_readl(MXC_CCM_PDR4);
+ if (reg & MXC_CCM_PDR4_USB_M_U)
+ usb_clk[0].parent = &cpu_clk;
+
+ mxc_clockout_scan();
+}
+
+int __init mxc_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2)
+{
+ struct clk **clkp;
+ for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++)
+ clk_register(*clkp);
+
+ /* Turn off all possible clocks */
+ __raw_writel(MXC_CCM_CGR0_ECT_MASK | MXC_CCM_CGR0_EMI_MASK,
+ MXC_CCM_CGR0);
+ __raw_writel(MXC_CCM_CGR1_GPIO1_MASK | MXC_CCM_CGR1_GPIO2_MASK |
+ MXC_CCM_CGR1_GPIO3_MASK | MXC_CCM_CGR1_GPT_MASK |
+ MXC_CCM_CGR1_IOMUXC_MASK, MXC_CCM_CGR1);
+ __raw_writel(MXC_CCM_CGR2_MAX_MASK | MXC_CCM_CGR2_SPBA_MASK |
+ MXC_CCM_CGR2_AUDMUX_MASK | MXC_CCM_CGR2_MAX_ENABLE,
+ MXC_CCM_CGR2);
+ __raw_writel(MXC_CCM_CGR3_IIM_MASK, MXC_CCM_CGR3);
+
+ mxc_update_clocks();
+ pr_info("Clock input source is %ld\n", ckih_clk.rate);
+
+ /* Determine which high frequency clock source is coming in */
+ cpu_wp_tbl = get_cpu_wp(&cpu_wp_nr);
+ sync_cpu_wb();
+
+ /* This will propagate to all children and init all the clock rates */
+ propagate_rate(&ckih_clk);
+ propagate_rate(&ckil_clk);
+ propagate_rate(&ckie_clk);
+
+ clk_enable(&mcu_pll_clk);
+ clk_enable(&gpt_clk);
+ clk_enable(&emi_clk);
+ clk_enable(&iim_clk);
+ clk_enable(&spba_clk);
+
+ /* Init serial PLL according */
+ clk_set_rate(&peri_pll_clk, 300000000);
+
+ clk_enable(&peri_pll_clk);
+ return 0;
+}
+
diff --git a/arch/arm/mach-mx35/cpu.c b/arch/arm/mach-mx35/cpu.c
new file mode 100644
index 000000000000..90848a55e0ad
--- /dev/null
+++ b/arch/arm/mach-mx35/cpu.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file mach-mx35/cpu.c
+ *
+ * @brief This file contains the CPU initialization code.
+ *
+ * @ingroup MSL_MX35
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <mach/hardware.h>
+#include <linux/io.h>
+#include <asm/hardware/cache-l2x0.h>
+
+/*!
+ * CPU initialization. It is called by fixup_mxc_board()
+ */
+void __init mxc_cpu_init(void)
+{
+
+ /* Setup Peripheral Port Remap register for AVIC */
+ asm("ldr r0, =0xC0000015 \n\
+ mcr p15, 0, r0, c15, c2, 4");
+ /*TODO:Add code to check chip version */
+
+ if (!system_rev)
+ mxc_set_system_rev(0x35, CHIP_REV_1_0);
+
+}
+
+/*!
+ * Post CPU init code
+ *
+ * @return 0 always
+ */
+static int __init post_cpu_init(void)
+{
+ void *l2_base;
+ unsigned long aips_reg;
+
+ /* Initialize L2 cache */
+ l2_base = ioremap(L2CC_BASE_ADDR, SZ_4K);
+ if (l2_base)
+ l2x0_init(l2_base, 0x00030024, 0x00000000);
+
+ /*
+ * S/W workaround: Clear the off platform peripheral modules
+ * Supervisor Protect bit for SDMA to access them.
+ */
+ __raw_writel(0x0, IO_ADDRESS(AIPS1_BASE_ADDR + 0x40));
+ __raw_writel(0x0, IO_ADDRESS(AIPS1_BASE_ADDR + 0x44));
+ __raw_writel(0x0, IO_ADDRESS(AIPS1_BASE_ADDR + 0x48));
+ __raw_writel(0x0, IO_ADDRESS(AIPS1_BASE_ADDR + 0x4C));
+ aips_reg = __raw_readl(IO_ADDRESS(AIPS1_BASE_ADDR + 0x50));
+ aips_reg &= 0x00FFFFFF;
+ __raw_writel(aips_reg, IO_ADDRESS(AIPS1_BASE_ADDR + 0x50));
+ __raw_writel(0x0, IO_ADDRESS(AIPS2_BASE_ADDR + 0x40));
+ __raw_writel(0x0, IO_ADDRESS(AIPS2_BASE_ADDR + 0x44));
+ __raw_writel(0x0, IO_ADDRESS(AIPS2_BASE_ADDR + 0x48));
+ __raw_writel(0x0, IO_ADDRESS(AIPS2_BASE_ADDR + 0x4C));
+ aips_reg = __raw_readl(IO_ADDRESS(AIPS2_BASE_ADDR + 0x50));
+ aips_reg &= 0x00FFFFFF;
+ __raw_writel(aips_reg, IO_ADDRESS(AIPS2_BASE_ADDR + 0x50));
+
+ return 0;
+}
+
+postcore_initcall(post_cpu_init);
diff --git a/arch/arm/mach-mx35/crm_regs.h b/arch/arm/mach-mx35/crm_regs.h
new file mode 100644
index 000000000000..837ea3958c81
--- /dev/null
+++ b/arch/arm/mach-mx35/crm_regs.h
@@ -0,0 +1,423 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ARCH_ARM_MACH_MX35_CRM_REGS_H__
+#define __ARCH_ARM_MACH_MX35_CRM_REGS_H__
+
+#define CKIH_CLK_FREQ 24000000
+#define CKIE_CLK_FREQ 24576000
+#define CKIL_CLK_FREQ 32000
+
+#define MXC_CCM_BASE ((char *)IO_ADDRESS(CCM_BASE_ADDR))
+
+/* Register addresses */
+#define MXC_CCM_CCMR (MXC_CCM_BASE + 0x00)
+#define MXC_CCM_PDR0 (MXC_CCM_BASE + 0x04)
+#define MXC_CCM_PDR1 (MXC_CCM_BASE + 0x08)
+#define MXC_CCM_PDR2 (MXC_CCM_BASE + 0x0C)
+#define MXC_CCM_PDR3 (MXC_CCM_BASE + 0x10)
+#define MXC_CCM_PDR4 (MXC_CCM_BASE + 0x14)
+#define MXC_CCM_RCSR (MXC_CCM_BASE + 0x18)
+#define MXC_CCM_MPCTL (MXC_CCM_BASE + 0x1C)
+#define MXC_CCM_PPCTL (MXC_CCM_BASE + 0x20)
+#define MXC_CCM_ACMR (MXC_CCM_BASE + 0x24)
+#define MXC_CCM_COSR (MXC_CCM_BASE + 0x28)
+#define MXC_CCM_CGR0 (MXC_CCM_BASE + 0x2C)
+#define MXC_CCM_CGR1 (MXC_CCM_BASE + 0x30)
+#define MXC_CCM_CGR2 (MXC_CCM_BASE + 0x34)
+#define MXC_CCM_CGR3 (MXC_CCM_BASE + 0x38)
+#define MXC_CCM_RESV (MXC_CCM_BASE + 0x3C)
+#define MXC_CCM_DCVR0 (MXC_CCM_BASE + 0x40)
+#define MXC_CCM_DCVR1 (MXC_CCM_BASE + 0x44)
+#define MXC_CCM_DCVR2 (MXC_CCM_BASE + 0x48)
+#define MXC_CCM_DCVR3 (MXC_CCM_BASE + 0x4C)
+#define MXC_CCM_LTR0 (MXC_CCM_BASE + 0x50)
+#define MXC_CCM_LTR1 (MXC_CCM_BASE + 0x54)
+#define MXC_CCM_LTR2 (MXC_CCM_BASE + 0x58)
+#define MXC_CCM_LTR3 (MXC_CCM_BASE + 0x5C)
+#define MXC_CCM_LTBR0 (MXC_CCM_BASE + 0x60)
+#define MXC_CCM_LTBR1 (MXC_CCM_BASE + 0x64)
+#define MXC_CCM_PMCR0 (MXC_CCM_BASE + 0x68)
+#define MXC_CCM_PMCR1 (MXC_CCM_BASE + 0x6C)
+#define MXC_CCM_PMCR2 (MXC_CCM_BASE + 0x70)
+
+/* Register bit definitions */
+#define MXC_CCM_CCMR_WFI (1 << 30)
+#define MXC_CCM_CCMR_STBY_EXIT_SRC (1 << 29)
+#define MXC_CCM_CCMR_VSTBY (1 << 28)
+#define MXC_CCM_CCMR_WBEN (1 << 27)
+#define MXC_CCM_CCMR_VOL_RDY_CNT_OFFSET 20
+#define MXC_CCM_CCMR_VOL_RDY_CNT_MASK (0xF << 20)
+#define MXC_CCM_CCMR_ROMW_OFFSET 18
+#define MXC_CCM_CCMR_ROMW_MASK (0x3 << 18)
+#define MXC_CCM_CCMR_RAMW_OFFSET 21
+#define MXC_CCM_CCMR_RAMW_MASK (0x3 << 21)
+#define MXC_CCM_CCMR_LPM_OFFSET 14
+#define MXC_CCM_CCMR_LPM_MASK (0x3 << 14)
+#define MXC_CCM_CCMR_UPE (1 << 9)
+#define MXC_CCM_CCMR_MPE (1 << 3)
+
+#define MXC_CCM_PDR0_PER_SEL (1 << 26)
+#define MXC_CCM_PDR0_IPU_HND_BYP (1 << 23)
+#define MXC_CCM_PDR0_HSP_PODF_OFFSET 20
+#define MXC_CCM_PDR0_HSP_PODF_MASK (0x3 << 20)
+#define MXC_CCM_PDR0_CON_MUX_DIV_OFFSET 16
+#define MXC_CCM_PDR0_CON_MUX_DIV_MASK (0xF << 16)
+#define MXC_CCM_PDR0_CKIL_SEL (1 << 15)
+#define MXC_CCM_PDR0_PER_PODF_OFFSET 12
+#define MXC_CCM_PDR0_PER_PODF_MASK (0xF << 12)
+#define MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET 9
+#define MXC_CCM_PDR0_AUTO_MUX_DIV_MASK (0x7 << 9)
+#define MXC_CCM_PDR0_AUTO_CON 0x1
+
+#define MXC_CCM_PDR1_MSHC_PRDF_OFFSET 28
+#define MXC_CCM_PDR1_MSHC_PRDF_MASK (0x7 << 28)
+#define MXC_CCM_PDR1_MSHC_PODF_OFFSET 22
+#define MXC_CCM_PDR1_MSHC_PODF_MASK (0x3F << 22)
+#define MXC_CCM_PDR1_MSHC_M_U (1 << 7)
+
+#define MXC_CCM_PDR2_SSI2_PRDF_OFFSET 27
+#define MXC_CCM_PDR2_SSI2_PRDF_MASK (0x7 << 27)
+#define MXC_CCM_PDR2_SSI1_PRDF_OFFSET 24
+#define MXC_CCM_PDR2_SSI1_PRDF_MASK (0x7 << 24)
+#define MXC_CCM_PDR2_CSI_PRDF_OFFSET 19
+#define MXC_CCM_PDR2_CSI_PRDF_MASK (0x7 << 19)
+#define MXC_CCM_PDR2_CSI_PODF_OFFSET 16
+#define MXC_CCM_PDR2_CSI_PODF_MASK (0x7 << 16)
+#define MXC_CCM_PDR2_SSI2_PODF_OFFSET 8
+#define MXC_CCM_PDR2_SSI2_PODF_MASK (0x3F << 8)
+#define MXC_CCM_PDR2_CSI_M_U (1 << 7)
+#define MXC_CCM_PDR2_SSI_M_U (1 << 6)
+#define MXC_CCM_PDR2_SSI1_PODF_OFFSET 0
+#define MXC_CCM_PDR2_SSI1_PODF_MASK (0x3F)
+
+/* Extra definitions for Chip Version 2*/
+#define MXC_CCM_PDR2_CSI_PODF_MASK_V2 (0x3F << 16)
+
+#define MXC_CCM_PDR3_SPDIF_PRDF_OFFSET 29
+#define MXC_CCM_PDR3_SPDIF_PRDF_MASK (0x7 << 29)
+#define MXC_CCM_PDR3_SPDIF_PODF_OFFSET 23
+#define MXC_CCM_PDR3_SPDIF_PODF_MASK (0x3F << 23)
+#define MXC_CCM_PDR3_SPDIF_M_U (1 << 22)
+#define MXC_CCM_PDR3_ESDHC3_PRDF_OFFSET 19
+#define MXC_CCM_PDR3_ESDHC3_PRDF_MASK (0x7 << 19)
+#define MXC_CCM_PDR3_ESDHC3_PODF_OFFSET 16
+#define MXC_CCM_PDR3_ESDHC3_PODF_MASK (0x7 << 16)
+#define MXC_CCM_PDR3_UART_M_U (1 << 15)
+#define MXC_CCM_PDR3_ESDHC2_PRDF_OFFSET 11
+#define MXC_CCM_PDR3_ESDHC2_PRDF_MASK (0x7 << 11)
+#define MXC_CCM_PDR3_ESDHC2_PODF_OFFSET 8
+#define MXC_CCM_PDR3_ESDHC2_PODF_MASK (0x7 << 8)
+#define MXC_CCM_PDR3_ESDHC_M_U (1 << 6)
+#define MXC_CCM_PDR3_ESDHC1_PRDF_OFFSET 3
+#define MXC_CCM_PDR3_ESDHC1_PRDF_MASK (0x7 << 3)
+#define MXC_CCM_PDR3_ESDHC1_PODF_OFFSET 0
+#define MXC_CCM_PDR3_ESDHC1_PODF_MASK (0x7)
+
+/* Extra definitions for Chip Version 2 */
+#define MXC_CCM_PDR3_ESDHC3_PODF_MASK_V2 (0x3F << 16)
+#define MXC_CCM_PDR3_ESDHC2_PODF_MASK_V2 (0x3F << 8)
+#define MXC_CCM_PDR3_ESDHC1_PODF_MASK_V2 0x3F
+
+#define MXC_CCM_PDR4_NFC_PODF_OFFSET 28
+#define MXC_CCM_PDR4_NFC_PODF_MASK (0xF << 28)
+#define MXC_CCM_PDR4_USB_PRDF_OFFSET 25
+#define MXC_CCM_PDR4_USB_PRDF_MASK (0x7 << 25)
+#define MXC_CCM_PDR4_USB_PODF_OFFSET 22
+#define MXC_CCM_PDR4_USB_PODF_MASK (0x7 << 22)
+#define MXC_CCM_PDR4_PER0_PRDF_OFFSET 19
+#define MXC_CCM_PDR4_PER0_PRDF_MASK (0x7 << 19)
+#define MXC_CCM_PDR4_PER0_PODF_OFFSET 16
+#define MXC_CCM_PDR4_PER0_PODF_MASK (0x7 << 16)
+#define MXC_CCM_PDR4_UART_PRDF_OFFSET 13
+#define MXC_CCM_PDR4_UART_PRDF_MASK (0x7 << 13)
+#define MXC_CCM_PDR4_UART_PODF_OFFSET 10
+#define MXC_CCM_PDR4_UART_PODF_MASK (0x7 << 10)
+#define MXC_CCM_PDR4_USB_M_U (1 << 9)
+
+/* Extra definitions for Chip Version 2 */
+#define MXC_CCM_PDR4_USB_PODF_MASK_V2 (0x3F << 22)
+#define MXC_CCM_PDR4_PER0_PODF_MASK_V2 (0x3F << 16)
+#define MXC_CCM_PDR4_UART_PODF_MASK_V2 (0x3F << 10)
+
+/* Bit definitions for RCSR */
+#define MXC_CCM_RCSR_BUS_WIDTH (1 << 29)
+#define MXC_CCM_RCSR_BUS_16BIT (1 << 29)
+#define MXC_CCM_RCSR_PAGE_SIZE (3 << 27)
+#define MXC_CCM_RCSR_PAGE_512 (0 << 27)
+#define MXC_CCM_RCSR_PAGE_2K (1 << 27)
+#define MXC_CCM_RCSR_PAGE_4K1 (2 << 27)
+#define MXC_CCM_RCSR_PAGE_4K2 (3 << 27)
+#define MXC_CCM_RCSR_SOFT_RESET (1 << 15)
+#define MXC_CCM_RCSR_NF16B (1 << 14)
+#define MXC_CCM_RCSR_NFC_4K (1 << 9)
+#define MXC_CCM_RCSR_NFC_FMS (1 << 8)
+
+/* Bit definitions for both MCU, PERIPHERAL PLL control registers */
+#define MXC_CCM_PCTL_BRM 0x80000000
+#define MXC_CCM_PCTL_PD_OFFSET 26
+#define MXC_CCM_PCTL_PD_MASK (0xF << 26)
+#define MXC_CCM_PCTL_MFD_OFFSET 16
+#define MXC_CCM_PCTL_MFD_MASK (0x3FF << 16)
+#define MXC_CCM_PCTL_MFI_OFFSET 10
+#define MXC_CCM_PCTL_MFI_MASK (0xF << 10)
+#define MXC_CCM_PCTL_MFN_OFFSET 0
+#define MXC_CCM_PCTL_MFN_MASK 0x3FF
+
+/* Bit definitions for Audio clock mux register*/
+#define MXC_CCM_ACMR_ESAI_CLK_SEL_OFFSET 12
+#define MXC_CCM_ACMR_ESAI_CLK_SEL_MASK (0xF << 12)
+#define MXC_CCM_ACMR_SPDIF_CLK_SEL_OFFSET 8
+#define MXC_CCM_ACMR_SPDIF_CLK_SEL_MASK (0xF << 8)
+#define MXC_CCM_ACMR_SSI1_CLK_SEL_OFFSET 4
+#define MXC_CCM_ACMR_SSI1_CLK_SEL_MASK (0xF << 4)
+#define MXC_CCM_ACMR_SSI2_CLK_SEL_OFFSET 0
+#define MXC_CCM_ACMR_SSI2_CLK_SEL_MASK (0xF << 0)
+
+/* Extra definitions for Version 2 */
+#define MXC_CCM_ACMR_CKILH_PODF0_OFFSET 16
+#define MXC_CCM_ACMR_CKILH_PODF1_OFFSET 19
+#define MXC_CCM_ACMR_CKILH_PODF2_OFFSET 22
+#define MXC_CCM_ACMR_CKILH_PODF3_OFFSET 25
+#define MXC_CCM_ACMR_CKILH_PODF_MASK 0x7
+
+/* Bit definitions for Clock gating Register*/
+#define MXC_CCM_CGR0_ASRC_OFFSET 0
+#define MXC_CCM_CGR0_ASRC_MASK (0x3 << 0)
+#define MXC_CCM_CGR0_ATA_OFFSET 2
+#define MXC_CCM_CGR0_ATA_MASK (0x3 << 2)
+#define MXC_CCM_CGR0_CAN1_OFFSET 6
+#define MXC_CCM_CGR0_CAN1_MASK (0x3 << 6)
+#define MXC_CCM_CGR0_CAN2_OFFSET 8
+#define MXC_CCM_CGR0_CAN2_MASK (0x3 << 8)
+#define MXC_CCM_CGR0_CSPI1_OFFSET 10
+#define MXC_CCM_CGR0_CSPI1_MASK (0x3 << 10)
+#define MXC_CCM_CGR0_CSPI2_OFFSET 12
+#define MXC_CCM_CGR0_CSPI2_MASK (0x3 << 12)
+#define MXC_CCM_CGR0_ECT_OFFSET 14
+#define MXC_CCM_CGR0_ECT_MASK (0x3 << 14)
+#define MXC_CCM_CGR0_EMI_OFFSET 18
+#define MXC_CCM_CGR0_EMI_MASK (0x3 << 18)
+#define MXC_CCM_CGR0_EPIT1_OFFSET 20
+#define MXC_CCM_CGR0_EPIT1_MASK (0x3 << 20)
+#define MXC_CCM_CGR0_EPIT2_OFFSET 22
+#define MXC_CCM_CGR0_EPIT2_MASK (0x3 << 22)
+#define MXC_CCM_CGR0_ESAI_OFFSET 24
+#define MXC_CCM_CGR0_ESAI_MASK (0x3 << 24)
+#define MXC_CCM_CGR0_ESDHC1_OFFSET 26
+#define MXC_CCM_CGR0_ESDHC1_MASK (0x3 << 26)
+#define MXC_CCM_CGR0_ESDHC2_OFFSET 28
+#define MXC_CCM_CGR0_ESDHC2_MASK (0x3 << 28)
+#define MXC_CCM_CGR0_ESDHC3_OFFSET 30
+#define MXC_CCM_CGR0_ESDHC3_MASK (0x3 << 30)
+
+#define MXC_CCM_CGR1_FEC_OFFSET 0
+#define MXC_CCM_CGR1_FEC_MASK (0x3 << 0)
+#define MXC_CCM_CGR1_GPIO1_OFFSET 2
+#define MXC_CCM_CGR1_GPIO1_MASK (0x3 << 2)
+#define MXC_CCM_CGR1_GPIO2_OFFSET 4
+#define MXC_CCM_CGR1_GPIO2_MASK (0x3 << 4)
+#define MXC_CCM_CGR1_GPIO3_OFFSET 6
+#define MXC_CCM_CGR1_GPIO3_MASK (0x3 << 6)
+#define MXC_CCM_CGR1_GPT_OFFSET 8
+#define MXC_CCM_CGR1_GPT_MASK (0x3 << 8)
+#define MXC_CCM_CGR1_I2C1_OFFSET 10
+#define MXC_CCM_CGR1_I2C1_MASK (0x3 << 10)
+#define MXC_CCM_CGR1_I2C2_OFFSET 12
+#define MXC_CCM_CGR1_I2C2_MASK (0x3 << 12)
+#define MXC_CCM_CGR1_I2C3_OFFSET 14
+#define MXC_CCM_CGR1_I2C3_MASK (0x3 << 14)
+#define MXC_CCM_CGR1_IOMUXC_OFFSET 16
+#define MXC_CCM_CGR1_IOMUXC_MASK (0x3 << 16)
+#define MXC_CCM_CGR1_IPU_OFFSET 18
+#define MXC_CCM_CGR1_IPU_MASK (0x3 << 18)
+#define MXC_CCM_CGR1_KPP_OFFSET 20
+#define MXC_CCM_CGR1_KPP_MASK (0x3 << 20)
+#define MXC_CCM_CGR1_MLB_OFFSET 22
+#define MXC_CCM_CGR1_MLB_MASK (0x3 << 22)
+#define MXC_CCM_CGR1_MSHC_OFFSET 24
+#define MXC_CCM_CGR1_MSHC_MASK (0x3 << 24)
+#define MXC_CCM_CGR1_OWIRE_OFFSET 26
+#define MXC_CCM_CGR1_OWIRE_MASK (0x3 << 26)
+#define MXC_CCM_CGR1_PWM_OFFSET 28
+#define MXC_CCM_CGR1_PWM_MASK (0x3 << 28)
+#define MXC_CCM_CGR1_RNGC_OFFSET 30
+#define MXC_CCM_CGR1_RNGC_MASK (0x3 << 30)
+
+#define MXC_CCM_CGR2_RTC_OFFSET 0
+#define MXC_CCM_CGR2_RTC_MASK (0x3 << 0)
+#define MXC_CCM_CGR2_RTIC_OFFSET 2
+#define MXC_CCM_CGR2_RTIC_MASK (0x3 << 2)
+#define MXC_CCM_CGR2_SCC_OFFSET 4
+#define MXC_CCM_CGR2_SCC_MASK (0x3 << 4)
+#define MXC_CCM_CGR2_SDMA_OFFSET 6
+#define MXC_CCM_CGR2_SDMA_MASK (0x3 << 6)
+#define MXC_CCM_CGR2_SPBA_OFFSET 8
+#define MXC_CCM_CGR2_SPBA_MASK (0x3 << 8)
+#define MXC_CCM_CGR2_SPDIF_OFFSET 10
+#define MXC_CCM_CGR2_SPDIF_MASK (0x3 << 10)
+#define MXC_CCM_CGR2_SSI1_OFFSET 12
+#define MXC_CCM_CGR2_SSI1_MASK (0x3 << 12)
+#define MXC_CCM_CGR2_SSI2_OFFSET 14
+#define MXC_CCM_CGR2_SSI2_MASK (0x3 << 14)
+#define MXC_CCM_CGR2_UART1_OFFSET 16
+#define MXC_CCM_CGR2_UART1_MASK (0x3 << 16)
+#define MXC_CCM_CGR2_UART2_OFFSET 18
+#define MXC_CCM_CGR2_UART2_MASK (0x3 << 18)
+#define MXC_CCM_CGR2_UART3_OFFSET 20
+#define MXC_CCM_CGR2_UART3_MASK (0x3 << 20)
+#define MXC_CCM_CGR2_USBOTG_OFFSET 22
+#define MXC_CCM_CGR2_USBOTG_MASK (0x3 << 22)
+#define MXC_CCM_CGR2_WDOG_OFFSET 24
+#define MXC_CCM_CGR2_WDOG_MASK (0x3 << 24)
+#define MXC_CCM_CGR2_MAX_OFFSET 26
+#define MXC_CCM_CGR2_MAX_MASK (0x3 << 26)
+#define MXC_CCM_CGR2_MAX_ENABLE (0x2 << 26)
+#define MXC_CCM_CGR2_AUDMUX_OFFSET 30
+#define MXC_CCM_CGR2_AUDMUX_MASK (0x3 << 30)
+
+#define MXC_CCM_CGR3_CSI_OFFSET 0
+#define MXC_CCM_CGR3_CSI_MASK (0x3 << 0)
+#define MXC_CCM_CGR3_IIM_OFFSET 2
+#define MXC_CCM_CGR3_IIM_MASK (0x3 << 2)
+#define MXC_CCM_CGR3_GPU2D_OFFSET 4
+#define MXC_CCM_CGR3_GPU2D_MASK (0x3 << 4)
+/*
+ * LTR0 register offsets
+ */
+#define MXC_CCM_LTR0_DNTHR_OFFSET 16
+#define MXC_CCM_LTR0_DNTHR_MASK (0x3F << 16)
+#define MXC_CCM_LTR0_UPTHR_OFFSET 22
+#define MXC_CCM_LTR0_UPTHR_MASK (0x3F << 22)
+#define MXC_CCM_LTR0_DIV3CK_OFFSET 1
+#define MXC_CCM_LTR0_DIV3CK_MASK (0x3 << 1)
+
+/*
+ * LTR1 register offsets
+ */
+#define MXC_CCM_LTR1_PNCTHR_OFFSET 0
+#define MXC_CCM_LTR1_PNCTHR_MASK 0x3F
+#define MXC_CCM_LTR1_UPCNT_OFFSET 6
+#define MXC_CCM_LTR1_UPCNT_MASK (0xFF << 6)
+#define MXC_CCM_LTR1_DNCNT_OFFSET 14
+#define MXC_CCM_LTR1_DNCNT_MASK (0xFF << 14)
+#define MXC_CCM_LTR1_LTBRSR_MASK 0x400000
+#define MXC_CCM_LTR1_LTBRSR_OFFSET 22
+#define MXC_CCM_LTR1_LTBRSR 0x400000
+#define MXC_CCM_LTR1_LTBRSH 0x800000
+
+/*
+ * LTR2 bit definitions. x ranges from 0 for WSW9 to 6 for WSW15
+ */
+#define MXC_CCM_LTR2_WSW_OFFSET(x) (11 + (x) * 3)
+#define MXC_CCM_LTR2_WSW_MASK(x) (0x7 << MXC_CCM_LTR2_WSW_OFFSET((x)))
+#define MXC_CCM_LTR2_EMAC_OFFSET 0
+#define MXC_CCM_LTR2_EMAC_MASK 0x1FF
+
+/*
+ * LTR3 bit definitions. x ranges from 0 for WSW0 to 8 for WSW8
+ */
+#define MXC_CCM_LTR3_WSW_OFFSET(x) (5 + (x) * 3)
+#define MXC_CCM_LTR3_WSW_MASK(x) (0x7 << MXC_CCM_LTR3_WSW_OFFSET((x)))
+
+#define DVSUP_TURBO 0
+#define DVSUP_HIGH 1
+#define DVSUP_MEDIUM 2
+#define DVSUP_LOW 3
+#define MXC_CCM_PMCR0_DVSUP_TURBO (DVSUP_TURBO << 28)
+#define MXC_CCM_PMCR0_DVSUP_HIGH (DVSUP_HIGH << 28)
+#define MXC_CCM_PMCR0_DVSUP_MEDIUM (DVSUP_MEDIUM << 28)
+#define MXC_CCM_PMCR0_DVSUP_LOW (DVSUP_LOW << 28)
+#define MXC_CCM_PMCR0_DVSUP_OFFSET 28
+#define MXC_CCM_PMCR0_DVSUP_MASK (0x3 << 28)
+#define MXC_CCM_PMCR0_DVFS_UPDATE_FINISH 0x01000000
+#define MXC_CCM_PMCR0_DVFEV 0x00800000
+#define MXC_CCM_PMCR0_DVFIS 0x00400000
+#define MXC_CCM_PMCR0_LBMI 0x00200000
+#define MXC_CCM_PMCR0_LBFL 0x00100000
+#define MXC_CCM_PMCR0_LBCF_4 (0x0 << 18)
+#define MXC_CCM_PMCR0_LBCF_8 (0x1 << 18)
+#define MXC_CCM_PMCR0_LBCF_12 (0x2 << 18)
+#define MXC_CCM_PMCR0_LBCF_16 (0x3 << 18)
+#define MXC_CCM_PMCR0_LBCF_OFFSET 18
+#define MXC_CCM_PMCR0_LBCF_MASK (0x3 << 18)
+#define MXC_CCM_PMCR0_PTVIS 0x00020000
+#define MXC_CCM_PMCR0_DVFS_START 0x00010000
+#define MXC_CCM_PMCR0_DVFS_START_MASK 0x1 << 16)
+#define MXC_CCM_PMCR0_FSVAIM 0x00008000
+#define MXC_CCM_PMCR0_FSVAI_OFFSET 13
+#define MXC_CCM_PMCR0_FSVAI_MASK (0x3 << 13)
+#define MXC_CCM_PMCR0_DPVCR 0x00001000
+#define MXC_CCM_PMCR0_DPVV 0x00000800
+#define MXC_CCM_PMCR0_WFIM 0x00000400
+#define MXC_CCM_PMCR0_DRCE3 0x00000200
+#define MXC_CCM_PMCR0_DRCE2 0x00000100
+#define MXC_CCM_PMCR0_DRCE1 0x00000080
+#define MXC_CCM_PMCR0_DRCE0 0x00000040
+#define MXC_CCM_PMCR0_DCR 0x00000020
+#define MXC_CCM_PMCR0_DVFEN 0x00000010
+#define MXC_CCM_PMCR0_PTVAIM 0x00000008
+#define MXC_CCM_PMCR0_PTVAI_OFFSET 1
+#define MXC_CCM_PMCR0_PTVAI_MASK (0x3 << 1)
+#define MXC_CCM_PMCR0_DPTEN 0x00000001
+
+#define MXC_CCM_PMCR1_DVGP_OFFSET 0
+#define MXC_CCM_PMCR1_DVGP_MASK (0xF)
+
+#define MXC_CCM_PMCR1_PLLRDIS (0x1 << 7)
+#define MXC_CCM_PMCR1_EMIRQ_EN (0x1 << 8)
+
+#define MXC_CCM_DCVR_ULV_MASK (0x3FF << 22)
+#define MXC_CCM_DCVR_ULV_OFFSET 22
+#define MXC_CCM_DCVR_LLV_MASK (0x3FF << 12)
+#define MXC_CCM_DCVR_LLV_OFFSET 12
+#define MXC_CCM_DCVR_ELV_MASK (0x3FF << 2)
+#define MXC_CCM_DCVR_ELV_OFFSET 2
+
+#define MXC_CCM_PDR2_MST2_PDF_MASK (0x3F << 7)
+#define MXC_CCM_PDR2_MST2_PDF_OFFSET 7
+#define MXC_CCM_PDR2_MST1_PDF_MASK 0x3F
+#define MXC_CCM_PDR2_MST1_PDF_OFFSET 0
+
+#define MXC_CCM_COSR_CLKOSEL_MASK 0x1F
+#define MXC_CCM_COSR_CLKOSEL_OFFSET 0
+#define MXC_CCM_COSR_CLKOEN (1 << 5)
+#define MXC_CCM_COSR_CLKOUTDIV_1 (1 << 6)
+#define MXC_CCM_COSR_CLKOUT_PREDIV_MASK (0x7 << 13)
+#define MXC_CCM_COSR_CLKOUT_PREDIV_OFFSET 13
+#define MXC_CCM_COSR_CLKOUT_PRODIV_MASK (0x7 << 10)
+#define MXC_CCM_COSR_CLKOUT_PRODIV_OFFSET 10
+#define MXC_CCM_COSR_SSI1_RX_SRC_SEL_MASK (0x3 << 16)
+#define MXC_CCM_COSR_SSI1_RX_SRC_SEL_OFFSET 16
+#define MXC_CCM_COSR_SSI1_TX_SRC_SEL_MASK (0x3 << 18)
+#define MXC_CCM_COSR_SSI1_TX_SRC_SEL_OFFSET 18
+#define MXC_CCM_COSR_SSI2_RX_SRC_SEL_MASK (0x3 << 20)
+#define MXC_CCM_COSR_SSI2_RX_SRC_SEL_OFFSET 20
+#define MXC_CCM_COSR_SSI2_TX_SRC_SEL_MASK (0x3 << 22)
+#define MXC_CCM_COSR_SSI2_TX_SRC_SEL_OFFSET 22
+#define MXC_CCM_COSR_ASRC_AUDIO_EN (1 << 24)
+#define MXC_CCM_COSR_ASRC_AUDIO_PODF_MASK (0x3F << 26)
+#define MXC_CCM_COSR_ASRC_AUDIO_PODF_OFFSET 26
+
+/* extra definitions for Version 2 */
+#define MXC_CCM_COSR_CKIL_CKIH_MASK (1 << 7)
+#define MXC_CCM_COSR_CKIL_CKIH_OFFSET 7
+#define MXC_CCM_COSR_CLKOUT_PRODIV_MASK_V2 (0x3F << 10)
+
+/*
+ * PMCR0 register offsets
+ */
+#define MXC_CCM_PMCR0_LBFL_OFFSET 20
+#define MXC_CCM_PMCR0_DFSUP0_OFFSET 30
+#define MXC_CCM_PMCR0_DFSUP1_OFFSET 31
+
+#endif /* __ARCH_ARM_MACH_MX3_CRM_REGS_H__ */
diff --git a/arch/arm/mach-mx35/devices.c b/arch/arm/mach-mx35/devices.c
new file mode 100644
index 000000000000..f0c5545ccad9
--- /dev/null
+++ b/arch/arm/mach-mx35/devices.c
@@ -0,0 +1,729 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
+
+#include <mach/hardware.h>
+#include <mach/mmc.h>
+#include <mach/spba.h>
+#include <mach/sdma.h>
+
+#include "iomux.h"
+#include "sdma_script_code.h"
+#include "sdma_script_code_v2.h"
+#include "board-mx35_3stack.h"
+
+void mxc_sdma_get_script_info(sdma_script_start_addrs * sdma_script_addr)
+{
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1) {
+ sdma_script_addr->mxc_sdma_ap_2_ap_addr = ap_2_ap_ADDR;
+ sdma_script_addr->mxc_sdma_ap_2_bp_addr = -1;
+ sdma_script_addr->mxc_sdma_bp_2_ap_addr = -1;
+ sdma_script_addr->mxc_sdma_loopback_on_dsp_side_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_interrupt_only_addr = -1;
+
+ sdma_script_addr->mxc_sdma_firi_2_per_addr = -1;
+ sdma_script_addr->mxc_sdma_firi_2_mcu_addr = -1;
+ sdma_script_addr->mxc_sdma_per_2_firi_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_2_firi_addr = -1;
+
+ sdma_script_addr->mxc_sdma_uart_2_per_addr = uart_2_per_ADDR;
+ sdma_script_addr->mxc_sdma_uart_2_mcu_addr = uart_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_per_2_app_addr = per_2_app_ADDR;
+ sdma_script_addr->mxc_sdma_mcu_2_app_addr = mcu_2_app_ADDR;
+
+ sdma_script_addr->mxc_sdma_per_2_per_addr = p_2_p_ADDR;
+
+ sdma_script_addr->mxc_sdma_uartsh_2_per_addr =
+ uartsh_2_per_ADDR;
+ sdma_script_addr->mxc_sdma_uartsh_2_mcu_addr =
+ uartsh_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_per_2_shp_addr = per_2_shp_ADDR;
+ sdma_script_addr->mxc_sdma_mcu_2_shp_addr = mcu_2_shp_ADDR;
+
+ sdma_script_addr->mxc_sdma_ata_2_mcu_addr = ata_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_mcu_2_ata_addr = mcu_2_ata_ADDR;
+
+ sdma_script_addr->mxc_sdma_app_2_per_addr = app_2_per_ADDR;
+ sdma_script_addr->mxc_sdma_app_2_mcu_addr = app_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_shp_2_per_addr = shp_2_per_ADDR;
+ sdma_script_addr->mxc_sdma_shp_2_mcu_addr = shp_2_mcu_ADDR;
+
+ sdma_script_addr->mxc_sdma_mshc_2_mcu_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_2_mshc_addr = -1;
+
+ sdma_script_addr->mxc_sdma_spdif_2_mcu_addr = spdif_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_mcu_2_spdif_addr = mcu_2_spdif_ADDR;
+
+ sdma_script_addr->mxc_sdma_asrc_2_mcu_addr = asrc__mcu_ADDR;
+
+ sdma_script_addr->mxc_sdma_dptc_dvfs_addr = -1;
+ sdma_script_addr->mxc_sdma_ext_mem_2_ipu_addr =
+ ext_mem__ipu_ram_ADDR;
+ sdma_script_addr->mxc_sdma_descrambler_addr = -1;
+
+ sdma_script_addr->mxc_sdma_start_addr =
+ (unsigned short *)sdma_code;
+ sdma_script_addr->mxc_sdma_ram_code_size = RAM_CODE_SIZE;
+ sdma_script_addr->mxc_sdma_ram_code_start_addr =
+ RAM_CODE_START_ADDR;
+ } else {
+ sdma_script_addr->mxc_sdma_ap_2_ap_addr = ap_2_ap_ADDR_V2;
+ sdma_script_addr->mxc_sdma_ap_2_bp_addr = -1;
+ sdma_script_addr->mxc_sdma_bp_2_ap_addr = -1;
+ sdma_script_addr->mxc_sdma_loopback_on_dsp_side_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_interrupt_only_addr = -1;
+
+ sdma_script_addr->mxc_sdma_firi_2_per_addr = -1;
+ sdma_script_addr->mxc_sdma_firi_2_mcu_addr = -1;
+ sdma_script_addr->mxc_sdma_per_2_firi_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_2_firi_addr = -1;
+
+ sdma_script_addr->mxc_sdma_uart_2_per_addr = uart_2_per_ADDR_V2;
+ sdma_script_addr->mxc_sdma_uart_2_mcu_addr = uart_2_mcu_ADDR_V2;
+ sdma_script_addr->mxc_sdma_per_2_app_addr = per_2_app_ADDR_V2;
+ sdma_script_addr->mxc_sdma_mcu_2_app_addr = mcu_2_app_ADDR_V2;
+
+ sdma_script_addr->mxc_sdma_per_2_per_addr = p_2_p_ADDR_V2;
+
+ sdma_script_addr->mxc_sdma_uartsh_2_per_addr =
+ uartsh_2_per_ADDR_V2;
+ sdma_script_addr->mxc_sdma_uartsh_2_mcu_addr =
+ uartsh_2_mcu_ADDR_V2;
+ sdma_script_addr->mxc_sdma_per_2_shp_addr = per_2_shp_ADDR_V2;
+ sdma_script_addr->mxc_sdma_mcu_2_shp_addr = mcu_2_shp_ADDR_V2;
+
+ sdma_script_addr->mxc_sdma_ata_2_mcu_addr = ata_2_mcu_ADDR_V2;
+ sdma_script_addr->mxc_sdma_mcu_2_ata_addr = mcu_2_ata_ADDR_V2;
+
+ sdma_script_addr->mxc_sdma_app_2_per_addr = app_2_per_ADDR_V2;
+ sdma_script_addr->mxc_sdma_app_2_mcu_addr = app_2_mcu_ADDR_V2;
+ sdma_script_addr->mxc_sdma_shp_2_per_addr = shp_2_per_ADDR_V2;
+ sdma_script_addr->mxc_sdma_shp_2_mcu_addr = shp_2_mcu_ADDR_V2;
+
+ sdma_script_addr->mxc_sdma_mshc_2_mcu_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_2_mshc_addr = -1;
+
+ sdma_script_addr->mxc_sdma_spdif_2_mcu_addr =
+ spdif_2_mcu_ADDR_V2;
+ sdma_script_addr->mxc_sdma_mcu_2_spdif_addr =
+ mcu_2_spdif_ADDR_V2;
+
+ sdma_script_addr->mxc_sdma_asrc_2_mcu_addr = asrc__mcu_ADDR_V2;
+
+ sdma_script_addr->mxc_sdma_dptc_dvfs_addr = -1;
+ sdma_script_addr->mxc_sdma_ext_mem_2_ipu_addr =
+ ext_mem__ipu_ram_ADDR_V2;
+ sdma_script_addr->mxc_sdma_descrambler_addr = -1;
+
+ sdma_script_addr->mxc_sdma_start_addr =
+ (unsigned short *)sdma_code_v2;
+ sdma_script_addr->mxc_sdma_ram_code_size = RAM_CODE_SIZE;
+ sdma_script_addr->mxc_sdma_ram_code_start_addr =
+ RAM_CODE_START_ADDR_V2;
+ }
+}
+
+static void mxc_nop_release(struct device *dev)
+{
+ /* Nothing */
+}
+
+#if defined(CONFIG_RTC_MXC) || defined(CONFIG_RTC_MXC_MODULE)
+static struct resource rtc_resources[] = {
+ {
+ .start = RTC_BASE_ADDR,
+ .end = RTC_BASE_ADDR + 0x30,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_INT_RTC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+static struct platform_device mxc_rtc_device = {
+ .name = "mxc_rtc",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resource = rtc_resources,
+};
+static void mxc_init_rtc(void)
+{
+ (void)platform_device_register(&mxc_rtc_device);
+}
+#else
+static inline void mxc_init_rtc(void)
+{
+}
+#endif
+
+#if defined(CONFIG_MXC_MC9SDZ60_RTC) || defined(CONFIG_MXC_MC9SDZ60_RTC_MODULE)
+static struct resource pmic_rtc_resources[] = {
+ {
+ .start = MXC_PSEUDO_IRQ_RTC,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+static struct platform_device pmic_rtc_device = {
+ .name = "pmic_rtc",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(pmic_rtc_resources),
+ .resource = pmic_rtc_resources,
+};
+static void pmic_init_rtc(void)
+{
+ platform_device_register(&pmic_rtc_device);
+}
+#else
+static void pmic_init_rtc(void)
+{
+}
+#endif
+
+#if defined(CONFIG_MXC_WATCHDOG) || defined(CONFIG_MXC_WATCHDOG_MODULE)
+static struct resource wdt_resources[] = {
+ {
+ .start = WDOG1_BASE_ADDR,
+ .end = WDOG1_BASE_ADDR + 0x30,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device mxc_wdt_device = {
+ .name = "mxc_wdt",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+static void mxc_init_wdt(void)
+{
+ (void)platform_device_register(&mxc_wdt_device);
+}
+#else
+static inline void mxc_init_wdt(void)
+{
+}
+#endif
+
+#if defined(CONFIG_MXC_IPU) || defined(CONFIG_MXC_IPU_MODULE)
+static struct mxc_ipu_config mxc_ipu_data = {
+ .rev = 2,
+};
+
+static struct resource ipu_resources[] = {
+ {
+ .start = IPU_CTRL_BASE_ADDR,
+ .end = IPU_CTRL_BASE_ADDR + SZ_4K,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_INT_IPU_SYN,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MXC_INT_IPU_ERR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mxc_ipu_device = {
+ .name = "mxc_ipu",
+ .id = -1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_ipu_data,
+ },
+ .num_resources = ARRAY_SIZE(ipu_resources),
+ .resource = ipu_resources,
+};
+
+static void mxc_init_ipu(void)
+{
+ platform_device_register(&mxc_ipu_device);
+}
+#else
+static inline void mxc_init_ipu(void)
+{
+}
+#endif
+
+/* SPI controller and device data */
+#if defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE)
+
+#ifdef CONFIG_SPI_MXC_SELECT1
+/*!
+ * Resource definition for the CSPI1
+ */
+static struct resource mxcspi1_resources[] = {
+ [0] = {
+ .start = CSPI1_BASE_ADDR,
+ .end = CSPI1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_CSPI1,
+ .end = MXC_INT_CSPI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC CSPI1 */
+static struct mxc_spi_master mxcspi1_data = {
+ .maxchipselect = 4,
+ .spi_version = 7,
+};
+
+/*! Device Definition for MXC CSPI1 */
+static struct platform_device mxcspi1_device = {
+ .name = "mxc_spi",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxcspi1_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcspi1_resources),
+ .resource = mxcspi1_resources,
+};
+
+#endif /* CONFIG_SPI_MXC_SELECT1 */
+
+#ifdef CONFIG_SPI_MXC_SELECT2
+/*!
+ * Resource definition for the CSPI2
+ */
+static struct resource mxcspi2_resources[] = {
+ [0] = {
+ .start = CSPI2_BASE_ADDR,
+ .end = CSPI2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_CSPI2,
+ .end = MXC_INT_CSPI2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC CSPI2 */
+static struct mxc_spi_master mxcspi2_data = {
+ .maxchipselect = 4,
+ .spi_version = 7,
+};
+
+/*! Device Definition for MXC CSPI2 */
+static struct platform_device mxcspi2_device = {
+ .name = "mxc_spi",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxcspi2_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcspi2_resources),
+ .resource = mxcspi2_resources,
+};
+#endif /* CONFIG_SPI_MXC_SELECT2 */
+
+static inline void mxc_init_spi(void)
+{
+ /* SPBA configuration for CSPI2 - MCU is set */
+ spba_take_ownership(SPBA_CSPI2, SPBA_MASTER_A);
+#ifdef CONFIG_SPI_MXC_SELECT1
+ if (platform_device_register(&mxcspi1_device) < 0)
+ printk(KERN_ERR "Error: Registering the SPI Controller_1\n");
+#endif /* CONFIG_SPI_MXC_SELECT1 */
+#ifdef CONFIG_SPI_MXC_SELECT2
+ if (platform_device_register(&mxcspi2_device) < 0)
+ printk(KERN_ERR "Error: Registering the SPI Controller_2\n");
+#endif /* CONFIG_SPI_MXC_SELECT2 */
+}
+#else
+static inline void mxc_init_spi(void)
+{
+}
+#endif
+
+/* I2C controller and device data */
+#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE)
+
+#ifdef CONFIG_I2C_MXC_SELECT1
+/*!
+ * Resource definition for the I2C1
+ */
+static struct resource mxci2c1_resources[] = {
+ [0] = {
+ .start = I2C_BASE_ADDR,
+ .end = I2C_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_I2C,
+ .end = MXC_INT_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC I2C */
+static struct mxc_i2c_platform_data mxci2c1_data = {
+ .i2c_clk = 100000,
+};
+#endif
+
+/*!
+ * Resource definition for the I2C2
+ */
+static struct resource mxci2c2_resources[] = {
+ [0] = {
+ .start = I2C2_BASE_ADDR,
+ .end = I2C2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_I2C2,
+ .end = MXC_INT_I2C2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC I2C */
+static struct mxc_i2c_platform_data mxci2c2_data = {
+ .i2c_clk = 100000,
+};
+
+#ifdef CONFIG_I2C_MXC_SELECT3
+/*!
+ * Resource definition for the I2C3
+ */
+static struct resource mxci2c3_resources[] = {
+ [0] = {
+ .start = I2C3_BASE_ADDR,
+ .end = I2C3_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_I2C3,
+ .end = MXC_INT_I2C3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC I2C */
+static struct mxc_i2c_platform_data mxci2c3_data = {
+ .i2c_clk = 100000,
+};
+#endif
+
+/*! Device Definition for MXC I2C1 */
+static struct platform_device mxci2c_devices[] = {
+#ifdef CONFIG_I2C_MXC_SELECT1
+ {
+ .name = "mxc_i2c",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxci2c1_data,
+ },
+ .num_resources = ARRAY_SIZE(mxci2c1_resources),
+ .resource = mxci2c1_resources,},
+#endif
+ {
+ .name = "mxc_i2c_slave",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxci2c2_data,
+ },
+ .num_resources = ARRAY_SIZE(mxci2c2_resources),
+ .resource = mxci2c2_resources,},
+#ifdef CONFIG_I2C_MXC_SELECT3
+ {
+ .name = "mxc_i2c",
+ .id = 2,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxci2c3_data,
+ },
+ .num_resources = ARRAY_SIZE(mxci2c3_resources),
+ .resource = mxci2c3_resources,},
+#endif
+};
+
+static inline void mxc_init_i2c(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mxci2c_devices); i++) {
+ if (platform_device_register(&mxci2c_devices[i]) < 0)
+ dev_err(&mxci2c_devices[i].dev,
+ "Unable to register I2C device\n");
+ }
+}
+#else
+static inline void mxc_init_i2c(void)
+{
+}
+#endif
+
+struct mxc_gpio_port mxc_gpio_ports[GPIO_PORT_NUM] = {
+ {
+ .num = 0,
+ .base = IO_ADDRESS(GPIO1_BASE_ADDR),
+ .irq = MXC_INT_GPIO1,
+ .virtual_irq_start = MXC_GPIO_INT_BASE,
+ },
+ {
+ .num = 1,
+ .base = IO_ADDRESS(GPIO2_BASE_ADDR),
+ .irq = MXC_INT_GPIO2,
+ .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN,
+ },
+ {
+ .num = 2,
+ .base = IO_ADDRESS(GPIO3_BASE_ADDR),
+ .irq = MXC_INT_GPIO3,
+ .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 2,
+ },
+};
+
+static struct platform_device mxc_dma_device = {
+ .name = "mxc_dma",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+};
+
+static inline void mxc_init_dma(void)
+{
+ (void)platform_device_register(&mxc_dma_device);
+}
+
+static struct resource spdif_resources[] = {
+ {
+ .start = SPDIF_BASE_ADDR,
+ .end = SPDIF_BASE_ADDR + 0x50,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct mxc_spdif_platform_data mxc_spdif_data = {
+ .spdif_tx = 1,
+ .spdif_rx = 1,
+ .spdif_clk_44100 = 3, /* spdif_ext_clk source for 44.1KHz */
+ .spdif_clk_48000 = 0, /* audio osc source */
+ .spdif_clkid = 0,
+ .spdif_clk = NULL, /* spdif bus clk */
+};
+
+static struct platform_device mxc_alsa_spdif_device = {
+ .name = "mxc_alsa_spdif",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_spdif_data,
+ },
+ .num_resources = ARRAY_SIZE(spdif_resources),
+ .resource = spdif_resources,
+};
+
+static inline void mxc_init_spdif(void)
+{
+ mxc_spdif_data.spdif_clk = clk_get(NULL, "spdif_ipg_clk");
+ clk_put(mxc_spdif_data.spdif_clk);
+ mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_clk");
+ clk_put(mxc_spdif_data.spdif_core_clk);
+ platform_device_register(&mxc_alsa_spdif_device);
+}
+
+static struct mxc_audio_platform_data mxc_audio_data;
+
+static struct platform_device mxc_alsa_device = {
+ .name = "imx-3stack-ak4647",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_audio_data,
+ },
+
+};
+
+static void mxc_init_audio(void)
+{
+ if (board_is_mx35(BOARD_REV_2))
+ return;
+ mxc_audio_data.ssi_num = 1;
+ mxc_audio_data.src_port = 1;
+ mxc_audio_data.ext_port = 4;
+ mxc_audio_data.intr_id_hp = MXC_PSEUDO_IRQ_HEADPHONE;
+ platform_device_register(&mxc_alsa_device);
+}
+
+static struct platform_device mxc_alsa_surround_device = {
+ .name = "imx-3stack-wm8580",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+};
+
+static void mxc_init_surround_audio(void)
+{
+ platform_device_register(&mxc_alsa_surround_device);
+}
+
+static struct mxc_audio_platform_data mxc_bt_audio_data;
+
+static struct platform_device mxc_bt_alsa_device = {
+ .name = "imx-3stack-bt",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_bt_audio_data,
+ },
+
+};
+
+static void mxc_init_bt_audio(void)
+{
+ mxc_bt_audio_data.src_port = 2;
+ mxc_bt_audio_data.ext_port = 5;
+ mxc_bt_audio_data.ext_ram = 1;
+ platform_device_register(&mxc_bt_alsa_device);
+}
+
+static struct resource asrc_resources[] = {
+ {
+ .start = ASRC_BASE_ADDR,
+ .end = ASRC_BASE_ADDR + 0x9C,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct mxc_asrc_platform_data mxc_asrc_data;
+
+static struct platform_device mxc_asrc_device = {
+ .name = "mxc_asrc",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_asrc_data,
+ },
+ .num_resources = ARRAY_SIZE(asrc_resources),
+ .resource = asrc_resources,
+};
+
+static inline void mxc_init_asrc(void)
+{
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 1)
+ mxc_asrc_data.channel_bits = 3;
+ else
+ mxc_asrc_data.channel_bits = 4;
+
+ mxc_asrc_data.asrc_core_clk = clk_get(NULL, "asrc_clk");
+ clk_put(mxc_asrc_data.asrc_core_clk);
+ mxc_asrc_data.asrc_audio_clk = clk_get(NULL, "asrc_audio_clk");
+ clk_set_rate(mxc_asrc_data.asrc_audio_clk, 768000);
+ clk_put(mxc_asrc_data.asrc_audio_clk);
+ platform_device_register(&mxc_asrc_device);
+}
+
+#if defined(CONFIG_CAN_FLEXCAN) || defined(CONFIG_CAN_FLEXCAN_MODULE)
+
+static struct resource flexcan1_resources[] = {
+ {
+ .start = CAN1_BASE_ADDR,
+ .end = CAN1_BASE_ADDR + 0x97F,
+ .flags = IORESOURCE_MEM,},
+ {
+ .start = MXC_INT_CAN1,
+ .end = MXC_INT_CAN1,
+ .flags = IORESOURCE_IRQ,}
+};
+
+static struct resource flexcan2_resources[] = {
+ {
+ .start = CAN2_BASE_ADDR,
+ .end = CAN2_BASE_ADDR + 0x97F,
+ .flags = IORESOURCE_MEM,},
+ {
+ .start = MXC_INT_CAN2,
+ .end = MXC_INT_CAN2,
+ .flags = IORESOURCE_IRQ,}
+};
+
+static struct platform_device flexcan_devices[] = {
+ {
+ .name = "FlexCAN",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &flexcan_data[0],
+ },
+ .num_resources = ARRAY_SIZE(flexcan1_resources),
+ .resource = flexcan1_resources,},
+ {
+ .name = "FlexCAN",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &flexcan_data[1],
+ },
+ .num_resources = ARRAY_SIZE(flexcan2_resources),
+ .resource = flexcan2_resources,},
+};
+
+static inline void mxc_init_flexcan(void)
+{
+ platform_device_register(&flexcan_devices[0]);
+ platform_device_register(&flexcan_devices[1]);
+}
+#else
+static inline void mxc_init_flexcan(void)
+{
+}
+#endif
+
+int __init mxc_init_devices(void)
+{
+ mxc_init_wdt();
+ mxc_init_ipu();
+ mxc_init_spi();
+ mxc_init_i2c();
+ pmic_init_rtc();
+ mxc_init_rtc();
+ mxc_init_dma();
+ mxc_init_bt_audio();
+ mxc_init_spdif();
+ mxc_init_audio();
+ mxc_init_surround_audio();
+ mxc_init_asrc();
+ mxc_init_flexcan();
+
+ /* SPBA configuration for SSI2 - SDMA and MCU are set */
+ spba_take_ownership(SPBA_SSI2, SPBA_MASTER_C | SPBA_MASTER_A);
+ return 0;
+}
diff --git a/arch/arm/mach-mx35/dma.c b/arch/arm/mach-mx35/dma.c
new file mode 100644
index 000000000000..790181eea955
--- /dev/null
+++ b/arch/arm/mach-mx35/dma.c
@@ -0,0 +1,753 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/init.h>
+#include <linux/device.h>
+#include <asm/dma.h>
+#include <mach/hardware.h>
+
+#include "serial.h"
+
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+#define soc_trans_type int_2_per
+#else
+#define soc_trans_type emi_2_per
+#endif
+
+#define MXC_SPDIF_TXFIFO_WML 8
+#define MXC_SPDIF_RXFIFO_WML 8
+#define MXC_SPDIF_TX_REG 0x2C
+#define MXC_SPDIF_RX_REG 0x14
+
+#define MXC_SSI_TX0_REG 0x0
+#define MXC_SSI_TX1_REG 0x4
+#define MXC_SSI_RX0_REG 0x8
+#define MXC_SSI_RX1_REG 0xC
+#define MXC_SSI_TXFIFO_WML 0x4
+#define MXC_SSI_RXFIFO_WML 0x6
+
+#define MXC_ASRC_FIFO_WML 0x40
+#define MXC_ASRCA_RX_REG 0x60
+#define MXC_ASRCA_TX_REG 0x64
+#define MXC_ASRCB_RX_REG 0x68
+#define MXC_ASRCB_TX_REG 0x6C
+#define MXC_ASRCC_RX_REG 0x70
+#define MXC_ASRCC_TX_REG 0x74
+
+#define MXC_ESAI_TX_REG 0x00
+#define MXC_ESAI_RX_REG 0x04
+#define MXC_ESAI_FIFO_WML 0x40
+
+struct mxc_sdma_info_entry_s {
+ mxc_dma_device_t device;
+ mxc_sdma_channel_params_t *chnl_info;
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart1_rx_params = {
+ .chnl_params = {
+ .watermark_level = UART1_UFCR_RXTL,
+ .per_address = UART1_BASE_ADDR,
+ .peripheral_type = UART,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_UART1_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART1_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart1_tx_params = {
+ .chnl_params = {
+ .watermark_level = UART1_UFCR_TXTL,
+ .per_address = UART1_BASE_ADDR + MXC_UARTUTXD,
+ .peripheral_type = UART,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_UART1_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART1_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart2_rx_params = {
+ .chnl_params = {
+ .watermark_level = UART2_UFCR_RXTL,
+ .per_address = UART2_BASE_ADDR,
+ .peripheral_type = UART,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_UART2_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART2_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart2_tx_params = {
+ .chnl_params = {
+ .watermark_level = UART2_UFCR_TXTL,
+ .per_address = UART2_BASE_ADDR + MXC_UARTUTXD,
+ .peripheral_type = UART,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_UART2_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART2_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart3_rx_params = {
+ .chnl_params = {
+ .watermark_level = UART3_UFCR_RXTL,
+ .per_address = UART3_BASE_ADDR,
+ .peripheral_type = UART_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_UART3_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART3_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart3_tx_params = {
+ .chnl_params = {
+ .watermark_level = UART3_UFCR_TXTL,
+ .per_address = UART3_BASE_ADDR + MXC_UARTUTXD,
+ .peripheral_type = UART_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_UART3_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART3_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_spdif_16bit_tx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SPDIF_TXFIFO_WML,
+ .per_address = SPDIF_BASE_ADDR + MXC_SPDIF_TX_REG,
+ .peripheral_type = SPDIF,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SPDIF_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SPDIF_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_spdif_32bit_tx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SPDIF_TXFIFO_WML,
+ .per_address = SPDIF_BASE_ADDR + MXC_SPDIF_TX_REG,
+ .peripheral_type = SPDIF,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SPDIF_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SPDIF_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_spdif_32bit_rx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SPDIF_RXFIFO_WML,
+ .per_address = SPDIF_BASE_ADDR + MXC_SPDIF_RX_REG,
+ .peripheral_type = SPDIF,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SPDIF_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SPDIF_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_memory_params = {
+ .chnl_params = {
+ .peripheral_type = MEMORY,
+ .transfer_type = emi_2_emi,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_MEMORY,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = soc_trans_type,
+ .event_id = DMA_REQ_SSI1_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = soc_trans_type,
+ .event_id = DMA_REQ_SSI1_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = soc_trans_type,
+ .event_id = DMA_REQ_SSI1_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = soc_trans_type,
+ .event_id = DMA_REQ_SSI1_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = soc_trans_type,
+ .event_id = DMA_REQ_SSI1_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = soc_trans_type,
+ .event_id = DMA_REQ_SSI1_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_asrca_rx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_ASRC_FIFO_WML,
+ .per_address = ASRC_BASE_ADDR + MXC_ASRCA_RX_REG,
+ .peripheral_type = ASRC,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_ASRC_DMA1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_ASRCA_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_asrca_tx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_ASRC_FIFO_WML,
+ .per_address = ASRC_BASE_ADDR + MXC_ASRCA_TX_REG,
+ .peripheral_type = ASRC,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_ASRC_DMA4,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_ASRCA_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_asrcb_rx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_ASRC_FIFO_WML,
+ .per_address = ASRC_BASE_ADDR + MXC_ASRCB_RX_REG,
+ .peripheral_type = ASRC,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_ASRC_DMA2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_ASRCB_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_asrcb_tx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_ASRC_FIFO_WML,
+ .per_address = ASRC_BASE_ADDR + MXC_ASRCB_TX_REG,
+ .peripheral_type = ASRC,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_ASRC_DMA5,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_ASRCB_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_asrcc_rx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_ASRC_FIFO_WML * 3,
+ .per_address = ASRC_BASE_ADDR + MXC_ASRCC_RX_REG,
+ .peripheral_type = ASRC,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_ASRC_DMA3,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_ASRCC_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_asrcc_tx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_ASRC_FIFO_WML * 3,
+ .per_address = ASRC_BASE_ADDR + MXC_ASRCC_TX_REG,
+ .peripheral_type = ASRC,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_ASRC_DMA6,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_ASRCC_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_esai_16bit_rx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_ESAI_FIFO_WML,
+ .per_address = ESAI_BASE_ADDR + MXC_ESAI_RX_REG,
+ .peripheral_type = ESAI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_ESAI_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_ESAI_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_esai_16bit_tx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_ESAI_FIFO_WML,
+ .per_address = ESAI_BASE_ADDR + MXC_ESAI_TX_REG,
+ .peripheral_type = ESAI,
+ .transfer_type = soc_trans_type,
+ .event_id = DMA_REQ_ESAI_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_ESAI_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_esai_24bit_rx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_ESAI_FIFO_WML,
+ .per_address = ESAI_BASE_ADDR + MXC_ESAI_RX_REG,
+ .peripheral_type = ESAI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_ESAI_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_ESAI_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_esai_24bit_tx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_ESAI_FIFO_WML,
+ .per_address = ESAI_BASE_ADDR + MXC_ESAI_TX_REG,
+ .peripheral_type = ESAI,
+ .transfer_type = soc_trans_type,
+ .event_id = DMA_REQ_ESAI_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_ESAI_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static struct mxc_sdma_info_entry_s mxc_sdma_active_dma_info[] = {
+ {MXC_DMA_UART1_RX, &mxc_sdma_uart1_rx_params},
+ {MXC_DMA_UART1_TX, &mxc_sdma_uart1_tx_params},
+ {MXC_DMA_UART2_RX, &mxc_sdma_uart2_rx_params},
+ {MXC_DMA_UART2_TX, &mxc_sdma_uart2_tx_params},
+ {MXC_DMA_UART3_RX, &mxc_sdma_uart3_rx_params},
+ {MXC_DMA_UART3_TX, &mxc_sdma_uart3_tx_params},
+ {MXC_DMA_SPDIF_16BIT_TX, &mxc_sdma_spdif_16bit_tx_params},
+ {MXC_DMA_SPDIF_32BIT_TX, &mxc_sdma_spdif_32bit_tx_params},
+ {MXC_DMA_SPDIF_32BIT_RX, &mxc_sdma_spdif_32bit_rx_params},
+ {MXC_DMA_SSI1_8BIT_RX0, &mxc_sdma_ssi1_8bit_rx0_params},
+ {MXC_DMA_SSI1_8BIT_TX0, &mxc_sdma_ssi1_8bit_tx0_params},
+ {MXC_DMA_SSI1_16BIT_RX0, &mxc_sdma_ssi1_16bit_rx0_params},
+ {MXC_DMA_SSI1_16BIT_TX0, &mxc_sdma_ssi1_16bit_tx0_params},
+ {MXC_DMA_SSI1_24BIT_RX0, &mxc_sdma_ssi1_24bit_rx0_params},
+ {MXC_DMA_SSI1_24BIT_TX0, &mxc_sdma_ssi1_24bit_tx0_params},
+ {MXC_DMA_SSI1_8BIT_RX1, &mxc_sdma_ssi1_8bit_rx1_params},
+ {MXC_DMA_SSI1_8BIT_TX1, &mxc_sdma_ssi1_8bit_tx1_params},
+ {MXC_DMA_SSI1_16BIT_RX1, &mxc_sdma_ssi1_16bit_rx1_params},
+ {MXC_DMA_SSI1_16BIT_TX1, &mxc_sdma_ssi1_16bit_tx1_params},
+ {MXC_DMA_SSI1_24BIT_RX1, &mxc_sdma_ssi1_24bit_rx1_params},
+ {MXC_DMA_SSI1_24BIT_TX1, &mxc_sdma_ssi1_24bit_tx1_params},
+ {MXC_DMA_SSI2_8BIT_RX0, &mxc_sdma_ssi2_8bit_rx0_params},
+ {MXC_DMA_SSI2_8BIT_TX0, &mxc_sdma_ssi2_8bit_tx0_params},
+ {MXC_DMA_SSI2_16BIT_RX0, &mxc_sdma_ssi2_16bit_rx0_params},
+ {MXC_DMA_SSI2_16BIT_TX0, &mxc_sdma_ssi2_16bit_tx0_params},
+ {MXC_DMA_SSI2_24BIT_RX0, &mxc_sdma_ssi2_24bit_rx0_params},
+ {MXC_DMA_SSI2_24BIT_TX0, &mxc_sdma_ssi2_24bit_tx0_params},
+ {MXC_DMA_SSI2_8BIT_RX1, &mxc_sdma_ssi2_8bit_rx1_params},
+ {MXC_DMA_SSI2_8BIT_TX1, &mxc_sdma_ssi2_8bit_tx1_params},
+ {MXC_DMA_SSI2_16BIT_RX1, &mxc_sdma_ssi2_16bit_rx1_params},
+ {MXC_DMA_SSI2_16BIT_TX1, &mxc_sdma_ssi2_16bit_tx1_params},
+ {MXC_DMA_SSI2_24BIT_RX1, &mxc_sdma_ssi2_24bit_rx1_params},
+ {MXC_DMA_SSI2_24BIT_TX1, &mxc_sdma_ssi2_24bit_tx1_params},
+ {MXC_DMA_ASRC_A_RX, &mxc_sdma_asrca_rx_params},
+ {MXC_DMA_ASRC_A_TX, &mxc_sdma_asrca_tx_params},
+ {MXC_DMA_ASRC_B_RX, &mxc_sdma_asrcb_rx_params},
+ {MXC_DMA_ASRC_B_TX, &mxc_sdma_asrcb_tx_params},
+ {MXC_DMA_ASRC_C_RX, &mxc_sdma_asrcc_rx_params},
+ {MXC_DMA_ASRC_C_TX, &mxc_sdma_asrcc_tx_params},
+ {MXC_DMA_ESAI_16BIT_RX, &mxc_sdma_esai_16bit_rx_params},
+ {MXC_DMA_ESAI_16BIT_TX, &mxc_sdma_esai_16bit_tx_params},
+ {MXC_DMA_ESAI_24BIT_RX, &mxc_sdma_esai_24bit_rx_params},
+ {MXC_DMA_ESAI_24BIT_TX, &mxc_sdma_esai_24bit_tx_params},
+ {MXC_DMA_MEMORY, &mxc_sdma_memory_params},
+};
+
+static int mxc_sdma_info_entrys =
+ sizeof(mxc_sdma_active_dma_info) / sizeof(mxc_sdma_active_dma_info[0]);
+/*!
+ * This functions Returns the SDMA paramaters associated for a module
+ *
+ * @param channel_id the ID of the module requesting DMA
+ * @return returns the sdma parameters structure for the device
+ */
+mxc_sdma_channel_params_t *mxc_sdma_get_channel_params(mxc_dma_device_t
+ channel_id)
+{
+ struct mxc_sdma_info_entry_s *p = mxc_sdma_active_dma_info;
+ int i;
+
+ for (i = 0; i < mxc_sdma_info_entrys; i++, p++) {
+ if (p->device == channel_id)
+ return p->chnl_info;
+ }
+ return NULL;
+}
+
+EXPORT_SYMBOL(mxc_sdma_get_channel_params);
+
+/*!
+ * This functions marks the SDMA channels that are statically allocated
+ *
+ * @param chnl the channel array used to store channel information
+ */
+void mxc_get_static_channels(mxc_dma_channel_t *chnl)
+{
+ /* No channels statically allocated for MX35 */
+#ifdef CONFIG_SDMA_IRAM
+ int i;
+ for (i = MXC_DMA_CHANNEL_IRAM; i < MAX_DMA_CHANNELS; i++)
+ chnl[i].dynamic = 0;
+#endif
+}
+
+EXPORT_SYMBOL(mxc_get_static_channels);
diff --git a/arch/arm/mach-mx35/dvfs.c b/arch/arm/mach-mx35/dvfs.c
new file mode 100644
index 000000000000..05477a9bc9f5
--- /dev/null
+++ b/arch/arm/mach-mx35/dvfs.c
@@ -0,0 +1,598 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * @file dvfs.c
+ *
+ * @brief A simplied driver for the Freescale Semiconductor MXC DVFS module.
+ *
+ * Upon initialization, the DVFS driver initializes the DVFS hardware
+ * sets up driver nodes attaches to the DVFS interrupt and initializes internal
+ * data structures. When the DVFS interrupt occurs the driver checks the cause
+ * of the interrupt (lower frequency, increase frequency or emergency) and
+ * changes the CPU voltage according to translation table that is loaded into
+ * the driver.
+ *
+ * @ingroup PM
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/regulator/regulator.h>
+#include <mach/hardware.h>
+#include "crm_regs.h"
+
+/*
+ * The frequency of div_3_clk will affect the dvfs sample rate..
+ */
+#define DVFS_DIV3CK (3 << MXC_CCM_LTR0_DIV3CK_OFFSET)
+
+/*
+ * Panic threshold. Panic frequency change request
+ * will be sent if DVFS counter value will be more than this value.
+ */
+#define DVFS_PNCTHR (63 << MXC_CCM_LTR1_PNCTHR_OFFSET)
+
+/*
+ * Load tracking buffer source: 1 for ld_add; 0 for pre_ld_add
+ */
+#define DVFS_LTBRSR (1 << MXC_CCM_LTR1_LTBRSR_OFFSET)
+
+/* EMAC defines how many samples are included in EMA calculation */
+#define DVFS_EMAC (0x20 << MXC_CCM_LTR2_EMAC_OFFSET)
+
+/*
+ * Frequency increase threshold. Increase frequency change request
+ * will be sent if DVFS counter value will be more than this value.
+ */
+#define DVFS_UPTHR(val) (val << MXC_CCM_LTR0_UPTHR_OFFSET)
+
+/*
+ * Frequency decrease threshold. Decrease frequency change request
+ * will be sent if DVFS counter value will be less than this value.
+ */
+#define DVFS_DNTHR(val) (val << MXC_CCM_LTR0_DNTHR_OFFSET)
+
+/*
+ * DNCNT defines the amount of times the down threshold should be exceeded
+ * before DVFS will trigger frequency decrease request.
+ */
+#define DVFS_DNCNT(val) (val << MXC_CCM_LTR1_DNCNT_OFFSET)
+
+/*
+ * UPCNT defines the amount of times the up threshold should be exceeded
+ * before DVFS will trigger frequency increase request.
+ */
+#define DVFS_UPCNT(val) (val << MXC_CCM_LTR1_UPCNT_OFFSET)
+
+#define DVFS_DVSUP(val) (val << MXC_CCM_PMCR0_DVSUP_OFFSET)
+
+#define MXC_DVFS_MAX_WP_NUM 2
+
+enum {
+ FSVAI_FREQ_NOCHANGE = 0x0,
+ FSVAI_FREQ_INCREASE,
+ FSVAI_FREQ_DECREASE,
+ FSVAI_FREQ_EMERG,
+};
+
+struct dvfs_wp {
+ unsigned long cpu_rate;
+ u32 core_voltage;
+ u32 dvsup;
+ u32 dnthr;
+ u32 upthr;
+ u32 dncnt;
+ u32 upcnt;
+};
+
+/* the default working points for MX35 TO2 DVFS. */
+static struct dvfs_wp dvfs_wp_tbl[MXC_DVFS_MAX_WP_NUM] = {
+ {399000000, 1200000, DVFS_DVSUP(DVSUP_LOW), DVFS_DNTHR(18),
+ DVFS_UPTHR(31), DVFS_DNCNT(0x33),
+ DVFS_UPCNT(0x33)},
+/* TBD: Need to set default voltage according to published data sheet */
+ {532000000, 1350000, DVFS_DVSUP(DVSUP_TURBO), DVFS_DNTHR(18),
+ DVFS_UPTHR(30), DVFS_DNCNT(0x33),
+ DVFS_UPCNT(0x33)}
+};
+
+static u8 dvfs_wp_num = MXC_DVFS_MAX_WP_NUM;
+
+ /* Used for tracking the number of interrupts */
+static u32 dvfs_nr_up[MXC_DVFS_MAX_WP_NUM];
+static u32 dvfs_nr_dn[MXC_DVFS_MAX_WP_NUM];
+static unsigned long stored_cpu_rate; /* cpu rate before DVFS starts */
+static u32 stored_pmcr0;
+static int dvfs_is_active; /* indicate DVFS is active or not */
+
+static struct delayed_work dvfs_work;
+
+/*
+ * Clock structures
+ */
+static struct clk *cpu_clk;
+static struct regulator *core_reg;
+
+const static u8 ltr_gp_weight[] = {
+ 0, /* 0 */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, /* 5 */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, /* 10 */
+ 0,
+ 0,
+ 0,
+ 0,
+ 0, /* 15 */
+};
+
+DEFINE_SPINLOCK(mxc_dvfs_lock);
+
+/*!
+ * This function sets the weight of general purpose signals
+ * @param gp_id number of general purpose bit
+ * @param weight the weight of the general purpose bit
+ */
+static void set_gp_weight(int gp_id, u8 weight)
+{
+ u32 reg;
+
+ if (gp_id < 9) {
+ reg = __raw_readl(MXC_CCM_LTR3);
+ reg = (reg & ~(MXC_CCM_LTR3_WSW_MASK(gp_id))) |
+ (weight << MXC_CCM_LTR3_WSW_OFFSET(gp_id));
+ __raw_writel(reg, MXC_CCM_LTR3);
+ } else if (gp_id < 16) {
+ reg = __raw_readl(MXC_CCM_LTR2);
+ reg = (reg & ~(MXC_CCM_LTR2_WSW_MASK(gp_id))) |
+ (weight << MXC_CCM_LTR2_WSW_OFFSET(gp_id));
+ __raw_writel(reg, MXC_CCM_LTR2);
+ }
+}
+
+/*!
+ * This function sets upper threshold, lower threshold,
+ * up-counter, down-counter for load tracking.
+ * @param upthr upper threshold
+ * @param dnthr lower threshold
+ * @param upcnt up counter
+ * @param dncnt down counter
+ */
+static void set_ltr_thres_counter(u32 upthr, u32 dnthr, u32 upcnt, u32 dncnt)
+{
+ u32 reg;
+ reg = __raw_readl(MXC_CCM_LTR0);
+ reg =
+ (reg &
+ ~(MXC_CCM_LTR0_UPTHR_MASK |
+ MXC_CCM_LTR0_DNTHR_MASK)) | upthr | dnthr;
+ __raw_writel(reg, MXC_CCM_LTR0);
+
+ reg = __raw_readl(MXC_CCM_LTR1);
+ reg =
+ (reg &
+ ~(MXC_CCM_LTR1_UPCNT_MASK |
+ MXC_CCM_LTR1_DNCNT_MASK)) | upcnt | dncnt;
+ __raw_writel(reg, MXC_CCM_LTR1);
+}
+
+/*!
+ * This function is called for module initialization.
+ * It sets up the DVFS hardware.
+ * It sets default values for DVFS thresholds and counters. The default
+ * values was chosen from a set of different reasonable values. They was tested
+ * and the default values in the driver gave the best results.
+ * More work should be done to find optimal values.
+ *
+ * @return 0 if successful; non-zero otherwise.
+ *
+ */
+static int init_dvfs_controller(void)
+{
+ u32 i, reg;
+
+ /* setup LTR0 */
+ reg = __raw_readl(MXC_CCM_LTR0);
+ reg = (reg & ~(MXC_CCM_LTR0_DIV3CK_MASK)) | DVFS_DIV3CK;
+ __raw_writel(reg, MXC_CCM_LTR0);
+
+ /* set up LTR1 */
+ reg = __raw_readl(MXC_CCM_LTR1);
+ reg = (reg & ~(MXC_CCM_LTR1_PNCTHR_MASK | MXC_CCM_LTR1_LTBRSR_MASK));
+ reg = reg | DVFS_PNCTHR | DVFS_LTBRSR;
+ __raw_writel(reg, MXC_CCM_LTR1);
+
+ /* setup LTR2 */
+ reg = __raw_readl(MXC_CCM_LTR2);
+ reg = (reg & ~(MXC_CCM_LTR2_EMAC_MASK)) | DVFS_EMAC;
+ __raw_writel(reg, MXC_CCM_LTR2);
+
+ /* Set general purpose weights to 0 */
+ for (i = 0; i < 16; i++)
+ set_gp_weight(i, ltr_gp_weight[i]);
+
+ /* ARM interrupt, mask load buf full interrupt */
+ reg = __raw_readl(MXC_CCM_PMCR0);
+ reg |= MXC_CCM_PMCR0_DVFIS | MXC_CCM_PMCR0_LBMI;
+ __raw_writel(reg, MXC_CCM_PMCR0);
+
+ return 0;
+}
+
+static void dvfs_workqueue_handler(struct work_struct *work)
+{
+ u32 pmcr0 = stored_pmcr0;
+ u32 fsvai = (pmcr0 & MXC_CCM_PMCR0_FSVAI_MASK) >>
+ MXC_CCM_PMCR0_FSVAI_OFFSET;
+ u32 dvsup = (pmcr0 & MXC_CCM_PMCR0_DVSUP_MASK) >>
+ MXC_CCM_PMCR0_DVSUP_OFFSET;
+ u32 curr_cpu;
+ u8 curr_dvfs;
+
+ if (!dvfs_is_active)
+ return;
+
+ if (fsvai == FSVAI_FREQ_NOCHANGE) {
+ /* Do nothing. Freq change is not required */
+ printk(KERN_WARNING "fsvai should not be 0\n");
+ goto exit;
+ }
+
+ if (((dvsup == DVSUP_LOW) && (fsvai == FSVAI_FREQ_DECREASE)) ||
+ ((dvsup == DVSUP_TURBO) && ((fsvai == FSVAI_FREQ_INCREASE) ||
+ (fsvai == FSVAI_FREQ_EMERG)))) {
+ /* Interrupt should be disabled in these cases according to
+ * the spec since DVFS is already at lowest (highest) state */
+ printk(KERN_WARNING "Something is wrong?\n");
+ goto exit;
+ }
+
+ /*Disable DPTC voltage update */
+ pmcr0 = pmcr0 & ~MXC_CCM_PMCR0_DPVCR;
+ __raw_writel(pmcr0, MXC_CCM_PMCR0);
+
+ curr_cpu = clk_get_rate(cpu_clk);
+ for (curr_dvfs = 0; curr_dvfs < dvfs_wp_num; curr_dvfs++) {
+ if (dvfs_wp_tbl[curr_dvfs].cpu_rate == curr_cpu) {
+ if (fsvai == FSVAI_FREQ_DECREASE) {
+ curr_dvfs--;
+ dvfs_nr_dn[dvsup]++;
+ /*reduce frequency and then voltage */
+ clk_set_rate(cpu_clk,
+ dvfs_wp_tbl[curr_dvfs].cpu_rate);
+ regulator_set_voltage(core_reg,
+ dvfs_wp_tbl[curr_dvfs].
+ core_voltage);
+ pr_info("Decrease frequency to: %ld \n",
+ dvfs_wp_tbl[curr_dvfs].cpu_rate);
+ } else {
+ /*increase freq to the highest one */
+ curr_dvfs = dvfs_wp_num - 1;
+ dvfs_nr_up[dvsup]++;
+ /*Increase voltage and then frequency */
+ regulator_set_voltage(core_reg,
+ dvfs_wp_tbl[curr_dvfs].
+ core_voltage);
+ clk_set_rate(cpu_clk,
+ dvfs_wp_tbl[curr_dvfs].cpu_rate);
+ pr_info("Increase frequency to: %ld \n",
+ dvfs_wp_tbl[curr_dvfs].cpu_rate);
+ }
+ pmcr0 = (pmcr0 & ~MXC_CCM_PMCR0_DVSUP_MASK)
+ | (dvfs_wp_tbl[curr_dvfs].dvsup);
+ __raw_writel(pmcr0, MXC_CCM_PMCR0);
+
+ set_ltr_thres_counter(dvfs_wp_tbl[curr_dvfs].upthr,
+ dvfs_wp_tbl[curr_dvfs].dnthr,
+ dvfs_wp_tbl[curr_dvfs].upcnt,
+ dvfs_wp_tbl[curr_dvfs].dncnt);
+ break;
+ }
+ }
+
+ exit:
+ /* unmask interrupt */
+ pmcr0 = pmcr0 & ~MXC_CCM_PMCR0_FSVAIM;
+ __raw_writel(pmcr0, MXC_CCM_PMCR0);
+ /*DVFS update finish */
+ pmcr0 = (pmcr0 | MXC_CCM_PMCR0_DVFS_UPDATE_FINISH);
+ __raw_writel(pmcr0, MXC_CCM_PMCR0);
+}
+
+static irqreturn_t dvfs_irq(int irq, void *dev_id)
+{
+
+ u32 pmcr0 = __raw_readl(MXC_CCM_PMCR0);
+
+ /* Config dvfs_start bit */
+ pmcr0 = pmcr0 | MXC_CCM_PMCR0_DVFS_START;
+ /*Mask interrupt */
+ pmcr0 = pmcr0 | MXC_CCM_PMCR0_FSVAIM;
+ __raw_writel(pmcr0, MXC_CCM_PMCR0);
+
+ stored_pmcr0 = pmcr0;
+ schedule_delayed_work(&dvfs_work, 0);
+
+ return IRQ_RETVAL(1);
+}
+
+/*!
+ * This function enables the DVFS module.
+ */
+static int start_dvfs(void)
+{
+ u32 reg = 0;
+ unsigned long flags;
+ u8 i;
+
+ if (dvfs_is_active) {
+ pr_info("DVFS is already started\n");
+ return 0;
+ }
+
+ spin_lock_irqsave(&mxc_dvfs_lock, flags);
+
+ stored_cpu_rate = clk_get_rate(cpu_clk);
+ for (i = 0; i < dvfs_wp_num; i++) {
+ if (dvfs_wp_tbl[i].cpu_rate == stored_cpu_rate) {
+ /*Set LTR0 and LTR1 */
+ set_ltr_thres_counter(dvfs_wp_tbl[i].upthr,
+ dvfs_wp_tbl[i].dnthr,
+ dvfs_wp_tbl[i].upcnt,
+ dvfs_wp_tbl[i].dncnt);
+
+ reg = __raw_readl(MXC_CCM_PMCR0);
+ reg =
+ (reg & ~MXC_CCM_PMCR0_DVSUP_MASK) | (dvfs_wp_tbl[i].
+ dvsup);
+ /* enable dvfs and interrupt */
+ reg =
+ (reg & ~MXC_CCM_PMCR0_FSVAIM) | MXC_CCM_PMCR0_DVFEN;
+
+ __raw_writel(reg, MXC_CCM_PMCR0);
+
+ dvfs_is_active = 1;
+ pr_info("DVFS Starts\n");
+ break;
+ }
+ }
+
+ spin_unlock_irqrestore(&mxc_dvfs_lock, flags);
+ if (dvfs_is_active)
+ return 0;
+ else
+ return 1;
+}
+
+/*!
+ * This function disables the DVFS module.
+ */
+static void stop_dvfs(void)
+{
+ u32 pmcr0;
+ unsigned long curr_cpu = clk_get_rate(cpu_clk);
+ u8 index;
+
+ if (dvfs_is_active) {
+
+ pmcr0 = __raw_readl(MXC_CCM_PMCR0);
+ /* disable dvfs and its interrupt */
+ pmcr0 = (pmcr0 & ~MXC_CCM_PMCR0_DVFEN) | MXC_CCM_PMCR0_FSVAIM;
+ __raw_writel(pmcr0, MXC_CCM_PMCR0);
+
+ if (stored_cpu_rate < curr_cpu) {
+ for (index = 0; index < dvfs_wp_num; index++) {
+ if (dvfs_wp_tbl[index].cpu_rate ==
+ stored_cpu_rate)
+ break;
+ }
+ clk_set_rate(cpu_clk, stored_cpu_rate);
+ regulator_set_voltage(core_reg,
+ dvfs_wp_tbl[index].core_voltage);
+ } else if (stored_cpu_rate > curr_cpu) {
+ for (index = 0; index < dvfs_wp_num; index++) {
+ if (dvfs_wp_tbl[index].cpu_rate ==
+ stored_cpu_rate)
+ break;
+ }
+ regulator_set_voltage(core_reg,
+ dvfs_wp_tbl[index].core_voltage);
+ clk_set_rate(cpu_clk, stored_cpu_rate);
+ }
+
+ dvfs_is_active = 0;
+ }
+
+ pr_info("DVFS is stopped\n");
+}
+
+static ssize_t dvfs_enable_store(struct sys_device *dev, struct sysdev_attribute *attr,
+ const char *buf, size_t size)
+{
+ if (strstr(buf, "1") != NULL) {
+ if (start_dvfs() != 0)
+ printk(KERN_ERR "Failed to start DVFS\n");
+ } else if (strstr(buf, "0") != NULL) {
+ stop_dvfs();
+ }
+
+ return size;
+}
+
+static ssize_t dvfs_status_show(struct sys_device *dev, struct sysdev_attribute *attr,
+ char *buf)
+{
+ int size = 0, i;
+
+ if (dvfs_is_active)
+ size = sprintf(buf, "DVFS is enabled\n");
+ else
+ size = sprintf(buf, "DVFS is disabled\n");
+
+ size += sprintf((buf + size), "UP:\t");
+ for (i = 0; i < MXC_DVFS_MAX_WP_NUM; i++)
+ size += sprintf((buf + size), "%d\t", dvfs_nr_up[i]);
+ size += sprintf((buf + size), "\n");
+
+ size += sprintf((buf + size), "DOWN:\t");
+ for (i = 0; i < MXC_DVFS_MAX_WP_NUM; i++)
+ size += sprintf((buf + size), "%d\t", dvfs_nr_dn[i]);
+ size += sprintf((buf + size), "\n");
+
+ return size;
+}
+
+static ssize_t dvfs_status_store(struct sys_device *dev, struct sysdev_attribute *attr,
+ const char *buf, size_t size)
+{
+ if (strstr(buf, "reset") != NULL) {
+ int i;
+ for (i = 0; i < MXC_DVFS_MAX_WP_NUM; i++) {
+ dvfs_nr_up[i] = 0;
+ dvfs_nr_dn[i] = 0;
+ }
+ }
+
+ return size;
+}
+
+static SYSDEV_ATTR(enable, 0200, NULL, dvfs_enable_store);
+static SYSDEV_ATTR(status, 0644, dvfs_status_show, dvfs_status_store);
+
+static struct sysdev_class dvfs_sysclass = {
+ .name = "dvfs",
+};
+
+static struct sys_device dvfs_device = {
+ .id = 0,
+ .cls = &dvfs_sysclass,
+};
+
+static int dvfs_sysdev_ctrl_init(void)
+{
+ int err;
+
+ err = sysdev_class_register(&dvfs_sysclass);
+ if (!err)
+ err = sysdev_register(&dvfs_device);
+ if (!err) {
+ err = sysdev_create_file(&dvfs_device, &attr_enable);
+ err = sysdev_create_file(&dvfs_device, &attr_status);
+ }
+
+ return err;
+}
+
+static void dvfs_sysdev_ctrl_exit(void)
+{
+ sysdev_remove_file(&dvfs_device, &attr_enable);
+ sysdev_remove_file(&dvfs_device, &attr_status);
+ sysdev_unregister(&dvfs_device);
+ sysdev_class_unregister(&dvfs_sysclass);
+}
+
+static int __init dvfs_init(void)
+{
+ int err = 0;
+ u8 index;
+ unsigned long curr_cpu;
+
+ if (cpu_is_mx35_rev(CHIP_REV_1_0) == 1) {
+ /*
+ * Don't support DVFS for auto path in TO1 because
+ * the voltages under 399M are all 1.2v
+ */
+ if (!(__raw_readl(MXC_CCM_PDR0) & MXC_CCM_PDR0_AUTO_CON)) {
+ pr_info("MX35 TO1 auto path, no need to use DVFS \n");
+ return -1;
+ }
+ }
+
+ cpu_clk = clk_get(NULL, "cpu_clk");
+ curr_cpu = clk_get_rate(cpu_clk);
+
+ if (board_is_mx35(BOARD_REV_2))
+ core_reg = regulator_get(NULL, "SW2");
+ else
+ core_reg = regulator_get(NULL, "SW3");
+
+ dvfs_is_active = 0;
+
+ /*Set voltage */
+ for (index = 0; index < dvfs_wp_num; index++) {
+ if (dvfs_wp_tbl[index].cpu_rate == curr_cpu) {
+ regulator_set_voltage(core_reg,
+ dvfs_wp_tbl[index].core_voltage);
+ break;
+ }
+ }
+
+ err = init_dvfs_controller();
+ if (err) {
+ printk(KERN_ERR "DVFS: Unable to initialize DVFS");
+ return err;
+ }
+
+ INIT_DELAYED_WORK(&dvfs_work, dvfs_workqueue_handler);
+
+ /* request the DVFS interrupt */
+ err = request_irq(MXC_INT_DVFS, dvfs_irq, IRQF_DISABLED, "dvfs", NULL);
+ if (err) {
+ printk(KERN_ERR "DVFS: Unable to attach to DVFS interrupt");
+ return err;
+ }
+
+ err = dvfs_sysdev_ctrl_init();
+ if (err) {
+ printk(KERN_ERR
+ "DVFS: Unable to register sysdev entry for dvfs");
+ return err;
+ }
+
+ return err;
+}
+
+static void __exit dvfs_cleanup(void)
+{
+ stop_dvfs();
+
+ /* release the DVFS interrupt */
+ free_irq(MXC_INT_DVFS, NULL);
+
+ dvfs_sysdev_ctrl_exit();
+
+ clk_put(cpu_clk);
+ regulator_put(core_reg, NULL);
+}
+
+module_init(dvfs_init);
+module_exit(dvfs_cleanup);
+
+MODULE_AUTHOR("Freescale Seminconductor, Inc.");
+MODULE_DESCRIPTION("DVFS driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-mx35/iomux.c b/arch/arm/mach-mx35/iomux.c
new file mode 100644
index 000000000000..65a4f9511988
--- /dev/null
+++ b/arch/arm/mach-mx35/iomux.c
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup GPIO_MX35 Board GPIO and Muxing Setup
+ * @ingroup MSL_MX35
+ */
+/*!
+ * @file mach-mx35/iomux.c
+ *
+ * @brief I/O Muxing control functions
+ *
+ * @ingroup GPIO_MX35
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include "iomux.h"
+
+/*!
+ * IOMUX register (base) addresses
+ */
+enum iomux_reg_addr {
+ IOMUXGPR = IO_ADDRESS(IOMUXC_BASE_ADDR),
+ /*!< General purpose */
+ IOMUXSW_MUX_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR) + 4,
+ /*!< MUX control */
+ IOMUXSW_MUX_END = IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x324,
+ /*!< last MUX control register */
+ IOMUXSW_PAD_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x328,
+ /*!< Pad control */
+ IOMUXSW_PAD_END = IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x794,
+ /*!< last Pad control register */
+ IOMUXSW_INPUT_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x7AC,
+ /*!< input select register */
+ IOMUXSW_INPUT_END = IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x9F4,
+ /*!< last input select register */
+};
+
+#define MUX_PIN_NUM_MAX \
+ (((IOMUXSW_PAD_END - IOMUXSW_PAD_CTL) >> 2) + 1)
+#define MUX_INPUT_NUM_MUX \
+ (((IOMUXSW_INPUT_END - IOMUXSW_INPUT_CTL) >> 2) + 1)
+
+#define PIN_TO_IOMUX_INDEX(pin) ((PIN_TO_IOMUX_PAD(pin) - 0x328) >> 2)
+
+static DEFINE_SPINLOCK(gpio_mux_lock);
+static u8 iomux_pin_res_table[MUX_PIN_NUM_MAX];
+
+/*!
+ * This function is used to configure a pin through the IOMUX module.
+ * FIXED ME: for backward compatible. Will be static function!
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param cfg an output function as defined in \b #iomux_pin_cfg_t
+ *
+ * @return 0 if successful; Non-zero otherwise
+ */
+static int iomux_config_mux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
+{
+ u32 ret = 0;
+ u32 pin_index = PIN_TO_IOMUX_INDEX(pin);
+ u32 mux_reg = PIN_TO_IOMUX_MUX(pin);
+ u8 *rp;
+
+ BUG_ON(pin_index > MUX_PIN_NUM_MAX);
+ if (mux_reg != NON_MUX_I) {
+ mux_reg += IOMUXGPR;
+ BUG_ON((mux_reg > IOMUXSW_MUX_END)
+ || (mux_reg < IOMUXSW_MUX_CTL));
+ spin_lock(&gpio_mux_lock);
+ __raw_writel(cfg, mux_reg);
+ /*
+ * Log a warning if a pin changes ownership
+ */
+ rp = iomux_pin_res_table + pin_index;
+ if ((cfg & *rp) && (*rp != cfg)) {
+ /*Console: how to do */
+ printk(KERN_ERR "iomux_config_mux: Warning: iomux pin"
+ " config changed, index=%d register=%d, "
+ " prev=0x%x new=0x%x\n", pin_index, mux_reg,
+ *rp, cfg);
+ ret = -EINVAL;
+ }
+ *rp = cfg;
+ spin_unlock(&gpio_mux_lock);
+ }
+
+ return ret;
+}
+
+/*!
+ * Request ownership for an IO pin. This function has to be the first one
+ * being called before that pin is used. The caller has to check the
+ * return value to make sure it returns 0.
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param cfg an input function as defined in \b #iomux_pin_cfg_t
+ *
+ * @return 0 if successful; Non-zero otherwise
+ */
+int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
+{
+ int ret = iomux_config_mux(pin, cfg);
+ if (GPIO_TO_PORT(IOMUX_TO_GPIO(pin)) < GPIO_PORT_NUM) {
+ if (((cfg & (~MUX_CONFIG_SION)) == MUX_CONFIG_GPIO) ||
+ (((cfg & (~MUX_CONFIG_SION)) == MUX_CONFIG_FUNC) &&
+ ((pin == MX35_PIN_GPIO1_0) || (pin == MX35_PIN_GPIO1_1) ||
+ (pin == MX35_PIN_GPIO2_0) || (pin == MX35_PIN_GPIO3_0))))
+ ret |= mxc_request_gpio(pin);
+ }
+ return ret;
+}
+
+EXPORT_SYMBOL(mxc_request_iomux);
+
+/*!
+ * Release ownership for an IO pin
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param cfg an input function as defined in \b #iomux_pin_cfg_t
+ */
+void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg)
+{
+ u32 pin_index = PIN_TO_IOMUX_INDEX(pin);
+ u8 *rp = iomux_pin_res_table + pin_index;
+
+ BUG_ON((pin_index > MUX_PIN_NUM_MAX));
+
+ *rp = 0;
+ if (GPIO_TO_PORT(IOMUX_TO_GPIO(pin)) < GPIO_PORT_NUM) {
+ if (((cfg & (~MUX_CONFIG_SION)) == MUX_CONFIG_GPIO) ||
+ (((cfg & (~MUX_CONFIG_SION)) == MUX_CONFIG_FUNC) &&
+ ((pin == MX35_PIN_GPIO1_0) || (pin == MX35_PIN_GPIO1_1) ||
+ (pin == MX35_PIN_GPIO2_0) || (pin == MX35_PIN_GPIO3_0))))
+ mxc_free_gpio(pin);
+ }
+}
+
+EXPORT_SYMBOL(mxc_free_iomux);
+
+/*!
+ * This function configures the pad value for a IOMUX pin.
+ *
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param config the ORed value of elements defined in \b #iomux_pad_config_t
+ */
+void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config)
+{
+ u32 pad_reg = IOMUXGPR + PIN_TO_IOMUX_PAD(pin);
+
+ BUG_ON((pad_reg > IOMUXSW_PAD_END) || (pad_reg < IOMUXSW_PAD_CTL));
+
+ spin_lock(&gpio_mux_lock);
+ __raw_writel(config, pad_reg);
+ spin_unlock(&gpio_mux_lock);
+}
+
+EXPORT_SYMBOL(mxc_iomux_set_pad);
+
+/*!
+ * This function enables/disables the general purpose function for a particular
+ * signal.
+ *
+ * @param gp one signal as defined in \b #iomux_gp_func_t
+ * @param en \b #true to enable; \b #false to disable
+ */
+void mxc_iomux_set_gpr(iomux_gp_func_t gp, bool en)
+{
+ u32 l;
+
+ spin_lock(&gpio_mux_lock);
+ l = __raw_readl(IOMUXGPR);
+
+ if (en)
+ l |= gp;
+ else
+ l &= ~gp;
+
+ __raw_writel(l, IOMUXGPR);
+ spin_unlock(&gpio_mux_lock);
+}
+
+EXPORT_SYMBOL(mxc_iomux_set_gpr);
+
+/*!
+ * This function configures input path.
+ *
+ * @param input index of input select register as defined in \b
+ * #iomux_input_select_t
+ * @param config the binary value of elements defined in \b
+ * #iomux_input_config_t
+ */
+void mxc_iomux_set_input(iomux_input_select_t input, u32 config)
+{
+ u32 reg = IOMUXSW_INPUT_CTL + (input << 2);
+
+ BUG_ON(input >= MUX_INPUT_NUM_MUX);
+
+ spin_lock(&gpio_mux_lock);
+ __raw_writel(config, reg);
+ spin_unlock(&gpio_mux_lock);
+}
+
+EXPORT_SYMBOL(mxc_iomux_set_input);
diff --git a/arch/arm/mach-mx35/iomux.h b/arch/arm/mach-mx35/iomux.h
new file mode 100644
index 000000000000..6a12ded8aa7e
--- /dev/null
+++ b/arch/arm/mach-mx35/iomux.h
@@ -0,0 +1,292 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __MACH_MX35_IOMUX_H__
+#define __MACH_MX35_IOMUX_H__
+
+#include <linux/types.h>
+#include <mach/gpio.h>
+#include "mx35_pins.h"
+
+/*!
+ * @file mach-mx35/iomux.h
+ *
+ * @brief I/O Muxing control definitions and functions
+ *
+ * @ingroup GPIO_MX35
+ */
+
+/*!
+ * various IOMUX functions
+ */
+typedef enum iomux_pin_config {
+ MUX_CONFIG_FUNC = 0, /*!< used as function */
+ MUX_CONFIG_ALT1, /*!< used as alternate function 1 */
+ MUX_CONFIG_ALT2, /*!< used as alternate function 2 */
+ MUX_CONFIG_ALT3, /*!< used as alternate function 3 */
+ MUX_CONFIG_ALT4, /*!< used as alternate function 4 */
+ MUX_CONFIG_ALT5, /*!< used as alternate function 5 */
+ MUX_CONFIG_ALT6, /*!< used as alternate function 6 */
+ MUX_CONFIG_ALT7, /*!< used as alternate function 7 */
+ MUX_CONFIG_SION = 0x1 << 4, /*!< used as LOOPBACK:MUX SION bit */
+ MUX_CONFIG_GPIO = MUX_CONFIG_ALT5, /*!< used as GPIO */
+} iomux_pin_cfg_t;
+
+/*!
+ * various IOMUX pad functions
+ */
+typedef enum iomux_pad_config {
+ PAD_CTL_DRV_3_3V = 0x0 << 13,
+ PAD_CTL_DRV_1_8V = 0x1 << 13,
+ PAD_CTL_HYS_CMOS = 0x0 << 8,
+ PAD_CTL_HYS_SCHMITZ = 0x1 << 8,
+ PAD_CTL_PKE_NONE = 0x0 << 7,
+ PAD_CTL_PKE_ENABLE = 0x1 << 7,
+ PAD_CTL_PUE_KEEPER = 0x0 << 6,
+ PAD_CTL_PUE_PUD = 0x1 << 6,
+ PAD_CTL_100K_PD = 0x0 << 4,
+ PAD_CTL_47K_PU = 0x1 << 4,
+ PAD_CTL_100K_PU = 0x2 << 4,
+ PAD_CTL_22K_PU = 0x3 << 4,
+ PAD_CTL_ODE_CMOS = 0x0 << 3,
+ PAD_CTL_ODE_OpenDrain = 0x1 << 3,
+ PAD_CTL_DRV_NORMAL = 0x0 << 1,
+ PAD_CTL_DRV_HIGH = 0x1 << 1,
+ PAD_CTL_DRV_MAX = 0x2 << 1,
+ PAD_CTL_SRE_SLOW = 0x0 << 0,
+ PAD_CTL_SRE_FAST = 0x1 << 0
+} iomux_pad_config_t;
+
+/*!
+ * various IOMUX general purpose functions
+ */
+typedef enum iomux_gp_func {
+ MUX_SDCTL_CSD0_SEL = 0x1 << 0,
+ MUX_SDCTL_CSD1_SEL = 0x1 << 1,
+ MUX_TAMPER_DETECT_EN = 0x1 << 2,
+} iomux_gp_func_t;
+
+/*!
+ * various IOMUX input select register index
+ */
+typedef enum iomux_input_select {
+ MUX_IN_AMX_P5_RXCLK = 0,
+ MUX_IN_AMX_P5_RXFS,
+ MUX_IN_AMX_P6_DA,
+ MUX_IN_AMX_P6_DB,
+ MUX_IN_AMX_P6_RXCLK,
+ MUX_IN_AMX_P6_RXFS,
+ MUX_IN_AMX_P6_TXCLK,
+ MUX_IN_AMX_P6_TXFS,
+ MUX_IN_CAN1_CANRX,
+ MUX_IN_CAN2_CANRX,
+ MUX_IN_CCM_32K_MUXED,
+ MUX_IN_CCM_PMIC_RDY,
+ MUX_IN_CSPI1_SS2_B,
+ MUX_IN_CSPI1_SS3_B,
+ MUX_IN_CSPI2_CLK_IN,
+ MUX_IN_CSPI2_DATAREADY_B,
+ MUX_IN_CSPI2_MISO,
+ MUX_IN_CSPI2_MOSI,
+ MUX_IN_CSPI2_SS0_B,
+ MUX_IN_CSPI2_SS1_B,
+ MUX_IN_CSPI2_SS2_B,
+ MUX_IN_CSPI2_SS3_B,
+ MUX_IN_EMI_WEIM_DTACK_B,
+ MUX_IN_ESDHC1_DAT4_IN,
+ MUX_IN_ESDHC1_DAT5_IN,
+ MUX_IN_ESDHC1_DAT6_IN,
+ MUX_IN_ESDHC1_DAT7_IN,
+ MUX_IN_ESDHC3_CARD_CLK_IN,
+ MUX_IN_ESDHC3_CMD_IN,
+ MUX_IN_ESDHC3_DAT0,
+ MUX_IN_ESDHC3_DAT1,
+ MUX_IN_ESDHC3_DAT2,
+ MUX_IN_ESDHC3_DAT3,
+ MUX_IN_GPIO1_IN_0,
+ MUX_IN_GPIO1_IN_10,
+ MUX_IN_GPIO1_IN_11,
+ MUX_IN_GPIO1_IN_1,
+ MUX_IN_GPIO1_IN_20,
+ MUX_IN_GPIO1_IN_21,
+ MUX_IN_GPIO1_IN_22,
+ MUX_IN_GPIO1_IN_2,
+ MUX_IN_GPIO1_IN_3,
+ MUX_IN_GPIO1_IN_4,
+ MUX_IN_GPIO1_IN_5,
+ MUX_IN_GPIO1_IN_6,
+ MUX_IN_GPIO1_IN_7,
+ MUX_IN_GPIO1_IN_8,
+ MUX_IN_GPIO1_IN_9,
+ MUX_IN_GPIO2_IN_0,
+ MUX_IN_GPIO2_IN_10,
+ MUX_IN_GPIO2_IN_11,
+ MUX_IN_GPIO2_IN_12,
+ MUX_IN_GPIO2_IN_13,
+ MUX_IN_GPIO2_IN_14,
+ MUX_IN_GPIO2_IN_15,
+ MUX_IN_GPIO2_IN_16,
+ MUX_IN_GPIO2_IN_17,
+ MUX_IN_GPIO2_IN_18,
+ MUX_IN_GPIO2_IN_19,
+ MUX_IN_GPIO2_IN_20,
+ MUX_IN_GPIO2_IN_21,
+ MUX_IN_GPIO2_IN_22,
+ MUX_IN_GPIO2_IN_23,
+ MUX_IN_GPIO2_IN_24,
+ MUX_IN_GPIO2_IN_25,
+ MUX_IN_GPIO2_IN_26,
+ MUX_IN_GPIO2_IN_27,
+ MUX_IN_GPIO2_IN_28,
+ MUX_IN_GPIO2_IN_29,
+ MUX_IN_GPIO2_IN_2,
+ MUX_IN_GPIO2_IN_30,
+ MUX_IN_GPIO2_IN_31,
+ MUX_IN_GPIO2_IN_3,
+ MUX_IN_GPIO2_IN_4,
+ MUX_IN_GPIO2_IN_5,
+ MUX_IN_GPIO2_IN_6,
+ MUX_IN_GPIO2_IN_7,
+ MUX_IN_GPIO2_IN_8,
+ MUX_IN_GPIO2_IN_9,
+ MUX_IN_GPIO3_IN_0,
+ MUX_IN_GPIO3_IN_10,
+ MUX_IN_GPIO3_IN_11,
+ MUX_IN_GPIO3_IN_12,
+ MUX_IN_GPIO3_IN_13,
+ MUX_IN_GPIO3_IN_14,
+ MUX_IN_GPIO3_IN_15,
+ MUX_IN_GPIO3_IN_4,
+ MUX_IN_GPIO3_IN_5,
+ MUX_IN_GPIO3_IN_6,
+ MUX_IN_GPIO3_IN_7,
+ MUX_IN_GPIO3_IN_8,
+ MUX_IN_GPIO3_IN_9,
+ MUX_IN_I2C3_SCL_IN,
+ MUX_IN_I2C3_SDA_IN,
+ MUX_IN_IPU_DISPB_D0_VSYNC,
+ MUX_IN_IPU_DISPB_D12_VSYNC,
+ MUX_IN_IPU_DISPB_SD_D,
+ MUX_IN_IPU_SENSB_DATA_0,
+ MUX_IN_IPU_SENSB_DATA_1,
+ MUX_IN_IPU_SENSB_DATA_2,
+ MUX_IN_IPU_SENSB_DATA_3,
+ MUX_IN_IPU_SENSB_DATA_4,
+ MUX_IN_IPU_SENSB_DATA_5,
+ MUX_IN_IPU_SENSB_DATA_6,
+ MUX_IN_IPU_SENSB_DATA_7,
+ MUX_IN_KPP_COL_0,
+ MUX_IN_KPP_COL_1,
+ MUX_IN_KPP_COL_2,
+ MUX_IN_KPP_COL_3,
+ MUX_IN_KPP_COL_4,
+ MUX_IN_KPP_COL_5,
+ MUX_IN_KPP_COL_6,
+ MUX_IN_KPP_COL_7,
+ MUX_IN_KPP_ROW_0,
+ MUX_IN_KPP_ROW_1,
+ MUX_IN_KPP_ROW_2,
+ MUX_IN_KPP_ROW_3,
+ MUX_IN_KPP_ROW_4,
+ MUX_IN_KPP_ROW_5,
+ MUX_IN_KPP_ROW_6,
+ MUX_IN_KPP_ROW_7,
+ MUX_IN_OWIRE_BATTERY_LINE,
+ MUX_IN_SPDIF_HCKT_CLK2,
+ MUX_IN_SPDIF_SPDIF_IN1,
+ MUX_IN_UART3_UART_RTS_B,
+ MUX_IN_UART3_UART_RXD_MUX,
+ MUX_IN_USB_OTG_DATA_0,
+ MUX_IN_USB_OTG_DATA_1,
+ MUX_IN_USB_OTG_DATA_2,
+ MUX_IN_USB_OTG_DATA_3,
+ MUX_IN_USB_OTG_DATA_4,
+ MUX_IN_USB_OTG_DATA_5,
+ MUX_IN_USB_OTG_DATA_6,
+ MUX_IN_USB_OTG_DATA_7,
+ MUX_IN_USB_OTG_DIR,
+ MUX_IN_USB_OTG_NXT,
+ MUX_IN_USB_UH2_DATA_0,
+ MUX_IN_USB_UH2_DATA_1,
+ MUX_IN_USB_UH2_DATA_2,
+ MUX_IN_USB_UH2_DATA_3,
+ MUX_IN_USB_UH2_DATA_4,
+ MUX_IN_USB_UH2_DATA_5,
+ MUX_IN_USB_UH2_DATA_6,
+ MUX_IN_USB_UH2_DATA_7,
+ MUX_IN_USB_UH2_DIR,
+ MUX_IN_USB_UH2_NXT,
+ MUX_IN_USB_UH2_USB_OC,
+} iomux_input_select_t;
+
+/*!
+ * various IOMUX input functions
+ */
+typedef enum iomux_input_config {
+ INPUT_CTL_PATH0 = 0x0,
+ INPUT_CTL_PATH1,
+ INPUT_CTL_PATH2,
+ INPUT_CTL_PATH3,
+ INPUT_CTL_PATH4,
+ INPUT_CTL_PATH5,
+ INPUT_CTL_PATH6,
+ INPUT_CTL_PATH7,
+} iomux_input_cfg_t;
+
+/*!
+ * Request ownership for an IO pin. This function has to be the first one
+ * being called before that pin is used. The caller has to check the
+ * return value to make sure it returns 0.
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param cfg an input function as defined in \b #iomux_pin_cfg_t
+ *
+ * @return 0 if successful; Non-zero otherwise
+ */
+int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg);
+
+/*!
+ * Release ownership for an IO pin
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param cfg an input function as defined in \b #iomux_pin_cfg_t
+ */
+void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t cfg);
+
+/*!
+ * This function enables/disables the general purpose function for a particular
+ * signal.
+ *
+ * @param gp one signal as defined in \b #iomux_gp_func_t
+ * @param en \b #true to enable; \b #false to disable
+ */
+void mxc_iomux_set_gpr(iomux_gp_func_t gp, bool en);
+
+/*!
+ * This function configures the pad value for a IOMUX pin.
+ *
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param config the ORed value of elements defined in \b
+ * #iomux_pad_config_t
+ */
+void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config);
+
+/*!
+ * This function configures input path.
+ *
+ * @param input index of input select register as defined in \b
+ * #iomux_input_select_t
+ * @param config the binary value of elements defined in \b
+ * #iomux_input_cfg_t
+ */
+void mxc_iomux_set_input(iomux_input_select_t input, u32 config);
+#endif
diff --git a/arch/arm/mach-mx35/mm.c b/arch/arm/mach-mx35/mm.c
new file mode 100644
index 000000000000..81ca3eb797ee
--- /dev/null
+++ b/arch/arm/mach-mx35/mm.c
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <mach/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+/*!
+ * @file mach-mx35/mm.c
+ *
+ * @brief This file creates static mapping between physical to virtual memory.
+ *
+ * @ingroup Memory_MX35
+ */
+
+/*!
+ * This structure defines the MX35 memory map.
+ */
+static struct map_desc mxc_io_desc[] __initdata = {
+ {
+ .virtual = IRAM_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(IRAM_BASE_ADDR),
+ .length = IRAM_SIZE,
+ .type = MT_DEVICE_NONSHARED},
+ {
+ .virtual = X_MEMC_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(X_MEMC_BASE_ADDR),
+ .length = X_MEMC_SIZE,
+ .type = MT_DEVICE},
+ {
+ .virtual = NFC_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(NFC_BASE_ADDR),
+ .length = NFC_SIZE,
+ .type = MT_DEVICE_NONSHARED},
+ {
+ .virtual = AVIC_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AVIC_BASE_ADDR),
+ .length = AVIC_SIZE,
+ .type = MT_DEVICE_NONSHARED},
+ {
+ .virtual = AIPS1_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
+ .length = AIPS1_SIZE,
+ .type = MT_DEVICE_NONSHARED},
+ {
+ .virtual = SPBA0_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
+ .length = SPBA0_SIZE,
+ .type = MT_DEVICE_NONSHARED},
+ {
+ .virtual = AIPS2_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
+ .length = AIPS2_SIZE,
+ .type = MT_DEVICE_NONSHARED},
+};
+
+/*!
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory map for
+ * the IO modules.
+ */
+void __init mxc_map_io(void)
+{
+ iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
+}
diff --git a/arch/arm/mach-mx35/mx35_3stack.c b/arch/arm/mach-mx35/mx35_3stack.c
new file mode 100644
index 000000000000..17436f63e537
--- /dev/null
+++ b/arch/arm/mach-mx35/mx35_3stack.c
@@ -0,0 +1,1168 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/ata.h>
+#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE)
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+#include <linux/delay.h>
+#include <linux/regulator/mcu_max8660-bus.h>
+#include <linux/regulator/regulator.h>
+
+#include <asm/mach/flash.h>
+#endif
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+#include <mach/memory.h>
+#include <mach/gpio.h>
+#include <mach/mmc.h>
+#include <mach/pmic_external.h>
+
+#include "board-mx35_3stack.h"
+#include "crm_regs.h"
+#include "iomux.h"
+
+/*!
+ * @file mach-mx35/mx35_3stack.c
+ *
+ * @brief This file contains the board specific initialization routines.
+ *
+ * @ingroup MSL_MX35
+ */
+
+unsigned int mx35_3stack_board_io;
+
+static void mxc_nop_release(struct device *dev)
+{
+ /* Nothing */
+}
+
+/* MTD NOR flash */
+
+#if defined(CONFIG_MTD_MXC) || defined(CONFIG_MTD_MXC_MODULE)
+
+static struct mtd_partition mxc_nor_partitions[] = {
+ {
+ .name = "Bootloader",
+ .size = 512 * 1024,
+ .offset = 0x00000000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "nor.Kernel",
+ .size = 4 * 1024 * 1024,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = 0},
+ {
+ .name = "nor.userfs",
+ .size = 30 * 1024 * 1024,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = 0},
+ {
+ .name = "nor.rootfs",
+ .size = 28 * 1024 * 1024,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE},
+ {
+ .name = "FIS directory",
+ .size = 12 * 1024,
+ .offset = 0x01FE0000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "Redboot config",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0x01FFF000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+};
+
+static struct flash_platform_data mxc_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+ .parts = mxc_nor_partitions,
+ .nr_parts = ARRAY_SIZE(mxc_nor_partitions),
+};
+
+static struct resource mxc_flash_resource = {
+ .start = 0xa0000000,
+ .end = 0xa0000000 + 0x04000000 - 1,
+ .flags = IORESOURCE_MEM,
+
+};
+
+static struct platform_device mxc_nor_mtd_device = {
+ .name = "mxc_nor_flash",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &mxc_flash_resource,
+};
+
+static void mxc_init_nor_mtd(void)
+{
+ (void)platform_device_register(&mxc_nor_mtd_device);
+}
+#else
+static void mxc_init_nor_mtd(void)
+{
+}
+#endif
+
+/* MTD NAND flash */
+
+#if defined(CONFIG_MTD_NAND_MXC) || defined(CONFIG_MTD_NAND_MXC_MODULE) \
+|| defined(CONFIG_MTD_NAND_MXC_V2) || defined(CONFIG_MTD_NAND_MXC_V2_MODULE)
+
+static struct mtd_partition mxc_nand_partitions[] = {
+ {
+ .name = "nand.bootloader",
+ .offset = 0,
+ .size = 1024 * 1024},
+ {
+ .name = "nand.kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 5 * 1024 * 1024},
+ {
+ .name = "nand.rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 96 * 1024 * 1024},
+ {
+ .name = "nand.configure",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024},
+ {
+ .name = "nand.userfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL},
+};
+
+static struct flash_platform_data mxc_nand_data = {
+ .parts = mxc_nand_partitions,
+ .nr_parts = ARRAY_SIZE(mxc_nand_partitions),
+ .width = 1,
+};
+
+static struct platform_device mxc_nand_mtd_device = {
+ .name = "mxc_nandv2_flash",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_nand_data,
+ },
+};
+
+static void mxc_init_nand_mtd(void)
+{
+ if (__raw_readl(MXC_CCM_RCSR) & MXC_CCM_RCSR_NF16B)
+ mxc_nand_data.width = 2;
+
+ platform_device_register(&mxc_nand_mtd_device);
+}
+#else
+static inline void mxc_init_nand_mtd(void)
+{
+}
+#endif
+
+static struct mxc_lcd_platform_data lcd_data = {
+ .io_reg = "LCD"
+};
+
+static struct platform_device lcd_dev = {
+ .name = "lcd_claa",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = (void *)&lcd_data,
+ },
+};
+
+static void mxc_init_lcd(void)
+{
+ platform_device_register(&lcd_dev);
+}
+
+#if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE)
+/* mxc lcd driver */
+static struct platform_device mxc_fb_device = {
+ .name = "mxc_sdc_fb",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+};
+
+static void mxc_init_fb(void)
+{
+ (void)platform_device_register(&mxc_fb_device);
+}
+#else
+static inline void mxc_init_fb(void)
+{
+}
+#endif
+
+#if defined(CONFIG_BACKLIGHT_MXC)
+static struct platform_device mxcbl_devices[] = {
+#if defined(CONFIG_BACKLIGHT_MXC_IPU) || defined(CONFIG_BACKLIGHT_MXC_IPU_MODULE)
+ {
+ .name = "mxc_ipu_bl",
+ .id = 0,
+ .dev = {
+ .platform_data = (void *)3, /* DISP # for this backlight */
+ },
+ }
+#endif
+};
+
+static inline void mxc_init_bl(void)
+{
+ int i;
+ for (i = 0; i < ARRAY_SIZE(mxcbl_devices); i++) {
+ platform_device_register(&mxcbl_devices[i]);
+ }
+}
+#else
+static inline void mxc_init_bl(void)
+{
+}
+#endif
+
+#if defined(CONFIG_MXC_MLB) || defined(CONFIG_MXC_MLB_MODULE)
+static struct resource mlb_resource[] = {
+ [0] = {
+ .start = MLB_BASE_ADDR,
+ .end = MLB_BASE_ADDR + 0x300,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_MLB,
+ .end = MXC_INT_MLB,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct mxc_mlb_platform_data mlb_data = {
+ .buf_address = IRAM_BASE_ADDR_VIRT + MLB_IRAM_ADDR_OFFSET,
+ .phy_address = IRAM_BASE_ADDR + MLB_IRAM_ADDR_OFFSET,
+ .reg_nvcc = "VVIDEO",
+ .mlb_clk = "mlb_clk",
+};
+
+static struct platform_device mlb_dev = {
+ .name = "mxc_mlb",
+ .id = 0,
+ .dev = {
+ .platform_data = &mlb_data,
+ },
+ .num_resources = ARRAY_SIZE(mlb_resource),
+ .resource = mlb_resource,
+};
+
+static inline void mxc_init_mlb(void)
+{
+ platform_device_register(&mlb_dev);
+}
+#else
+static inline void mxc_init_mlb(void)
+{
+}
+#endif
+
+#if defined(CONFIG_SDIO_UNIFI_FS) || defined(CONFIG_SDIO_UNIFI_FS_MODULE)
+static void mxc_unifi_hardreset(void)
+{
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 1, 0);
+ msleep(100);
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 1, 1);
+}
+
+static void mxc_unifi_enable(int en)
+{
+ if (en) {
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 5, 1);
+ msleep(10);
+ } else
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 5, 0);
+}
+
+static struct mxc_unifi_platform_data unifi_data = {
+ .hardreset = mxc_unifi_hardreset,
+ .enable = mxc_unifi_enable,
+ .reg_gpo1 = "GPO2",
+ .reg_gpo2 = "GPO3",
+ .reg_1v5_ana_bb = "PWGT1",
+ .reg_vdd_vpa = "VAUDIO",
+ .reg_1v5_dd = "SW1",
+ .host_id = 1,
+};
+
+struct mxc_unifi_platform_data *get_unifi_plat_data(void)
+{
+ return &unifi_data;
+}
+#else
+struct mxc_unifi_platform_data *get_unifi_plat_data(void)
+{
+ return NULL;
+}
+#endif
+
+EXPORT_SYMBOL(get_unifi_plat_data);
+
+static struct mxc_tsc_platform_data tsc2007_data = {
+ .vdd_reg = "SW1",
+ .penup_threshold = 30,
+ .active = gpio_tsc_active,
+ .inactive = gpio_tsc_inactive,
+};
+
+static struct mxc_camera_platform_data camera_data = {
+ .core_regulator = "SW1",
+ .io_regulator = "VAUDIO",
+ .analog_regulator = "VIOHI",
+ .gpo_regulator = "PWGT1",
+ .mclk = 27000000,
+};
+
+void si4702_reset(void)
+{
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 4, 0);
+ msleep(100);
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 4, 1);
+ msleep(100);
+}
+
+void si4702_clock_ctl(int flag)
+{
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 7, flag);
+}
+
+static void si4702_gpio_get(void)
+{
+}
+
+static void si4702_gpio_put(void)
+{
+}
+
+static struct mxc_fm_platform_data si4702_data = {
+ .reg_vio = "GPO2",
+ .reg_vdd = "GPO2",
+ .gpio_get = si4702_gpio_get,
+ .gpio_put = si4702_gpio_put,
+ .reset = si4702_reset,
+ .clock_ctl = si4702_clock_ctl,
+};
+
+static void adv7180_pwdn(int pwdn)
+{
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 1, pwdn);
+}
+
+static void adv7180_reset(void)
+{
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 6, 0);
+ msleep(5);
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 6, 1);
+ msleep(5);
+}
+
+static struct mxc_tvin_platform_data adv7180_data = {
+ .dvddio_reg = NULL,
+ .dvdd_reg = "SW3",
+ .avdd_reg = "PWGT2",
+ .pvdd_reg = NULL,
+ .pwdn = adv7180_pwdn,
+ .reset = adv7180_reset,
+};
+
+static struct i2c_board_info mxc_i2c_board_info[] __initdata = {
+ {
+ .type = "mc9sdz60",
+ .addr = 0x69,
+ },
+ {
+ .type = "max8660",
+ .addr = 0x34,
+ },
+ {
+ .type = "tsc2007",
+ .addr = 0x48,
+ .platform_data = &tsc2007_data,
+ .irq = IOMUX_TO_IRQ(MX35_PIN_CAPTURE),
+ },
+ {
+ .type = "ov2640",
+ .addr = 0x30,
+ .platform_data = (void *)&camera_data,
+ },
+ {
+ .type = "sgtl5000-i2c",
+ .addr = 0x0a,
+ },
+ {
+ .type = "ak4647-i2c",
+ .addr = 0x12,
+ },
+#if defined(CONFIG_I2C_SLAVE_CLIENT)
+ {
+ .type = "i2c-slave-client",
+ .addr = 0x55,
+ },
+#endif
+ {
+ .type = "si4702",
+ .addr = 0x10,
+ .platform_data = (void *)&si4702_data,
+ },
+ {
+ .type = "adv7180",
+ .addr = 0x21,
+ .platform_data = (void *)&adv7180_data,
+ },
+ {
+ .type = "mc13892",
+ .addr = 0x08,
+ .platform_data = (void *)MX35_PIN_GPIO2_0,
+ },
+};
+
+static struct spi_board_info mxc_spi_board_info[] __initdata = {
+ {
+ .modalias = "wm8580_spi",
+ .max_speed_hz = 8000000, /* max spi SCK clock speed in HZ */
+ .bus_num = 1,
+ .chip_select = 1,
+ },
+};
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+static struct resource smsc911x_resources[] = {
+ {
+ .start = LAN9217_BASE_ADDR,
+ .end = LAN9217_BASE_ADDR + 0x100,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = LAN9217_IRQ,
+ .end = LAN9217_IRQ,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct platform_device mxc_smsc911x_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+};
+
+static void mxc_init_enet(void)
+{
+ platform_device_register(&mxc_smsc911x_device);
+}
+#else
+static inline void mxc_init_enet(void)
+{
+}
+#endif
+
+#if defined(CONFIG_FEC) || defined(CONFIG_FEC_MODULE)
+unsigned int expio_intr_fec;
+
+EXPORT_SYMBOL(expio_intr_fec);
+#endif
+
+#if defined(CONFIG_MMC_IMX_ESDHCI) || defined(CONFIG_MMC_IMX_ESDHCI_MODULE)
+static struct mxc_mmc_platform_data mmc0_data = {
+ .ocr_mask = MMC_VDD_32_33,
+#if defined(CONFIG_SDIO_UNIFI_FS) || defined(CONFIG_SDIO_UNIFI_FS_MODULE)
+ .caps = MMC_CAP_4_BIT_DATA,
+#else
+ .caps = MMC_CAP_8_BIT_DATA,
+#endif
+ .min_clk = 400000,
+ .max_clk = 52000000,
+ .card_inserted_state = 0,
+ .status = sdhc_get_card_det_status,
+ .wp_status = sdhc_write_protect,
+ .clock_mmc = "sdhc_clk",
+};
+
+/*!
+ * Resource definition for the SDHC1
+ */
+static struct resource mxcsdhc1_resources[] = {
+ [0] = {
+ .start = MMC_SDHC1_BASE_ADDR,
+ .end = MMC_SDHC1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_MMC_SDHC1,
+ .end = MXC_INT_MMC_SDHC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = MXC_PSEUDO_IRQ_SD1_CD,
+ .end = MXC_PSEUDO_IRQ_SD1_CD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Device Definition for MXC SDHC1 */
+static struct platform_device mxcsdhc1_device = {
+ .name = "mxsdhci",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mmc0_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcsdhc1_resources),
+ .resource = mxcsdhc1_resources,
+};
+
+#if defined(CONFIG_SDIO_UNIFI_FS) || defined(CONFIG_SDIO_UNIFI_FS_MODULE)
+static struct mxc_mmc_platform_data mmc1_data = {
+ .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 |
+ MMC_VDD_31_32,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .min_clk = 150000,
+ .max_clk = 50000000,
+ .card_inserted_state = 0,
+ .status = sdhc_get_card_det_status,
+ .wp_status = sdhc_write_protect,
+ .clock_mmc = "sdhc_clk",
+};
+
+static struct resource mxcsdhc2_resources[] = {
+ [0] = {
+ .start = MMC_SDHC2_BASE_ADDR,
+ .end = MMC_SDHC2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_MMC_SDHC2,
+ .end = MXC_INT_MMC_SDHC2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mxcsdhc2_device = {
+ .name = "mxsdhci",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mmc1_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcsdhc2_resources),
+ .resource = mxcsdhc2_resources,
+};
+#endif
+
+static inline void mxc_init_mmc(void)
+{
+ (void)platform_device_register(&mxcsdhc1_device);
+#if defined(CONFIG_SDIO_UNIFI_FS) || defined(CONFIG_SDIO_UNIFI_FS_MODULE)
+ (void)platform_device_register(&mxcsdhc2_device);
+#endif
+}
+#else
+static inline void mxc_init_mmc(void)
+{
+}
+#endif
+
+#ifdef CONFIG_MXC_PSEUDO_IRQS
+/*! Device Definition for MXC SDHC1 */
+static struct platform_device mxc_pseudo_irq_device = {
+ .name = "mxc_pseudo_irq",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+};
+
+static inline int mxc_init_pseudo_irq(void)
+{
+ return platform_device_register(&mxc_pseudo_irq_device);
+}
+
+late_initcall(mxc_init_pseudo_irq);
+
+/*!
+ * Power Key interrupt handler.
+ */
+static irqreturn_t power_key_int(int irq, void *dev_id)
+{
+ pr_info(KERN_INFO "on-off key pressed\n");
+ return 0;
+}
+
+/*!
+ * Power Key initialization.
+ */
+static int __init mxc_init_power_key(void)
+{
+ if (!board_is_mx35(BOARD_REV_2)) {
+ /*Set power key as wakeup resource */
+ int irq, ret;
+ irq = MXC_PSEUDO_IRQ_POWER_KEY;
+ set_irq_type(irq, IRQF_TRIGGER_RISING);
+ ret = request_irq(irq, power_key_int, 0, "power_key", 0);
+ if (ret)
+ pr_info("register on-off key interrupt failed\n");
+ else
+ enable_irq_wake(irq);
+ return ret;
+ }
+ return 0;
+}
+
+late_initcall(mxc_init_power_key);
+#endif
+
+/*!
+ * the event handler for power on event
+ */
+static void power_on_evt_handler(void)
+{
+ pr_info("pwr on event1 is received \n");
+}
+
+/*!
+ * pmic board initialization code
+ */
+static int __init mxc_init_pmic(void)
+{
+ if (board_is_mx35(BOARD_REV_2)) {
+#if defined(CONFIG_MXC_PMIC_MC13892_MODULE) || defined(CONFIG_MXC_PMIC_MC13892)
+ unsigned int value;
+ pmic_event_callback_t power_key_event;
+ struct regulator *sw2_stby_reg;
+
+ /* subscribe PWRON1 event. */
+ power_key_event.param = NULL;
+ power_key_event.func = (void *)power_on_evt_handler;
+ pmic_event_subscribe(EVENT_PWRONI, power_key_event);
+
+ pmic_read_reg(REG_POWER_CTL2, &value, 0xffffff);
+ /* Bit 11 (STANDBYSECINV): Active Low */
+ value |= 0x00800;
+ pmic_write_reg(REG_POWER_CTL2, value, 0xffffff);
+
+ sw2_stby_reg = regulator_get(NULL, "SW2_STBY");
+
+ /* TBD: If core voltage is expected to be updated above 1.375v,
+ * this code needs to be moved before entering standby mode,
+ * which is decided by MC13892 Hi bit behavior */
+ regulator_set_voltage(sw2_stby_reg, 1000000);
+ regulator_put(sw2_stby_reg, NULL);
+#endif
+ }
+ return 0;
+}
+
+late_initcall(mxc_init_pmic);
+
+#if defined(CONFIG_PATA_FSL) || defined(CONFIG_PATA_FSL_MODULE)
+extern void gpio_ata_active(void);
+extern void gpio_ata_inactive(void);
+
+static int ata_init(struct platform_device *pdev)
+{
+ /* Configure the pins */
+ gpio_ata_active();
+
+ return 0;
+}
+
+static void ata_exit(void)
+{
+ /* Free the pins */
+ gpio_ata_inactive();
+}
+
+static struct fsl_ata_platform_data ata_data = {
+ .adma_flag = 1, /* 0:smart dma, 1:ADMA */
+ .udma_mask = 0x3F,
+ .mwdma_mask = 0x1F,
+ .pio_mask = ATA_PIO4,
+ .fifo_alarm = MXC_IDE_DMA_WATERMARK / 2,
+ .max_sg = MXC_IDE_DMA_BD_NR,
+ .init = ata_init,
+ .exit = ata_exit,
+ .core_reg = NULL, /*"LDO2", */
+ .io_reg = NULL, /*"LDO3", */
+};
+
+static struct resource pata_fsl_resources[] = {
+ [0] = { /* I/O */
+ .start = ATA_BASE_ADDR,
+ .end = ATA_BASE_ADDR + 0x000000C8,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = { /* IRQ */
+ .start = MXC_INT_ATA,
+ .end = MXC_INT_ATA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pata_fsl_device = {
+ .name = "pata_fsl",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pata_fsl_resources),
+ .resource = pata_fsl_resources,
+ .dev = {
+ .platform_data = &ata_data,
+ .coherent_dma_mask = ~0,
+ },
+};
+
+static void __init mxc_init_pata(void)
+{
+ (void)platform_device_register(&pata_fsl_device);
+}
+#else /* CONFIG_PATA_FSL */
+static void __init mxc_init_pata(void)
+{
+}
+#endif /* CONFIG_PATA_FSL */
+
+#if defined(CONFIG_GPS_IOCTRL) || defined(CONFIG_GPS_IOCTRL_MODULE)
+static struct mxc_gps_platform_data gps_data = {
+ .core_reg = "SW3",
+ .analog_reg = "PWGT2",
+};
+
+static struct platform_device mxc_gps_device = {
+ .name = "gps_ioctrl",
+ .id = 0,
+ .dev = {
+ .platform_data = &gps_data,
+ },
+};
+
+static void __init mxc_init_gps(void)
+{
+ (void)platform_device_register(&mxc_gps_device);
+}
+#else
+static void __init mxc_init_gps(void)
+{
+}
+#endif
+
+/*!
+ * Board specific fixup function. It is called by \b setup_arch() in
+ * setup.c file very early on during kernel starts. It allows the user to
+ * statically fill in the proper values for the passed-in parameters. None of
+ * the parameters is used currently.
+ *
+ * @param desc pointer to \b struct \b machine_desc
+ * @param tags pointer to \b struct \b tag
+ * @param cmdline pointer to the command line
+ * @param mi pointer to \b struct \b meminfo
+ */
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ mxc_cpu_init();
+
+#ifdef CONFIG_DISCONTIGMEM
+ do {
+ int nid;
+ mi->nr_banks = MXC_NUMNODES;
+ for (nid = 0; nid < mi->nr_banks; nid++)
+ SET_NODE(mi, nid);
+ } while (0);
+#endif
+}
+
+static void bt_reset(void)
+{
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 2, 0);
+ msleep(5);
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 2, 1);
+}
+
+static struct mxc_bt_platform_data mxc_bt_data = {
+ .bt_vdd = "GPO2",
+ .bt_vdd_parent = NULL,
+ .bt_vusb = NULL,
+ .bt_vusb_parent = NULL,
+ .bt_reset = bt_reset,
+};
+
+static struct platform_device mxc_bt_device = {
+ .name = "mxc_bt",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_bt_data,
+ },
+};
+
+static void mxc_init_bluetooth(void)
+{
+ (void)platform_device_register(&mxc_bt_device);
+}
+
+#if defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000) \
+ || defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000_MODULE)
+
+unsigned int headphone_det_status(void)
+{
+ int ret = 0;
+ if (0 != pmic_gpio_get_designation_bit_val(0, &ret))
+ printk(KERN_ERR "Get headphone status error.");
+ return ret;
+}
+
+static struct mxc_sgtl5000_platform_data sgtl5000_data = {
+ .ssi_num = 1,
+ .src_port = 1,
+ .ext_port = 4,
+ .hp_irq = MXC_PSEUDO_IRQ_HEADPHONE,
+ .hp_status = headphone_det_status,
+ .vddio_reg = NULL,
+ .vdda_reg = "VCAM",
+ .amp_gpo = "SPKR",
+ .vddio = 0,
+ .vdda = 3000000,
+ .vddd = 0,
+ .sysclk = 12000000,
+};
+
+static struct platform_device sgtl5000_device = {
+ .name = "sgtl5000-imx",
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &sgtl5000_data,
+ } ,
+};
+
+static void mxc_sgtl5000_init(void)
+{
+ int err;
+ struct clk *cko1, *parent;
+ unsigned long rate;
+
+ /* for board v1.1 do nothing*/
+ if (!board_is_mx35(BOARD_REV_2))
+ return;
+
+ cko1 = clk_get(NULL, "cko1_clk");
+ if (IS_ERR(cko1))
+ return;
+ parent = clk_get(NULL, "ckih");
+ if (IS_ERR(parent))
+ return;
+ clk_set_parent(cko1, parent);
+ rate = clk_round_rate(cko1, 12000000);
+ if (rate < 8000000 || rate > 27000000) {
+ printk(KERN_ERR "Error: SGTL5000 mclk freq %d out of range!\n",
+ rate);
+ clk_put(parent);
+ clk_put(cko1);
+ return;
+ }
+ clk_set_rate(cko1, rate);
+ clk_enable(cko1);
+ sgtl5000_data.sysclk = rate;
+ platform_device_register(&sgtl5000_device);
+}
+#else
+static void mxc_sgtl5000_init(void)
+{
+}
+#endif
+
+#if defined(CONFIG_CAN_FLEXCAN) || defined(CONFIG_CAN_FLEXCAN_MODULE)
+static void flexcan_xcvr_enable(int id, int en)
+{
+ static int pwdn;
+
+ if (id < 0 || id > 1)
+ return;
+
+ if (en) {
+ if (!(pwdn++))
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_2,
+ 1, 0);
+ } else {
+ if (!(--pwdn))
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_2,
+ 1, 1);
+ }
+}
+
+struct flexcan_platform_data flexcan_data[] = {
+ {
+ .core_reg = "GPO2",
+ .io_reg = NULL,
+ .xcvr_enable = flexcan_xcvr_enable,
+ .active = gpio_can_active,
+ .inactive = gpio_can_inactive,},
+ {
+ .core_reg = "GPO2",
+ .io_reg = NULL,
+ .xcvr_enable = flexcan_xcvr_enable,
+ .active = gpio_can_active,
+ .inactive = gpio_can_inactive,},
+};
+#endif
+
+/*!
+ * fixup for mx35 3stack board v1.0 (MAX8660)
+ */
+static void mx35_3stack_fixup_for_board_v1(void)
+{
+#if defined(CONFIG_MXC_MLB) || defined(CONFIG_MXC_MLB_MODULE)
+ mlb_data.reg_nvcc = "LDO6";
+#endif
+
+#if defined(CONFIG_SDIO_UNIFI_FS) || defined(CONFIG_SDIO_UNIFI_FS_MODULE)
+ unifi_data.reg_gpo1 = NULL;
+ unifi_data.reg_gpo2 = NULL;
+ unifi_data.reg_1v5_ana_bb = "SW4";
+ unifi_data.reg_vdd_vpa = "SW1";
+ unifi_data.reg_1v5_dd = "SW4";
+#endif
+ camera_data.analog_regulator = "LDO7";
+ camera_data.core_regulator = NULL;
+ camera_data.io_regulator = NULL;
+ camera_data.gpo_regulator = NULL;
+ camera_data.mclk = 20000000;
+
+ adv7180_data.dvddio_reg = NULL;
+ adv7180_data.dvdd_reg = NULL;
+ adv7180_data.avdd_reg = NULL;
+ adv7180_data.pvdd_reg = NULL;
+
+#if defined(CONFIG_GPS_IOCTRL) || defined(CONFIG_GPS_IOCTRL_MODULE)
+ gps_data.core_reg = "SW1";
+ gps_data.analog_reg = "SW2";
+#endif
+
+ mxc_bt_data.bt_vdd = "SW1";
+
+#if defined(CONFIG_CAN_FLEXCAN) || defined(CONFIG_CAN_FLEXCAN_MODULE)
+ flexcan_data[0].core_reg = "SW1";
+ flexcan_data[1].core_reg = "SW1";
+#endif
+}
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ mxc_cpu_common_init();
+
+ early_console_setup(saved_command_line);
+ mxc_gpio_init();
+ mxc_init_devices();
+ if (!board_is_mx35(BOARD_REV_2))
+ mx35_3stack_fixup_for_board_v1();
+ mx35_3stack_gpio_init();
+ mxc_init_enet();
+ mxc_init_nor_mtd();
+ mxc_init_nand_mtd();
+
+ mxc_init_lcd();
+ mxc_init_fb();
+ mxc_init_bl();
+ mxc_sgtl5000_init();
+
+ i2c_register_board_info(0, mxc_i2c_board_info,
+ ARRAY_SIZE(mxc_i2c_board_info));
+
+ spi_register_board_info(mxc_spi_board_info,
+ ARRAY_SIZE(mxc_spi_board_info));
+ mxc_init_mmc();
+ mxc_init_pata();
+ mxc_init_bluetooth();
+ mxc_init_gps();
+ mxc_init_mlb();
+}
+
+#define PLL_PCTL_REG(brmo, pd, mfd, mfi, mfn) \
+ (((brmo) << 31) + (((pd) - 1) << 26) + (((mfd) - 1) << 16) + \
+ ((mfi) << 10) + mfn)
+
+/* For 24MHz input clock */
+#define PLL_665MHZ PLL_PCTL_REG(1, 1, 48, 13, 41)
+#define PLL_532MHZ PLL_PCTL_REG(1, 1, 12, 11, 1)
+#define PLL_399MHZ PLL_PCTL_REG(0, 1, 16, 8, 5)
+
+/* working point(wp): 0,1 - 133MHz; 2,3 - 266MHz; 4,5 - 399MHz;*/
+/* auto input clock table */
+static struct cpu_wp cpu_wp_auto[] = {
+ {
+ .pll_reg = PLL_399MHZ,
+ .pll_rate = 399000000,
+ .cpu_rate = 133000000,
+ .pdr0_reg = (0x2 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_399MHZ,
+ .pll_rate = 399000000,
+ .cpu_rate = 133000000,
+ .pdr0_reg = (0x6 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_399MHZ,
+ .pll_rate = 399000000,
+ .cpu_rate = 266000000,
+ .pdr0_reg = (0x1 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_399MHZ,
+ .pll_rate = 399000000,
+ .cpu_rate = 266000000,
+ .pdr0_reg = (0x5 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_399MHZ,
+ .pll_rate = 399000000,
+ .cpu_rate = 399000000,
+ .pdr0_reg = (0x0 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_399MHZ,
+ .pll_rate = 399000000,
+ .cpu_rate = 399000000,
+ .pdr0_reg = (0x6 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),},
+};
+
+/* consumer input clock table */
+static struct cpu_wp cpu_wp_con[] = {
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 133000000,
+ .pdr0_reg = (0x6 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 133000000,
+ .pdr0_reg = (0xE << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 266000000,
+ .pdr0_reg = (0x2 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 266000000,
+ .pdr0_reg = (0xA << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 399000000,
+ .pdr0_reg = (0x1 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 399000000,
+ .pdr0_reg = (0x9 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 532000000,
+ .pdr0_reg = (0x0 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 532000000,
+ .pdr0_reg = (0x8 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_665MHZ,
+ .pll_rate = 665000000,
+ .cpu_rate = 665000000,
+ .pdr0_reg = (0x7 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+};
+
+struct cpu_wp *get_cpu_wp(int *wp)
+{
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) >= 1) {
+ *wp = 9;
+ return cpu_wp_con;
+ } else {
+ if (__raw_readl(MXC_CCM_PDR0) & MXC_CCM_PDR0_AUTO_CON) {
+ *wp = 9;
+ return cpu_wp_con;
+ } else {
+ *wp = 6;
+ return cpu_wp_auto;
+ }
+ }
+}
+
+static void __init mx35_3stack_timer_init(void)
+{
+ mxc_clocks_init(0, 0, 0, 0);
+ mxc_timer_init("gpt_clk");
+}
+
+static struct sys_timer mxc_timer = {
+ .init = mx35_3stack_timer_init,
+};
+
+/*
+ * The following uses standard kernel macros define in arch.h in order to
+ * initialize __mach_desc_MX35_3DS data structure.
+ */
+/* *INDENT-OFF* */
+MACHINE_START(MX35_3DS, "Freescale MX35 3-Stack Board")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .phys_io = AIPS1_BASE_ADDR,
+ .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = PHYS_OFFSET + 0x100,
+ .fixup = fixup_mxc_board,
+ .map_io = mxc_map_io,
+ .init_irq = mxc_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &mxc_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx35/mx35_3stack_cpld.c b/arch/arm/mach-mx35/mx35_3stack_cpld.c
new file mode 100644
index 000000000000..9d1dea68d44d
--- /dev/null
+++ b/arch/arm/mach-mx35/mx35_3stack_cpld.c
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/clk.h>
+
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+
+#include "board-mx35_3stack.h"
+#include "crm_regs.h"
+#include "iomux.h"
+
+/*!
+ * @file mach-mx35/mx35_3stack_cpld.c
+ *
+ * @brief This file contains the board specific initialization routines.
+ *
+ * @ingroup MSL_MX35
+ */
+static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 expio_irq;
+ u32 index, mask;
+ desc->chip->mask(irq); /* irq = gpio irq number */
+
+ index = __raw_readw(mx35_3stack_board_io + INTR_STATUS_REG);
+ mask = __raw_readw(mx35_3stack_board_io + INTR_MASK_REG);
+
+ if (unlikely(!(index & (~mask)))) {
+ printk(KERN_ERR "\nEXPIO: Spurious interrupt:0x%0x\n\n", index);
+ pr_info("CPLD IMR(0x38)=0x%x, PENDING(0x28)=0x%x\n", mask,
+ index);
+ goto out;
+ }
+ index = index & (~mask);
+ expio_irq = MXC_EXP_IO_BASE;
+ for (; index != 0; index >>= 1, expio_irq++) {
+ struct irq_desc *d;
+ if ((index & 1) == 0)
+ continue;
+ d = irq_desc + expio_irq;
+ if (unlikely(!(d->handle_irq))) {
+ printk(KERN_ERR "\nEXPIO irq: %d unhandeled\n",
+ expio_irq);
+ BUG(); /* oops */
+ }
+ d->handle_irq(expio_irq, d);
+ }
+
+ out:
+ desc->chip->ack(irq);
+ desc->chip->unmask(irq);
+}
+
+/*
+ * Disable an expio pin's interrupt by setting the bit in the imr.
+ * @param irq an expio virtual irq number
+ */
+static void expio_mask_irq(u32 irq)
+{
+ u16 reg, expio = MXC_IRQ_TO_EXPIO(irq);
+
+ reg = __raw_readw(mx35_3stack_board_io + INTR_MASK_REG);
+ /* mask the interrupt */
+ __raw_writew(reg | (1 << expio), mx35_3stack_board_io + INTR_MASK_REG);
+}
+
+/*
+ * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
+ * @param irq an expanded io virtual irq number
+ */
+static void expio_ack_irq(u32 irq)
+{
+ u32 expio = MXC_IRQ_TO_EXPIO(irq);
+ /* clear the interrupt status */
+ __raw_writew(1 << expio, mx35_3stack_board_io + INTR_RESET_REG);
+ __raw_writew(0, mx35_3stack_board_io + INTR_RESET_REG);
+ /* mask the interrupt */
+ expio_mask_irq(irq);
+}
+
+/*
+ * Enable a expio pin's interrupt by clearing the bit in the imr.
+ * @param irq a expio virtual irq number
+ */
+static void expio_unmask_irq(u32 irq)
+{
+ u16 reg, expio = MXC_IRQ_TO_EXPIO(irq);
+
+ reg = __raw_readw(mx35_3stack_board_io + INTR_MASK_REG);
+ /* unmask the interrupt */
+ __raw_writew(reg & (~(1 << expio)),
+ mx35_3stack_board_io + INTR_MASK_REG);
+}
+
+static struct irq_chip expio_irq_chip = {
+ .ack = expio_ack_irq,
+ .mask = expio_mask_irq,
+ .unmask = expio_unmask_irq,
+};
+
+static int __init mxc_expio_init(void)
+{
+ int i;
+
+ mx35_3stack_board_io = (u32) ioremap(BOARD_IO_ADDR, SZ_4K);
+ if (mx35_3stack_board_io == 0)
+ return -ENOMEM;
+
+ if ((__raw_readw(mx35_3stack_board_io + MAGIC_NUMBER1_REG) != 0xAAAA) ||
+ (__raw_readw(mx35_3stack_board_io + MAGIC_NUMBER2_REG) != 0x5555))
+ return -ENODEV;
+
+ pr_info("3-Stack Debug board detected, rev = 0x%04X\n",
+ readw(mx35_3stack_board_io + CPLD_CODE_VER_REG));
+
+ /*
+ * Configure INT line as GPIO input
+ */
+ mxc_request_iomux(EXPIO_PARENT_INT, MUX_CONFIG_FUNC);
+ mxc_set_gpio_direction(EXPIO_PARENT_INT, 1);
+
+ /* disable the interrupt and clear the status */
+ __raw_writew(0, mx35_3stack_board_io + INTR_MASK_REG);
+ __raw_writew(0xFFFF, mx35_3stack_board_io + INTR_RESET_REG);
+ __raw_writew(0, mx35_3stack_board_io + INTR_RESET_REG);
+ __raw_writew(0x1F, mx35_3stack_board_io + INTR_MASK_REG);
+ for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
+ i++) {
+ set_irq_chip(i, &expio_irq_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+ set_irq_type(IOMUX_TO_IRQ(EXPIO_PARENT_INT), IRQF_TRIGGER_LOW);
+ set_irq_chained_handler(IOMUX_TO_IRQ(EXPIO_PARENT_INT),
+ mxc_expio_irq_handler);
+ return 0;
+}
+
+arch_initcall(mxc_expio_init);
diff --git a/arch/arm/mach-mx35/mx35_3stack_gpio.c b/arch/arm/mach-mx35/mx35_3stack_gpio.c
new file mode 100644
index 000000000000..757817f999f7
--- /dev/null
+++ b/arch/arm/mach-mx35/mx35_3stack_gpio.c
@@ -0,0 +1,1353 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include <linux/regulator/mcu_max8660-bus.h>
+#include "board-mx35_3stack.h"
+#include "iomux.h"
+
+/*!
+ * @file mach-mx35/mx35_3stack_gpio.c
+ *
+ * @brief This file contains all the GPIO setup functions for the board.
+ *
+ * @ingroup GPIO_MX35
+ */
+
+/*!
+ * This system-wise GPIO function initializes the pins during system startup.
+ * All the statically linked device drivers should put the proper GPIO
+ * initialization code inside this function. It is called by \b fixup_mx31ads()
+ * during system startup. This function is board specific.
+ */
+void mx35_3stack_gpio_init(void)
+{
+ /* config CS5 */
+ mxc_request_iomux(MX35_PIN_CS5, MUX_CONFIG_FUNC);
+
+}
+
+/*!
+ * Setup GPIO for a UART port to be active
+ *
+ * @param port a UART port
+ * @param no_irda indicates if the port is used for SIR
+ */
+void gpio_uart_active(int port, int no_irda)
+{
+ /*
+ * Configure the IOMUX control registers for the UART signals
+ */
+ switch (port) {
+ /* UART 1 IOMUX Configs */
+ case 0:
+ mxc_request_iomux(MX35_PIN_RXD1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_TXD1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_RTS1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CTS1, MUX_CONFIG_FUNC);
+
+ mxc_iomux_set_pad(MX35_PIN_RXD1,
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX35_PIN_TXD1,
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_RTS1,
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX35_PIN_CTS1,
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
+
+ break;
+ /* UART 2 IOMUX Configs */
+ case 1:
+ mxc_request_iomux(MX35_PIN_TXD2, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_RXD2, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_RTS2, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CTS2, MUX_CONFIG_FUNC);
+ mxc_iomux_set_pad(MX35_PIN_RXD2,
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX35_PIN_TXD2,
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_RTS2,
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX35_PIN_CTS2,
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
+ break;
+ /* UART 3 IOMUX Configs */
+ case 2:
+ mxc_request_iomux(MX35_PIN_FEC_TX_CLK, MUX_CONFIG_ALT2);
+ mxc_request_iomux(MX35_PIN_FEC_RX_CLK, MUX_CONFIG_ALT2);
+ mxc_request_iomux(MX35_PIN_FEC_COL, MUX_CONFIG_ALT2);
+ mxc_request_iomux(MX35_PIN_FEC_RX_DV, MUX_CONFIG_ALT2);
+
+ mxc_iomux_set_pad(MX35_PIN_FEC_TX_CLK,
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX35_PIN_FEC_RX_CLK,
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_RX_DV,
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX35_PIN_FEC_COL,
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
+
+ mxc_iomux_set_input(MUX_IN_UART3_UART_RTS_B, INPUT_CTL_PATH2);
+ mxc_iomux_set_input(MUX_IN_UART3_UART_RXD_MUX, INPUT_CTL_PATH3);
+ break;
+ default:
+ break;
+ }
+
+}
+
+EXPORT_SYMBOL(gpio_uart_active);
+
+/*!
+ * Setup GPIO for a UART port to be inactive
+ *
+ * @param port a UART port
+ * @param no_irda indicates if the port is used for SIR
+ */
+void gpio_uart_inactive(int port, int no_irda)
+{
+ switch (port) {
+ case 0:
+ mxc_request_gpio(MX35_PIN_RXD1);
+ mxc_request_gpio(MX35_PIN_TXD1);
+ mxc_request_gpio(MX35_PIN_RTS1);
+ mxc_request_gpio(MX35_PIN_CTS1);
+
+ mxc_free_iomux(MX35_PIN_RXD1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_TXD1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_RTS1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_CTS1, MUX_CONFIG_GPIO);
+ break;
+ case 1:
+ mxc_request_gpio(MX35_PIN_RXD2);
+ mxc_request_gpio(MX35_PIN_TXD2);
+ mxc_request_gpio(MX35_PIN_RTS2);
+ mxc_request_gpio(MX35_PIN_CTS2);
+
+ mxc_free_iomux(MX35_PIN_RXD2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_TXD2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_RTS2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_CTS2, MUX_CONFIG_GPIO);
+ break;
+ case 2:
+ mxc_request_gpio(MX35_PIN_FEC_TX_CLK);
+ mxc_request_gpio(MX35_PIN_FEC_RX_CLK);
+ mxc_request_gpio(MX35_PIN_FEC_COL);
+ mxc_request_gpio(MX35_PIN_FEC_RX_DV);
+
+ mxc_free_iomux(MX35_PIN_FEC_TX_CLK, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_RX_CLK, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_COL, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_RX_DV, MUX_CONFIG_GPIO);
+
+ mxc_iomux_set_input(MUX_IN_UART3_UART_RTS_B, INPUT_CTL_PATH0);
+ mxc_iomux_set_input(MUX_IN_UART3_UART_RXD_MUX, INPUT_CTL_PATH0);
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_uart_inactive);
+
+/*!
+ * Configure the IOMUX GPR register to receive shared SDMA UART events
+ *
+ * @param port a UART port
+ */
+void config_uartdma_event(int port)
+{
+}
+
+EXPORT_SYMBOL(config_uartdma_event);
+
+void gpio_fec_active(void)
+{
+ mxc_request_iomux(MX35_PIN_FEC_TX_CLK, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_RX_CLK, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_RX_DV, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_COL, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_RDATA0, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_TDATA0, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_TX_EN, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_MDC, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_MDIO, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_TX_ERR, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_RX_ERR, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_CRS, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_RDATA1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_TDATA1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_RDATA2, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_TDATA2, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_RDATA3, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FEC_TDATA3, MUX_CONFIG_FUNC);
+
+#define FEC_PAD_CTL_COMMON (PAD_CTL_DRV_3_3V|PAD_CTL_PUE_PUD| \
+ PAD_CTL_ODE_CMOS|PAD_CTL_DRV_NORMAL|PAD_CTL_SRE_SLOW)
+ mxc_iomux_set_pad(MX35_PIN_FEC_TX_CLK, FEC_PAD_CTL_COMMON |
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_RX_CLK,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_RX_DV,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_COL,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_RDATA0,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_TDATA0,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_CMOS |
+ PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_TX_EN,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_CMOS |
+ PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_MDC,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_CMOS |
+ PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_MDIO,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_22K_PU);
+ mxc_iomux_set_pad(MX35_PIN_FEC_TX_ERR,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_CMOS |
+ PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_RX_ERR,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_CRS,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_RDATA1,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_TDATA1,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_CMOS |
+ PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_RDATA2,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_TDATA2,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_CMOS |
+ PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_RDATA3,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_FEC_TDATA3,
+ FEC_PAD_CTL_COMMON | PAD_CTL_HYS_CMOS |
+ PAD_CTL_PKE_NONE | PAD_CTL_100K_PD);
+#undef FEC_PAD_CTL_COMMON
+ /* Pull GPIO1_5 to be high for routing signal to FEC */
+ if (board_is_mx35(BOARD_REV_2)) {
+ mxc_request_iomux(MX35_PIN_COMPARE, MUX_CONFIG_GPIO);
+ mxc_iomux_set_pad(MX35_PIN_COMPARE, PAD_CTL_DRV_NORMAL |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU |
+ PAD_CTL_DRV_3_3V | PAD_CTL_PUE_PUD |
+ PAD_CTL_SRE_SLOW);
+ mxc_set_gpio_direction(MX35_PIN_COMPARE, 0);
+ mxc_set_gpio_dataout(MX35_PIN_COMPARE, 1);
+ }
+
+ /* FEC enable */
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 2, 1);
+ /* FEC reset */
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 7, 0);
+ msleep(10);
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 7, 1);
+ msleep(100);
+}
+
+EXPORT_SYMBOL(gpio_fec_active);
+
+void gpio_fec_inactive(void)
+{
+ mxc_request_gpio(MX35_PIN_FEC_TX_CLK);
+ mxc_request_gpio(MX35_PIN_FEC_RX_CLK);
+ mxc_request_gpio(MX35_PIN_FEC_RX_DV);
+ mxc_request_gpio(MX35_PIN_FEC_COL);
+ mxc_request_gpio(MX35_PIN_FEC_RDATA0);
+ mxc_request_gpio(MX35_PIN_FEC_TDATA0);
+ mxc_request_gpio(MX35_PIN_FEC_TX_EN);
+ mxc_request_gpio(MX35_PIN_FEC_MDC);
+ mxc_request_gpio(MX35_PIN_FEC_MDIO);
+ mxc_request_gpio(MX35_PIN_FEC_TX_ERR);
+ mxc_request_gpio(MX35_PIN_FEC_RX_ERR);
+ mxc_request_gpio(MX35_PIN_FEC_CRS);
+ mxc_request_gpio(MX35_PIN_FEC_RDATA1);
+ mxc_request_gpio(MX35_PIN_FEC_TDATA1);
+ mxc_request_gpio(MX35_PIN_FEC_RDATA2);
+ mxc_request_gpio(MX35_PIN_FEC_TDATA2);
+ mxc_request_gpio(MX35_PIN_FEC_RDATA3);
+ mxc_request_gpio(MX35_PIN_FEC_TDATA3);
+
+ mxc_free_iomux(MX35_PIN_FEC_TX_CLK, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_RX_CLK, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_RX_DV, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_COL, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_RDATA0, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_TDATA0, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_TX_EN, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_MDC, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_MDIO, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_TX_ERR, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_RX_ERR, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_CRS, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_RDATA1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_TDATA1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_RDATA2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_TDATA2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_RDATA3, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_TDATA3, MUX_CONFIG_GPIO);
+
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 2, 0);
+
+ /* Free GPIO1_5 */
+ if (board_is_mx35(BOARD_REV_2))
+ mxc_free_iomux(MX35_PIN_COMPARE, MUX_CONFIG_GPIO);
+}
+
+EXPORT_SYMBOL(gpio_fec_inactive);
+
+/*!
+ * Setup GPIO for an I2C device to be active
+ *
+ * @param i2c_num an I2C device
+ */
+void gpio_i2c_active(int i2c_num)
+{
+
+#define PAD_CONFIG (PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD | PAD_CTL_ODE_OpenDrain)
+
+ switch (i2c_num) {
+ case 0:
+ mxc_request_iomux(MX35_PIN_I2C1_CLK, MUX_CONFIG_SION);
+ mxc_request_iomux(MX35_PIN_I2C1_DAT, MUX_CONFIG_SION);
+
+ mxc_iomux_set_pad(MX35_PIN_I2C1_CLK, PAD_CONFIG);
+ mxc_iomux_set_pad(MX35_PIN_I2C1_DAT, PAD_CONFIG);
+ break;
+ case 1:
+ mxc_request_iomux(MX35_PIN_I2C2_CLK, MUX_CONFIG_SION);
+ mxc_request_iomux(MX35_PIN_I2C2_DAT, MUX_CONFIG_SION);
+
+ mxc_iomux_set_pad(MX35_PIN_I2C2_CLK, PAD_CONFIG);
+ mxc_iomux_set_pad(MX35_PIN_I2C2_DAT, PAD_CONFIG);
+
+ break;
+ case 2:
+ mxc_request_iomux(MX35_PIN_TX3_RX2, MUX_CONFIG_ALT1);
+ mxc_request_iomux(MX35_PIN_TX2_RX3, MUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX35_PIN_TX3_RX2, PAD_CONFIG);
+ mxc_iomux_set_pad(MX35_PIN_TX2_RX3, PAD_CONFIG);
+ break;
+ default:
+ break;
+ }
+
+#undef PAD_CONFIG
+
+}
+
+EXPORT_SYMBOL(gpio_i2c_active);
+
+/*!
+ * Setup GPIO for an I2C device to be inactive
+ *
+ * @param i2c_num an I2C device
+ */
+void gpio_i2c_inactive(int i2c_num)
+{
+ switch (i2c_num) {
+ case 0:
+ break;
+ case 1:
+ break;
+ case 2:
+ mxc_request_iomux(MX35_PIN_TX3_RX2, MUX_CONFIG_GPIO);
+ mxc_request_iomux(MX35_PIN_TX2_RX3, MUX_CONFIG_GPIO);
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_i2c_inactive);
+
+/*!
+ * Setup GPIO for a CSPI device to be active
+ *
+ * @param cspi_mod an CSPI device
+ */
+void gpio_spi_active(int cspi_mod)
+{
+ switch (cspi_mod) {
+ case 0:
+ /* SPI1 */
+ mxc_request_iomux(MX35_PIN_CSPI1_MOSI, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSPI1_MISO, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSPI1_SS0, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSPI1_SS1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSPI1_SCLK, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSPI1_SPI_RDY, MUX_CONFIG_FUNC);
+
+ mxc_iomux_set_pad(MX35_PIN_CSPI1_MOSI,
+ PAD_CTL_DRV_3_3V | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD |
+ PAD_CTL_100K_PD | PAD_CTL_DRV_NORMAL);
+ mxc_iomux_set_pad(MX35_PIN_CSPI1_MISO,
+ PAD_CTL_DRV_3_3V | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD |
+ PAD_CTL_100K_PD | PAD_CTL_DRV_NORMAL);
+ mxc_iomux_set_pad(MX35_PIN_CSPI1_SS0,
+ PAD_CTL_DRV_3_3V | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD |
+ PAD_CTL_100K_PU | PAD_CTL_ODE_CMOS |
+ PAD_CTL_DRV_NORMAL);
+ mxc_iomux_set_pad(MX35_PIN_CSPI1_SS1,
+ PAD_CTL_DRV_3_3V | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD |
+ PAD_CTL_100K_PU | PAD_CTL_ODE_CMOS |
+ PAD_CTL_DRV_NORMAL);
+ mxc_iomux_set_pad(MX35_PIN_CSPI1_SCLK,
+ PAD_CTL_DRV_3_3V | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD |
+ PAD_CTL_100K_PD | PAD_CTL_DRV_NORMAL);
+ mxc_iomux_set_pad(MX35_PIN_CSPI1_SPI_RDY,
+ PAD_CTL_DRV_3_3V | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD |
+ PAD_CTL_100K_PU | PAD_CTL_DRV_NORMAL);
+ break;
+ case 1:
+ /* SPI2 */
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_spi_active);
+
+/*!
+ * Setup GPIO for a CSPI device to be inactive
+ *
+ * @param cspi_mod a CSPI device
+ */
+void gpio_spi_inactive(int cspi_mod)
+{
+ switch (cspi_mod) {
+ case 0:
+ /* SPI1 */
+ mxc_request_gpio(MX35_PIN_CSPI1_MOSI);
+ mxc_request_gpio(MX35_PIN_CSPI1_MISO);
+ mxc_request_gpio(MX35_PIN_CSPI1_SS0);
+ mxc_request_gpio(MX35_PIN_CSPI1_SS1);
+ mxc_request_gpio(MX35_PIN_CSPI1_SCLK);
+ mxc_request_gpio(MX35_PIN_CSPI1_SPI_RDY);
+
+ mxc_free_iomux(MX35_PIN_CSPI1_MOSI, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_CSPI1_MISO, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_CSPI1_SS0, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_CSPI1_SS1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_CSPI1_SCLK, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_CSPI1_SPI_RDY, MUX_CONFIG_GPIO);
+ break;
+ case 1:
+ /* SPI2 */
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_spi_inactive);
+
+/*!
+ * Setup GPIO for LCD to be active
+ */
+void gpio_lcd_active(void)
+{
+ mxc_request_iomux(MX35_PIN_LD0, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD2, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD3, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD4, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD5, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD6, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD7, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD8, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD9, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD10, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD11, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD12, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD13, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD14, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD15, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD16, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_LD17, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_D3_VSYNC, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_D3_HSYNC, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_D3_FPSHIFT, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_D3_DRDY, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CONTRAST, MUX_CONFIG_FUNC);
+}
+
+EXPORT_SYMBOL(gpio_lcd_active);
+
+/*!
+ * Setup GPIO for LCD to be inactive
+ */
+void gpio_lcd_inactive(void)
+{
+}
+
+EXPORT_SYMBOL(gpio_lcd_inactive);
+
+/*!
+ * Setup pin for touchscreen
+ */
+void gpio_tsc_active(void)
+{
+ unsigned int pad_val = PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU;
+ mxc_request_iomux(MX35_PIN_CAPTURE, MUX_CONFIG_GPIO);
+ mxc_iomux_set_pad(MX35_PIN_CAPTURE, pad_val);
+ mxc_set_gpio_direction(MX35_PIN_CAPTURE, 1);
+}
+
+/*!
+ * Release pin for touchscreen
+ */
+void gpio_tsc_inactive(void)
+{
+ mxc_free_iomux(MX35_PIN_CAPTURE, MUX_CONFIG_GPIO);
+}
+
+/*!
+ * Setup GPIO for SDHC to be active
+ *
+ * @param module SDHC module number
+ */
+void gpio_sdhc_active(int module)
+{
+ unsigned int pad_val;
+
+ switch (module) {
+ case 0:
+ mxc_request_iomux(MX35_PIN_SD1_CLK,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_request_iomux(MX35_PIN_SD1_CMD,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_request_iomux(MX35_PIN_SD1_DATA0,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_request_iomux(MX35_PIN_SD1_DATA1,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_request_iomux(MX35_PIN_SD1_DATA2,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_request_iomux(MX35_PIN_SD1_DATA3,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+#if defined(CONFIG_SDIO_UNIFI_FS) || defined(CONFIG_SDIO_UNIFI_FS_MODULE)
+#else
+ /* MUX4_CTR , 0: SD2 to WIFI, 1:SD2 to SD1 8bit */
+ if (board_is_mx35(BOARD_REV_2))
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_2,
+ 7, 1);
+ mxc_request_iomux(MX35_PIN_SD2_CMD,
+ MUX_CONFIG_ALT2 | MUX_CONFIG_SION);
+ mxc_request_iomux(MX35_PIN_SD2_CLK,
+ MUX_CONFIG_ALT2 | MUX_CONFIG_SION);
+ mxc_request_iomux(MX35_PIN_SD2_DATA0,
+ MUX_CONFIG_ALT2 | MUX_CONFIG_SION);
+ mxc_request_iomux(MX35_PIN_SD2_DATA1,
+ MUX_CONFIG_ALT2 | MUX_CONFIG_SION);
+#endif
+
+ pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_MAX |
+ PAD_CTL_47K_PU | PAD_CTL_SRE_FAST;
+ mxc_iomux_set_pad(MX35_PIN_SD1_CMD, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_SD1_DATA0, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_SD1_DATA1, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_SD1_DATA2, pad_val);
+ pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_DRV_MAX | PAD_CTL_47K_PU | PAD_CTL_SRE_FAST;
+ mxc_iomux_set_pad(MX35_PIN_SD1_CLK, pad_val);
+ pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_MAX |
+ PAD_CTL_100K_PU | PAD_CTL_SRE_FAST;
+ mxc_iomux_set_pad(MX35_PIN_SD1_DATA3, pad_val);
+#if defined(CONFIG_SDIO_UNIFI_FS) || defined(CONFIG_SDIO_UNIFI_FS_MODULE)
+#else
+ pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_MAX |
+ PAD_CTL_47K_PU | PAD_CTL_SRE_FAST;
+ mxc_iomux_set_pad(MX35_PIN_SD2_CMD, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_SD2_DATA0, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_SD2_DATA1, pad_val);
+ pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_DRV_MAX | PAD_CTL_47K_PU | PAD_CTL_SRE_FAST;
+ mxc_iomux_set_pad(MX35_PIN_SD2_CLK, pad_val);
+#endif
+ break;
+ case 1:
+ /* MUX4_CTR , 0: SD2 to WIFI, 1:SD2 to SD1 8bit */
+ if (board_is_mx35(BOARD_REV_2))
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_2,
+ 7, 0);
+ mxc_request_iomux(MX35_PIN_SD2_CLK,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_request_iomux(MX35_PIN_SD2_CMD,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_request_iomux(MX35_PIN_SD2_DATA0,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_request_iomux(MX35_PIN_SD2_DATA1,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_request_iomux(MX35_PIN_SD2_DATA2,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_request_iomux(MX35_PIN_SD2_DATA3,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+
+ pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_MAX |
+ PAD_CTL_47K_PU | PAD_CTL_SRE_FAST;
+
+ mxc_iomux_set_pad(MX35_PIN_SD2_CLK, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_SD2_CMD, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_SD2_DATA0, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_SD2_DATA1, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_SD2_DATA2, pad_val);
+
+ pad_val = PAD_CTL_PUE_PUD | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_MAX |
+ PAD_CTL_100K_PU | PAD_CTL_SRE_FAST;
+
+ mxc_iomux_set_pad(MX35_PIN_SD2_DATA3, pad_val);
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_sdhc_active);
+
+/*!
+ * Setup GPIO for SDHC1 to be inactive
+ *
+ * @param module SDHC module number
+ */
+void gpio_sdhc_inactive(int module)
+{
+ switch (module) {
+ case 0:
+ mxc_free_iomux(MX35_PIN_SD1_CLK,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_free_iomux(MX35_PIN_SD1_CMD,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_free_iomux(MX35_PIN_SD1_DATA0,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_free_iomux(MX35_PIN_SD1_DATA1,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_free_iomux(MX35_PIN_SD1_DATA2,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_free_iomux(MX35_PIN_SD1_DATA3,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_free_iomux(MX35_PIN_SD2_CMD,
+ MUX_CONFIG_ALT2 | MUX_CONFIG_SION);
+ mxc_free_iomux(MX35_PIN_SD2_CLK,
+ MUX_CONFIG_ALT2 | MUX_CONFIG_SION);
+ mxc_free_iomux(MX35_PIN_SD2_DATA0,
+ MUX_CONFIG_ALT2 | MUX_CONFIG_SION);
+ mxc_free_iomux(MX35_PIN_SD2_DATA1,
+ MUX_CONFIG_ALT2 | MUX_CONFIG_SION);
+
+ mxc_iomux_set_pad(MX35_PIN_SD1_CLK,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX35_PIN_SD1_CMD,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX35_PIN_SD1_DATA0,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX35_PIN_SD1_DATA1,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX35_PIN_SD1_DATA2,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX35_PIN_SD1_DATA3,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX35_PIN_SD2_CMD,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX35_PIN_SD2_CLK,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX35_PIN_SD2_DATA0,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX35_PIN_SD2_DATA1,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ break;
+ case 1:
+ mxc_free_iomux(MX35_PIN_SD2_CLK,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_free_iomux(MX35_PIN_SD2_CMD,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_free_iomux(MX35_PIN_SD2_DATA0,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_free_iomux(MX35_PIN_SD2_DATA1,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_free_iomux(MX35_PIN_SD2_DATA2,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+ mxc_free_iomux(MX35_PIN_SD2_DATA3,
+ MUX_CONFIG_FUNC | MUX_CONFIG_SION);
+
+ mxc_iomux_set_pad(MX35_PIN_SD2_CLK,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX35_PIN_SD2_CMD,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX35_PIN_SD2_DATA0,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX35_PIN_SD2_DATA1,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX35_PIN_SD2_DATA2,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX35_PIN_SD2_DATA3,
+ (PAD_CTL_DRV_NORMAL | PAD_CTL_SRE_SLOW));
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_sdhc_inactive);
+
+/*
+ * Probe for the card. If present the GPIO data would be set.
+ */
+unsigned int sdhc_get_card_det_status(struct device *dev)
+{
+ unsigned int ret;
+
+ if (to_platform_device(dev)->id == 0) {
+ if (0 != pmic_gpio_get_designation_bit_val(2, &ret))
+ printk(KERN_ERR "Get cd status error.");
+ return ret;
+ } else { /* config the det pin for SDHC2 */
+ return 0;
+ }
+}
+
+EXPORT_SYMBOL(sdhc_get_card_det_status);
+
+/*!
+ * Get pin value to detect write protection
+ */
+int sdhc_write_protect(struct device *dev)
+{
+ unsigned int rc = 0;
+
+ if (0 != pmic_gpio_get_designation_bit_val(3, &rc))
+ printk(KERN_ERR "Get wp status error.");
+ return rc;
+}
+
+EXPORT_SYMBOL(sdhc_write_protect);
+
+/*
+ * USB Host2
+ */
+int gpio_usbh2_active(void)
+{
+ if (board_is_mx35(BOARD_REV_2)) {
+ /* MUX3_CTR to be low for USB Host2 DP&DM */
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_2, 6, 0);
+ /* CAN_PWDN to be high for USB Host2 Power&OC */
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_2, 1, 1);
+ }
+
+ mxc_request_iomux(MX35_PIN_I2C2_CLK, MUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX35_PIN_I2C2_CLK, 0x0040);
+
+ mxc_request_iomux(MX35_PIN_I2C2_DAT, MUX_CONFIG_ALT2);
+ mxc_iomux_set_input(MUX_IN_USB_UH2_USB_OC, INPUT_CTL_PATH0);
+ mxc_iomux_set_pad(MX35_PIN_I2C2_DAT, 0x01c0);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(gpio_usbh2_active);
+
+void gpio_usbh2_inactive(void)
+{
+ mxc_request_gpio(MX35_PIN_I2C2_DAT);
+ mxc_free_iomux(MX35_PIN_I2C2_DAT, MUX_CONFIG_GPIO);
+ mxc_request_gpio(MX35_PIN_I2C2_CLK);
+ mxc_free_iomux(MX35_PIN_I2C2_CLK, MUX_CONFIG_GPIO);
+}
+
+EXPORT_SYMBOL(gpio_usbh2_inactive);
+
+/*
+ * USB OTG UTMI
+ */
+int gpio_usbotg_utmi_active(void)
+{
+ mxc_request_iomux(MX35_PIN_USBOTG_PWR, MUX_CONFIG_FUNC);
+ mxc_iomux_set_pad(MX35_PIN_USBOTG_PWR, 0x0040);
+ mxc_request_iomux(MX35_PIN_USBOTG_OC, MUX_CONFIG_FUNC);
+ mxc_iomux_set_pad(MX35_PIN_USBOTG_OC, 0x01c0);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(gpio_usbotg_utmi_active);
+
+void gpio_usbotg_utmi_inactive(void)
+{
+ mxc_request_gpio(MX35_PIN_USBOTG_PWR);
+ mxc_free_iomux(MX35_PIN_USBOTG_PWR, MUX_CONFIG_GPIO);
+ mxc_request_gpio(MX35_PIN_USBOTG_OC);
+ mxc_free_iomux(MX35_PIN_USBOTG_OC, MUX_CONFIG_GPIO);
+}
+
+EXPORT_SYMBOL(gpio_usbotg_utmi_inactive);
+
+void gpio_sensor_active(void)
+{
+ /*CSI D6 */
+ mxc_request_iomux(MX35_PIN_TX1, MUX_CONFIG_ALT6);
+ /*CSI D7 */
+ mxc_request_iomux(MX35_PIN_TX0, MUX_CONFIG_ALT6);
+ mxc_request_iomux(MX35_PIN_CSI_D8, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSI_D9, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSI_D10, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSI_D11, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSI_D12, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSI_D13, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSI_D14, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSI_D15, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSI_HSYNC, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSI_MCLK, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSI_PIXCLK, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSI_VSYNC, MUX_CONFIG_FUNC);
+}
+
+EXPORT_SYMBOL(gpio_sensor_active);
+
+void gpio_sensor_inactive(void)
+{
+ mxc_request_iomux(MX35_PIN_TX1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_TX0, MUX_CONFIG_FUNC);
+}
+
+EXPORT_SYMBOL(gpio_sensor_inactive);
+
+/*!
+ * Setup GPIO for spdif tx/rx to be active
+ */
+void gpio_spdif_active(void)
+{
+ /* SPDIF OUT */
+ mxc_request_iomux(MX35_PIN_STXD5, MUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX35_PIN_STXD5, PAD_CTL_PKE_NONE | PAD_CTL_PUE_PUD);
+ /* SPDIF IN */
+ mxc_request_iomux(MX35_PIN_SRXD5, MUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX35_PIN_SRXD5, PAD_CTL_PKE_ENABLE
+ | PAD_CTL_100K_PU | PAD_CTL_HYS_SCHMITZ);
+ /* SPDIF ext clock */
+ mxc_request_iomux(MX35_PIN_SCK5, MUX_CONFIG_ALT1);
+ if (board_is_mx35(BOARD_REV_2))
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_2, 5, 1);
+ else
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_2, 0, 1);
+}
+
+EXPORT_SYMBOL(gpio_spdif_active);
+
+/*!
+ * Setup GPIO for spdif tx/rx to be inactive
+ */
+void gpio_spdif_inactive(void)
+{
+ /* SPDIF OUT */
+ mxc_free_iomux(MX35_PIN_STXD5, MUX_CONFIG_ALT1);
+ /* SPDIF IN */
+ mxc_free_iomux(MX35_PIN_SRXD5, MUX_CONFIG_ALT1);
+ /* SPDIF ext clock */
+ mxc_free_iomux(MX35_PIN_SCK5, MUX_CONFIG_ALT1);
+}
+
+EXPORT_SYMBOL(gpio_spdif_inactive);
+
+/*!
+ * This function activates DAM ports 3 to enable
+ * audio I/O.
+ */
+void gpio_activate_audio_ports(void)
+{
+ unsigned int pad_val;
+
+ mxc_request_iomux(MX35_PIN_STXD4, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_SRXD4, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_SCK4, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_STXFS4, MUX_CONFIG_FUNC);
+
+ pad_val = PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU |
+ PAD_CTL_PUE_PUD;
+ mxc_iomux_set_pad(MX35_PIN_STXD4, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_SRXD4, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_SCK4, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_STXFS4, pad_val);
+}
+
+EXPORT_SYMBOL(gpio_activate_audio_ports);
+
+/*!
+ * This function activates DAM ports 5 to enable
+ * audio I/O.
+ */
+void gpio_activate_bt_audio_port(void)
+{
+ unsigned int pad_val;
+
+ mxc_request_iomux(MX35_PIN_STXD5, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_SRXD5, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_SCK5, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_STXFS5, MUX_CONFIG_FUNC);
+
+ pad_val = PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU |
+ PAD_CTL_PUE_PUD;
+ mxc_iomux_set_pad(MX35_PIN_STXD5, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_SRXD5, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_SCK5, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_STXFS5, pad_val);
+ if (board_is_mx35(BOARD_REV_2))
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_2, 5, 0);
+ else
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_2, 0, 0);
+}
+
+EXPORT_SYMBOL(gpio_activate_bt_audio_port);
+
+/*!
+ * Setup GPIO for bluetooth audio to be inactive
+ */
+void gpio_inactivate_bt_audio_port(void)
+{
+ mxc_free_iomux(MX35_PIN_STXD5, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_SRXD5, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_SCK5, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_STXFS5, MUX_CONFIG_FUNC);
+}
+
+EXPORT_SYMBOL(gpio_inactivate_bt_audio_port);
+
+/*!
+ * Setup GPIO for ATA interface
+ *
+ */
+void gpio_ata_active(void)
+{
+ unsigned int ata_ctl_pad_cfg, ata_dat_pad_cfg;
+
+ /*IOMUX Settings */
+ /*PATA_DIOR */
+ mxc_request_iomux(MX35_PIN_ATA_DIOR, MUX_CONFIG_FUNC);
+ /*PATA_DIOW */
+ mxc_request_iomux(MX35_PIN_ATA_DIOW, MUX_CONFIG_FUNC);
+ /*PATA_DMARQ_B */
+ mxc_request_iomux(MX35_PIN_ATA_DMARQ, MUX_CONFIG_FUNC);
+ /*PATA_DMACK */
+ mxc_request_iomux(MX35_PIN_ATA_DMACK, MUX_CONFIG_FUNC);
+ /*PATA_RESET_B */
+ mxc_request_iomux(MX35_PIN_ATA_RESET_B, MUX_CONFIG_FUNC);
+ /*PATA_IORDY */
+ mxc_request_iomux(MX35_PIN_ATA_IORDY, MUX_CONFIG_FUNC);
+ /*PATA_INTRQ_B */
+ mxc_request_iomux(MX35_PIN_ATA_INTRQ, MUX_CONFIG_FUNC);
+ /*PATA_CS_0 */
+ mxc_request_iomux(MX35_PIN_ATA_CS0, MUX_CONFIG_FUNC);
+ /*PATA_CS_1 */
+ mxc_request_iomux(MX35_PIN_ATA_CS1, MUX_CONFIG_FUNC);
+ /*PATA_DA0 */
+ mxc_request_iomux(MX35_PIN_ATA_DA0, MUX_CONFIG_FUNC);
+ /*PATA_DA1 */
+ mxc_request_iomux(MX35_PIN_ATA_DA1, MUX_CONFIG_FUNC);
+ /*PATA_DA2 */
+ mxc_request_iomux(MX35_PIN_ATA_DA2, MUX_CONFIG_FUNC);
+ /* BUFFER_ENABLE - HDD_ENABLE_B */
+ mxc_request_iomux(MX35_PIN_ATA_BUFF_EN, MUX_CONFIG_FUNC);
+
+ /*PATA_D0 */
+ mxc_request_iomux(MX35_PIN_ATA_DATA0, MUX_CONFIG_FUNC);
+ /*PATA_D1 */
+ mxc_request_iomux(MX35_PIN_ATA_DATA1, MUX_CONFIG_FUNC);
+ /*PATA_D2 */
+ mxc_request_iomux(MX35_PIN_ATA_DATA2, MUX_CONFIG_FUNC);
+ /*PATA_D3 */
+ mxc_request_iomux(MX35_PIN_ATA_DATA3, MUX_CONFIG_FUNC);
+ /*PATA_D4 */
+ mxc_request_iomux(MX35_PIN_ATA_DATA4, MUX_CONFIG_FUNC);
+ /*PATA_D5 */
+ mxc_request_iomux(MX35_PIN_ATA_DATA5, MUX_CONFIG_FUNC);
+ /*PATA_D6 */
+ mxc_request_iomux(MX35_PIN_ATA_DATA6, MUX_CONFIG_FUNC);
+ /*PATA_D7 */
+ mxc_request_iomux(MX35_PIN_ATA_DATA7, MUX_CONFIG_FUNC);
+ /*PATA_D8 */
+ mxc_request_iomux(MX35_PIN_ATA_DATA8, MUX_CONFIG_FUNC);
+ /*PATA_D9 */
+ mxc_request_iomux(MX35_PIN_ATA_DATA9, MUX_CONFIG_FUNC);
+ /*PATA_D10 */
+ mxc_request_iomux(MX35_PIN_ATA_DATA10, MUX_CONFIG_FUNC);
+ /*PATA_D11 */
+ mxc_request_iomux(MX35_PIN_ATA_DATA11, MUX_CONFIG_FUNC);
+ /*PATA_D12 */
+ mxc_request_iomux(MX35_PIN_ATA_DATA12, MUX_CONFIG_FUNC);
+ /*PATA_D13 */
+ mxc_request_iomux(MX35_PIN_ATA_DATA13, MUX_CONFIG_FUNC);
+ /*PATA_D14 */
+ mxc_request_iomux(MX35_PIN_ATA_DATA14, MUX_CONFIG_FUNC);
+ /*PATA_D15 */
+ mxc_request_iomux(MX35_PIN_ATA_DATA15, MUX_CONFIG_FUNC);
+
+ /* IOMUX Pad Settings */
+ ata_ctl_pad_cfg = PAD_CTL_SRE_SLOW | PAD_CTL_DRV_NORMAL |
+ PAD_CTL_ODE_CMOS | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PD |
+ PAD_CTL_HYS_CMOS | PAD_CTL_DRV_3_3V;
+ ata_dat_pad_cfg = PAD_CTL_SRE_FAST | PAD_CTL_DRV_MAX |
+ PAD_CTL_ODE_CMOS | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PD |
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_DRV_3_3V;
+
+ mxc_iomux_set_pad(MX35_PIN_ATA_DMARQ, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DIOR, ata_ctl_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DIOW, ata_ctl_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DMACK, ata_ctl_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_RESET_B, PAD_CTL_SRE_SLOW |
+ PAD_CTL_DRV_NORMAL | PAD_CTL_ODE_CMOS |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD |
+ PAD_CTL_100K_PU | PAD_CTL_HYS_CMOS |
+ PAD_CTL_DRV_3_3V);
+ mxc_iomux_set_pad(MX35_PIN_ATA_IORDY, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_INTRQ, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_CS0, ata_ctl_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_CS1, ata_ctl_pad_cfg);
+
+ mxc_iomux_set_pad(MX35_PIN_ATA_DATA0, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DATA1, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DATA2, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DATA3, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DATA4, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DATA5, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DATA6, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DATA7, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DATA8, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DATA9, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DATA10, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DATA11, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DATA12, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DATA13, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DATA14, ata_dat_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DATA15, ata_dat_pad_cfg);
+
+ mxc_iomux_set_pad(MX35_PIN_ATA_DA0, ata_ctl_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DA1, ata_ctl_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_DA2, ata_ctl_pad_cfg);
+ mxc_iomux_set_pad(MX35_PIN_ATA_BUFF_EN, ata_ctl_pad_cfg);
+
+ /* HDD_ENBALE */
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 3, 0);
+ /* Power On the HDD */
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 4, 1);
+ msleep(300);
+}
+
+EXPORT_SYMBOL(gpio_ata_active);
+
+/*!
+ * Restore ATA interface pins to reset values
+ *
+ */
+void gpio_ata_inactive(void)
+{
+ /*Turn off the IOMUX for ATA group B signals */
+ mxc_free_iomux(MX35_PIN_ATA_DATA0, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DATA1, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DATA2, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DATA3, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DATA4, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DATA5, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DATA6, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DATA7, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DATA8, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DATA9, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DATA10, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DATA11, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DATA12, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DATA13, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DATA14, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DATA15, MUX_CONFIG_FUNC);
+
+ /* Config the multiplex pin of ATA interface DIR, DA0-2, INTRQ, DMARQ */
+ mxc_free_iomux(MX35_PIN_ATA_DMARQ, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DIOR, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DIOW, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DMACK, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_RESET_B, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_IORDY, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_INTRQ, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_CS0, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_CS1, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DA0, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DA1, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_DA2, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_ATA_BUFF_EN, MUX_CONFIG_FUNC);
+
+ /* Power Off the HDD */
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 4, 0);
+ /* HDD_ENBALE */
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 3, 1);
+}
+
+EXPORT_SYMBOL(gpio_ata_inactive);
+
+/*!
+ * This function activates ESAI ports to enable
+ * surround sound I/O
+ */
+void gpio_activate_esai_ports(void)
+{
+ unsigned int pad_val;
+ /* ESAI TX - WM8580 */
+ mxc_request_iomux(MX35_PIN_HCKT, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_SCKT, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FST, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_TX0, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_TX1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_TX2_RX3, MUX_CONFIG_FUNC);
+
+ /* ESAI RX - AK5702 */
+ /*mxc_request_iomux(MX35_PIN_HCKR, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_SCKR, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_FSR, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_TX3_RX2, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_TX4_RX1, MUX_CONFIG_FUNC);*/
+
+ pad_val = PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU |
+ PAD_CTL_PUE_PUD;
+ /* ESAI TX - WM8580 */
+ mxc_iomux_set_pad(MX35_PIN_SCKT, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_FST, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_TX0, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_TX1, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_TX2_RX3, pad_val);
+
+ /* ESAI RX - AK5702 */
+ /*mxc_iomux_set_pad(MX35_PIN_SCKR, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_FSR, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_TX3_RX2, pad_val);
+ mxc_iomux_set_pad(MX35_PIN_TX4_RX1, pad_val);*/
+
+ pad_val =
+ PAD_CTL_DRV_HIGH | PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU |
+ PAD_CTL_PUE_PUD;
+
+ /* ESAI TX - WM8580 */
+ mxc_iomux_set_pad(MX35_PIN_HCKT, pad_val);
+ /* ESAI RX - AK5702 */
+ /*mxc_iomux_set_pad(MX35_PIN_HCKR, pad_val);*/
+}
+
+EXPORT_SYMBOL(gpio_activate_esai_ports);
+
+/*!
+ * This function deactivates ESAI ports to disable
+ * surround sound I/O
+ */
+void gpio_deactivate_esai_ports(void)
+{
+
+ mxc_free_iomux(MX35_PIN_HCKT, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_SCKT, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FST, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_TX0, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_TX1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_TX2_RX3, MUX_CONFIG_GPIO);
+ /*mxc_free_iomux(MX35_PIN_HCKR, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_SCKR, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FSR, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_TX3_RX2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_TX4_RX1, MUX_CONFIG_GPIO);*/
+}
+
+EXPORT_SYMBOL(gpio_deactivate_esai_ports);
+
+/*!
+ * This function enable and reset GPS GPIO
+ */
+void gpio_gps_active(void)
+{
+ /* Pull GPIO1_5 to be low for routing signal to UART3/GPS */
+ if (board_is_mx35(BOARD_REV_2)) {
+ mxc_request_iomux(MX35_PIN_COMPARE, MUX_CONFIG_GPIO);
+ mxc_iomux_set_pad(MX35_PIN_COMPARE, PAD_CTL_DRV_NORMAL |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU |
+ PAD_CTL_DRV_3_3V | PAD_CTL_PUE_PUD |
+ PAD_CTL_SRE_SLOW);
+ mxc_set_gpio_direction(MX35_PIN_COMPARE, 0);
+ mxc_set_gpio_dataout(MX35_PIN_COMPARE, 0);
+ }
+
+ /* PWR_EN_GPS is set to be 0, will be toggled on in app by ioctl */
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_2, 0, 0);
+
+ /* GPS 32KHz clock enbale */
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_1, 7, 1);
+
+ /* GPS reset */
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 5, 0);
+ msleep(5);
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 5, 1);
+ msleep(5);
+}
+
+EXPORT_SYMBOL(gpio_gps_active);
+
+/*!
+ * This function get GPS GPIO status.
+ */
+int gpio_gps_access(int para)
+{
+ unsigned int gps_val;
+
+ if (para & 0x4) { /* Read GPIO */
+ if (para & 0x1) /* Read PWR_EN */
+ pmic_gpio_get_bit_val(MCU_GPIO_REG_GPIO_CONTROL_2, 0,
+ &gps_val);
+ else /* Read nReset */
+ pmic_gpio_get_bit_val(MCU_GPIO_REG_RESET_1, 5,
+ &gps_val);
+ return gps_val;
+ } else { /* Write GPIO */
+ gps_val = (para & 0x2) ? 1 : 0;
+ if (para & 0x1)
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_2, 0,
+ gps_val);
+ else
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_RESET_1, 5, gps_val);
+ }
+ return 0;
+}
+
+EXPORT_SYMBOL(gpio_gps_access);
+
+/*!
+ * This function disable GPS GPIO
+ */
+void gpio_gps_inactive(void)
+{
+ /* GPS disable */
+ pmic_gpio_set_bit_val(MCU_GPIO_REG_GPIO_CONTROL_2, 0, 0);
+ /* Free GPIO1_5 */
+ if (board_is_mx35(BOARD_REV_2))
+ mxc_free_iomux(MX35_PIN_COMPARE, MUX_CONFIG_GPIO);
+}
+
+EXPORT_SYMBOL(gpio_gps_inactive);
+
+/*!
+ * The MLB gpio configuration routine
+ */
+void gpio_mlb_active(void)
+{
+ mxc_request_iomux(MX35_PIN_MLB_CLK, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_MLB_SIG, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_MLB_DAT, MUX_CONFIG_FUNC);
+}
+
+EXPORT_SYMBOL(gpio_mlb_active);
+
+void gpio_mlb_inactive(void)
+{
+ mxc_free_iomux(MX35_PIN_MLB_CLK, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_MLB_SIG, MUX_CONFIG_FUNC);
+ mxc_free_iomux(MX35_PIN_MLB_DAT, MUX_CONFIG_FUNC);
+}
+
+EXPORT_SYMBOL(gpio_mlb_inactive);
+
+void gpio_can_active(int id)
+{
+ int pad;
+
+ switch (id) {
+ case 0:
+ pad = PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE | \
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH;
+ mxc_request_iomux(MX35_PIN_I2C2_CLK, MUX_CONFIG_ALT1);
+ mxc_request_iomux(MX35_PIN_I2C2_DAT, MUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX35_PIN_I2C2_CLK, pad);
+ mxc_iomux_set_pad(MX35_PIN_I2C2_DAT, pad);
+ mxc_iomux_set_input(MUX_IN_CAN1_CANRX, INPUT_CTL_PATH0);
+ break;
+ case 1:
+ pad = PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD | PAD_CTL_100K_PU;
+ mxc_request_iomux(MX35_PIN_FEC_MDC, MUX_CONFIG_ALT1);
+ mxc_request_iomux(MX35_PIN_FEC_MDIO, MUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX35_PIN_FEC_MDC, pad);
+ mxc_iomux_set_pad(MX35_PIN_FEC_MDIO, pad);
+ mxc_iomux_set_input(MUX_IN_CAN2_CANRX, INPUT_CTL_PATH2);
+ break;
+ default:
+ printk(KERN_ERR "NO such device\n");
+ }
+}
+
+void gpio_can_inactive(int id)
+{
+ switch (id) {
+ case 0:
+ mxc_free_iomux(MX35_PIN_I2C2_CLK, MUX_CONFIG_ALT1);
+ mxc_free_iomux(MX35_PIN_I2C2_DAT, MUX_CONFIG_ALT1);
+ mxc_iomux_set_input(MUX_IN_CAN1_CANRX, INPUT_CTL_PATH0);
+ break;
+ case 1:
+ mxc_free_iomux(MX35_PIN_FEC_MDC, MUX_CONFIG_ALT1);
+ mxc_free_iomux(MX35_PIN_FEC_MDIO, MUX_CONFIG_ALT1);
+ mxc_iomux_set_input(MUX_IN_CAN2_CANRX, INPUT_CTL_PATH0);
+ break;
+ default:
+ printk(KERN_ERR "NO such device\n");
+ }
+}
+
+void gpio_pmic_active(void)
+{
+ unsigned int pad_val = PAD_CTL_SRE_SLOW | PAD_CTL_DRV_NORMAL
+ | PAD_CTL_HYS_CMOS | PAD_CTL_100K_PU | PAD_CTL_DRV_3_3V;
+ mxc_request_iomux(MX35_PIN_GPIO2_0, MUX_CONFIG_FUNC);
+ mxc_iomux_set_pad(MX35_PIN_GPIO2_0, pad_val);
+ mxc_set_gpio_direction(MX35_PIN_GPIO2_0, 1);
+}
+
+EXPORT_SYMBOL(gpio_pmic_active);
+
+
diff --git a/arch/arm/mach-mx35/mx35_3stack_irq.c b/arch/arm/mach-mx35/mx35_3stack_irq.c
new file mode 100644
index 000000000000..98228b8741df
--- /dev/null
+++ b/arch/arm/mach-mx35/mx35_3stack_irq.c
@@ -0,0 +1,371 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/regulator/mcu_max8660-bus.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/bitops.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+
+#include <mach/gpio.h>
+
+#include "board-mx35_3stack.h"
+#include "iomux.h"
+
+/*!
+ * @file mach-mx35/mx35_3stack_irq.c
+ *
+ * @brief This file contains the board specific initialization routines.
+ *
+ * @ingroup MSL_MX35
+ */
+#ifdef CONFIG_MXC_PSEUDO_IRQS
+
+/*
+ * The interrupt status and mask variables.
+ */
+static unsigned long pseudo_irq_pending;
+static unsigned long pseudo_irq_enable;
+static unsigned long pseudo_irq_wakeup;
+static unsigned long pseudo_suspend;
+static atomic_t pseudo_irq_state = ATOMIC_INIT(0);
+
+/*
+ * The declaration of handler of two work queue.
+ * The one is the work queue to indentify the events from MCU.
+ * The another is the work queue to change the events mask.
+ */
+static void mcu_event_handler(struct work_struct *work);
+static void mcu_state_handler(struct work_struct *work);
+static void mcu_event_delay(unsigned long data);
+
+/*!
+ * The work structure for mcu events.
+ */
+static DECLARE_WORK(mcu_event_ws, mcu_event_handler);
+static DECLARE_WORK(mcu_state_ws, mcu_state_handler);
+static DEFINE_TIMER(mcu_delay_timer, mcu_event_delay, HZ, 0);
+
+static inline void mxc_pseudo_irq_ack(void)
+{
+ disable_irq(MXC_PSEUDO_PARENT);
+ atomic_set(&pseudo_irq_state, 0);
+}
+
+static inline void mxc_pseudo_irq_trigger(void)
+{
+ if (!atomic_xchg(&pseudo_irq_state, 1))
+ enable_irq(MXC_PSEUDO_PARENT);
+}
+
+/*
+ * mask a pseudo interrupt by setting the bit in the mask variable.
+ * @param irq a pseudo virtual irq number
+ */
+static void pseudo_mask_irq(u32 irq)
+{
+ int index = irq - MXC_PSEUDO_IO_BASE;
+ clear_bit(index, &pseudo_irq_enable);
+}
+
+/*
+ * disable a pseudo interrupt by triggerring a work queue
+ * @param irq a pseudo virtual irq number
+ */
+static void pseudo_disable_irq(u32 irq)
+{
+ struct irq_desc *desc = irq_desc + irq;
+ desc->chip->mask(irq);
+ desc->status |= IRQ_MASKED;
+ schedule_work(&mcu_state_ws);
+}
+
+/*
+ * Acknowledge a pseudo interrupt by clearing the bit in the isr variable.
+ * @param irq a pseudo virtual irq number
+ */
+static void pseudo_ack_irq(u32 irq)
+{
+ int index = irq - MXC_PSEUDO_IO_BASE;
+ /* clear the interrupt status */
+ clear_bit(index, &pseudo_irq_pending);
+}
+
+/*
+ * unmask a pseudo interrupt by clearing the bit in the imr.
+ * @param irq a pseudo virtual irq number
+ */
+static void pseudo_unmask_irq(u32 irq)
+{
+ int index = irq - MXC_PSEUDO_IO_BASE;
+
+ set_bit(index, &pseudo_irq_enable);
+
+ if (test_bit(index, &pseudo_irq_pending))
+ mxc_pseudo_irq_trigger();
+}
+
+/*
+ * Enable a pseudo interrupt by triggerring a work queue
+ * @param irq a pseudo virtual irq number
+ */
+static void pseudo_enable_irq(u32 irq)
+{
+ struct irq_desc *desc = irq_desc + irq;
+ desc->chip->unmask(irq);
+ desc->status &= ~IRQ_MASKED;
+ schedule_work(&mcu_state_ws);
+}
+
+/*
+ * set pseudo irq as a wake-up source.
+ * @param irq a pseudo virtual irq number
+ * @param enable enable as wake-up if equal to non-ero
+ * @return This function return 0 on success
+ */
+static int pseudo_set_wake_irq(u32 irq, u32 enable)
+{
+ int index = irq - MXC_PSEUDO_IO_BASE;
+
+ if (index >= MXC_MAX_PSEUDO_IO_LINES)
+ return -ENODEV;
+
+ if (enable) {
+ if (!pseudo_irq_wakeup)
+ enable_irq_wake(IOMUX_TO_IRQ(MX35_PIN_GPIO1_0));
+ pseudo_irq_wakeup |= (1 << index);
+ } else {
+ pseudo_irq_wakeup &= ~(1 << index);
+ if (!pseudo_irq_wakeup)
+ disable_irq_wake(IOMUX_TO_IRQ(MX35_PIN_GPIO1_0));
+ }
+ return 0;
+}
+
+static struct irq_chip pseudo_irq_chip = {
+ .ack = pseudo_ack_irq,
+ .mask = pseudo_mask_irq,
+ .disable = pseudo_disable_irq,
+ .unmask = pseudo_unmask_irq,
+ .enable = pseudo_enable_irq,
+ .set_wake = pseudo_set_wake_irq,
+};
+
+static void mxc_pseudo_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 pseudo_irq;
+ u32 index, mask;
+
+ desc->chip->mask(irq);
+ mxc_pseudo_irq_ack();
+
+ mask = pseudo_irq_enable;
+ index = pseudo_irq_pending;
+
+ if (unlikely(!(index & mask))) {
+ printk(KERN_ERR "\nPseudo IRQ: Spurious interrupt:0x%0x\n\n",
+ index);
+ pr_info("IEN=0x%x, PENDING=0x%x\n", mask, index);
+ return;
+ }
+
+ index = index & mask;
+ pseudo_irq = MXC_PSEUDO_IO_BASE;
+ for (; index != 0; index >>= 1, pseudo_irq++) {
+ struct irq_desc *d;
+ if ((index & 1) == 0)
+ continue;
+ d = irq_desc + pseudo_irq;
+ if (unlikely(!(d->handle_irq))) {
+ printk(KERN_ERR "\nPseudo irq: %d unhandeled\n",
+ pseudo_irq);
+ BUG(); /* oops */
+ }
+ d->handle_irq(pseudo_irq, d);
+ d->chip->ack(pseudo_irq);
+ }
+}
+
+static void mcu_event_delay(unsigned long data)
+{
+ schedule_work(&mcu_event_ws);
+}
+
+/*!
+ * This function is called when mcu interrupt occurs on the processor.
+ * It is the interrupt handler for the mcu.
+ *
+ * @param irq the irq number
+ * @param dev_id the pointer on the device
+ *
+ * @return The function returns IRQ_HANDLED when handled.
+ */
+static irqreturn_t mcu_irq_handler(int irq, void *dev_id)
+{
+ disable_irq(IOMUX_TO_IRQ(MX35_PIN_GPIO1_0));
+ if (pseudo_suspend)
+ mod_timer(&mcu_delay_timer, jiffies + HZ);
+ else
+ schedule_work(&mcu_event_ws);
+
+ return IRQ_HANDLED;
+}
+
+/*!
+ * This function is the work handler of mcu interrupt.
+ * It reads the events status and trigger the pseudo irq.
+ */
+static void mcu_event_handler(struct work_struct *work)
+{
+ int i, err;
+ unsigned int flag1, flag2;
+
+ /* read int flags and ack int */
+ for (i = 0; i < 3; i++) {
+ err = mcu_pmic_read_reg(REG_MCU_INT_FLAG_1, &flag1, 0xFFFFFFFF);
+ err |= mcu_pmic_read_reg(REG_MCU_INT_FLAG_2,
+ &flag2, 0xFFFFFFFF);
+ err |= mcu_pmic_write_reg(REG_MCU_INT_FLAG_1, 0, 0xFFFFFFFF);
+ err |= mcu_pmic_write_reg(REG_MCU_INT_FLAG_2, 0, 0xFFFFFFFF);
+ if (err == 0)
+ break;
+ }
+
+ if (i >= 3) {
+ printk(KERN_ERR "Reads MCU event fail\n");
+ goto no_new_events;
+ }
+
+ for (i = 0; flag1 && (i < MCU_INT_RTC); i++, flag1 >>= 1)
+ if (flag1 & 1)
+ set_bit(i, &pseudo_irq_pending);
+
+ for (i = MCU_INT_RTC; flag2 && (i <= MCU_INT_KEYPAD); i++, flag2 >>= 1)
+ if (flag2 & 1)
+ set_bit(i, &pseudo_irq_pending);
+ no_new_events:
+ if (pseudo_irq_pending & pseudo_irq_enable)
+ mxc_pseudo_irq_trigger();
+ enable_irq(IOMUX_TO_IRQ(MX35_PIN_GPIO1_0));
+}
+
+static void mcu_state_handler(struct work_struct *work)
+{
+ int err, i;
+ unsigned int event1, event2;
+ event1 = pseudo_irq_enable & ((1 << MCU_INT_RTC) - 1);
+ event2 = pseudo_irq_enable >> MCU_INT_RTC;
+
+ for (i = 0; i < 3; i++) {
+ err = mcu_pmic_write_reg(REG_MCU_INT_ENABLE_1, event1, 0xFF);
+ err |= mcu_pmic_write_reg(REG_MCU_INT_ENABLE_2, event2, 0xFF);
+ if (err == 0)
+ break;
+ }
+ if (i >= 3)
+ printk(KERN_ERR "Change MCU event mask fail\n");
+}
+
+static int __init mxc_pseudo_init(void)
+{
+ int i;
+
+ /* disable the interrupt and clear the status */
+ pseudo_irq_pending = 0;
+ pseudo_irq_enable = 0;
+
+ pr_info("3-Stack Pseudo interrupt rev=0.1v\n");
+
+ for (i = MXC_PSEUDO_IO_BASE;
+ i < (MXC_PSEUDO_IO_BASE + MXC_MAX_PSEUDO_IO_LINES); i++) {
+ set_irq_chip(i, &pseudo_irq_chip);
+ set_irq_handler(i, handle_simple_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+
+ set_irq_flags(MXC_PSEUDO_PARENT, IRQF_NOAUTOEN);
+ set_irq_handler(MXC_PSEUDO_PARENT, mxc_pseudo_irq_handler);
+
+ /* Set and install PMIC IRQ handler */
+ mxc_request_iomux(MX35_PIN_GPIO1_0, MUX_CONFIG_FUNC);
+ mxc_iomux_set_pad(MX35_PIN_GPIO1_0, PAD_CTL_PKE_NONE);
+ mxc_set_gpio_direction(MX35_PIN_GPIO1_0, 1);
+
+ set_irq_type(IOMUX_TO_IRQ(MX35_PIN_GPIO1_0), IRQF_TRIGGER_RISING);
+ if (request_irq(IOMUX_TO_IRQ(MX35_PIN_GPIO1_0), mcu_irq_handler,
+ 0, "MCU_IRQ", 0)) {
+ printk(KERN_ERR "mcu request irq failed\n");
+ return -1;
+ }
+ return 0;
+}
+
+fs_initcall_sync(mxc_pseudo_init);
+
+static int mxc_pseudo_irq_suspend(struct platform_device *dev,
+ pm_message_t mesg)
+{
+ int err, i;
+ unsigned int event1, event2;
+
+ if (!pseudo_irq_wakeup)
+ return 0;
+
+ event1 = pseudo_irq_wakeup & ((1 << MCU_INT_RTC) - 1);
+ event2 = pseudo_irq_wakeup >> MCU_INT_RTC;
+
+ for (i = 0; i < 3; i++) {
+ err = mcu_pmic_write_reg(REG_MCU_INT_ENABLE_1, event1, 0xFF);
+ err |= mcu_pmic_write_reg(REG_MCU_INT_ENABLE_2, event2, 0xFF);
+ if (err == 0)
+ break;
+ }
+ pseudo_suspend = 1;
+ return err;
+}
+
+static int mxc_pseudo_irq_resume(struct platform_device *dev)
+{
+ if (!pseudo_irq_wakeup)
+ return 0;
+
+ schedule_work(&mcu_state_ws);
+ pseudo_suspend = 0;
+ return 0;
+}
+
+static struct platform_driver mxc_pseudo_irq_driver = {
+ .driver = {
+ .name = "mxc_pseudo_irq",
+ },
+ .suspend = mxc_pseudo_irq_suspend,
+ .resume = mxc_pseudo_irq_resume,
+};
+
+static int __init mxc_pseudo_sysinit(void)
+{
+ return platform_driver_register(&mxc_pseudo_irq_driver);
+}
+
+late_initcall(mxc_pseudo_sysinit);
+#endif /* CONFIG_MXC_PSEUDO_IRQS */
diff --git a/arch/arm/mach-mx35/mx35_pins.h b/arch/arm/mach-mx35/mx35_pins.h
new file mode 100644
index 000000000000..90fcb849b4a9
--- /dev/null
+++ b/arch/arm/mach-mx35/mx35_pins.h
@@ -0,0 +1,333 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_MXC_MX35_PINS_H__
+#define __ASM_ARCH_MXC_MX35_PINS_H__
+
+/*!
+ * @file arch-mxc/mx35_pins.h
+ *
+ * @brief MX35 I/O Pin List
+ *
+ * @ingroup GPIO_MX35
+ */
+
+#ifndef __ASSEMBLY__
+
+/*!
+ * @name IOMUX/PAD Bit field definitions
+ */
+
+/*! @{ */
+
+/*!
+ * In order to identify pins more effectively, each mux-controlled pin's
+ * enumerated value is constructed in the following way:
+ *
+ * -------------------------------------------------------------------
+ * 31-29 | 28 - 24 |23 - 21| 20 - 10| 9 - 0
+ * -------------------------------------------------------------------
+ * IO_P | IO_I | RSVD | PAD_I | MUX_I
+ * -------------------------------------------------------------------
+ *
+ * Bit 0 to 7 contains MUX_I used to identify the register
+ * offset (base is IOMUX_module_base ) defined in the Section
+ * "sw_pad_ctl & sw_mux_ctl details" of the IC Spec. The similar field
+ * definitions are used for the pad control register.the MX35_PIN_A0 is
+ * defined in the enumeration: ( 0x28 << MUX_I) |( 0x368 << PAD_I)
+ * So the absolute address is: IOMUX_module_base + 0x28.
+ * The pad control register offset is: 0x368.
+ */
+
+/*!
+ * Starting bit position within each entry of \b iomux_pins to represent the
+ * MUX control register offset
+ */
+#define MUX_I 0
+/*!
+ * Starting bit position within each entry of \b iomux_pins to represent the
+ * PAD control register offset
+ */
+#define PAD_I 10
+
+/*!
+ * Starting bit position within each entry of \b iomux_pins to represent the
+ * reserved filed
+ */
+#define RSVD_I 21
+
+#define NON_GPIO_I 0x7
+#define PIN_TO_MUX_MASK ((1<<(PAD_I - MUX_I)) - 1)
+#define PIN_TO_PAD_MASK ((1<<(RSVD_I - PAD_I)) - 1)
+#define NON_MUX_I PIN_TO_MUX_MASK
+
+#define _MXC_BUILD_PIN(gp, gi, mi, pi) \
+ (((gp) << MUX_IO_P) | ((gi) << MUX_IO_I) | \
+ ((mi) << MUX_I) | ((pi) << PAD_I))
+
+#define _MXC_BUILD_GPIO_PIN(gp, gi, mi, pi) \
+ _MXC_BUILD_PIN(gp, gi, mi, pi)
+
+#define _MXC_BUILD_NON_GPIO_PIN(mi, pi) \
+ _MXC_BUILD_PIN(NON_GPIO_I, 0, mi, pi)
+
+#define PIN_TO_IOMUX_MUX(pin) ((pin >> MUX_I) & PIN_TO_MUX_MASK)
+#define PIN_TO_IOMUX_PAD(pin) ((pin >> PAD_I) & PIN_TO_PAD_MASK)
+
+/*! @} End IOMUX/PAD Bit field definitions */
+
+/*!
+ * This enumeration is constructed based on the Section
+ * "sw_pad_ctl & sw_mux_ctl details" of the MX35 IC Spec. Each enumerated
+ * value is constructed based on the rules described above.
+ */
+enum iomux_pins {
+ MX35_PIN_CAPTURE = _MXC_BUILD_GPIO_PIN(0, 4, 0x4, 0x328),
+ MX35_PIN_COMPARE = _MXC_BUILD_GPIO_PIN(0, 5, 0x8, 0x32C),
+ MX35_PIN_WATCHDOG_RST = _MXC_BUILD_GPIO_PIN(0, 6, 0xC, 0x330),
+ MX35_PIN_GPIO1_0 = _MXC_BUILD_GPIO_PIN(0, 0, 0x10, 0x334),
+ MX35_PIN_GPIO1_1 = _MXC_BUILD_GPIO_PIN(0, 1, 0x14, 0x338),
+ MX35_PIN_GPIO2_0 = _MXC_BUILD_GPIO_PIN(1, 0, 0x18, 0x33C),
+ MX35_PIN_GPIO3_0 = _MXC_BUILD_GPIO_PIN(2, 1, 0x1C, 0x340),
+ MX35_PIN_CLKO = _MXC_BUILD_GPIO_PIN(0, 8, 0x20, 0x34C),
+
+ MX35_PIN_POWER_FAIL = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x360),
+ MX35_PIN_VSTBY = _MXC_BUILD_GPIO_PIN(0, 7, 0x24, 0x364),
+ MX35_PIN_A0 = _MXC_BUILD_NON_GPIO_PIN(0x28, 0x368),
+ MX35_PIN_A1 = _MXC_BUILD_NON_GPIO_PIN(0x2C, 0x36C),
+ MX35_PIN_A2 = _MXC_BUILD_NON_GPIO_PIN(0x30, 0x370),
+ MX35_PIN_A3 = _MXC_BUILD_NON_GPIO_PIN(0x34, 0x374),
+ MX35_PIN_A4 = _MXC_BUILD_NON_GPIO_PIN(0x38, 0x378),
+ MX35_PIN_A5 = _MXC_BUILD_NON_GPIO_PIN(0x3C, 0x37C),
+ MX35_PIN_A6 = _MXC_BUILD_NON_GPIO_PIN(0x40, 0x380),
+ MX35_PIN_A7 = _MXC_BUILD_NON_GPIO_PIN(0x44, 0x384),
+ MX35_PIN_A8 = _MXC_BUILD_NON_GPIO_PIN(0x48, 0x388),
+ MX35_PIN_A9 = _MXC_BUILD_NON_GPIO_PIN(0x4C, 0x38C),
+ MX35_PIN_A10 = _MXC_BUILD_NON_GPIO_PIN(0x50, 0x390),
+ MX35_PIN_MA10 = _MXC_BUILD_NON_GPIO_PIN(0x54, 0x394),
+ MX35_PIN_A11 = _MXC_BUILD_NON_GPIO_PIN(0x58, 0x398),
+ MX35_PIN_A12 = _MXC_BUILD_NON_GPIO_PIN(0x5C, 0x39C),
+ MX35_PIN_A13 = _MXC_BUILD_NON_GPIO_PIN(0x60, 0x3A0),
+ MX35_PIN_A14 = _MXC_BUILD_NON_GPIO_PIN(0x64, 0x3A4),
+ MX35_PIN_A15 = _MXC_BUILD_NON_GPIO_PIN(0x68, 0x3A8),
+ MX35_PIN_A16 = _MXC_BUILD_NON_GPIO_PIN(0x6C, 0x3AC),
+ MX35_PIN_A17 = _MXC_BUILD_NON_GPIO_PIN(0x70, 0x3B0),
+ MX35_PIN_A18 = _MXC_BUILD_NON_GPIO_PIN(0x74, 0x3B4),
+ MX35_PIN_A19 = _MXC_BUILD_NON_GPIO_PIN(0x78, 0x3B8),
+ MX35_PIN_A20 = _MXC_BUILD_NON_GPIO_PIN(0x7C, 0x3BC),
+ MX35_PIN_A21 = _MXC_BUILD_NON_GPIO_PIN(0x80, 0x3C0),
+ MX35_PIN_A22 = _MXC_BUILD_NON_GPIO_PIN(0x84, 0x3C4),
+ MX35_PIN_A23 = _MXC_BUILD_NON_GPIO_PIN(0x88, 0x3C8),
+ MX35_PIN_A24 = _MXC_BUILD_NON_GPIO_PIN(0x8C, 0x3CC),
+ MX35_PIN_A25 = _MXC_BUILD_NON_GPIO_PIN(0x90, 0x3D0),
+
+ MX35_PIN_EB0 = _MXC_BUILD_NON_GPIO_PIN(0x94, 0x46C),
+ MX35_PIN_EB1 = _MXC_BUILD_NON_GPIO_PIN(0x98, 0x470),
+ MX35_PIN_OE = _MXC_BUILD_NON_GPIO_PIN(0x9C, 0x474),
+ MX35_PIN_CS0 = _MXC_BUILD_NON_GPIO_PIN(0xA0, 0x478),
+ MX35_PIN_CS1 = _MXC_BUILD_NON_GPIO_PIN(0xA4, 0x47C),
+ MX35_PIN_CS2 = _MXC_BUILD_NON_GPIO_PIN(0xA8, 0x480),
+ MX35_PIN_CS3 = _MXC_BUILD_NON_GPIO_PIN(0xAC, 0x484),
+ MX35_PIN_CS4 = _MXC_BUILD_GPIO_PIN(0, 20, 0xB0, 0x488),
+ MX35_PIN_CS5 = _MXC_BUILD_GPIO_PIN(0, 21, 0xB4, 0x48C),
+ MX35_PIN_NFCE_B = _MXC_BUILD_GPIO_PIN(0, 22, 0xB8, 0x490),
+
+ MX35_PIN_LBA = _MXC_BUILD_NON_GPIO_PIN(0xBC, 0x498),
+ MX35_PIN_BCLK = _MXC_BUILD_NON_GPIO_PIN(0xC0, 0x49C),
+ MX35_PIN_RW = _MXC_BUILD_NON_GPIO_PIN(0xC4, 0x4A0),
+
+ MX35_PIN_NFWE_B = _MXC_BUILD_GPIO_PIN(0, 18, 0xC8, 0x4CC),
+ MX35_PIN_NFRE_B = _MXC_BUILD_GPIO_PIN(0, 19, 0xCC, 0x4D0),
+ MX35_PIN_NFALE = _MXC_BUILD_GPIO_PIN(0, 20, 0xD0, 0x4D4),
+ MX35_PIN_NFCLE = _MXC_BUILD_GPIO_PIN(0, 21, 0xD4, 0x4D8),
+ MX35_PIN_NFWP_B = _MXC_BUILD_GPIO_PIN(0, 22, 0xD8, 0x4DC),
+ MX35_PIN_NFRB = _MXC_BUILD_GPIO_PIN(0, 23, 0xDC, 0x4E0),
+
+ MX35_PIN_D15 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x4E4),
+ MX35_PIN_D14 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x4E8),
+ MX35_PIN_D13 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x4EC),
+ MX35_PIN_D12 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x4F0),
+ MX35_PIN_D11 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x4F4),
+ MX35_PIN_D10 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x4F8),
+ MX35_PIN_D9 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x4FC),
+ MX35_PIN_D8 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x500),
+ MX35_PIN_D7 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x504),
+ MX35_PIN_D6 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x508),
+ MX35_PIN_D5 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x50C),
+ MX35_PIN_D4 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x510),
+ MX35_PIN_D3 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x514),
+ MX35_PIN_D2 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x518),
+ MX35_PIN_D1 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x51C),
+ MX35_PIN_D0 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x520),
+
+ MX35_PIN_CSI_D8 = _MXC_BUILD_GPIO_PIN(0, 20, 0xE0, 0x524),
+ MX35_PIN_CSI_D9 = _MXC_BUILD_GPIO_PIN(0, 21, 0xE4, 0x528),
+ MX35_PIN_CSI_D10 = _MXC_BUILD_GPIO_PIN(0, 22, 0xE8, 0x52C),
+ MX35_PIN_CSI_D11 = _MXC_BUILD_GPIO_PIN(0, 23, 0xEC, 0x530),
+ MX35_PIN_CSI_D12 = _MXC_BUILD_GPIO_PIN(0, 24, 0xF0, 0x534),
+ MX35_PIN_CSI_D13 = _MXC_BUILD_GPIO_PIN(0, 25, 0xF4, 0x538),
+ MX35_PIN_CSI_D14 = _MXC_BUILD_GPIO_PIN(0, 26, 0xF8, 0x53C),
+ MX35_PIN_CSI_D15 = _MXC_BUILD_GPIO_PIN(0, 27, 0xFC, 0x540),
+ MX35_PIN_CSI_MCLK = _MXC_BUILD_GPIO_PIN(0, 28, 0x100, 0x544),
+ MX35_PIN_CSI_VSYNC = _MXC_BUILD_GPIO_PIN(0, 29, 0x104, 0x548),
+ MX35_PIN_CSI_HSYNC = _MXC_BUILD_GPIO_PIN(0, 30, 0x108, 0x54C),
+ MX35_PIN_CSI_PIXCLK = _MXC_BUILD_GPIO_PIN(0, 31, 0x10C, 0x550),
+
+ MX35_PIN_I2C1_CLK = _MXC_BUILD_GPIO_PIN(1, 24, 0x110, 0x554),
+ MX35_PIN_I2C1_DAT = _MXC_BUILD_GPIO_PIN(1, 25, 0x114, 0x558),
+ MX35_PIN_I2C2_CLK = _MXC_BUILD_GPIO_PIN(1, 26, 0x118, 0x55C),
+ MX35_PIN_I2C2_DAT = _MXC_BUILD_GPIO_PIN(1, 27, 0x11C, 0x560),
+
+ MX35_PIN_STXD4 = _MXC_BUILD_GPIO_PIN(1, 28, 0x120, 0x564),
+ MX35_PIN_SRXD4 = _MXC_BUILD_GPIO_PIN(1, 29, 0x124, 0x568),
+ MX35_PIN_SCK4 = _MXC_BUILD_GPIO_PIN(1, 30, 0x128, 0x56C),
+ MX35_PIN_STXFS4 = _MXC_BUILD_GPIO_PIN(1, 31, 0x12C, 0x570),
+ MX35_PIN_STXD5 = _MXC_BUILD_GPIO_PIN(0, 0, 0x130, 0x574),
+ MX35_PIN_SRXD5 = _MXC_BUILD_GPIO_PIN(0, 1, 0x134, 0x578),
+ MX35_PIN_SCK5 = _MXC_BUILD_GPIO_PIN(0, 2, 0x138, 0x57C),
+ MX35_PIN_STXFS5 = _MXC_BUILD_GPIO_PIN(0, 3, 0x13C, 0x580),
+
+ MX35_PIN_SCKR = _MXC_BUILD_GPIO_PIN(0, 4, 0x140, 0x584),
+ MX35_PIN_FSR = _MXC_BUILD_GPIO_PIN(0, 5, 0x144, 0x588),
+ MX35_PIN_HCKR = _MXC_BUILD_GPIO_PIN(0, 6, 0x148, 0x58C),
+ MX35_PIN_SCKT = _MXC_BUILD_GPIO_PIN(0, 7, 0x14C, 0x590),
+ MX35_PIN_FST = _MXC_BUILD_GPIO_PIN(0, 8, 0x150, 0x594),
+ MX35_PIN_HCKT = _MXC_BUILD_GPIO_PIN(0, 9, 0x154, 0x598),
+ MX35_PIN_TX5_RX0 = _MXC_BUILD_GPIO_PIN(0, 10, 0x158, 0x59C),
+ MX35_PIN_TX4_RX1 = _MXC_BUILD_GPIO_PIN(0, 11, 0x15C, 0x5A0),
+ MX35_PIN_TX3_RX2 = _MXC_BUILD_GPIO_PIN(0, 12, 0x160, 0x5A4),
+ MX35_PIN_TX2_RX3 = _MXC_BUILD_GPIO_PIN(0, 13, 0x164, 0x5A8),
+ MX35_PIN_TX1 = _MXC_BUILD_GPIO_PIN(0, 14, 0x168, 0x5AC),
+ MX35_PIN_TX0 = _MXC_BUILD_GPIO_PIN(0, 15, 0x16C, 0x5B0),
+
+ MX35_PIN_CSPI1_MOSI = _MXC_BUILD_GPIO_PIN(0, 16, 0x170, 0x5B4),
+ MX35_PIN_CSPI1_MISO = _MXC_BUILD_GPIO_PIN(0, 17, 0x174, 0x5B8),
+ MX35_PIN_CSPI1_SS0 = _MXC_BUILD_GPIO_PIN(0, 18, 0x178, 0x5BC),
+ MX35_PIN_CSPI1_SS1 = _MXC_BUILD_GPIO_PIN(0, 19, 0x17C, 0x5C0),
+ MX35_PIN_CSPI1_SCLK = _MXC_BUILD_GPIO_PIN(2, 4, 0x180, 0x5C4),
+ MX35_PIN_CSPI1_SPI_RDY = _MXC_BUILD_GPIO_PIN(2, 5, 0x184, 0x5C8),
+
+ MX35_PIN_RXD1 = _MXC_BUILD_GPIO_PIN(2, 6, 0x188, 0x5CC),
+ MX35_PIN_TXD1 = _MXC_BUILD_GPIO_PIN(2, 7, 0x18C, 0x5D0),
+ MX35_PIN_RTS1 = _MXC_BUILD_GPIO_PIN(2, 8, 0x190, 0x5D4),
+ MX35_PIN_CTS1 = _MXC_BUILD_GPIO_PIN(2, 9, 0x194, 0x5D8),
+ MX35_PIN_RXD2 = _MXC_BUILD_GPIO_PIN(2, 10, 0x198, 0x5DC),
+ MX35_PIN_TXD2 = _MXC_BUILD_GPIO_PIN(1, 11, 0x19C, 0x5E0),
+ MX35_PIN_RTS2 = _MXC_BUILD_GPIO_PIN(1, 12, 0x1A0, 0x5E4),
+ MX35_PIN_CTS2 = _MXC_BUILD_GPIO_PIN(1, 13, 0x1A4, 0x5E8),
+
+ MX35_PIN_USBOTG_PWR = _MXC_BUILD_GPIO_PIN(2, 14, 0x1A8, 0x60C),
+ MX35_PIN_USBOTG_OC = _MXC_BUILD_GPIO_PIN(2, 15, 0x1AC, 0x610),
+
+ MX35_PIN_LD0 = _MXC_BUILD_GPIO_PIN(1, 0, 0x1B0, 0x614),
+ MX35_PIN_LD1 = _MXC_BUILD_GPIO_PIN(1, 1, 0x1B4, 0x618),
+ MX35_PIN_LD2 = _MXC_BUILD_GPIO_PIN(1, 2, 0x1B8, 0x61C),
+ MX35_PIN_LD3 = _MXC_BUILD_GPIO_PIN(1, 3, 0x1BC, 0x620),
+ MX35_PIN_LD4 = _MXC_BUILD_GPIO_PIN(1, 4, 0x1C0, 0x624),
+ MX35_PIN_LD5 = _MXC_BUILD_GPIO_PIN(1, 5, 0x1C4, 0x628),
+ MX35_PIN_LD6 = _MXC_BUILD_GPIO_PIN(1, 6, 0x1C8, 0x62C),
+ MX35_PIN_LD7 = _MXC_BUILD_GPIO_PIN(1, 7, 0x1CC, 0x630),
+ MX35_PIN_LD8 = _MXC_BUILD_GPIO_PIN(1, 8, 0x1D0, 0x634),
+ MX35_PIN_LD9 = _MXC_BUILD_GPIO_PIN(1, 9, 0x1D4, 0x638),
+ MX35_PIN_LD10 = _MXC_BUILD_GPIO_PIN(1, 10, 0x1D8, 0x63C),
+ MX35_PIN_LD11 = _MXC_BUILD_GPIO_PIN(1, 11, 0x1DC, 0x640),
+ MX35_PIN_LD12 = _MXC_BUILD_GPIO_PIN(1, 12, 0x1E0, 0x644),
+ MX35_PIN_LD13 = _MXC_BUILD_GPIO_PIN(1, 13, 0x1E4, 0x648),
+ MX35_PIN_LD14 = _MXC_BUILD_GPIO_PIN(1, 14, 0x1E8, 0x64C),
+ MX35_PIN_LD15 = _MXC_BUILD_GPIO_PIN(1, 15, 0x1EC, 0x650),
+ MX35_PIN_LD16 = _MXC_BUILD_GPIO_PIN(1, 16, 0x1F0, 0x654),
+ MX35_PIN_LD17 = _MXC_BUILD_GPIO_PIN(1, 17, 0x1F4, 0x658),
+ MX35_PIN_LD18 = _MXC_BUILD_GPIO_PIN(2, 24, 0x1F8, 0x65C),
+ MX35_PIN_LD19 = _MXC_BUILD_GPIO_PIN(2, 25, 0x1FC, 0x660),
+ MX35_PIN_LD20 = _MXC_BUILD_GPIO_PIN(2, 26, 0x200, 0x664),
+ MX35_PIN_LD21 = _MXC_BUILD_GPIO_PIN(2, 27, 0x204, 0x668),
+ MX35_PIN_LD22 = _MXC_BUILD_GPIO_PIN(2, 28, 0x208, 0x66C),
+ MX35_PIN_LD23 = _MXC_BUILD_GPIO_PIN(2, 29, 0x20C, 0x670),
+
+ MX35_PIN_D3_HSYNC = _MXC_BUILD_GPIO_PIN(2, 30, 0x210, 0x674),
+ MX35_PIN_D3_FPSHIFT = _MXC_BUILD_GPIO_PIN(2, 31, 0x214, 0x678),
+ MX35_PIN_D3_DRDY = _MXC_BUILD_GPIO_PIN(0, 0, 0x218, 0x67C),
+ MX35_PIN_CONTRAST = _MXC_BUILD_GPIO_PIN(0, 1, 0x21C, 0x680),
+ MX35_PIN_D3_VSYNC = _MXC_BUILD_GPIO_PIN(0, 2, 0x220, 0x684),
+ MX35_PIN_D3_REV = _MXC_BUILD_GPIO_PIN(0, 3, 0x224, 0x688),
+ MX35_PIN_D3_CLS = _MXC_BUILD_GPIO_PIN(0, 4, 0x228, 0x68C),
+ MX35_PIN_D3_SPL = _MXC_BUILD_GPIO_PIN(0, 5, 0x22C, 0x690),
+
+ MX35_PIN_SD1_CMD = _MXC_BUILD_GPIO_PIN(0, 6, 0x230, 0x694),
+ MX35_PIN_SD1_CLK = _MXC_BUILD_GPIO_PIN(0, 7, 0x234, 0x698),
+ MX35_PIN_SD1_DATA0 = _MXC_BUILD_GPIO_PIN(0, 8, 0x238, 0x69C),
+ MX35_PIN_SD1_DATA1 = _MXC_BUILD_GPIO_PIN(0, 9, 0x23C, 0x6A0),
+ MX35_PIN_SD1_DATA2 = _MXC_BUILD_GPIO_PIN(0, 10, 0x240, 0x6A4),
+ MX35_PIN_SD1_DATA3 = _MXC_BUILD_GPIO_PIN(0, 11, 0x244, 0x6A8),
+ MX35_PIN_SD2_CMD = _MXC_BUILD_GPIO_PIN(1, 0, 0x248, 0x6AC),
+ MX35_PIN_SD2_CLK = _MXC_BUILD_GPIO_PIN(1, 1, 0x24C, 0x6B0),
+ MX35_PIN_SD2_DATA0 = _MXC_BUILD_GPIO_PIN(1, 2, 0x250, 0x6B4),
+ MX35_PIN_SD2_DATA1 = _MXC_BUILD_GPIO_PIN(1, 3, 0x254, 0x6B8),
+ MX35_PIN_SD2_DATA2 = _MXC_BUILD_GPIO_PIN(1, 4, 0x258, 0x6BC),
+ MX35_PIN_SD2_DATA3 = _MXC_BUILD_GPIO_PIN(1, 5, 0x25C, 0x6C0),
+
+ MX35_PIN_ATA_CS0 = _MXC_BUILD_GPIO_PIN(1, 6, 0x260, 0x6C4),
+ MX35_PIN_ATA_CS1 = _MXC_BUILD_GPIO_PIN(1, 7, 0x264, 0x6C8),
+ MX35_PIN_ATA_DIOR = _MXC_BUILD_GPIO_PIN(1, 8, 0x268, 0x6CC),
+ MX35_PIN_ATA_DIOW = _MXC_BUILD_GPIO_PIN(1, 9, 0x26C, 0x6D0),
+ MX35_PIN_ATA_DMACK = _MXC_BUILD_GPIO_PIN(1, 10, 0x270, 0x6D4),
+ MX35_PIN_ATA_RESET_B = _MXC_BUILD_GPIO_PIN(1, 11, 0x274, 0x6D8),
+ MX35_PIN_ATA_IORDY = _MXC_BUILD_GPIO_PIN(1, 12, 0x278, 0x6DC),
+ MX35_PIN_ATA_DATA0 = _MXC_BUILD_GPIO_PIN(1, 13, 0x27C, 0x6E0),
+ MX35_PIN_ATA_DATA1 = _MXC_BUILD_GPIO_PIN(1, 14, 0x280, 0x6E4),
+ MX35_PIN_ATA_DATA2 = _MXC_BUILD_GPIO_PIN(1, 15, 0x284, 0x6E8),
+ MX35_PIN_ATA_DATA3 = _MXC_BUILD_GPIO_PIN(1, 16, 0x288, 0x6EC),
+ MX35_PIN_ATA_DATA4 = _MXC_BUILD_GPIO_PIN(1, 17, 0x28C, 0x6F0),
+ MX35_PIN_ATA_DATA5 = _MXC_BUILD_GPIO_PIN(1, 18, 0x290, 0x6F4),
+ MX35_PIN_ATA_DATA6 = _MXC_BUILD_GPIO_PIN(1, 19, 0x294, 0x6F8),
+ MX35_PIN_ATA_DATA7 = _MXC_BUILD_GPIO_PIN(1, 20, 0x298, 0x6FC),
+ MX35_PIN_ATA_DATA8 = _MXC_BUILD_GPIO_PIN(1, 21, 0x29C, 0x700),
+ MX35_PIN_ATA_DATA9 = _MXC_BUILD_GPIO_PIN(1, 22, 0x2A0, 0x704),
+ MX35_PIN_ATA_DATA10 = _MXC_BUILD_GPIO_PIN(1, 23, 0x2A4, 0x708),
+ MX35_PIN_ATA_DATA11 = _MXC_BUILD_GPIO_PIN(1, 24, 0x2A8, 0x70C),
+ MX35_PIN_ATA_DATA12 = _MXC_BUILD_GPIO_PIN(1, 25, 0x2AC, 0x710),
+ MX35_PIN_ATA_DATA13 = _MXC_BUILD_GPIO_PIN(1, 26, 0x2B0, 0x714),
+ MX35_PIN_ATA_DATA14 = _MXC_BUILD_GPIO_PIN(1, 27, 0x2B4, 0x718),
+ MX35_PIN_ATA_DATA15 = _MXC_BUILD_GPIO_PIN(1, 28, 0x2B8, 0x71C),
+ MX35_PIN_ATA_INTRQ = _MXC_BUILD_GPIO_PIN(1, 29, 0x2BC, 0x720),
+ MX35_PIN_ATA_BUFF_EN = _MXC_BUILD_GPIO_PIN(1, 30, 0x2C0, 0x724),
+ MX35_PIN_ATA_DMARQ = _MXC_BUILD_GPIO_PIN(1, 31, 0x2C4, 0x728),
+ MX35_PIN_ATA_DA0 = _MXC_BUILD_GPIO_PIN(2, 0, 0x2C8, 0x72C),
+ MX35_PIN_ATA_DA1 = _MXC_BUILD_GPIO_PIN(2, 1, 0x2CC, 0x730),
+ MX35_PIN_ATA_DA2 = _MXC_BUILD_GPIO_PIN(2, 2, 0x2D0, 0x734),
+
+ MX35_PIN_MLB_CLK = _MXC_BUILD_GPIO_PIN(2, 3, 0x2D4, 0x738),
+ MX35_PIN_MLB_DAT = _MXC_BUILD_GPIO_PIN(2, 4, 0x2D8, 0x73C),
+ MX35_PIN_MLB_SIG = _MXC_BUILD_GPIO_PIN(2, 5, 0x2DC, 0x740),
+
+ MX35_PIN_FEC_TX_CLK = _MXC_BUILD_GPIO_PIN(2, 6, 0x2E0, 0x744),
+ MX35_PIN_FEC_RX_CLK = _MXC_BUILD_GPIO_PIN(2, 7, 0x2E4, 0x748),
+ MX35_PIN_FEC_RX_DV = _MXC_BUILD_GPIO_PIN(2, 8, 0x2E8, 0x74C),
+ MX35_PIN_FEC_COL = _MXC_BUILD_GPIO_PIN(2, 9, 0x2EC, 0x750),
+ MX35_PIN_FEC_RDATA0 = _MXC_BUILD_GPIO_PIN(2, 10, 0x2F0, 0x754),
+ MX35_PIN_FEC_TDATA0 = _MXC_BUILD_GPIO_PIN(2, 11, 0x2F4, 0x758),
+ MX35_PIN_FEC_TX_EN = _MXC_BUILD_GPIO_PIN(2, 12, 0x2F8, 0x75C),
+ MX35_PIN_FEC_MDC = _MXC_BUILD_GPIO_PIN(2, 13, 0x2FC, 0x760),
+ MX35_PIN_FEC_MDIO = _MXC_BUILD_GPIO_PIN(2, 14, 0x300, 0x764),
+ MX35_PIN_FEC_TX_ERR = _MXC_BUILD_GPIO_PIN(2, 15, 0x304, 0x768),
+ MX35_PIN_FEC_RX_ERR = _MXC_BUILD_GPIO_PIN(2, 16, 0x308, 0x76C),
+ MX35_PIN_FEC_CRS = _MXC_BUILD_GPIO_PIN(2, 17, 0x30C, 0x770),
+ MX35_PIN_FEC_RDATA1 = _MXC_BUILD_GPIO_PIN(2, 18, 0x310, 0x774),
+ MX35_PIN_FEC_TDATA1 = _MXC_BUILD_GPIO_PIN(2, 19, 0x314, 0x778),
+ MX35_PIN_FEC_RDATA2 = _MXC_BUILD_GPIO_PIN(2, 20, 0x318, 0x77C),
+ MX35_PIN_FEC_TDATA2 = _MXC_BUILD_GPIO_PIN(2, 21, 0x31C, 0x780),
+ MX35_PIN_FEC_RDATA3 = _MXC_BUILD_GPIO_PIN(2, 22, 0x320, 0x784),
+ MX35_PIN_FEC_TDATA3 = _MXC_BUILD_GPIO_PIN(2, 23, 0x324, 0x788),
+};
+
+#endif
+#endif
diff --git a/arch/arm/mach-mx35/mx35evb.c b/arch/arm/mach-mx35/mx35evb.c
new file mode 100644
index 000000000000..be595245dd57
--- /dev/null
+++ b/arch/arm/mach-mx35/mx35evb.c
@@ -0,0 +1,396 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/spi/spi.h>
+#include <linux/platform_device.h>
+#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE)
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/flash.h>
+#endif
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <asm/mach/keypad.h>
+#include <mach/memory.h>
+#include <mach/gpio.h>
+
+#include "board-mx35evb.h"
+#include "crm_regs.h"
+#include "iomux.h"
+
+/*!
+ * @file mach-mx35/mx35evb.c
+ *
+ * @brief This file contains the board specific initialization routines.
+ *
+ * @ingroup MSL_MX35
+ */
+
+unsigned int mx35evb_board_io;
+
+static void mxc_nop_release(struct device *dev)
+{
+ /* Nothing */
+}
+
+/* MTD NOR flash */
+
+#if defined(CONFIG_MTD_MXC) || defined(CONFIG_MTD_MXC_MODULE)
+
+static struct mtd_partition mxc_nor_partitions[] = {
+ {
+ .name = "Bootloader",
+ .size = 512 * 1024,
+ .offset = 0x00000000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "nor.Kernel",
+ .size = 4 * 1024 * 1024,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = 0},
+ {
+ .name = "nor.userfs",
+ .size = 30 * 1024 * 1024,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = 0},
+ {
+ .name = "nor.rootfs",
+ .size = 28 * 1024 * 1024,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE},
+ {
+ .name = "FIS directory",
+ .size = 12 * 1024,
+ .offset = 0x01FE0000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+ {
+ .name = "Redboot config",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0x01FFF000,
+ .mask_flags = MTD_WRITEABLE /* force read-only */
+ },
+};
+
+static struct flash_platform_data mxc_flash_data = {
+ .map_name = "cfi_probe",
+ .width = 2,
+ .parts = mxc_nor_partitions,
+ .nr_parts = ARRAY_SIZE(mxc_nor_partitions),
+};
+
+static struct resource mxc_flash_resource = {
+ .start = 0xa0000000,
+ .end = 0xa0000000 + 0x04000000 - 1,
+ .flags = IORESOURCE_MEM,
+
+};
+
+static struct platform_device mxc_nor_mtd_device = {
+ .name = "mxc_nor_flash",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_flash_data,
+ },
+ .num_resources = 1,
+ .resource = &mxc_flash_resource,
+};
+
+static void mxc_init_nor_mtd(void)
+{
+ (void)platform_device_register(&mxc_nor_mtd_device);
+}
+#else
+static void mxc_init_nor_mtd(void)
+{
+}
+#endif
+
+/* MTD NAND flash */
+
+#if defined(CONFIG_MTD_NAND_MXC) || defined(CONFIG_MTD_NAND_MXC_MODULE)
+
+static struct mtd_partition mxc_nand_partitions[] = {
+ {
+ .name = "IPL-SPL",
+ .offset = 0,
+ .size = 256 * 1024},
+ {
+ .name = "nand.kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 4 * 1024 * 1024},
+ {
+ .name = "nand.rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 96 * 1024 * 1024},
+ {
+ .name = "nand.configure",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 8 * 1024 * 1024},
+ {
+ .name = "nand.userfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL},
+};
+
+static struct flash_platform_data mxc_nand_data = {
+ .parts = mxc_nand_partitions,
+ .nr_parts = ARRAY_SIZE(mxc_nand_partitions),
+ .width = 1,
+};
+
+static struct platform_device mxc_nand_mtd_device = {
+ .name = "mxc_nand_flash",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_nand_data,
+ },
+};
+
+static void mxc_init_nand_mtd(void)
+{
+ if (__raw_readl(MXC_CCM_RCSR) & MXC_CCM_RCSR_NF16B)
+ mxc_nand_data.width = 2;
+
+ platform_device_register(&mxc_nand_mtd_device);
+}
+#else
+static inline void mxc_init_nand_mtd(void)
+{
+}
+#endif
+
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+static struct resource smsc911x_resources[] = {
+ {
+ .start = ENET_BASE_ADDRESS,
+ .end = ENET_BASE_ADDRESS + 0x100,
+ .flags = IORESOURCE_MEM,},
+ {
+ .start = EXPIO_INT_ENET,
+ .end = EXPIO_INT_ENET,
+ .flags = IORESOURCE_IRQ,}
+};
+
+static struct platform_device mxc_smsc911x_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+};
+
+static void mxc_init_enet(void)
+{
+ int i;
+ /*reset ext uart in cpld */
+ __raw_writew(PBC_BCTRL1_ENET_RST_B, PBC_BCTRL1_SET);
+ /*delay some time for reset finish */
+ for (i = 0; i < 10000; i++) ;
+ __raw_writew(PBC_BCTRL1_ENET_RST_B, PBC_BCTRL1_CLR);
+
+ platform_device_register(&mxc_smsc911x_device);
+}
+#else
+static inline void mxc_init_enet(void)
+{
+}
+#endif
+
+#if defined(CONFIG_FEC) || defined(CONFIG_FEC_MODULE)
+unsigned int expio_intr_fec;
+
+EXPORT_SYMBOL(expio_intr_fec);
+#endif
+
+/*!
+ * Board specific fixup function. It is called by \b setup_arch() in
+ * setup.c file very early on during kernel starts. It allows the user to
+ * statically fill in the proper values for the passed-in parameters. None of
+ * the parameters is used currently.
+ *
+ * @param desc pointer to \b struct \b machine_desc
+ * @param tags pointer to \b struct \b tag
+ * @param cmdline pointer to the command line
+ * @param mi pointer to \b struct \b meminfo
+ */
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ mxc_cpu_init();
+
+#ifdef CONFIG_DISCONTIGMEM
+ do {
+ int nid;
+ mi->nr_banks = MXC_NUMNODES;
+ for (nid = 0; nid < mi->nr_banks; nid++)
+ SET_NODE(mi, nid);
+ } while (0);
+#endif
+}
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ mxc_cpu_common_init();
+ mxc_clocks_init();
+ early_console_setup(saved_command_line);
+ mxc_gpio_init();
+ mx35evb_gpio_init();
+ mxc_init_enet();
+ mxc_init_nor_mtd();
+ mxc_init_nand_mtd();
+
+}
+
+#define PLL_PCTL_REG(brmo, pd, mfd, mfi, mfn) \
+ (((brmo) << 31) + (((pd) - 1) << 26) + (((mfd) - 1) << 16) + \
+ ((mfi) << 10) + mfn)
+
+/* For 24MHz input clock */
+#define PLL_665MHZ PLL_PCTL_REG(1, 1, 48, 13, 41)
+#define PLL_532MHZ PLL_PCTL_REG(1, 1, 12, 11, 1)
+#define PLL_399MHZ PLL_PCTL_REG(0, 1, 16, 8, 5)
+
+/* working point(wp): 0,1 - 133MHz; 2,3 - 266MHz; 4,5 - 399MHz;*/
+/* auto input clock table */
+static struct cpu_wp cpu_wp_auto[] = {
+ {
+ .pll_reg = PLL_399MHZ,
+ .pll_rate = 399000000,
+ .cpu_rate = 133000000,
+ .pdr0_reg = (0x2 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_399MHZ,
+ .pll_rate = 399000000,
+ .cpu_rate = 133000000,
+ .pdr0_reg = (0x6 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_399MHZ,
+ .pll_rate = 399000000,
+ .cpu_rate = 266000000,
+ .pdr0_reg = (0x1 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_399MHZ,
+ .pll_rate = 399000000,
+ .cpu_rate = 266000000,
+ .pdr0_reg = (0x5 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_399MHZ,
+ .pll_rate = 399000000,
+ .cpu_rate = 399000000,
+ .pdr0_reg = (0x0 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_399MHZ,
+ .pll_rate = 399000000,
+ .cpu_rate = 399000000,
+ .pdr0_reg = (0x6 << MXC_CCM_PDR0_AUTO_MUX_DIV_OFFSET),},
+};
+
+/* consumer input clock table */
+static struct cpu_wp cpu_wp_con[] = {
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 133000000,
+ .pdr0_reg = (0x6 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 133000000,
+ .pdr0_reg = (0xE << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 266000000,
+ .pdr0_reg = (0x2 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 266000000,
+ .pdr0_reg = (0xA << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 399000000,
+ .pdr0_reg = (0x1 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 399000000,
+ .pdr0_reg = (0x9 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 532000000,
+ .pdr0_reg = (0x0 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_532MHZ,
+ .pll_rate = 532000000,
+ .cpu_rate = 532000000,
+ .pdr0_reg = (0x8 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+ {
+ .pll_reg = PLL_665MHZ,
+ .pll_rate = 665000000,
+ .cpu_rate = 665000000,
+ .pdr0_reg = (0x7 << MXC_CCM_PDR0_CON_MUX_DIV_OFFSET),},
+};
+
+struct cpu_wp *get_cpu_wp(int *wp)
+{
+ if (__raw_readl(MXC_CCM_PDR0) & MXC_CCM_PDR0_AUTO_CON) {
+ *wp = 9;
+ return cpu_wp_con;
+ } else {
+ *wp = 6;
+ return cpu_wp_auto;
+ }
+}
+
+/*
+ * The following uses standard kernel macros define in arch.h in order to
+ * initialize __mach_desc_MX35EVB data structure.
+ */
+/* *INDENT-OFF* */
+MACHINE_START(MX35EVB, "Freescale MX35 EVB")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .phys_io = AIPS1_BASE_ADDR,
+ .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = PHYS_OFFSET + 0x100,
+ .fixup = fixup_mxc_board,
+ .map_io = mxc_map_io,
+ .init_irq = mxc_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &mxc_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx35/mx35evb_cpld.c b/arch/arm/mach-mx35/mx35evb_cpld.c
new file mode 100644
index 000000000000..fbf9188f3671
--- /dev/null
+++ b/arch/arm/mach-mx35/mx35evb_cpld.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
+#include <mach/gpio.h>
+
+#include "board-mx35evb.h"
+#include "iomux.h"
+
+/*!
+ * @file mach-mx35/mx35evb_cpld.c
+ *
+ * @brief This file contains the board specific initialization routines.
+ *
+ * @ingroup MSL_MX35
+ */
+
+static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ /*TODO:virtual interrupt dispatcher */
+}
+
+/*
+ * Disable an expio pin's interrupt by setting the bit in the imr.
+ * @param irq an expio virtual irq number
+ */
+static void expio_mask_irq(u32 irq)
+{
+ /*TODO:mask virtual interrupt #irq */
+}
+
+/*
+ * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
+ * @param irq an expanded io virtual irq number
+ */
+static void expio_ack_irq(u32 irq)
+{
+ /*TODO:ack & mask virtual interrupt #irq */
+}
+
+/*
+ * Enable a expio pin's interrupt by clearing the bit in the imr.
+ * @param irq a expio virtual irq number
+ */
+static void expio_unmask_irq(u32 irq)
+{
+ /*TODO:enable virtual interrupt #irq */
+}
+
+static struct irq_chip expio_irq_chip = {
+ .ack = expio_ack_irq,
+ .mask = expio_mask_irq,
+ .unmask = expio_unmask_irq,
+};
+
+static int __init mxc_expio_init(void)
+{
+ /*TODO:enable virtual interrupts generated by CPLD */
+ return 0;
+}
+
+arch_initcall(mxc_expio_init);
diff --git a/arch/arm/mach-mx35/mx35evb_gpio.c b/arch/arm/mach-mx35/mx35evb_gpio.c
new file mode 100644
index 000000000000..cd24048bbcf0
--- /dev/null
+++ b/arch/arm/mach-mx35/mx35evb_gpio.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include "board-mx35evb.h"
+#include "iomux.h"
+
+/*!
+ * @file mach-mx35/mx35evb_gpio.c
+ *
+ * @brief This file contains all the GPIO setup functions for the board.
+ *
+ * @ingroup GPIO_MX35
+ */
+
+/*!
+ * This system-wise GPIO function initializes the pins during system startup.
+ * All the statically linked device drivers should put the proper GPIO
+ * initialization code inside this function. It is called by \b fixup_mx31ads()
+ * during system startup. This function is board specific.
+ */
+void mx35evb_gpio_init(void)
+{
+ /* config CS4 */
+ mxc_request_iomux(MX35_PIN_CS4, MUX_CONFIG_FUNC);
+
+}
+
+/*!
+ * Setup GPIO for a UART port to be active
+ *
+ * @param port a UART port
+ * @param no_irda indicates if the port is used for SIR
+ */
+void gpio_uart_active(int port, int no_irda)
+{
+ /*
+ * Configure the IOMUX control registers for the UART signals
+ */
+ switch (port) {
+ /* UART 1 IOMUX Configs */
+ case 0:
+ mxc_request_iomux(MX35_PIN_RXD1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_TXD1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_RTS1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CTS1, MUX_CONFIG_FUNC);
+
+ mxc_iomux_set_pad(MX35_PIN_RXD1,
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX35_PIN_TXD1,
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_RTS1,
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX35_PIN_CTS1,
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
+
+ break;
+ /* UART 2 IOMUX Configs */
+ case 1:
+ mxc_request_iomux(MX35_PIN_TXD2, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_RXD2, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_RTS2, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CTS2, MUX_CONFIG_FUNC);
+
+ mxc_iomux_set_pad(MX35_PIN_RXD2,
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX35_PIN_TXD2,
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
+ mxc_iomux_set_pad(MX35_PIN_RTS2,
+ PAD_CTL_HYS_SCHMITZ | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PU);
+ mxc_iomux_set_pad(MX35_PIN_CTS2,
+ PAD_CTL_PUE_PUD | PAD_CTL_100K_PD);
+
+ break;
+ /* UART 3 IOMUX Configs */
+ case 2:
+ mxc_request_iomux(MX35_PIN_FEC_TX_CLK, MUX_CONFIG_ALT2);
+ mxc_request_iomux(MX35_PIN_FEC_RX_CLK, MUX_CONFIG_ALT2);
+ mxc_request_iomux(MX35_PIN_FEC_COL, MUX_CONFIG_ALT2);
+ mxc_request_iomux(MX35_PIN_FEC_RX_DV, MUX_CONFIG_ALT2);
+
+ mxc_iomux_set_input(MUX_IN_UART3_UART_RTS_B, INPUT_CTL_PATH2);
+ mxc_iomux_set_input(MUX_IN_UART3_UART_RXD_MUX, INPUT_CTL_PATH3);
+ break;
+ default:
+ break;
+ }
+
+}
+
+EXPORT_SYMBOL(gpio_uart_active);
+
+/*!
+ * Setup GPIO for a UART port to be inactive
+ *
+ * @param port a UART port
+ * @param no_irda indicates if the port is used for SIR
+ */
+void gpio_uart_inactive(int port, int no_irda)
+{
+ switch (port) {
+ case 0:
+ mxc_request_gpio(MX35_PIN_RXD1);
+ mxc_request_gpio(MX35_PIN_TXD1);
+ mxc_request_gpio(MX35_PIN_RTS1);
+ mxc_request_gpio(MX35_PIN_CTS1);
+
+ mxc_free_iomux(MX35_PIN_RXD1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_TXD1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_RTS1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_CTS1, MUX_CONFIG_GPIO);
+ break;
+ case 1:
+ mxc_request_gpio(MX35_PIN_RXD2);
+ mxc_request_gpio(MX35_PIN_TXD2);
+ mxc_request_gpio(MX35_PIN_RTS2);
+ mxc_request_gpio(MX35_PIN_CTS2);
+
+ mxc_free_iomux(MX35_PIN_RXD2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_TXD2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_RTS2, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_CTS2, MUX_CONFIG_GPIO);
+ break;
+ case 2:
+ mxc_request_gpio(MX35_PIN_FEC_TX_CLK);
+ mxc_request_gpio(MX35_PIN_FEC_RX_CLK);
+ mxc_request_gpio(MX35_PIN_FEC_COL);
+ mxc_request_gpio(MX35_PIN_FEC_RX_DV);
+
+ mxc_free_iomux(MX35_PIN_FEC_TX_CLK, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_RX_CLK, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_COL, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_FEC_RX_DV, MUX_CONFIG_GPIO);
+
+ mxc_iomux_set_input(MUX_IN_UART3_UART_RTS_B, INPUT_CTL_PATH0);
+ mxc_iomux_set_input(MUX_IN_UART3_UART_RXD_MUX, INPUT_CTL_PATH0);
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_uart_inactive);
+
+/*!
+ * Configure the IOMUX GPR register to receive shared SDMA UART events
+ *
+ * @param port a UART port
+ */
+void config_uartdma_event(int port)
+{
+}
+
+EXPORT_SYMBOL(config_uartdma_event);
+
+void gpio_fec_active(void)
+{
+ /*TODO:require the pins related with FEC */
+}
+
+EXPORT_SYMBOL(gpio_fec_active);
+
+void gpio_fec_inactive(void)
+{
+ /*TODO:release the pins related with FEC */
+}
+
+EXPORT_SYMBOL(gpio_fec_inactive);
+
+/*!
+ * Setup GPIO for a CSPI device to be active
+ *
+ * @param cspi_mod an CSPI device
+ */
+void gpio_spi_active(int cspi_mod)
+{
+ switch (cspi_mod) {
+ case 0:
+ /* SPI1 */
+ mxc_request_iomux(MX35_PIN_CSPI1_MOSI, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSPI1_MISO, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSPI1_SS0, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSPI1_SS1, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSPI1_SCLK, MUX_CONFIG_FUNC);
+ mxc_request_iomux(MX35_PIN_CSPI1_SPI_RDY, MUX_CONFIG_FUNC);
+
+ mxc_iomux_set_pad(MX35_PIN_CSPI1_MOSI,
+ PAD_CTL_DRV_3_3V | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD |
+ PAD_CTL_100K_PD | PAD_CTL_DRV_NORMAL);
+ mxc_iomux_set_pad(MX35_PIN_CSPI1_MISO,
+ PAD_CTL_DRV_3_3V | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD |
+ PAD_CTL_100K_PD | PAD_CTL_DRV_NORMAL);
+ mxc_iomux_set_pad(MX35_PIN_CSPI1_SS0,
+ PAD_CTL_DRV_3_3V | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD |
+ PAD_CTL_100K_PU | PAD_CTL_ODE_CMOS |
+ PAD_CTL_DRV_NORMAL);
+ mxc_iomux_set_pad(MX35_PIN_CSPI1_SS1,
+ PAD_CTL_DRV_3_3V | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD |
+ PAD_CTL_100K_PU | PAD_CTL_ODE_CMOS |
+ PAD_CTL_DRV_NORMAL);
+ mxc_iomux_set_pad(MX35_PIN_CSPI1_SCLK,
+ PAD_CTL_DRV_3_3V | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD |
+ PAD_CTL_100K_PD | PAD_CTL_DRV_NORMAL);
+ mxc_iomux_set_pad(MX35_PIN_CSPI1_SPI_RDY,
+ PAD_CTL_DRV_3_3V | PAD_CTL_HYS_SCHMITZ |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PUD |
+ PAD_CTL_100K_PU | PAD_CTL_DRV_NORMAL);
+ break;
+ case 1:
+ /* SPI2 */
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_spi_active);
+
+/*!
+ * Setup GPIO for a CSPI device to be inactive
+ *
+ * @param cspi_mod a CSPI device
+ */
+void gpio_spi_inactive(int cspi_mod)
+{
+ switch (cspi_mod) {
+ case 0:
+ /* SPI1 */
+ mxc_request_gpio(MX35_PIN_CSPI1_MOSI);
+ mxc_request_gpio(MX35_PIN_CSPI1_MISO);
+ mxc_request_gpio(MX35_PIN_CSPI1_SS0);
+ mxc_request_gpio(MX35_PIN_CSPI1_SS1);
+ mxc_request_gpio(MX35_PIN_CSPI1_SCLK);
+ mxc_request_gpio(MX35_PIN_CSPI1_SPI_RDY);
+
+ mxc_free_iomux(MX35_PIN_CSPI1_MOSI, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_CSPI1_MISO, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_CSPI1_SS0, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_CSPI1_SS1, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_CSPI1_SCLK, MUX_CONFIG_GPIO);
+ mxc_free_iomux(MX35_PIN_CSPI1_SPI_RDY, MUX_CONFIG_GPIO);
+ break;
+ case 1:
+ /* SPI2 */
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_spi_inactive);
diff --git a/arch/arm/mach-mx35/pm.c b/arch/arm/mach-mx35/pm.c
new file mode 100644
index 000000000000..ad375ce2fb78
--- /dev/null
+++ b/arch/arm/mach-mx35/pm.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+
+/*!
+ * @defgroup MSL_MX35 i.MX35 Machine Specific Layer (MSL)
+ */
+
+/*!
+ * @file mach-mx35/pm.c
+ * @brief This file contains suspend operations
+ *
+ * @ingroup MSL_MX35
+ */
+static int mx35_suspend_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ mxc_cpu_lp_set(STOP_POWER_OFF);
+ break;
+ case PM_SUSPEND_STANDBY:
+ mxc_cpu_lp_set(STOP_POWER_ON);
+ break;
+ default:
+ return -EINVAL;
+ }
+ /* Executing CP15 (Wait-for-Interrupt) Instruction */
+ cpu_do_idle();
+ return 0;
+}
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int mx35_suspend_prepare(void)
+{
+ return 0;
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+static void mx35_suspend_finish(void)
+{
+}
+
+static int mx35_pm_valid(suspend_state_t state)
+{
+ return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX);
+}
+
+struct platform_suspend_ops mx35_suspend_ops = {
+ .valid = mx35_pm_valid,
+ .prepare = mx35_suspend_prepare,
+ .enter = mx35_suspend_enter,
+ .finish = mx35_suspend_finish,
+};
+
+static int __init mx35_pm_init(void)
+{
+ pr_info("Static Power Management for Freescale i.MX35\n");
+ suspend_set_ops(&mx35_suspend_ops);
+
+ return 0;
+}
+
+late_initcall(mx35_pm_init);
diff --git a/arch/arm/mach-mx35/sdma_script_code.h b/arch/arm/mach-mx35/sdma_script_code.h
new file mode 100644
index 000000000000..e1b6b59bc31e
--- /dev/null
+++ b/arch/arm/mach-mx35/sdma_script_code.h
@@ -0,0 +1,254 @@
+/*
+ * Copyright 2008 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 */
+
+/*!
+ * @file sdma_script_code.h
+ * @brief This file contains functions of SDMA scripts code initialization
+ *
+ * The file was generated automatically. Based on sdma scripts library.
+ *
+ * @ingroup SDMA
+ */
+/*******************************************************************************
+
+ SDMA RELEASE LABEL: "SS15_RINGO"
+
+*******************************************************************************/
+
+#ifndef __SDMA_SCRIPT_CODE_H__
+#define __SDMA_SCRIPT_CODE_H__
+
+/*!
+* SDMA ROM scripts start addresses and sizes
+*/
+
+#define start_ADDR 0
+#define start_SIZE 22
+
+#define core_ADDR 80
+#define core_SIZE 232
+
+#define common_ADDR 312
+#define common_SIZE 330
+
+#define ap_2_ap_ADDR 642
+#define ap_2_ap_SIZE 41
+
+#define app_2_mcu_ADDR 683
+#define app_2_mcu_SIZE 64
+
+#define mcu_2_app_ADDR 747
+#define mcu_2_app_SIZE 70
+
+#define uart_2_mcu_ADDR 817
+#define uart_2_mcu_SIZE 75
+
+#define shp_2_mcu_ADDR 892
+#define shp_2_mcu_SIZE 69
+
+#define mcu_2_shp_ADDR 961
+#define mcu_2_shp_SIZE 72
+
+#define per_2_shp_ADDR 1033
+#define per_2_shp_SIZE 78
+
+#define shp_2_per_ADDR 1111
+#define shp_2_per_SIZE 72
+
+#define uartsh_2_mcu_ADDR 1183
+#define uartsh_2_mcu_SIZE 69
+
+#define mcu_2_ata_ADDR 1252
+#define mcu_2_ata_SIZE 81
+
+#define ata_2_mcu_ADDR 1333
+#define ata_2_mcu_SIZE 96
+
+#define loop_DMAs_routines_ADDR 1429
+#define loop_DMAs_routines_SIZE 227
+
+#define test_ADDR 1656
+#define test_SIZE 63
+
+#define signature_ADDR 1023
+#define signature_SIZE 1
+
+/*!
+* SDMA RAM scripts start addresses and sizes
+*/
+
+#define app_2_per_ADDR 6144
+#define app_2_per_SIZE 66
+
+#define asrc__mcu_ADDR 6210
+#define asrc__mcu_SIZE 114
+
+#define ext_mem__ipu_ram_ADDR 6324
+#define ext_mem__ipu_ram_SIZE 123
+
+#define mcu_2_spdif_ADDR 6447
+#define mcu_2_spdif_SIZE 103
+
+#define p_2_p_ADDR 6550
+#define p_2_p_SIZE 254
+
+#define per_2_app_ADDR 6804
+#define per_2_app_SIZE 74
+
+#define spdif_2_mcu_ADDR 6878
+#define spdif_2_mcu_SIZE 47
+
+#define uart_2_per_ADDR 6925
+#define uart_2_per_SIZE 73
+
+#define uartsh_2_per_ADDR 6998
+#define uartsh_2_per_SIZE 67
+
+/*!
+* SDMA RAM image start address and size
+*/
+
+#define RAM_CODE_START_ADDR 6144
+#define RAM_CODE_SIZE 921
+
+/*!
+* Buffer that holds the SDMA RAM image
+*/
+__attribute__ ((__aligned__(4)))
+#ifndef CONFIG_XIP_KERNEL
+const
+#endif
+static const short sdma_code[] = {
+ 0xc1e3, 0x57db, 0x52fb, 0x6ac3, 0x52f3, 0x6ad7, 0x008f, 0x00d5,
+ 0x7d01, 0x008d, 0x05a0, 0x0478, 0x7d03, 0x0479, 0x7d1c, 0x7c21,
+ 0x0479, 0x7c14, 0x6ddd, 0x56ee, 0x62c8, 0x7e28, 0x0660, 0x7d02,
+ 0x0210, 0x0212, 0x6ac8, 0x7f22, 0x0212, 0x6ac8, 0x7f1f, 0x0212,
+ 0x6ac8, 0x7f1c, 0x2003, 0x4800, 0x7cef, 0x9836, 0x6ddd, 0x7802,
+ 0x62c8, 0x6ac8, 0x9835, 0x6dde, 0x0015, 0x7802, 0x62c8, 0x6ac8,
+ 0x9835, 0x0015, 0x0015, 0x7801, 0x62d8, 0x7c08, 0x6ddf, 0x7f06,
+ 0x0000, 0x4d00, 0x7d05, 0xc1fa, 0x57db, 0x9806, 0xc273, 0x0454,
+ 0xc20a, 0x9801, 0xc1d9, 0xc1e3, 0x56f3, 0x57db, 0x047a, 0x7d07,
+ 0x072f, 0x076e, 0x7d02, 0x6ec7, 0x9855, 0x6ed7, 0x9855, 0x074f,
+ 0x076e, 0x7d02, 0x6e01, 0x9855, 0x6e05, 0x5ce3, 0x048f, 0x0410,
+ 0x3c0f, 0x5c93, 0x0eff, 0x06bf, 0x06d5, 0x7d01, 0x068d, 0x05a6,
+ 0x5deb, 0x55fb, 0x008e, 0x0768, 0x7d02, 0x0769, 0x7c04, 0x06d4,
+ 0x7d01, 0x008c, 0x04a0, 0x06a0, 0x076f, 0x7d0c, 0x076e, 0x7d05,
+ 0x7802, 0x62c8, 0x5a05, 0x7c2b, 0x9887, 0x7802, 0x5205, 0x6ac8,
+ 0x7c26, 0x9887, 0x076e, 0x7d05, 0x7802, 0x620b, 0x5a05, 0x7c21,
+ 0x9887, 0x7802, 0x5205, 0x6a0b, 0x7c1c, 0x6a28, 0x7f1a, 0x0768,
+ 0x7d02, 0x0769, 0x7c0a, 0x4c00, 0x7c08, 0x0768, 0x7d03, 0x5a05,
+ 0x7f11, 0x9894, 0x5205, 0x7e0e, 0x5493, 0x4e00, 0x7ccb, 0x0000,
+ 0x54e3, 0x55eb, 0x4d00, 0x7d0a, 0xc1fa, 0x57db, 0x9856, 0x68cc,
+ 0x98a2, 0x680c, 0x009e, 0x0007, 0x54e3, 0xd8a8, 0xc20a, 0x9844,
+ 0x55eb, 0x009d, 0x058c, 0x0aff, 0x0211, 0x1aff, 0x05ba, 0x05a0,
+ 0x04b2, 0x04ad, 0x0454, 0x0006, 0x0e70, 0x0611, 0x5616, 0xc13c,
+ 0x7d2a, 0x5ade, 0x008e, 0xc14e, 0x7c26, 0x5be0, 0x5ef0, 0x5ce8,
+ 0x0688, 0x08ff, 0x0011, 0x28ff, 0x00bc, 0x53f6, 0x05df, 0x7d0b,
+ 0x6dc5, 0x03df, 0x7d03, 0x6bd5, 0xd903, 0x98df, 0x6b05, 0xc5f5,
+ 0x7e27, 0x7f29, 0x98df, 0x6d01, 0x03df, 0x7d05, 0x6bd5, 0xc61f,
+ 0x7e18, 0x7f1a, 0x98df, 0x6b05, 0xc595, 0x7e07, 0x7f06, 0x52de,
+ 0x53e6, 0xc159, 0x7dd7, 0x0200, 0x98b7, 0x0007, 0x6004, 0x680c,
+ 0x53f6, 0x028e, 0x00a3, 0xc256, 0x048b, 0x0498, 0x0454, 0x068a,
+ 0x98df, 0x0207, 0x680c, 0x6ddf, 0x0107, 0x68ff, 0x60d0, 0x98e8,
+ 0x0207, 0x68ff, 0x6d28, 0x0107, 0x6004, 0x680c, 0x98e8, 0x0007,
+ 0x68ff, 0x60d0, 0x98e8, 0x0288, 0x03a5, 0x3b03, 0x3d03, 0x4d00,
+ 0x7d0a, 0x0804, 0x00a5, 0x00da, 0x7d1a, 0x02a0, 0x7b01, 0x65d8,
+ 0x7eee, 0x65ff, 0x7eec, 0x0804, 0x02d0, 0x7d11, 0x4b00, 0x7c0f,
+ 0x008a, 0x3003, 0x6dcf, 0x6bdf, 0x0015, 0x0015, 0x7b02, 0x65d8,
+ 0x0000, 0x7edd, 0x63ff, 0x7edb, 0x3a03, 0x6dcd, 0x6bdd, 0x008a,
+ 0x7b02, 0x65d8, 0x0000, 0x7ed3, 0x65ff, 0x7ed1, 0x0006, 0xc1d9,
+ 0xc1e3, 0x57db, 0x52f3, 0x047a, 0x7d06, 0x0479, 0x7c02, 0x6ac6,
+ 0x993c, 0x6ac7, 0x993c, 0x6a01, 0x008f, 0x00d5, 0x7d01, 0x008d,
+ 0x05a0, 0x5deb, 0x56fb, 0x0478, 0x7d4e, 0x0479, 0x7c1f, 0x0015,
+ 0x0388, 0x047a, 0x7d03, 0x62c8, 0x7e39, 0x9950, 0x620a, 0x7e38,
+ 0x0808, 0x7801, 0x0217, 0x5a06, 0x7f34, 0x2301, 0x047a, 0x7d03,
+ 0x62c8, 0x7e2c, 0x995d, 0x620a, 0x7e2b, 0x0808, 0x7801, 0x0217,
+ 0x5a26, 0x7f27, 0x2301, 0x4b00, 0x7ce4, 0x997c, 0x0015, 0x0015,
+ 0x0015, 0x047a, 0x7d09, 0x7806, 0x0b00, 0x62c8, 0x5a06, 0x0b01,
+ 0x62c8, 0x5a26, 0x7c13, 0x997c, 0x7806, 0x0b00, 0x620b, 0x5a06,
+ 0x0b01, 0x620b, 0x5a26, 0x7c0c, 0x0b70, 0x0311, 0x5313, 0x0000,
+ 0x55eb, 0x4d00, 0x7d11, 0xc1fa, 0x57db, 0x993c, 0x68cc, 0x9989,
+ 0x680c, 0x0007, 0x0479, 0x7c02, 0x008b, 0x9990, 0x0017, 0x00a3,
+ 0x0b70, 0x0311, 0x5313, 0xc213, 0xc20a, 0x9931, 0x0b70, 0x0311,
+ 0x5313, 0x076c, 0x7c01, 0xc1d9, 0x5efb, 0x068a, 0x076b, 0x7c01,
+ 0xc1d9, 0x5ef3, 0x59db, 0x58d3, 0x018f, 0x0110, 0x390f, 0x008b,
+ 0xc13c, 0x7d2b, 0x5ac0, 0x5bc8, 0xc14e, 0x7c27, 0x0388, 0x0689,
+ 0x5ce3, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x073e, 0x4d00, 0x7d18,
+ 0x0870, 0x0011, 0x077e, 0x7d09, 0x077d, 0x7d02, 0x5228, 0x99c1,
+ 0x52f8, 0x54db, 0x02bc, 0x02cc, 0x7c09, 0x077c, 0x7d02, 0x5228,
+ 0x99ca, 0x52f8, 0x54d3, 0x02bc, 0x02cc, 0x7d09, 0x0400, 0x99b8,
+ 0x008b, 0x52c0, 0x53c8, 0xc159, 0x7dd6, 0x0200, 0x99a8, 0x08ff,
+ 0x00bf, 0x077f, 0x7d15, 0x0488, 0x00d5, 0x7d01, 0x008d, 0x05a0,
+ 0x5deb, 0x028f, 0x0212, 0x0212, 0x3aff, 0x05da, 0x7c02, 0x073e,
+ 0x99f3, 0x02a4, 0x02dd, 0x7d02, 0x073e, 0x99f3, 0x075e, 0x99f3,
+ 0x55eb, 0x0598, 0x5deb, 0x52f3, 0x54fb, 0x076a, 0x7d26, 0x076c,
+ 0x7d01, 0x9a30, 0x076b, 0x7c57, 0x0769, 0x7d04, 0x0768, 0x7d02,
+ 0x0e01, 0x9a0a, 0x5893, 0x00d6, 0x7d01, 0x008e, 0x5593, 0x05a0,
+ 0x5d93, 0x06a0, 0x7802, 0x5502, 0x5d04, 0x7c1d, 0x4e00, 0x7c08,
+ 0x0769, 0x7d03, 0x5502, 0x7e17, 0x9a17, 0x5d04, 0x7f14, 0x0689,
+ 0x5093, 0x4800, 0x7d01, 0x9a02, 0x9a7b, 0x0015, 0x7806, 0x5502,
+ 0x5d04, 0x074f, 0x5502, 0x5d24, 0x072f, 0x7c01, 0x9a7b, 0x0017,
+ 0x076f, 0x7c01, 0x2001, 0x5593, 0x009d, 0x0007, 0xda82, 0x99d0,
+ 0x6cd3, 0x0769, 0x7d04, 0x0768, 0x7d02, 0x0e01, 0x9a3f, 0x5893,
+ 0x00d6, 0x7d01, 0x008e, 0x5593, 0x05a0, 0x5d93, 0x06a0, 0x7802,
+ 0x5502, 0x6dc8, 0x7c0f, 0x4e00, 0x7c08, 0x0769, 0x7d03, 0x5502,
+ 0x7e09, 0x9a4c, 0x6dc8, 0x7f06, 0x0689, 0x5093, 0x4800, 0x7d01,
+ 0x9a37, 0x9a7b, 0x9a75, 0x6ac3, 0x0769, 0x7d04, 0x0768, 0x7d02,
+ 0x0e01, 0x9a62, 0x5893, 0x00d6, 0x7d01, 0x008e, 0x5593, 0x05a0,
+ 0x5d93, 0x06a0, 0x7802, 0x65c8, 0x5d04, 0x7c0f, 0x4e00, 0x7c08,
+ 0x0769, 0x7d03, 0x65c8, 0x7e09, 0x9a6f, 0x5d04, 0x7f06, 0x0689,
+ 0x5093, 0x4800, 0x7d01, 0x9a5a, 0x9a7b, 0x5593, 0x009d, 0x0007,
+ 0x6cff, 0xda82, 0x99d0, 0x0000, 0x54e3, 0x55eb, 0x4d00, 0x7c01,
+ 0x99d0, 0x99b8, 0x54e3, 0x55eb, 0x0aff, 0x0211, 0x1aff, 0x077f,
+ 0x7c02, 0x05a0, 0x9a8f, 0x009d, 0x058c, 0x05ba, 0x05a0, 0x0210,
+ 0x04ba, 0x04ad, 0x0454, 0x0006, 0xc1e3, 0x57db, 0x52f3, 0x6ac5,
+ 0x52fb, 0x6ad3, 0x008f, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5deb,
+ 0x0478, 0x7d03, 0x0479, 0x7d20, 0x7c25, 0x0479, 0x7c19, 0x59e3,
+ 0x56ee, 0x61c8, 0x7e2e, 0x62c8, 0x7e2c, 0x65c8, 0x7e2a, 0x0660,
+ 0x7d03, 0x0112, 0x0112, 0x9ab6, 0x0512, 0x0512, 0x0211, 0x02a9,
+ 0x02ad, 0x6ac8, 0x7f1e, 0x2003, 0x4800, 0x7ceb, 0x51e3, 0x9ad0,
+ 0x7802, 0x62c8, 0x6ac8, 0x9acf, 0x6dce, 0x0015, 0x7802, 0x62c8,
+ 0x6ac8, 0x9acf, 0x6dcf, 0x0015, 0x0015, 0x7801, 0x62d8, 0x7c09,
+ 0x6ddf, 0x7f07, 0x0000, 0x55eb, 0x4d00, 0x7d06, 0xc1fa, 0x57db,
+ 0x9a9a, 0x0007, 0x68ff, 0xc213, 0xc20a, 0x9a95, 0xc1d9, 0xc1e3,
+ 0x57db, 0x52f3, 0x047a, 0x7d02, 0x6ad7, 0x9ae7, 0x6a05, 0x008f,
+ 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x56fb, 0x0015, 0x0015, 0x0015,
+ 0x047a, 0x7d07, 0x7804, 0x5206, 0x6ac8, 0x5226, 0x6ac8, 0x7c0f,
+ 0x9b01, 0x7804, 0x5206, 0x6a0b, 0x5226, 0x6a0b, 0x7c0a, 0x6a28,
+ 0x7f08, 0x0000, 0x4d00, 0x7d07, 0xc1fa, 0x57db, 0x9ae7, 0xc273,
+ 0x9b0a, 0xc277, 0x0454, 0xc20a, 0x9ae0, 0xc1e3, 0x57db, 0x52f3,
+ 0x6ad5, 0x56fb, 0x028e, 0x1a94, 0x6ac3, 0x62c8, 0x0269, 0x7d1e,
+ 0x1e94, 0x6ee3, 0x62d0, 0x5aeb, 0x62c8, 0x0248, 0x6ed3, 0x6ac8,
+ 0x2694, 0x52eb, 0x6ad5, 0x6ee3, 0x62c8, 0x026e, 0x7d27, 0x6ac8,
+ 0x7f23, 0x2501, 0x4d00, 0x7d26, 0x028e, 0x1a98, 0x6ac3, 0x62c8,
+ 0x6ec3, 0x0260, 0x7df1, 0x62d0, 0xc27a, 0x9b52, 0x6ee3, 0x008f,
+ 0x2001, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x62c8, 0x026e, 0x7d0e,
+ 0x6ac8, 0x7f0a, 0x2001, 0x7cf9, 0x6add, 0x7f06, 0x0000, 0x4d00,
+ 0x7d09, 0xc1fa, 0x57db, 0x9b11, 0x0007, 0x6aff, 0x62d0, 0xc27a,
+ 0x0458, 0x0454, 0x6add, 0x7ff8, 0xc20a, 0x9b0e, 0xc1d9, 0xc1e3,
+ 0x57db, 0x52f3, 0x6ad5, 0x56fb, 0x028e, 0x1a94, 0x5202, 0x0269,
+ 0x7d17, 0x1e94, 0x5206, 0x0248, 0x5a06, 0x2694, 0x5206, 0x026e,
+ 0x7d26, 0x6ac8, 0x7f22, 0x2501, 0x4d00, 0x7d27, 0x028e, 0x1a98,
+ 0x5202, 0x0260, 0x7df3, 0x6add, 0x7f18, 0x62d0, 0xc27a, 0x9b95,
+ 0x008f, 0x2001, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5206, 0x026e,
+ 0x7d0e, 0x6ac8, 0x7f0a, 0x2001, 0x7cf9, 0x6add, 0x7f06, 0x0000,
+ 0x4d00, 0x7d0b, 0xc1fa, 0x57db, 0x9b5b, 0x0007, 0x6aff, 0x6add,
+ 0x7ffc, 0x62d0, 0xc27a, 0x0458, 0x0454, 0x6add, 0x7ff6, 0xc20a,
+ 0x9b58
+};
+#endif
diff --git a/arch/arm/mach-mx35/sdma_script_code_v2.h b/arch/arm/mach-mx35/sdma_script_code_v2.h
new file mode 100644
index 000000000000..1bd949e6c992
--- /dev/null
+++ b/arch/arm/mach-mx35/sdma_script_code_v2.h
@@ -0,0 +1,234 @@
+/*
+ * Copyright 2008 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 */
+
+/*!
+ * @file sdma_script_code.h
+ * @brief This file contains functions of SDMA scripts code initialization
+ *
+ * The file was generated automatically. Based on sdma scripts library.
+ *
+ * @ingroup SDMA
+ */
+/*******************************************************************************
+
+ SDMA RELEASE LABEL: "SDMA_RINGO.03.00.00"
+
+*******************************************************************************/
+
+#ifndef SDMA_SCRIPT_CODE_V2_H
+#define SDMA_SCRIPT_CODE_V2_H
+
+/*!
+* SDMA ROM scripts start addresses and sizes
+*/
+
+#define start_ADDR_V2 0
+#define start_SIZE_V2 24
+
+#define core_ADDR_V2 80
+#define core_SIZE_V2 233
+
+#define common_ADDR_V2 313
+#define common_SIZE_V2 416
+
+#define ap_2_ap_ADDR_V2 729
+#define ap_2_ap_SIZE_V2 41
+
+#define app_2_mcu_ADDR_V2 770
+#define app_2_mcu_SIZE_V2 64
+
+#define mcu_2_app_ADDR_V2 834
+#define mcu_2_app_SIZE_V2 70
+
+#define uart_2_mcu_ADDR_V2 904
+#define uart_2_mcu_SIZE_V2 75
+
+#define shp_2_mcu_ADDR_V2 979
+#define shp_2_mcu_SIZE_V2 69
+
+#define mcu_2_shp_ADDR_V2 1048
+#define mcu_2_shp_SIZE_V2 72
+
+#define per_2_shp_ADDR_V2 1120
+#define per_2_shp_SIZE_V2 78
+
+#define shp_2_per_ADDR_V2 1198
+#define shp_2_per_SIZE_V2 72
+
+#define uartsh_2_mcu_ADDR_V2 1270
+#define uartsh_2_mcu_SIZE_V2 69
+
+#define mcu_2_ata_ADDR_V2 1339
+#define mcu_2_ata_SIZE_V2 90
+
+#define ata_2_mcu_ADDR_V2 1429
+#define ata_2_mcu_SIZE_V2 102
+
+#define app_2_per_ADDR_V2 1531
+#define app_2_per_SIZE_V2 66
+
+#define per_2_app_ADDR_V2 1597
+#define per_2_app_SIZE_V2 74
+
+#define loop_DMAs_routines_ADDR_V2 1671
+#define loop_DMAs_routines_SIZE_V2 240
+
+#define test_ADDR_V2 1911
+#define test_SIZE_V2 63
+
+#define signature_ADDR_V2 1022
+#define signature_SIZE_V2 1
+
+/*!
+* SDMA RAM scripts start addresses and sizes
+*/
+
+#define asrc__mcu_ADDR_V2 6144
+#define asrc__mcu_SIZE_V2 116
+
+#define ext_mem__ipu_ram_ADDR_V2 6260
+#define ext_mem__ipu_ram_SIZE_V2 123
+
+#define mcu_2_spdif_ADDR_V2 6383
+#define mcu_2_spdif_SIZE_V2 103
+
+#define p_2_p_ADDR_V2 6486
+#define p_2_p_SIZE_V2 260
+
+#define spdif_2_mcu_ADDR_V2 6746
+#define spdif_2_mcu_SIZE_V2 47
+
+#define uart_2_per_ADDR_V2 6793
+#define uart_2_per_SIZE_V2 73
+
+#define uartsh_2_per_ADDR_V2 6866
+#define uartsh_2_per_SIZE_V2 67
+
+/*!
+* SDMA RAM image start address and size
+*/
+
+#define RAM_CODE_START_ADDR_V2 6144
+#define RAM_CODE_SIZE_V2 789
+
+/*!
+* Buffer that holds the SDMA RAM image
+*/
+
+static const short sdma_code_v2[] = {
+ 0xc230, 0xc23a, 0x56f3, 0x57db, 0x047a, 0x7d07, 0x072f, 0x076e,
+ 0x7d02, 0x6ec7, 0x9813, 0x6ed7, 0x9813, 0x074f, 0x076e, 0x7d02,
+ 0x6e01, 0x9813, 0x6e05, 0x5ce3, 0x048f, 0x0410, 0x3c0f, 0x5c93,
+ 0x0e03, 0x0611, 0x1eff, 0x06bf, 0x06d5, 0x7d01, 0x068d, 0x05a6,
+ 0x5deb, 0x55fb, 0x008e, 0x076a, 0x7d02, 0x076b, 0x7c04, 0x06d4,
+ 0x7d01, 0x008c, 0x04a0, 0x06a0, 0x076f, 0x7d0c, 0x076e, 0x7d05,
+ 0x7802, 0x62c8, 0x5a05, 0x7c2b, 0x9847, 0x7802, 0x5205, 0x6ac8,
+ 0x7c26, 0x9847, 0x076e, 0x7d05, 0x7802, 0x620b, 0x5a05, 0x7c21,
+ 0x9847, 0x7802, 0x5205, 0x6a0b, 0x7c1c, 0x6a28, 0x7f1a, 0x076a,
+ 0x7d02, 0x076b, 0x7c0a, 0x4c00, 0x7c08, 0x076a, 0x7d03, 0x5a05,
+ 0x7f11, 0x9854, 0x5205, 0x7e0e, 0x5493, 0x4e00, 0x7ccb, 0x0000,
+ 0x54e3, 0x55eb, 0x4d00, 0x7d0a, 0xc251, 0x57db, 0x9814, 0x68cc,
+ 0x9862, 0x680c, 0x009e, 0x0007, 0x54e3, 0xd868, 0xc261, 0x9802,
+ 0x55eb, 0x009d, 0x058c, 0x0aff, 0x0211, 0x1aff, 0x05ba, 0x05a0,
+ 0x04b2, 0x04ad, 0x0454, 0x0006, 0x0e70, 0x0611, 0x5616, 0xc18a,
+ 0x7d2a, 0x5ade, 0x008e, 0xc19c, 0x7c26, 0x5be0, 0x5ef0, 0x5ce8,
+ 0x0688, 0x08ff, 0x0011, 0x28ff, 0x00bc, 0x53f6, 0x05df, 0x7d0b,
+ 0x6dc5, 0x03df, 0x7d03, 0x6bd5, 0xd8c3, 0x989f, 0x6b05, 0xc6e7,
+ 0x7e27, 0x7f29, 0x989f, 0x6d01, 0x03df, 0x7d05, 0x6bd5, 0xc711,
+ 0x7e18, 0x7f1a, 0x989f, 0x6b05, 0xc687, 0x7e07, 0x7f06, 0x52de,
+ 0x53e6, 0xc1a8, 0x7dd7, 0x0200, 0x9877, 0x0007, 0x6004, 0x680c,
+ 0x53f6, 0x028e, 0x00a3, 0xc2ad, 0x048b, 0x0498, 0x0454, 0x068a,
+ 0x989f, 0x0207, 0x680c, 0x6ddf, 0x0107, 0x68ff, 0x60d0, 0x98a8,
+ 0x0207, 0x68ff, 0x6d28, 0x0107, 0x6004, 0x680c, 0x98a8, 0x0007,
+ 0x68ff, 0x60d0, 0x98a8, 0x0288, 0x03a5, 0x3b03, 0x3d03, 0x4d00,
+ 0x7d0a, 0x0804, 0x00a5, 0x00da, 0x7d1a, 0x02a0, 0x7b01, 0x65d8,
+ 0x7eee, 0x65ff, 0x7eec, 0x0804, 0x02d0, 0x7d11, 0x4b00, 0x7c0f,
+ 0x008a, 0x3003, 0x6dcf, 0x6bdf, 0x0015, 0x0015, 0x7b02, 0x65d8,
+ 0x0000, 0x7edd, 0x63ff, 0x7edb, 0x3a03, 0x6dcd, 0x6bdd, 0x008a,
+ 0x7b02, 0x65d8, 0x0000, 0x7ed3, 0x65ff, 0x7ed1, 0x0006, 0xc230,
+ 0xc23a, 0x57db, 0x52f3, 0x047a, 0x7d06, 0x0479, 0x7c02, 0x6ac6,
+ 0x98fc, 0x6ac7, 0x98fc, 0x6a01, 0x008f, 0x00d5, 0x7d01, 0x008d,
+ 0x05a0, 0x5deb, 0x56fb, 0x0478, 0x7d4e, 0x0479, 0x7c1f, 0x0015,
+ 0x0388, 0x047a, 0x7d03, 0x62c8, 0x7e39, 0x9910, 0x620a, 0x7e38,
+ 0x0808, 0x7801, 0x0217, 0x5a06, 0x7f34, 0x2301, 0x047a, 0x7d03,
+ 0x62c8, 0x7e2c, 0x991d, 0x620a, 0x7e2b, 0x0808, 0x7801, 0x0217,
+ 0x5a26, 0x7f27, 0x2301, 0x4b00, 0x7ce4, 0x993c, 0x0015, 0x0015,
+ 0x0015, 0x047a, 0x7d09, 0x7806, 0x0b00, 0x62c8, 0x5a06, 0x0b01,
+ 0x62c8, 0x5a26, 0x7c13, 0x993c, 0x7806, 0x0b00, 0x620b, 0x5a06,
+ 0x0b01, 0x620b, 0x5a26, 0x7c0c, 0x0b70, 0x0311, 0x5313, 0x0000,
+ 0x55eb, 0x4d00, 0x7d11, 0xc251, 0x57db, 0x98fc, 0x68cc, 0x9949,
+ 0x680c, 0x0007, 0x0479, 0x7c02, 0x008b, 0x9950, 0x0017, 0x00a3,
+ 0x0b70, 0x0311, 0x5313, 0xc26a, 0xc261, 0x98f1, 0x0b70, 0x0311,
+ 0x5313, 0x076c, 0x7c01, 0xc230, 0x5efb, 0x068a, 0x076b, 0x7c01,
+ 0xc230, 0x5ef3, 0x59db, 0x58d3, 0x018f, 0x0110, 0x390f, 0x008b,
+ 0xc18a, 0x7d2b, 0x5ac0, 0x5bc8, 0xc19c, 0x7c27, 0x0388, 0x0689,
+ 0x5ce3, 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x073e, 0x4d00, 0x7d18,
+ 0x0870, 0x0011, 0x077e, 0x7d09, 0x077d, 0x7d02, 0x5228, 0x9981,
+ 0x52f8, 0x54db, 0x02bc, 0x02cc, 0x7c09, 0x077c, 0x7d02, 0x5228,
+ 0x998a, 0x52f8, 0x54d3, 0x02bc, 0x02cc, 0x7d09, 0x0400, 0x9978,
+ 0x008b, 0x52c0, 0x53c8, 0xc1a8, 0x7dd6, 0x0200, 0x9968, 0x08ff,
+ 0x00bf, 0x077f, 0x7d1b, 0x0488, 0x00d5, 0x7d01, 0x008d, 0x05a0,
+ 0x5deb, 0x028f, 0x32ff, 0x0210, 0x32ff, 0x0210, 0x0212, 0x0217,
+ 0x0217, 0x32ff, 0x0212, 0x05da, 0x7c02, 0x073e, 0x99b9, 0x02a4,
+ 0x02dd, 0x7d02, 0x073e, 0x99b9, 0x075e, 0x99b9, 0x55eb, 0x0598,
+ 0x5deb, 0x52f3, 0x54fb, 0x076a, 0x7d26, 0x076c, 0x7d01, 0x99f6,
+ 0x076b, 0x7c57, 0x0769, 0x7d04, 0x0768, 0x7d02, 0x0e01, 0x99d0,
+ 0x5893, 0x00d6, 0x7d01, 0x008e, 0x5593, 0x05a0, 0x5d93, 0x06a0,
+ 0x7802, 0x5502, 0x5d04, 0x7c1d, 0x4e00, 0x7c08, 0x0769, 0x7d03,
+ 0x5502, 0x7e17, 0x99dd, 0x5d04, 0x7f14, 0x0689, 0x5093, 0x4800,
+ 0x7d01, 0x99c8, 0x9a41, 0x0015, 0x7806, 0x5502, 0x5d04, 0x074d,
+ 0x5502, 0x5d24, 0x072d, 0x7c01, 0x9a41, 0x0017, 0x076d, 0x7c01,
+ 0x2001, 0x5593, 0x009d, 0x0007, 0xda48, 0x9990, 0x6cd3, 0x0769,
+ 0x7d04, 0x0768, 0x7d02, 0x0e01, 0x9a05, 0x5893, 0x00d6, 0x7d01,
+ 0x008e, 0x5593, 0x05a0, 0x5d93, 0x06a0, 0x7802, 0x5502, 0x6dc8,
+ 0x7c0f, 0x4e00, 0x7c08, 0x0769, 0x7d03, 0x5502, 0x7e09, 0x9a12,
+ 0x6dc8, 0x7f06, 0x0689, 0x5093, 0x4800, 0x7d01, 0x99fd, 0x9a41,
+ 0x9a3b, 0x6ac3, 0x0769, 0x7d04, 0x0768, 0x7d02, 0x0e01, 0x9a28,
+ 0x5893, 0x00d6, 0x7d01, 0x008e, 0x5593, 0x05a0, 0x5d93, 0x06a0,
+ 0x7802, 0x65c8, 0x5d04, 0x7c0f, 0x4e00, 0x7c08, 0x0769, 0x7d03,
+ 0x65c8, 0x7e09, 0x9a35, 0x5d04, 0x7f06, 0x0689, 0x5093, 0x4800,
+ 0x7d01, 0x9a20, 0x9a41, 0x5593, 0x009d, 0x0007, 0x6cff, 0xda48,
+ 0x9990, 0x0000, 0x54e3, 0x55eb, 0x4d00, 0x7c01, 0x9990, 0x9978,
+ 0x54e3, 0x55eb, 0x0aff, 0x0211, 0x1aff, 0x077f, 0x7c02, 0x05a0,
+ 0x9a55, 0x009d, 0x058c, 0x05ba, 0x05a0, 0x0210, 0x04ba, 0x04ad,
+ 0x0454, 0x0006, 0xc230, 0xc23a, 0x57db, 0x52f3, 0x047a, 0x7d02,
+ 0x6ad7, 0x9a63, 0x6a05, 0x008f, 0x00d5, 0x7d01, 0x008d, 0x05a0,
+ 0x56fb, 0x0015, 0x0015, 0x0015, 0x047a, 0x7d07, 0x7804, 0x5206,
+ 0x6ac8, 0x5226, 0x6ac8, 0x7c0f, 0x9a7d, 0x7804, 0x5206, 0x6a0b,
+ 0x5226, 0x6a0b, 0x7c0a, 0x6a28, 0x7f08, 0x0000, 0x4d00, 0x7d07,
+ 0xc251, 0x57db, 0x9a63, 0xc2ca, 0x9a86, 0xc2ce, 0x0454, 0xc261,
+ 0x9a5c, 0xc23a, 0x57db, 0x52f3, 0x6ad5, 0x56fb, 0x028e, 0x1a94,
+ 0x6ac3, 0x62c8, 0x0269, 0x7d1e, 0x1e94, 0x6ee3, 0x62d0, 0x5aeb,
+ 0x62c8, 0x0248, 0x6ed3, 0x6ac8, 0x2694, 0x52eb, 0x6ad5, 0x6ee3,
+ 0x62c8, 0x026e, 0x7d27, 0x6ac8, 0x7f23, 0x2501, 0x4d00, 0x7d26,
+ 0x028e, 0x1a98, 0x6ac3, 0x62c8, 0x6ec3, 0x0260, 0x7df1, 0x62d0,
+ 0xc2d1, 0x9ace, 0x6ee3, 0x008f, 0x2001, 0x00d5, 0x7d01, 0x008d,
+ 0x05a0, 0x62c8, 0x026e, 0x7d0e, 0x6ac8, 0x7f0a, 0x2001, 0x7cf9,
+ 0x6add, 0x7f06, 0x0000, 0x4d00, 0x7d09, 0xc251, 0x57db, 0x9a8d,
+ 0x0007, 0x6aff, 0x62d0, 0xc2d1, 0x0458, 0x0454, 0x6add, 0x7ff8,
+ 0xc261, 0x9a8a, 0xc230, 0xc23a, 0x57db, 0x52f3, 0x6ad5, 0x56fb,
+ 0x028e, 0x1a94, 0x5202, 0x0269, 0x7d17, 0x1e94, 0x5206, 0x0248,
+ 0x5a06, 0x2694, 0x5206, 0x026e, 0x7d26, 0x6ac8, 0x7f22, 0x2501,
+ 0x4d00, 0x7d27, 0x028e, 0x1a98, 0x5202, 0x0260, 0x7df3, 0x6add,
+ 0x7f18, 0x62d0, 0xc2d1, 0x9b11, 0x008f, 0x2001, 0x00d5, 0x7d01,
+ 0x008d, 0x05a0, 0x5206, 0x026e, 0x7d0e, 0x6ac8, 0x7f0a, 0x2001,
+ 0x7cf9, 0x6add, 0x7f06, 0x0000, 0x4d00, 0x7d0b, 0xc251, 0x57db,
+ 0x9ad7, 0x0007, 0x6aff, 0x6add, 0x7ffc, 0x62d0, 0xc2d1, 0x0458,
+ 0x0454, 0x6add, 0x7ff6, 0xc261, 0x9ad4
+};
+#endif
diff --git a/arch/arm/mach-mx35/serial.c b/arch/arm/mach-mx35/serial.c
new file mode 100644
index 000000000000..37dafba6177e
--- /dev/null
+++ b/arch/arm/mach-mx35/serial.c
@@ -0,0 +1,180 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/*!
+ * @file mach-mx35/serial.c
+ *
+ * @brief This file contains the UART initiliazation.
+ *
+ * @ingroup MSL_MX35
+ */
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <mach/hardware.h>
+#include <mach/mxc_uart.h>
+#include <mach/spba.h>
+#include "serial.h"
+#include "board-mx35evb.h"
+#include "board-mx35_3stack.h"
+
+#if defined(CONFIG_SERIAL_MXC) || defined(CONFIG_SERIAL_MXC_MODULE)
+
+/*!
+ * This is an array where each element holds information about a UART port,
+ * like base address of the UART, interrupt numbers etc. This structure is
+ * passed to the serial_core.c file. Based on which UART is used, the core file
+ * passes back the appropriate port structure as an argument to the control
+ * functions.
+ */
+static uart_mxc_port mxc_ports[] = {
+ [0] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART1_BASE_ADDR),
+ .mapbase = UART1_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART1_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 0,
+ },
+ .ints_muxed = UART1_MUX_INTS,
+ .irqs = {UART1_INT2, UART1_INT3},
+ .mode = UART1_MODE,
+ .ir_mode = UART1_IR,
+ .enabled = UART1_ENABLED,
+ .hardware_flow = UART1_HW_FLOW,
+ .cts_threshold = UART1_UCR4_CTSTL,
+ .dma_enabled = UART1_DMA_ENABLE,
+ .dma_rxbuf_size = UART1_DMA_RXBUFSIZE,
+ .rx_threshold = UART1_UFCR_RXTL,
+ .tx_threshold = UART1_UFCR_TXTL,
+ .shared = UART1_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART1_TX,
+ .dma_rx_id = MXC_DMA_UART1_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ .ir_tx_inv = MXC_IRDA_TX_INV,
+ .ir_rx_inv = MXC_IRDA_RX_INV,
+ },
+ [1] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART2_BASE_ADDR),
+ .mapbase = UART2_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART2_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 1,
+ },
+ .ints_muxed = UART2_MUX_INTS,
+ .irqs = {UART2_INT2, UART2_INT3},
+ .mode = UART2_MODE,
+ .ir_mode = UART2_IR,
+ .enabled = UART2_ENABLED,
+ .hardware_flow = UART2_HW_FLOW,
+ .cts_threshold = UART2_UCR4_CTSTL,
+ .dma_enabled = UART2_DMA_ENABLE,
+ .dma_rxbuf_size = UART2_DMA_RXBUFSIZE,
+ .rx_threshold = UART2_UFCR_RXTL,
+ .tx_threshold = UART2_UFCR_TXTL,
+ .shared = UART2_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART2_TX,
+ .dma_rx_id = MXC_DMA_UART2_RX,
+ .rxd_mux = MXC_UART_IR_RXDMUX,
+ .ir_tx_inv = MXC_IRDA_TX_INV,
+ .ir_rx_inv = MXC_IRDA_RX_INV,
+ },
+#if UART3_ENABLED == 1
+ [2] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART3_BASE_ADDR),
+ .mapbase = UART3_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART3_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 2,
+ },
+ .ints_muxed = UART3_MUX_INTS,
+ .irqs = {UART3_INT2, UART3_INT3},
+ .mode = UART3_MODE,
+ .ir_mode = UART3_IR,
+ .enabled = UART3_ENABLED,
+ .hardware_flow = UART3_HW_FLOW,
+ .cts_threshold = UART3_UCR4_CTSTL,
+ .dma_enabled = UART3_DMA_ENABLE,
+ .dma_rxbuf_size = UART3_DMA_RXBUFSIZE,
+ .rx_threshold = UART3_UFCR_RXTL,
+ .tx_threshold = UART3_UFCR_TXTL,
+ .shared = UART3_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART3_TX,
+ .dma_rx_id = MXC_DMA_UART3_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ .ir_tx_inv = MXC_IRDA_TX_INV,
+ .ir_rx_inv = MXC_IRDA_RX_INV,
+ },
+#endif
+};
+
+static struct platform_device mxc_uart_device1 = {
+ .name = "mxcintuart",
+ .id = 0,
+ .dev = {
+ .platform_data = &mxc_ports[0],
+ },
+};
+
+static struct platform_device mxc_uart_device2 = {
+ .name = "mxcintuart",
+ .id = 1,
+ .dev = {
+ .platform_data = &mxc_ports[1],
+ },
+};
+
+#if UART3_ENABLED == 1
+static struct platform_device mxc_uart_device3 = {
+ .name = "mxcintuart",
+ .id = 2,
+ .dev = {
+ .platform_data = &mxc_ports[2],
+ },
+};
+#endif
+
+static int __init mxc_init_uart(void)
+{
+ /* Register all the MXC UART platform device structures */
+ platform_device_register(&mxc_uart_device1);
+ platform_device_register(&mxc_uart_device2);
+
+ /* Grab ownership of shared UARTs 3 and 4, only when enabled */
+#if UART3_ENABLED == 1
+#if UART3_DMA_ENABLE == 1
+ spba_take_ownership(UART3_SHARED_PERI, (SPBA_MASTER_A | SPBA_MASTER_C));
+#else
+ spba_take_ownership(UART3_SHARED_PERI, SPBA_MASTER_A);
+#endif /* UART3_DMA_ENABLE */
+ platform_device_register(&mxc_uart_device3);
+#endif /* UART3_ENABLED */
+
+ return 0;
+}
+
+#else
+static int __init mxc_init_uart(void)
+{
+ return 0;
+}
+#endif
+
+arch_initcall(mxc_init_uart);
diff --git a/arch/arm/mach-mx35/serial.h b/arch/arm/mach-mx35/serial.h
new file mode 100644
index 000000000000..467a4a437525
--- /dev/null
+++ b/arch/arm/mach-mx35/serial.h
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ARCH_ARM_MACH_MX35_SERIAL_H__
+#define __ARCH_ARM_MACH_MX35_SERIAL_H__
+
+/*!
+ * @file mach-mx35/serial.h
+ *
+ * @ingroup MSL_MX35
+ */
+#include <mach/mxc_uart.h>
+
+/* UART 1 configuration */
+/*!
+ * This option allows to choose either an interrupt-driven software controlled
+ * hardware flow control (set this option to 0) or hardware-driven hardware
+ * flow control (set this option to 1).
+ */
+#define UART1_HW_FLOW 1
+/*!
+ * This specifies the threshold at which the CTS pin is deasserted by the
+ * RXFIFO. Set this value in Decimal to anything from 0 to 32 for
+ * hardware-driven hardware flow control. Read the HW spec while specifying
+ * this value. When using interrupt-driven software controlled hardware
+ * flow control set this option to -1.
+ */
+#define UART1_UCR4_CTSTL 16
+/*!
+ * This is option to enable (set this option to 1) or disable DMA data transfer
+ */
+#define UART1_DMA_ENABLE 0
+/*!
+ * Specify the size of the DMA receive buffer. The minimum buffer size is 512
+ * bytes. The buffer size should be a multiple of 256.
+ */
+#define UART1_DMA_RXBUFSIZE 1024
+/*!
+ * Specify the MXC UART's Receive Trigger Level. This controls the threshold at
+ * which a maskable interrupt is generated by the RxFIFO. Set this value in
+ * Decimal to anything from 0 to 32. Read the HW spec while specifying this
+ * value.
+ */
+#define UART1_UFCR_RXTL 16
+/*!
+ * Specify the MXC UART's Transmit Trigger Level. This controls the threshold at
+ * which a maskable interrupt is generated by the TxFIFO. Set this value in
+ * Decimal to anything from 0 to 32. Read the HW spec while specifying this
+ * value.
+ */
+#define UART1_UFCR_TXTL 16
+/* UART 2 configuration */
+#define UART2_HW_FLOW 1
+#define UART2_UCR4_CTSTL 16
+#define UART2_DMA_ENABLE 0
+#define UART2_DMA_RXBUFSIZE 1024
+#define UART2_UFCR_RXTL 16
+#define UART2_UFCR_TXTL 16
+/* UART 3 configuration */
+#define UART3_HW_FLOW 1
+#define UART3_UCR4_CTSTL 16
+#define UART3_DMA_ENABLE 1
+#define UART3_DMA_RXBUFSIZE 1024
+#define UART3_UFCR_RXTL 16
+#define UART3_UFCR_TXTL 16
+
+/*
+ * UART Chip level Configuration that a user may not have to edit. These
+ * configuration vary depending on how the UART module is integrated with
+ * the ARM core
+ */
+/*
+ * Is the MUXED interrupt output sent to the ARM core
+ */
+#define INTS_NOTMUXED 0
+#define INTS_MUXED 1
+/* UART 1 configuration */
+/*!
+ * This define specifies whether the muxed ANDed interrupt line or the
+ * individual interrupts from the UART port is integrated with the ARM core.
+ * There exists a define like this for each UART port. Valid values that can
+ * be used are \b INTS_NOTMUXED or \b INTS_MUXED.
+ */
+#define UART1_MUX_INTS INTS_MUXED
+/*!
+ * This define specifies the transmitter interrupt number or the interrupt
+ * number of the ANDed interrupt in case the interrupts are muxed. There exists
+ * a define like this for each UART port.
+ */
+#define UART1_INT1 MXC_INT_UART1
+/*!
+ * This define specifies the receiver interrupt number. If the interrupts of
+ * the UART are muxed, then we specify here a dummy value -1. There exists a
+ * define like this for each UART port.
+ */
+#define UART1_INT2 -1
+/*!
+ * This specifies the master interrupt number. If the interrupts of the UART
+ * are muxed, then we specify here a dummy value of -1. There exists a define
+ * like this for each UART port.
+ */
+#define UART1_INT3 -1
+/*!
+ * This specifies if the UART is a shared peripheral. It holds the shared
+ * peripheral number if it is shared or -1 if it is not shared. There exists
+ * a define like this for each UART port.
+ */
+#define UART1_SHARED_PERI -1
+/* UART 2 configuration */
+#define UART2_MUX_INTS INTS_MUXED
+#define UART2_INT1 MXC_INT_UART2
+#define UART2_INT2 -1
+#define UART2_INT3 -1
+#define UART2_SHARED_PERI -1
+/* UART 3 configuration */
+#define UART3_MUX_INTS INTS_MUXED
+#define UART3_INT1 MXC_INT_UART3
+#define UART3_INT2 -1
+#define UART3_INT3 -1
+#define UART3_SHARED_PERI SPBA_UART3
+
+#endif /* __ARCH_ARM_MACH_MX35_SERIAL_H__ */
diff --git a/arch/arm/mach-mx35/system.c b/arch/arm/mach-mx35/system.c
new file mode 100644
index 000000000000..22daf58817bd
--- /dev/null
+++ b/arch/arm/mach-mx35/system.c
@@ -0,0 +1,126 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include "crm_regs.h"
+
+/*!
+ * @defgroup MSL_MX35 i.MX35 Machine Specific Layer (MSL)
+ */
+
+/*!
+ * @file mach-mx35/system.c
+ * @brief This file contains idle and reset functions.
+ *
+ * @ingroup MSL_MX35
+ */
+
+/*!
+* MX35 low-power mode
+*/
+enum mx35_low_pwr_mode {
+ MX35_RUN_MODE,
+ MX35_WAIT_MODE,
+ MX35_DOZE_MODE,
+ MX35_STOP_MODE
+};
+
+extern int mxc_jtag_enabled;
+
+/*!
+ * This function is used to set cpu low power mode before WFI instruction
+ *
+ * @param mode indicates different kinds of power modes
+ */
+void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
+{
+ unsigned int lpm;
+ unsigned long reg;
+
+ /*read CCMR value */
+ reg = __raw_readl(MXC_CCM_CCMR);
+
+ switch (mode) {
+ case WAIT_UNCLOCKED_POWER_OFF:
+ lpm = MX35_DOZE_MODE;
+ break;
+
+ case STOP_POWER_ON:
+ case STOP_POWER_OFF:
+ lpm = MX35_STOP_MODE;
+ /* Enabled Well Bias */
+ reg |= MXC_CCM_CCMR_WBEN;
+ if (board_is_mx35(BOARD_REV_2))
+ reg |= MXC_CCM_CCMR_VSTBY;
+ break;
+
+ case WAIT_CLOCKED:
+ case WAIT_UNCLOCKED:
+ default:
+ /* Wait is the default mode used when idle. */
+ lpm = MX35_WAIT_MODE;
+ break;
+ }
+
+ /* program LPM bit */
+ reg = (reg & (~MXC_CCM_CCMR_LPM_MASK)) | lpm << MXC_CCM_CCMR_LPM_OFFSET;
+ /* program Interrupt holdoff bit */
+ reg = reg | MXC_CCM_CCMR_WFI;
+ /* TBD: PMIC has put the voltage back to Normal if the voltage ready */
+ /* counter finished */
+ reg = reg | MXC_CCM_CCMR_STBY_EXIT_SRC;
+
+ __raw_writel(reg, MXC_CCM_CCMR);
+}
+
+EXPORT_SYMBOL(mxc_cpu_lp_set);
+
+/*!
+ * This function puts the CPU into idle mode. It is called by default_idle()
+ * in process.c file.
+ */
+void arch_idle(void)
+{
+ /*
+ * This should do all the clock switching
+ * and wait for interrupt tricks.
+ */
+ if (!mxc_jtag_enabled) {
+#ifdef CONFIG_MX35_DOZE_DURING_IDLE
+ /*set as Doze mode */
+ mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+#else
+ /* set as Wait mode */
+ mxc_cpu_lp_set(WAIT_UNCLOCKED);
+#endif
+ cpu_do_idle();
+ }
+}
+
+/*
+ * This function resets the system. It is called by machine_restart().
+ *
+ * @param mode indicates different kinds of resets
+ */
+void arch_reset(char mode)
+{
+ /* Assert SRS signal */
+ mxc_wd_reset();
+}
diff --git a/arch/arm/mach-mx35/usb.h b/arch/arm/mach-mx35/usb.h
new file mode 100644
index 000000000000..52b6f803bb50
--- /dev/null
+++ b/arch/arm/mach-mx35/usb.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2005-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+
+extern int usbotg_init(struct platform_device *pdev);
+extern void usbotg_uninit(struct fsl_usb2_platform_data *pdata);
+extern struct platform_device *host_pdev_register(struct resource *res,
+ int n_res, struct fsl_usb2_platform_data *config);
+
+extern int fsl_usb_host_init(struct platform_device *pdev);
+extern void fsl_usb_host_uninit(struct fsl_usb2_platform_data *pdata);
+extern int gpio_usbh2_active(void);
+extern void gpio_usbh2_inactive(void);
+extern int gpio_usbotg_utmi_active(void);
+extern void gpio_usbotg_utmi_inactive(void);
+
+/*
+ * Determine which platform_data struct to use for the DR controller,
+ * based on which transceiver is configured.
+ * PDATA is a pointer to it.
+ */
+static struct fsl_usb2_platform_data __maybe_unused dr_utmi_config;
+#define PDATA (&dr_utmi_config)
+
+
+/*
+ * Used to set pdata->operating_mode before registering the platform_device.
+ * If OTG is configured, the controller operates in OTG mode,
+ * otherwise it's either host or device.
+ */
+#ifdef CONFIG_USB_OTG
+#define DR_UDC_MODE FSL_USB2_DR_OTG
+#define DR_HOST_MODE FSL_USB2_DR_OTG
+#else
+#define DR_UDC_MODE FSL_USB2_DR_DEVICE
+#define DR_HOST_MODE FSL_USB2_DR_HOST
+#endif
+
+
+#ifdef CONFIG_USB_EHCI_ARC_OTG
+static inline void dr_register_host(struct resource *r, int rs)
+{
+ PDATA->operating_mode = DR_HOST_MODE;
+ host_pdev_register(r, rs, PDATA);
+}
+#else
+static inline void dr_register_host(struct resource *r, int rs)
+{
+}
+#endif
+
+#ifdef CONFIG_USB_GADGET_ARC
+static struct platform_device dr_udc_device;
+
+static inline void dr_register_udc(void)
+{
+ PDATA->operating_mode = DR_UDC_MODE;
+ dr_udc_device.dev.platform_data = PDATA;
+
+ if (platform_device_register(&dr_udc_device))
+ printk(KERN_ERR "usb: can't register DR gadget\n");
+ else
+ printk(KERN_INFO "usb: DR gadget (%s) registered\n",
+ PDATA->transceiver);
+}
+#else
+static inline void dr_register_udc(void)
+{
+}
+#endif
+
+#ifdef CONFIG_USB_OTG
+static struct platform_device dr_otg_device;
+
+/*
+ * set the proper operating_mode and
+ * platform_data pointer, then register the
+ * device.
+ */
+static inline void dr_register_otg(void)
+{
+ PDATA->operating_mode = FSL_USB2_DR_OTG;
+ dr_otg_device.dev.platform_data = PDATA;
+
+ if (platform_device_register(&dr_otg_device))
+ printk(KERN_ERR "usb: can't register otg device\n");
+ else
+ printk(KERN_INFO "usb: DR OTG registered\n");
+}
+#else
+static inline void dr_register_otg(void)
+{
+}
+#endif
diff --git a/arch/arm/mach-mx35/usb_dr.c b/arch/arm/mach-mx35/usb_dr.c
new file mode 100644
index 000000000000..72ba040d9a62
--- /dev/null
+++ b/arch/arm/mach-mx35/usb_dr.c
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <mach/arc_otg.h>
+#include "usb.h"
+
+/*
+ * platform data structs
+ * - Which one to use is determined by CONFIG options in usb.h
+ * - operating_mode plugged at run time
+ */
+static struct fsl_usb2_platform_data __maybe_unused dr_utmi_config = {
+ .name = "DR",
+ .platform_init = usbotg_init,
+ .platform_uninit = usbotg_uninit,
+ .phy_mode = FSL_USB2_PHY_UTMI_WIDE,
+ .power_budget = 500, /* 500 mA max power */
+ .gpio_usb_active = gpio_usbotg_utmi_active,
+ .gpio_usb_inactive = gpio_usbotg_utmi_inactive,
+ .transceiver = "utmi",
+};
+
+
+/*
+ * resources
+ */
+static struct resource otg_resources[] = {
+ [0] = {
+ .start = (u32)(USB_OTGREGS_BASE),
+ .end = (u32)(USB_OTGREGS_BASE + 0x1ff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_USB_OTG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+static u64 dr_udc_dmamask = ~(u32) 0;
+static void dr_udc_release(struct device *dev)
+{
+}
+
+static u64 dr_otg_dmamask = ~(u32) 0;
+static void dr_otg_release(struct device *dev)
+{
+}
+
+/*
+ * platform device structs
+ * dev.platform_data field plugged at run time
+ */
+static struct platform_device __maybe_unused dr_udc_device = {
+ .name = "fsl-usb2-udc",
+ .id = -1,
+ .dev = {
+ .release = dr_udc_release,
+ .dma_mask = &dr_udc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .resource = otg_resources,
+ .num_resources = ARRAY_SIZE(otg_resources),
+};
+
+static struct platform_device __maybe_unused dr_otg_device = {
+ .name = "fsl-usb2-otg",
+ .id = -1,
+ .dev = {
+ .release = dr_otg_release,
+ .dma_mask = &dr_otg_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .resource = otg_resources,
+ .num_resources = ARRAY_SIZE(otg_resources),
+};
+
+static int __init usb_dr_init(void)
+{
+ pr_debug("%s: \n", __func__);
+
+ /* i.MX35 1.0 should work in INCR mode */
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 0) {
+ PDATA->change_ahb_burst = 1;
+ PDATA->ahb_burst_mode = 0;
+ }
+
+ dr_register_otg();
+ dr_register_host(otg_resources, ARRAY_SIZE(otg_resources));
+ dr_register_udc();
+
+ return 0;
+}
+
+module_init(usb_dr_init);
diff --git a/arch/arm/mach-mx35/usb_h2.c b/arch/arm/mach-mx35/usb_h2.c
new file mode 100644
index 000000000000..d78deb09bf2a
--- /dev/null
+++ b/arch/arm/mach-mx35/usb_h2.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/usb/fsl_xcvr.h>
+
+#include <mach/arc_otg.h>
+#include "usb.h"
+
+static struct fsl_usb2_platform_data usbh2_config = {
+ .name = "Host 2",
+ .platform_init = fsl_usb_host_init,
+ .platform_uninit = fsl_usb_host_uninit,
+ .operating_mode = FSL_USB2_MPH_HOST,
+ .phy_mode = FSL_USB2_PHY_SERIAL,
+ .power_budget = 500, /* 500 mA max power */
+ .gpio_usb_active = gpio_usbh2_active,
+ .gpio_usb_inactive = gpio_usbh2_inactive,
+ .transceiver = "serial",
+};
+
+static struct resource usbh2_resources[] = {
+ [0] = {
+ .start = (u32) (USB_H2REGS_BASE),
+ .end = (u32) (USB_H2REGS_BASE + 0x1ff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_USB_HS,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+static int __init usbh2_init(void)
+{
+ pr_debug("%s: \n", __func__);
+
+ /* i.MX35 1.0 should work in INCR mode */
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 0) {
+ usbh2_config.change_ahb_burst = 1;
+ usbh2_config.ahb_burst_mode = 0;
+ }
+
+ host_pdev_register(usbh2_resources, ARRAY_SIZE(usbh2_resources),
+ &usbh2_config);
+ return 0;
+}
+module_init(usbh2_init);
diff --git a/arch/arm/mach-mx37/Kconfig b/arch/arm/mach-mx37/Kconfig
new file mode 100644
index 000000000000..2905ae42916d
--- /dev/null
+++ b/arch/arm/mach-mx37/Kconfig
@@ -0,0 +1,89 @@
+menu "MX37 Options"
+ depends on ARCH_MX37
+
+config MX37_OPTIONS
+ bool
+ default y
+ select CPU_V6
+ select ARM_ERRATA_411920
+ select CACHE_L2X0
+ select OUTER_CACHE
+ select USB_ARCH_HAS_EHCI
+ select ARCH_HAS_EVTMON
+ select MXC_TZIC
+
+config MACH_MX37_3DS
+ bool "Support MX37 3-Stack platforms"
+ default y
+ help
+ Include support for MX37 3-Stack platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MXC_SDMA_API
+ bool "Use SDMA API"
+ default y
+ help
+ This selects the Freescale MXC SDMA API.
+ If unsure, say N.
+
+menu "SDMA options"
+ depends on MXC_SDMA_API
+
+config SDMA_IRAM
+ bool "Use Internal RAM for SDMA transfer"
+ default n
+ help
+ Support Internal RAM as SDMA buffer or control structures
+
+config SDMA_IRAM_SIZE
+ hex "Reserved bytes of IRAM for SDMA (0x800-0x1000)"
+ range 0x800 0x1000
+ depends on SDMA_IRAM
+ default "0x1000"
+ help
+ Set the size of IRAM for SDMA. It must be a multiple of 512bytes.
+endmenu
+
+config ARCH_MXC_HAS_NFC_V3
+ bool "MXC NFC Hardware Version 3"
+ depends on ARCH_MX37
+ default y
+ help
+ This selects the Freescale MXC Nand Flash Controller Hardware Version 3
+ If unsure, say N.
+
+config ARCH_MXC_HAS_NFC_V3_1
+ bool "MXC NFC Hardware Version 3.1"
+ depends on ARCH_MXC_HAS_NFC_V3
+ default y
+ help
+ This selects the Freescale MXC Nand Flash Controller Hardware Version 3.1
+ If unsure, say N.
+
+menu "Device options"
+
+config I2C_MXC_SELECT1
+ bool "Enable I2C1 module"
+ default y
+ depends on I2C_MXC
+ help
+ Enable MX37 I2C1 module.
+
+config I2C_MXC_SELECT2
+ bool "Enable I2C2 module"
+ default n
+ depends on I2C_MXC
+ help
+ Enable MX37 I2C2 module.
+
+config I2C_MXC_SELECT3
+ bool "Enable I2C3 module"
+ default n
+ depends on I2C_MXC
+ help
+ Enable MX37 I2C3 module.
+
+endmenu
+
+endmenu
+
diff --git a/arch/arm/mach-mx37/Makefile b/arch/arm/mach-mx37/Makefile
new file mode 100644
index 000000000000..87d2b4f0c746
--- /dev/null
+++ b/arch/arm/mach-mx37/Makefile
@@ -0,0 +1,19 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+obj-y := system.o iomux.o cpu.o mm.o clock.o devices.o serial.o dma.o lpmodes.o dptc.o
+
+
+obj-$(CONFIG_MACH_MX37_3DS) += mx37_3stack.o mx37_3stack_gpio.o
+obj-$(CONFIG_SPI_MXC) += mx37_3stack_cpld.o
+obj-$(CONFIG_REGULATOR_WM8350) += mx37_3stack_pmic_wm8350.o
+
+# power management
+obj-$(CONFIG_PM) += pm.o
+
+ifneq ($(strip $(CONFIG_USB_GADGET_ARC) $(CONFIG_USB_EHCI_ARC_OTG)),)
+ obj-y += usb_dr.o
+endif
diff --git a/arch/arm/mach-mx37/Makefile.boot b/arch/arm/mach-mx37/Makefile.boot
new file mode 100644
index 000000000000..1568ad404d59
--- /dev/null
+++ b/arch/arm/mach-mx37/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x40008000
+params_phys-y := 0x40000100
+initrd_phys-y := 0x40800000
diff --git a/arch/arm/mach-mx37/board-mx37_3stack.h b/arch/arm/mach-mx37/board-mx37_3stack.h
new file mode 100644
index 000000000000..82eee4d47476
--- /dev/null
+++ b/arch/arm/mach-mx37/board-mx37_3stack.h
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX37_3STACK_H__
+#define __ASM_ARCH_MXC_BOARD_MX37_3STACK_H__
+
+/*!
+ * @defgroup BRDCFG_MX37 Board Configuration Options
+ * @ingroup MSL_MX37
+ */
+
+/*!
+ * @file mach-mx37/board-mx37_3stack.h
+ *
+ * @brief This file contains all the board level configuration options.
+ *
+ * It currently hold the options defined for MX31 ADS Platform.
+ *
+ * @ingroup BRDCFG_MX37
+ */
+
+/*
+ * Include Files
+ */
+#include <mach/mxc_uart.h>
+#include <mach/mxc_dptc.h>
+
+/*!
+ * @name MXC UART EVB board level configurations
+ */
+/*! @{ */
+/*!
+ * Specifies if the Irda transmit path is inverting
+ */
+#define MXC_IRDA_TX_INV 0
+/*!
+ * Specifies if the Irda receive path is inverting
+ */
+#define MXC_IRDA_RX_INV 0
+
+/* UART 1 configuration */
+/*!
+ * This define specifies if the UART port is configured to be in DTE or
+ * DCE mode. There exists a define like this for each UART port. Valid
+ * values that can be used are \b MODE_DTE or \b MODE_DCE.
+ */
+#define UART1_MODE MODE_DCE
+/*!
+ * This define specifies if the UART is to be used for IRDA. There exists a
+ * define like this for each UART port. Valid values that can be used are
+ * \b IRDA or \b NO_IRDA.
+ */
+#define UART1_IR NO_IRDA
+/*!
+ * This define is used to enable or disable a particular UART port. If
+ * disabled, the UART will not be registered in the file system and the user
+ * will not be able to access it. There exists a define like this for each UART
+ * port. Specify a value of 1 to enable the UART and 0 to disable it.
+ */
+#define UART1_ENABLED 1
+/*! @} */
+/* UART 2 configuration */
+#define UART2_MODE MODE_DCE
+#define UART2_IR NO_IRDA
+#define UART2_ENABLED 1
+/* UART 3 configuration */
+#define UART3_MODE MODE_DCE
+#define UART3_IR NO_IRDA
+#define UART3_ENABLED 1
+
+#define MXC_LL_UART_PADDR UART1_BASE_ADDR
+#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
+
+#define DEBUG_BASE_ADDRESS 0x78000000 /* Use a Dummy base address */
+/* LAN9217 ethernet base address */
+#define LAN9217_BASE_ADDR DEBUG_BASE_ADDRESS
+/* External UART */
+#define UARTA_BASE_ADDR (DEBUG_BASE_ADDRESS + 0x8000)
+#define UARTB_BASE_ADDR (DEBUG_BASE_ADDRESS + 0x10000)
+
+#define BOARD_IO_ADDR 0x20000
+/* LED switchs */
+#define LED_SWITCH_REG BOARD_IO_ADDR + 0x00
+/* buttons */
+#define SWITCH_BUTTONS_REG BOARD_IO_ADDR + 0x08
+/* status, interrupt */
+#define INTR_STATUS_REG BOARD_IO_ADDR + 0x10
+#define INTR_MASK_REG BOARD_IO_ADDR + 0x38
+#define INTR_RESET_REG BOARD_IO_ADDR + 0x20
+/* magic word for debug CPLD */
+#define MAGIC_NUMBER1_REG BOARD_IO_ADDR + 0x40
+#define MAGIC_NUMBER2_REG BOARD_IO_ADDR + 0x48
+/* CPLD code version */
+#define CPLD_CODE_VER_REG BOARD_IO_ADDR + 0x50
+
+extern unsigned int sdhc_get_card_det_status(struct device *dev);
+extern int sdhc_write_protect(struct device *dev);
+extern int sdhc_init_card_det(int id);
+extern struct tve_platform_data tve_data;
+extern struct mxc_dptc_data dptc_lp_data;
+extern struct mxc_dptc_data dptc_gp_data;
+extern struct mxc_dvfs_platform_data dvfs_core_data;
+extern char *gp_reg_id;
+extern char *lp_reg_id;
+
+extern int headphone_det_status(void);
+#endif /* __ASM_ARCH_MXC_BOARD_MX37_3STACK_H__ */
diff --git a/arch/arm/mach-mx37/clock.c b/arch/arm/mach-mx37/clock.c
new file mode 100644
index 000000000000..35fa2d782140
--- /dev/null
+++ b/arch/arm/mach-mx37/clock.c
@@ -0,0 +1,2992 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <asm/div64.h>
+#include <mach/hardware.h>
+#include <mach/clock.h>
+#include <mach/mxc_dptc.h>
+#include <mach/spba.h>
+#include <mach/mxc_uart.h>
+
+#include "crm_regs.h"
+#include "iomux.h"
+
+extern int mxc_jtag_enabled;
+
+static unsigned long pll_base[] = {
+ (unsigned long)MXC_DPLL1_BASE,
+ (unsigned long)MXC_DPLL2_BASE,
+ (unsigned long)MXC_DPLL3_BASE,
+};
+
+static struct clk pll1_main_clk;
+static struct clk pll1_sw_clk;
+static struct clk pll2_sw_clk;
+static struct clk pll3_sw_clk;
+static struct clk lp_apm_clk;
+static struct clk emi_core_clk;
+static struct clk emi_fast_clk;
+static struct clk emi_slow_clk;
+static struct clk emi_intr_clk;
+static struct clk ddr_clk;
+static struct clk ipu_clk[];
+static struct clk axi_a_clk;
+static struct clk axi_b_clk;
+static struct clk axi_c_clk;
+static int cpu_curr_wp;
+static struct cpu_wp *cpu_wp_tbl;
+
+int cpu_wp_nr;
+
+extern void propagate_rate(struct clk *tclk);
+extern void board_ref_clk_rate(unsigned long *ckil, unsigned long *osc,
+ unsigned long *ckih);
+static int cpu_clk_set_wp(int wp);
+
+static int _clk_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg |= MXC_CCM_CCGR_CG_MASK << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void _clk_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGR_CG_MASK << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static void _clk_disable_inwait(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGR_CG_MASK << clk->enable_shift);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+}
+
+/*
+ * For the 4-to-1 muxed input clock
+ */
+static inline u32 _get_mux(struct clk *parent, struct clk *m0,
+ struct clk *m1, struct clk *m2, struct clk *m3)
+{
+ if (parent == m0) {
+ return 0;
+ } else if (parent == m1) {
+ return 1;
+ } else if (parent == m2) {
+ return 2;
+ } else if (parent == m3) {
+ return 3;
+ } else {
+ BUG();
+ }
+ return 0;
+}
+
+static inline unsigned long _get_pll_base(struct clk *pll)
+{
+ if (pll == &pll1_main_clk) {
+ return pll_base[0];
+ } else if (pll == &pll2_sw_clk) {
+ return pll_base[1];
+ } else if (pll == &pll3_sw_clk) {
+ return pll_base[2];
+ } else {
+ BUG();
+ }
+ return 0;
+}
+
+static struct clk ckih_clk = {
+ .name = "ckih",
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk osc_clk = {
+ .name = "osc",
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk ckil_clk = {
+ .name = "ckil",
+ .flags = RATE_PROPAGATES,
+};
+
+static void _fpm_recalc(struct clk *clk)
+{
+ clk->rate = ckil_clk.rate * 512;
+ if ((__raw_readl(MXC_CCM_CCR) & MXC_CCM_CCR_FPM_MULT_MASK) != 0) {
+ clk->rate *= 2;
+ }
+}
+
+static int _fpm_enable(struct clk *clk)
+{
+ u32 reg = __raw_readl(MXC_CCM_CCR);
+ reg |= MXC_CCM_CCR_FPM_EN;
+ __raw_writel(reg, MXC_CCM_CCR);
+ return 0;
+}
+
+static void _fpm_disable(struct clk *clk)
+{
+ u32 reg = __raw_readl(MXC_CCM_CCR);
+ reg &= ~MXC_CCM_CCR_FPM_EN;
+ __raw_writel(reg, MXC_CCM_CCR);
+}
+
+static struct clk fpm_clk = {
+ .name = "fpm_clk",
+ .parent = &ckil_clk,
+ .recalc = _fpm_recalc,
+ .enable = _fpm_enable,
+ .disable = _fpm_disable,
+ .flags = RATE_PROPAGATES,
+};
+
+static void _fpm_div2_recalc(struct clk *clk)
+{
+ clk->rate = clk->parent->rate / 2;
+}
+
+static struct clk fpm_div2_clk = {
+ .name = "fpm_div2_clk",
+ .parent = &fpm_clk,
+ .recalc = _fpm_div2_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static void _clk_pll_recalc(struct clk *clk)
+{
+ long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+ unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
+ unsigned long pllbase;
+ s64 temp;
+
+ pllbase = _get_pll_base(clk);
+
+ dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+ dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
+
+ if (pll_hfsm == 0) {
+ dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
+ dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
+ dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
+ } else {
+ dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
+ dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
+ dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
+ }
+ pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
+ mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
+ mfi = (mfi <= 5) ? 5 : mfi;
+ mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
+ mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
+ /* Sign extend to 32-bits */
+ if (mfn >= 0x04000000) {
+ mfn |= 0xFC000000;
+ mfn_abs = -mfn;
+ }
+
+ ref_clk = 2 * clk->parent->rate;
+ if (dbl != 0) {
+ ref_clk *= 2;
+ }
+ ref_clk /= (pdf + 1);
+ temp = (u64) ref_clk *mfn_abs;
+ do_div(temp, mfd + 1);
+ if (mfn < 0)
+ temp = -temp;
+ temp = (ref_clk * mfi) + temp;
+
+ clk->rate = temp;
+}
+
+static int _clk_pll_enable(struct clk *clk)
+{
+ u32 reg;
+ u32 pllbase;
+
+ pllbase = _get_pll_base(clk);
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+
+ /* Wait for lock */
+ while (!(__raw_readl(pllbase + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_LRF)) ;
+
+ return 0;
+}
+
+static void _clk_pll_disable(struct clk *clk)
+{
+ u32 reg;
+ u32 pllbase;
+
+ pllbase = _get_pll_base(clk);
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+}
+
+static struct clk pll1_main_clk = {
+ .name = "pll1_main_clk",
+ .parent = &osc_clk,
+ .recalc = _clk_pll_recalc,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .flags = RATE_PROPAGATES,
+};
+
+static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ if (parent == &pll1_main_clk) {
+ reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ } else {
+ mux = _get_mux(parent, &lp_apm_clk, NULL, &pll2_sw_clk,
+ &pll3_sw_clk);
+ reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
+ (mux << MXC_CCM_CCSR_STEP_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CCSR);
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ }
+ __raw_writel(reg, MXC_CCM_CCSR);
+ return 0;
+}
+
+static void _clk_pll1_sw_recalc(struct clk *clk)
+{
+ u32 reg, div;
+ div = 1;
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ if (clk->parent == &pll2_sw_clk) {
+ div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >>
+ MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1;
+ } else if (clk->parent == &pll3_sw_clk) {
+ div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >>
+ MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1;
+ }
+ clk->rate = clk->parent->rate / div;
+}
+
+/* pll1 switch clock */
+static struct clk pll1_sw_clk = {
+ .name = "pll1_sw_clk",
+ .parent = &pll1_main_clk,
+ .set_parent = _clk_pll1_sw_set_parent,
+ .recalc = _clk_pll1_sw_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+/* same as pll2_main_clk. These two clocks should always be the same */
+static struct clk pll2_sw_clk = {
+ .name = "pll2",
+ .parent = &osc_clk,
+ .recalc = _clk_pll_recalc,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .flags = RATE_PROPAGATES,
+};
+
+/* same as pll3_main_clk. These two clocks should always be the same */
+static struct clk pll3_sw_clk = {
+ .name = "pll3",
+ .parent = &osc_clk,
+ .recalc = _clk_pll_recalc,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk gpc_dvfs_clk = {
+ .name = "gpc_dvfs_clk",
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG15_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ if (parent == &osc_clk) {
+ reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL;
+ } else if (parent == &fpm_clk) {
+ reg = __raw_readl(MXC_CCM_CCSR) | MXC_CCM_CCSR_LP_APM_SEL;
+ } else {
+ return -EINVAL;
+ }
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ return 0;
+}
+
+static struct clk lp_apm_clk = {
+ .name = "lp_apm",
+ .parent = &osc_clk,
+ .set_parent = _clk_lp_apm_set_parent,
+ .flags = RATE_PROPAGATES,
+};
+
+static void _clk_arm_recalc(struct clk *clk)
+{
+ u32 cacrr, div;
+
+ cacrr = __raw_readl(MXC_CCM_CACRR);
+ div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
+ clk->rate = clk->parent->rate / div;
+}
+
+static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 i;
+ for (i = 0; i < cpu_wp_nr; i++) {
+ if (rate == cpu_wp_tbl[i].cpu_rate)
+ break;
+ }
+ if (i > cpu_wp_nr)
+ return -EINVAL;
+ cpu_clk_set_wp(i);
+
+ return 0;
+}
+
+static unsigned long _clk_cpu_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 i;
+ u32 wp;
+
+ for (i = 0; i < cpu_wp_nr; i++) {
+ if (rate == cpu_wp_tbl[i].cpu_rate)
+ break;
+ }
+
+ if (i > cpu_wp_nr)
+ wp = 0;
+
+ return cpu_wp_tbl[wp].cpu_rate;
+}
+
+static struct clk cpu_clk = {
+ .name = "cpu_clk",
+ .parent = &pll1_sw_clk,
+ .recalc = _clk_arm_recalc,
+ .set_rate = _clk_cpu_set_rate,
+ .round_rate = _clk_cpu_round_rate,
+};
+
+static int _clk_periph_apm_set_parent(struct clk *clk,
+ struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL);
+
+ reg = __raw_readl(MXC_CCM_CAMR) & ~MXC_CCM_CAMR_PERIPH_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CAMR_PERIPH_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CAMR);
+
+ return 0;
+}
+
+static struct clk periph_apm_clk = {
+ .name = "periph_apm_clk",
+ .parent = &pll1_sw_clk,
+ .set_parent = _clk_periph_apm_set_parent,
+ .flags = RATE_PROPAGATES,
+};
+
+/* TODO: Need to sync with GPC to determine if DVFS is in place so that
+ * the DVFS_PODF divider can be applied in CDCR register.
+ */
+static void _clk_main_bus_recalc(struct clk *clk)
+{
+ clk->rate = clk->parent->rate;
+}
+
+static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, stat;
+
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.enable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.enable(&emi_slow_clk);
+ if (emi_intr_clk.usecount == 0)
+ emi_intr_clk.enable(&emi_intr_clk);
+
+ if (parent == &pll2_sw_clk) {
+ reg = __raw_readl(MXC_CCM_CBCDR6) &
+ ~MXC_CCM_CBCDR6_PERIPH_CLK_SEL;
+ } else if (parent == &periph_apm_clk) {
+ reg = __raw_readl(MXC_CCM_CBCDR6) |
+ MXC_CCM_CBCDR6_PERIPH_CLK_SEL;
+ } else {
+ return -EINVAL;
+ }
+ __raw_writel(reg, MXC_CCM_CBCDR6);
+
+ /* Set the Load-dividers bit in CCM */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg |= MXC_CCM_CCDR_LOAD_DIVIDERS;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ do {
+ stat = __raw_readl(MXC_CCM_CCDR) & MXC_CCM_CCDR_LOAD_DIVIDERS;
+ } while (stat);
+
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.disable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.disable(&emi_slow_clk);
+ if (emi_intr_clk.usecount == 0)
+ emi_intr_clk.disable(&emi_intr_clk);
+
+ return 0;
+}
+
+static struct clk main_bus_clk = {
+ .name = "main_bus_clk",
+ .parent = &pll2_sw_clk,
+ .set_parent = _clk_main_bus_set_parent,
+ .recalc = _clk_main_bus_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static int _clk_axi_a_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, stat;
+
+ div = clk->parent->rate / rate;
+ if (div == 0)
+ div++;
+ if (((clk->parent->rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ if (ddr_clk.parent == &axi_a_clk && emi_fast_clk.usecount == 0)
+ emi_fast_clk.enable(&emi_fast_clk);
+
+ reg = __raw_readl(MXC_CCM_CBCDR3);
+ reg &= ~MXC_CCM_CBCDR3_AXI_A_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR3_AXI_A_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR3);
+
+ /* Set the Load-dividers bit in CCM */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg |= MXC_CCM_CCDR_LOAD_DIVIDERS;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ do {
+ stat = __raw_readl(MXC_CCM_CCDR) & MXC_CCM_CCDR_LOAD_DIVIDERS;
+ } while (stat);
+ clk->rate = rate;
+
+ if (ddr_clk.parent == &axi_a_clk && emi_fast_clk.usecount == 0)
+ emi_fast_clk.disable(&emi_fast_clk);
+
+ return 0;
+}
+
+static void _clk_axi_a_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR3);
+ div = ((reg & MXC_CCM_CBCDR3_AXI_A_PODF_MASK) >>
+ MXC_CCM_CBCDR3_AXI_A_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+}
+
+static unsigned long _clk_axi_a_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+
+ div = clk->parent->rate / rate;
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+ return clk->parent->rate / div;
+}
+
+static struct clk axi_a_clk = {
+ .name = "axi_a_clk",
+ .parent = &main_bus_clk,
+ .recalc = _clk_axi_a_recalc,
+ .set_rate = _clk_axi_a_set_rate,
+ .round_rate = _clk_axi_a_round_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static int _clk_axi_b_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, stat;
+
+ div = clk->parent->rate / rate;
+ if (div == 0)
+ div++;
+ if (((clk->parent->rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ if (ddr_clk.parent == &axi_b_clk && emi_fast_clk.usecount == 0)
+ emi_fast_clk.enable(&emi_fast_clk);
+
+ reg = __raw_readl(MXC_CCM_CBCDR4);
+ reg &= ~MXC_CCM_CBCDR4_AXI_B_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR4_AXI_B_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR4);
+
+ /* Set the Load-dividers bit in CCM */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg |= MXC_CCM_CCDR_LOAD_DIVIDERS;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ do {
+ stat = __raw_readl(MXC_CCM_CCDR) & MXC_CCM_CCDR_LOAD_DIVIDERS;
+ } while (stat);
+ clk->rate = rate;
+
+ if (ddr_clk.parent == &axi_c_clk && emi_fast_clk.usecount == 0)
+ emi_fast_clk.disable(&emi_fast_clk);
+
+ return 0;
+}
+
+static void _clk_axi_b_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR4);
+ div = ((reg & MXC_CCM_CBCDR4_AXI_B_PODF_MASK) >>
+ MXC_CCM_CBCDR4_AXI_B_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+}
+
+static unsigned long _clk_axi_b_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+
+ div = clk->parent->rate / rate;
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+ return clk->parent->rate / div;
+}
+
+static struct clk axi_b_clk = {
+ .name = "axi_b_clk",
+ .parent = &main_bus_clk,
+ .recalc = _clk_axi_b_recalc,
+ .set_rate = _clk_axi_b_set_rate,
+ .round_rate = _clk_axi_b_round_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static int _clk_axi_c_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, stat;
+
+ div = clk->parent->rate / rate;
+ if (div == 0)
+ div++;
+ if (((clk->parent->rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ if (ddr_clk.parent == &axi_c_clk && emi_fast_clk.usecount == 0)
+ emi_fast_clk.enable(&emi_fast_clk);
+
+ reg = __raw_readl(MXC_CCM_CBCDR5);
+ reg &= ~MXC_CCM_CBCDR5_AXI_C_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR5_AXI_C_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR5);
+
+ /* Set the Load-dividers bit in CCM */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg |= MXC_CCM_CCDR_LOAD_DIVIDERS;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ do {
+ stat = __raw_readl(MXC_CCM_CCDR) & MXC_CCM_CCDR_LOAD_DIVIDERS;
+ } while (stat);
+ clk->rate = rate;
+
+ if (ddr_clk.parent == &axi_c_clk && emi_fast_clk.usecount == 0)
+ emi_fast_clk.disable(&emi_fast_clk);
+
+ return 0;
+}
+
+static void _clk_axi_c_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR5);
+ div = ((reg & MXC_CCM_CBCDR5_AXI_C_PODF_MASK) >>
+ MXC_CCM_CBCDR5_AXI_C_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+}
+
+static unsigned long _clk_axi_c_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+
+ div = clk->parent->rate / rate;
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+ return clk->parent->rate / div;
+}
+
+static struct clk axi_c_clk = {
+ .name = "axi_c_clk",
+ .parent = &main_bus_clk,
+ .recalc = _clk_axi_c_recalc,
+ .set_rate = _clk_axi_c_set_rate,
+ .round_rate = _clk_axi_c_round_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static void _clk_ahb_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR2);
+ div = ((reg & MXC_CCM_CBCDR2_AHB_PODF_MASK) >>
+ MXC_CCM_CBCDR2_AHB_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+}
+
+static int _clk_ahb_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+
+ div = clk->parent->rate / rate;
+ if (div == 0)
+ div++;
+ if (((clk->parent->rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CBCDR2);
+ reg &= ~MXC_CCM_CBCDR2_AHB_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR2_AHB_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR2);
+ clk->rate = rate;
+
+ return 0;
+}
+
+static unsigned long _clk_ahb_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+
+ div = clk->parent->rate / rate;
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+ return clk->parent->rate / div;
+}
+
+static struct clk ahb_clk = {
+ .name = "ahb_clk",
+ .parent = &main_bus_clk,
+ .recalc = _clk_ahb_recalc,
+ .set_rate = _clk_ahb_set_rate,
+ .round_rate = _clk_ahb_round_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk ahb_max_clk = {
+ .name = "max_clk",
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGR0_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static int _clk_emi_core_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, stat;
+
+ div = clk->parent->rate / rate;
+ if (div == 0)
+ div++;
+ if (((clk->parent->rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.enable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.enable(&emi_slow_clk);
+ if (emi_intr_clk.usecount == 0)
+ emi_intr_clk.enable(&emi_intr_clk);
+
+ reg = __raw_readl(MXC_CCM_CBCDR6);
+ reg &= ~MXC_CCM_CBCDR6_EMI_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR6_EMI_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR6);
+
+ /* Set the Load-dividers bit in CCM */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg |= MXC_CCM_CCDR_LOAD_DIVIDERS;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ do {
+ stat = __raw_readl(MXC_CCM_CCDR) & MXC_CCM_CCDR_LOAD_DIVIDERS;
+ } while (stat);
+
+ clk->rate = rate;
+
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.disable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.disable(&emi_slow_clk);
+ if (emi_intr_clk.usecount == 0)
+ emi_intr_clk.disable(&emi_intr_clk);
+
+ return 0;
+}
+
+static void _clk_emi_core_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR6);
+ div = ((reg & MXC_CCM_CBCDR6_EMI_PODF_MASK) >>
+ MXC_CCM_CBCDR6_EMI_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+}
+
+static int _clk_emi_core_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CBCDR6);
+ if (parent == &ahb_clk) {
+ reg |= MXC_CCM_CBCDR6_EMI_CLK_SEL;
+ } else if (parent == &main_bus_clk) {
+ reg &= ~MXC_CCM_CBCDR6_EMI_CLK_SEL;
+ } else {
+ BUG();
+ }
+ __raw_writel(reg, MXC_CCM_CBCDR6);
+
+ return 0;
+}
+
+static unsigned long _clk_emi_core_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+
+ div = clk->parent->rate / rate;
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+ return clk->parent->rate / div;
+}
+
+static struct clk emi_core_clk = {
+ .name = "emi_core_clk",
+ .set_parent = _clk_emi_core_set_parent,
+ .recalc = _clk_emi_core_recalc,
+ .set_rate = _clk_emi_core_set_rate,
+ .round_rate = _clk_emi_core_round_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk ahbmux1_clk = {
+ .name = "ahbmux1_clk",
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG4_OFFSET,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk ahbmux2_clk = {
+ .name = "ahbmux2_clk",
+ .id = 0,
+ .parent = &emi_core_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGR0_CG7_OFFSET,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk emi_fast_clk = {
+ .name = "emi_fast_clk",
+ .parent = &emi_core_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG12_OFFSET,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk emi_slow_clk = {
+ .name = "emi_slow_clk",
+ .parent = &emi_core_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG13_OFFSET,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk emi_intr_clk = {
+ .name = "emi_intr_clk",
+ .parent = &emi_core_clk,
+ .secondary = &ahbmux2_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG14_OFFSET,
+ .disable = _clk_disable_inwait,
+};
+
+static void _clk_ipg_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR2);
+ div = ((reg & MXC_CCM_CBCDR2_IPG_PODF_MASK) >>
+ MXC_CCM_CBCDR2_IPG_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+}
+
+static struct clk ipg_clk = {
+ .name = "ipg_clk",
+ .parent = &ahb_clk,
+ .recalc = _clk_ipg_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static void _clk_ipg_per_recalc(struct clk *clk)
+{
+ u32 reg, prediv1, prediv2, podf;
+
+ if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) {
+ /* the main_bus_clk is the one before the DVFS engine */
+ reg = __raw_readl(MXC_CCM_CBCDR2);
+ prediv1 = ((reg & MXC_CCM_CBCDR2_PERCLK_PRED1_MASK) >>
+ MXC_CCM_CBCDR2_PERCLK_PRED1_OFFSET) + 1;
+ prediv2 = ((reg & MXC_CCM_CBCDR2_PERCLK_PRED2_MASK) >>
+ MXC_CCM_CBCDR2_PERCLK_PRED2_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CBCDR2_PERCLK_PODF_MASK) >>
+ MXC_CCM_CBCDR2_PERCLK_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / (prediv1 * prediv2 * podf);
+ } else if (clk->parent == &ipg_clk) {
+ clk->rate = ipg_clk.rate;
+ } else {
+ BUG();
+ }
+}
+
+static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ mux = _get_mux(parent, &main_bus_clk, &lp_apm_clk, &ipg_clk, NULL);
+ if (mux == 2) {
+ reg |= MXC_CCM_CSCMR1_PERCLK_IPG_CLK_SEL;
+ } else {
+ reg &= ~MXC_CCM_CSCMR1_PERCLK_IPG_CLK_SEL;
+ if (mux == 0) {
+ reg &= ~MXC_CCM_CSCMR1_PERCLK_LP_APM_CLK_SEL;
+ } else {
+ reg |= MXC_CCM_CSCMR1_PERCLK_LP_APM_CLK_SEL;
+ }
+ }
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ipg_perclk = {
+ .name = "ipg_perclk",
+ .parent = &ipg_clk,
+ .recalc = _clk_ipg_per_recalc,
+ .set_parent = _clk_ipg_per_set_parent,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk aips_tz1_clk = {
+ .name = "aips_tz1_clk",
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGR0_CG13_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk aips_tz2_clk = {
+ .name = "aips_tz2_clk",
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGR0_CG14_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk sdma_clk[] = {
+ {
+ .name = "sdma_ahb_clk",
+ .parent = &ahb_clk,
+ .secondary = &emi_fast_clk,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG0_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "sdma_ipg_clk",
+ .parent = &ipg_clk,
+#ifdef CONFIG_SDMA_IRAM
+ .secondary = &emi_intr_clk,
+#endif
+ },
+};
+
+static int _clk_tve_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+
+ if (parent == &pll3_sw_clk) {
+ reg &= ~(MXC_CCM_CSCMR1_TVE_CLK_SEL);
+ } else if (parent == &osc_clk) {
+ reg |= MXC_CCM_CSCMR1_TVE_CLK_SEL;
+ reg &= MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL;
+ } else if (parent == &ckih_clk) {
+ reg |= MXC_CCM_CSCMR1_TVE_CLK_SEL;
+ reg |= MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL;
+ } else {
+ BUG();
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+ return 0;
+}
+
+static void _clk_tve_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if ((reg & MXC_CCM_CSCMR1_TVE_CLK_SEL) == 0) {
+ reg = __raw_readl(MXC_CCM_CDCDR) &
+ MXC_CCM_CDCDR_TVE_CLK_PRED_MASK;
+ div = (reg >> MXC_CCM_CDCDR_TVE_CLK_PRED_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+ } else {
+ clk->rate = clk->parent->rate;
+ }
+}
+
+static unsigned long _clk_tve_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (reg & MXC_CCM_CSCMR1_TVE_CLK_SEL) {
+ return -EINVAL;
+ }
+
+ div = clk->parent->rate / rate;
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+ return clk->parent->rate / div;
+}
+
+static int _clk_tve_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (reg & MXC_CCM_CSCMR1_TVE_CLK_SEL) {
+ return -EINVAL;
+ }
+
+ div = clk->parent->rate / rate;
+ if (div == 0)
+ div++;
+ if (((clk->parent->rate / div) != rate) || (div > 8)) {
+ return -EINVAL;
+ }
+
+ div--;
+ reg = __raw_readl(MXC_CCM_CDCDR) & ~MXC_CCM_CDCDR_TVE_CLK_PRED_MASK;
+ reg |= div << MXC_CCM_CDCDR_TVE_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CDCDR);
+ clk->rate = rate;
+ return 0;
+}
+
+static struct clk tve_clk = {
+ .name = "tve_clk",
+ .parent = &pll3_sw_clk,
+ .secondary = &aips_tz1_clk,
+ .set_parent = _clk_tve_set_parent,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGR0_CG10_OFFSET,
+ .recalc = _clk_tve_recalc,
+ .round_rate = _clk_tve_round_rate,
+ .set_rate = _clk_tve_set_rate,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk spba_clk = {
+ .name = "spba_clk",
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG1_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static void _clk_uart_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+}
+
+static int _clk_uart_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_UART_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static int _clk_uart_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, post_div = 1;
+
+ div = clk->parent->rate / rate;
+ if (div == 0)
+ div++;
+ if (((clk->parent->rate / div) != rate) || (div > 64) || (div == 1))
+ return -EINVAL;
+
+ if (div > 8) {
+ int i = 1;
+ while ((div / (2 * i)) > 8)
+ i++;
+ post_div = i * 2;
+ div = div / post_div;
+ }
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ reg &= ~MXC_CCM_CSCDR1_UART_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CSCDR1_UART_CLK_PRED_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET |
+ (post_div - 1) << MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+ clk->rate = rate;
+
+ return 0;
+}
+
+static unsigned long _clk_uart_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+
+ div = clk->parent->rate / rate;
+ if (div > 64)
+ div = 64;
+ else if (div == 0)
+ div++;
+ return clk->parent->rate / div;
+}
+
+static struct clk uart_main_clk = {
+ .name = "uart_main_clk",
+ .parent = &pll2_sw_clk,
+ .recalc = _clk_uart_recalc,
+ .set_parent = _clk_uart_set_parent,
+ .set_rate = _clk_uart_set_rate,
+ .round_rate = _clk_uart_round_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk uart1_clk[] = {
+ {
+ .name = "uart_clk",
+ .id = 0,
+ .parent = &uart_main_clk,
+ .secondary = &uart1_clk[1],
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG5_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "uart_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &aips_tz2_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk uart2_clk[] = {
+ {
+ .name = "uart_clk",
+ .id = 1,
+ .parent = &uart_main_clk,
+ .secondary = &uart2_clk[1],
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "uart_ipg_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .secondary = &aips_tz2_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk uart3_clk[] = {
+ {
+ .name = "uart_clk",
+ .id = 2,
+ .parent = &uart_main_clk,
+ .secondary = &uart3_clk[1],
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "uart_ipg_clk",
+ .id = 2,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk gpt_clk[] = {
+ {
+ .name = "gpt_clk",
+ .id = 0,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &gpt_clk[1],
+ },
+ {
+ .name = "gpt_ipg_clk",
+ .parent = &ipg_clk,
+ .id = 0,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "gpt_32k_clk",
+ .id = 0,
+ .parent = &ckil_clk,
+ },
+};
+
+static struct clk i2c_clk[] = {
+ {
+ .name = "i2c_clk",
+ .id = 0,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG14_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "i2c_clk",
+ .id = 1,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG15_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "i2c_clk",
+ .id = 2,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG0_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static void _clk_cspi_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+ prediv = ((reg & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+}
+
+static int _clk_cspi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static int _clk_cspi_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, post_div = 1;
+
+ div = clk->parent->rate / rate;
+ if (div == 0)
+ div++;
+ if (((clk->parent->rate / div) != rate) || (div > 512) || (div == 1))
+ return -EINVAL;
+
+ if (div > 8) {
+ int i = 1;
+ while ((div / (2 * i)) > 8)
+ i++;
+ post_div = i * 2;
+ div = div / post_div;
+ }
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+ reg &= ~MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK;
+ reg |= (div - 1) << MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET;
+ reg |= (post_div - 1) << MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR2);
+ clk->rate = rate;
+
+ return 0;
+}
+
+static unsigned long _clk_cspi_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+
+ div = clk->parent->rate / rate;
+ if (div > 512)
+ div = 8;
+ else if (div == 1)
+ div = 2;
+ else if (div == 0)
+ div++;
+ return clk->parent->rate / div;
+}
+
+static struct clk cspi_main_clk = {
+ .name = "cspi_main_clk",
+ .parent = &pll3_sw_clk,
+ .recalc = _clk_cspi_recalc,
+ .set_parent = _clk_cspi_set_parent,
+ .set_rate = _clk_cspi_set_rate,
+ .round_rate = _clk_cspi_round_rate,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk cspi1_clk[] = {
+ {
+ .name = "cspi_clk",
+ .id = 0,
+ .parent = &cspi_main_clk,
+ .secondary = &cspi1_clk[1],
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "cspi_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &aips_tz2_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk cspi2_clk[] = {
+ {
+ .name = "cspi_clk",
+ .id = 1,
+ .parent = &cspi_main_clk,
+ .secondary = &cspi2_clk[1],
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "cspi_ipg_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk cspi3_clk[] = {
+ {
+ .name = "cspi_clk",
+ .id = 2,
+ .parent = &cspi_main_clk,
+ .secondary = &cspi3_clk[1],
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "cspi_ipg_clk",
+ .id = 2,
+ .parent = &ipg_clk,
+ .secondary = &aips_tz2_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG11_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static int _clk_ssi_lp_apm_set_parent(struct clk *clk,
+ struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+
+ if (parent == &ckih_clk) {
+ reg &= ~MXC_CCM_CSCMR1_SSI_APM_CLK_SEL;
+ } else if (parent == &lp_apm_clk) {
+ reg |= MXC_CCM_CSCMR1_SSI_APM_CLK_SEL;
+ } else {
+ BUG();
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+ return 0;
+}
+
+static struct clk ssi_lp_apm_clk = {
+ .name = "ssi_lp_apm_clk",
+ .parent = &ckih_clk,
+ .set_parent = _clk_ssi_lp_apm_set_parent,
+};
+
+static void _clk_ssi1_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ prediv = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK) >>
+ MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK) >>
+ MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+}
+static int _clk_ssi1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk,
+ &pll3_sw_clk, &ssi_lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi1_clk[] = {
+ {
+ .name = "ssi_clk",
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ssi1_set_parent,
+ .secondary = &ssi1_clk[1],
+ .recalc = _clk_ssi1_recalc,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "ssi_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &ssi1_clk[2],
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "ssi_dep_clk",
+ .id = 0,
+ .parent = &aips_tz2_clk,
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+ .secondary = &emi_intr_clk,
+#else
+ .secondary = &emi_fast_clk,
+#endif
+ },
+};
+
+static void _clk_ssi2_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+ prediv = ((reg & MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK) >>
+ MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK) >>
+ MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+}
+
+static int _clk_ssi2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk,
+ &pll3_sw_clk, &ssi_lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi2_clk[] = {
+ {
+ .name = "ssi_clk",
+ .id = 1,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ssi2_set_parent,
+ .secondary = &ssi2_clk[1],
+ .recalc = _clk_ssi2_recalc,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "ssi_ipg_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .secondary = &ssi2_clk[2],
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "ssi_dep_clk",
+ .id = 1,
+ .parent = &spba_clk,
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+ .secondary = &emi_intr_clk,
+#else
+ .secondary = &emi_fast_clk,
+#endif
+ },
+};
+
+static void _clk_ssi_ext1_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ clk->rate = clk->parent->rate;
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if ((reg & MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL) == 0) {
+ reg = __raw_readl(MXC_CCM_CSECDR1);
+ prediv = ((reg & MXC_CCM_CSECDR1_SSI_EXT1_CLK_PRED_MASK) >>
+ MXC_CCM_CSECDR1_SSI_EXT1_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CSECDR1_SSI_EXT1_CLK_PODF_MASK) >>
+ MXC_CCM_CSECDR1_SSI_EXT1_CLK_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / (prediv * podf);
+ }
+}
+
+static int _clk_ssi_ext1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &ssi1_clk[0]) {
+ reg |= MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL;
+ } else {
+ reg &= ~MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL;
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &ssi_lp_apm_clk);
+ reg = (reg & ~MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET);
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi_ext1_clk = {
+ .name = "ssi_ext1_clk",
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ssi_ext1_set_parent,
+ .recalc = _clk_ssi_ext1_recalc,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG11_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static void _clk_ssi_ext2_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ clk->rate = clk->parent->rate;
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if ((reg & MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL) == 0) {
+ reg = __raw_readl(MXC_CCM_CSECDR2);
+ prediv = ((reg & MXC_CCM_CSECDR2_SSI_EXT2_CLK_PRED_MASK) >>
+ MXC_CCM_CSECDR2_SSI_EXT2_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CSECDR2_SSI_EXT2_CLK_PODF_MASK) >>
+ MXC_CCM_CSECDR2_SSI_EXT2_CLK_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / (prediv * podf);
+ }
+}
+
+static int _clk_ssi_ext2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &ssi2_clk[0]) {
+ reg |= MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL;
+ } else {
+ reg &= ~MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL;
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &ssi_lp_apm_clk);
+ reg = (reg & ~MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET);
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi_ext2_clk = {
+ .name = "ssi_ext2_clk",
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ssi_ext2_set_parent,
+ .recalc = _clk_ssi_ext2_recalc,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static struct clk iim_clk = {
+ .name = "iim_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGR0_CG15_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk tmax1_clk = {
+ .name = "tmax1_clk",
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG0_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk tmax2_clk = {
+ .name = "tmax2_clk",
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG1_OFFSET,
+ .disable = _clk_disable,
+};
+
+static void _clk_usboh2_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_USBOH2_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_USBOH2_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CSCDR1_USBOH2_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_USBOH2_CLK_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+}
+
+static int _clk_usboh2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USBOH2_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_USBOH2_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+/*
+ * This is USB core clock.
+ ** need access DDR/iram, TMAX
+ */
+static struct clk usb_core_clk[] = {
+ {
+ .name = "usb_ahb_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG11_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &usb_core_clk[1],
+ },
+ {
+ .name = "usb_tmax_clk",
+ .parent = &tmax1_clk,
+ .secondary = &usb_core_clk[2],
+ },
+ {
+ .name = "usb_ddr_clk",
+ .parent = &emi_fast_clk,
+#if defined CONFIG_USB_STATIC_IRAM_PPH || defined CONFIG_USB_STATIC_IRAM
+ .secondary = &usb_core_clk[3],
+#endif
+ },
+ /* iram patch, need access internal ram */
+ {
+ .name = "usb_iram_clk",
+ .parent = &emi_intr_clk,
+ },
+};
+
+/* used for connecting external PHY */
+static struct clk usboh2_clk = {
+ .name = "usboh2_clk",
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_usboh2_set_parent,
+ .recalc = _clk_usboh2_recalc,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG12_OFFSET,
+ .disable = _clk_disable,
+};
+
+static void _clk_usb_phy_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ if (clk->parent == &pll3_sw_clk) {
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ prediv = ((reg & MXC_CCM_CDCDR_USB_PHY_PRED_MASK) >>
+ MXC_CCM_CDCDR_USB_PHY_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CDCDR_USB_PHY_PODF_MASK) >>
+ MXC_CCM_CDCDR_USB_PHY_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+ } else
+ clk->rate = clk->parent->rate;
+}
+
+static int _clk_usb_phy_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &osc_clk) {
+ reg &= ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL;
+ } else if (parent == &pll3_sw_clk) {
+ reg |= MXC_CCM_CSCMR1_USB_PHY_CLK_SEL;
+ } else {
+ BUG();
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+ return 0;
+}
+
+static struct clk usb_phy_clk = {
+ .name = "usb_phy_clk",
+ .parent = &osc_clk,
+ .set_parent = _clk_usb_phy_set_parent,
+ .recalc = _clk_usb_phy_recalc,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGR0_CG6_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk esdhc_dep_clks = {
+ .name = "sd_dep_clk",
+ .parent = &spba_clk,
+ .secondary = &emi_fast_clk,
+};
+
+
+static void _clk_esdhc1_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+}
+
+static int _clk_esdhc1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) &
+ ~MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk esdhc1_clk[] = {
+ {
+ .name = "esdhc_clk",
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_esdhc1_set_parent,
+ .recalc = _clk_esdhc1_recalc,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG14_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc1_clk[1],
+ },
+ {
+ .name = "esdhc_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG13_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc1_clk[2],
+ },
+ {
+ .name = "esdhc1_sec_clk",
+ .parent = &tmax2_clk,
+ .secondary = &esdhc_dep_clks,
+ },
+};
+
+static void _clk_esdhc2_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+}
+
+static int _clk_esdhc2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) &
+ ~MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk esdhc2_clk[] = {
+ {
+ .name = "esdhc_clk",
+ .id = 1,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_esdhc2_set_parent,
+ .recalc = _clk_esdhc2_recalc,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG0_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc2_clk[1],
+ },
+ {
+ .name = "esdhc_ipg_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG15_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc2_clk[2],
+ },
+ {
+ .name = "esdhc2_sec_clk",
+ .parent = &ahb_max_clk,
+ .secondary = &esdhc_dep_clks,
+ },
+};
+
+static int _clk_esdhc3_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk[0]) {
+ reg &= ~MXC_CCM_CSCMR1_ESDHC3_CLK_SEL;
+ } else if (parent == &esdhc2_clk[0]) {
+ reg |= MXC_CCM_CSCMR1_ESDHC3_CLK_SEL;
+ } else {
+ BUG();
+ }
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk esdhc3_clk[] = {
+ {
+ .name = "esdhc_clk",
+ .id = 2,
+ .parent = &esdhc1_clk[0],
+ .set_parent = _clk_esdhc3_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG2_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc3_clk[1],
+ },
+ {
+ .name = "esdhc_ipg_clk",
+ .id = 2,
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG1_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc3_clk[2],
+ },
+ {
+ .name = "esdhc3_sec_clk",
+ .parent = &ahb_max_clk,
+ .secondary = &esdhc_dep_clks,
+ },
+
+};
+
+static void _clk_nfc_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR7);
+ div = ((reg & MXC_CCM_CBCDR7_NFC_PODF_MASK) >>
+ MXC_CCM_CBCDR7_NFC_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+}
+
+static int _clk_nfc_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div, stat;
+
+ div = clk->parent->rate / rate;
+ if (div == 0)
+ div++;
+ if (((clk->parent->rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.enable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.enable(&emi_slow_clk);
+ if (emi_intr_clk.usecount == 0)
+ emi_intr_clk.enable(&emi_intr_clk);
+
+ reg = __raw_readl(MXC_CCM_CBCDR7);
+ reg &= ~MXC_CCM_CBCDR7_NFC_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR7_NFC_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR7);
+
+ /* Set the Load-dividers bit in CCM */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg |= MXC_CCM_CCDR_LOAD_DIVIDERS;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ do {
+ stat = __raw_readl(MXC_CCM_CCDR) & MXC_CCM_CCDR_LOAD_DIVIDERS;
+ } while (stat);
+ clk->rate = rate;
+
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.disable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.disable(&emi_slow_clk);
+ if (emi_intr_clk.usecount == 0)
+ emi_intr_clk.disable(&emi_intr_clk);
+
+ return 0;
+}
+
+static unsigned long _clk_nfc_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+
+ div = clk->parent->rate / rate;
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+ return clk->parent->rate / div;
+}
+
+static struct clk nfc_clk = {
+ .name = "nfc_clk",
+ .parent = &emi_core_clk,
+ .secondary = &emi_slow_clk,
+ .recalc = _clk_nfc_recalc,
+ .set_rate = _clk_nfc_set_rate,
+ .round_rate = _clk_nfc_round_rate,
+};
+
+static int _clk_spdif_xtal_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &osc_clk) {
+ reg &= ~MXC_CCM_CSCMR1_SPDIF_CLK_SEL;
+ } else if (parent == &ckih_clk) {
+ reg |= MXC_CCM_CSCMR1_SPDIF_CLK_SEL;
+ } else {
+ BUG();
+ }
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk spdif_xtal_clk = {
+ .name = "spdif_xtal_clk",
+ .parent = &osc_clk,
+ .set_parent = _clk_spdif_xtal_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG10_OFFSET,
+ .disable = _clk_disable,
+};
+
+static int _clk_spdif0_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ reg |= MXC_CCM_CSCMR2_SPDIF0_COM;
+ if (parent != &ssi1_clk[0]) {
+ reg &= ~MXC_CCM_CSCMR2_SPDIF0_COM;
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &spdif_xtal_clk);
+ reg = (reg & ~MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_OFFSET);
+ }
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static void _clk_spdif0_recalc(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ if (clk->parent == &ssi1_clk[0]) {
+ clk->rate = clk->parent->rate;
+ } else {
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ pred = ((reg & MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK) >>
+ MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK) >>
+ MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / (pred * podf);
+ }
+}
+
+static struct clk spdif0_clk[] = {
+ {
+ .name = "spdif_clk",
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .secondary = &spdif0_clk[1],
+ .set_parent = _clk_spdif0_set_parent,
+ .recalc = _clk_spdif0_recalc,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG11_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "spdif_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG10_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static int _clk_spdif1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ reg |= MXC_CCM_CSCMR2_SPDIF1_COM;
+ if (parent != &ssi2_clk[0]) {
+ reg &= ~MXC_CCM_CSCMR2_SPDIF1_COM;
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &spdif_xtal_clk);
+ reg = (reg & ~MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_OFFSET);
+ }
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static void _clk_spdif1_recalc(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ if (clk->parent == &ssi2_clk[0]) {
+ clk->rate = clk->parent->rate;
+ } else {
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ pred = ((reg & MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK) >>
+ MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK) >>
+ MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / (pred * podf);
+ }
+}
+
+static struct clk spdif1_clk[] = {
+ {
+ .name = "spdif_clk",
+ .id = 1,
+ .parent = &pll3_sw_clk,
+ .secondary = &spdif1_clk[1],
+ .set_parent = _clk_spdif1_set_parent,
+ .recalc = _clk_spdif1_recalc,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG12_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "spdif_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG10_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static int _clk_ipu_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_enable(clk);
+ /* Handshake with IPU when certain clock rates are changed. */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg &= ~MXC_CCM_CCDR_IPU_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+ return 0;
+}
+
+static void _clk_ipu_disable(struct clk *clk)
+{
+ u32 reg;
+ _clk_disable(clk);
+
+ /* No handshake with IPU as its not enabled. */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg |= MXC_CCM_CCDR_IPU_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+}
+
+static int _clk_ipu_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ reg = __raw_readl(MXC_CCM_CAMR);
+ mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &axi_c_clk,
+ &emi_core_clk);
+ reg = (reg & ~MXC_CCM_CAMR_IPU_HSP_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CAMR_IPU_HSP_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CAMR);
+
+ return 0;
+}
+
+static struct clk ipu_clk[] = {
+ {
+ .name = "ipu_clk",
+ .parent = &axi_a_clk,
+ .secondary = &ipu_clk[1],
+ .set_parent = _clk_ipu_set_parent,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG15_OFFSET,
+ .enable = _clk_ipu_enable,
+ .disable = _clk_ipu_disable,
+ .flags = CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ .name = "ipu_sec_clk",
+ .parent = &emi_fast_clk,
+ .secondary = &ahbmux1_clk,
+ }
+};
+
+static int _clk_ipu_di_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ if (parent == &tve_clk) {
+ mxc_iomux_set_gpr(MUX_IPUv3D_CAMP, false, 0);
+ } else if (parent == &ckih_clk) {
+ mxc_iomux_set_gpr(MUX_IPUv3D_CAMP, true, 0);
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ reg |= MXC_CCM_CSCMR1_DI_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+ } else if (parent == &osc_clk) {
+ mxc_iomux_set_gpr(MUX_IPUv3D_CAMP, true, 0);
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ reg &= ~MXC_CCM_CSCMR1_DI_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+ } else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void _clk_ipu_di_recalc(struct clk *clk)
+{
+ if (clk->parent == &tve_clk) {
+ clk->rate = clk->parent->rate / 8;
+ } else {
+ clk->rate = clk->parent->rate;
+ }
+}
+
+static struct clk ipu_di_clk = {
+ .name = "ipu_di_clk",
+ .parent = &tve_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG14_OFFSET,
+ .recalc = _clk_ipu_di_recalc,
+ .set_parent = _clk_ipu_di_set_parent,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static int _clk_ddr_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ reg = __raw_readl(MXC_CCM_CAMR);
+ mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &axi_c_clk,
+ &emi_core_clk);
+ reg = (reg & ~MXC_CCM_CAMR_DDR_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CAMR_DDR_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CAMR);
+
+ return 0;
+}
+
+static struct clk ddr_clk = {
+ .name = "ddr_clk",
+ .parent = &axi_c_clk,
+ .set_parent = _clk_ddr_set_parent,
+};
+
+static int _clk_arm_axi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ reg = __raw_readl(MXC_CCM_CAMR);
+ mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &axi_c_clk,
+ &emi_core_clk);
+ reg = (reg & ~MXC_CCM_CAMR_ARM_AXI_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CAMR_ARM_AXI_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CAMR);
+
+ return 0;
+}
+
+static struct clk arm_axi_clk = {
+ .name = "arm_axi_clk",
+ .parent = &axi_a_clk,
+ .set_parent = _clk_arm_axi_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGR0_CG1_OFFSET,
+ .disable = _clk_disable,
+};
+
+static int _clk_vpu_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ reg = __raw_readl(MXC_CCM_CAMR);
+ mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &axi_c_clk,
+ &emi_core_clk);
+ reg = (reg & ~MXC_CCM_CAMR_VPU_AXI_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CAMR_VPU_AXI_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CAMR);
+
+ return 0;
+}
+
+static int _clk_vpu_core_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ reg = __raw_readl(MXC_CCM_CAMR);
+ mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &axi_c_clk,
+ &emi_core_clk);
+ reg = (reg & ~MXC_CCM_CAMR_VPU_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CAMR_VPU_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CAMR);
+
+ return 0;
+}
+
+static struct clk vpu_clk[] = {
+ {
+ .name = "vpu_clk",
+ .parent = &axi_a_clk,
+ .set_parent = _clk_vpu_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG7_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &vpu_clk[1],
+ .flags = CPU_FREQ_TRIG_UPDATE,
+ },
+ {
+ .name = "vpu_core_clk",
+ .parent = &axi_a_clk,
+ .secondary = &vpu_clk[2],
+ .set_parent = _clk_vpu_core_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG6_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "vpu_emi_clk",
+ .parent = &emi_fast_clk,
+#ifdef CONFIG_MXC_VPU_IRAM
+ .secondary = &emi_intr_clk,
+#endif
+ }
+};
+
+static int _clk_lpsr_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ mux = _get_mux(parent, &ckil_clk, &fpm_clk, &fpm_div2_clk, NULL);
+ reg = (reg & ~MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+static struct clk lpsr_clk = {
+ .name = "lpsr_clk",
+ .parent = &ckil_clk,
+ .set_parent = _clk_lpsr_set_parent,
+};
+
+static void _clk_pgc_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ div = (reg & MXC_CCM_CSCDR1_PGC_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET;
+ div = 1 >> div;
+ clk->rate = clk->parent->rate / div;
+}
+
+static struct clk pgc_clk = {
+ .name = "pgc_clk",
+ .parent = &ipg_clk,
+ .recalc = _clk_pgc_recalc,
+};
+
+/*usb OTG clock */
+/*Notes: in mx37, usb clock get from UTMI PHY, always 60MHz*/
+
+static struct clk usb_clk = {
+ .name = "usb_clk",
+ .rate = 60000000,
+};
+
+static struct clk rtc_clk = {
+ .name = "rtc_clk",
+ .parent = &ckil_clk,
+ .secondary = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG13_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk ata_clk = {
+ .name = "ata_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG14_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk rng_clk = {
+ .name = "rng_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG5_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk scc_clk = {
+ .name = "scc_clk",
+ .parent = &ipg_clk,
+ .secondary = &emi_fast_clk,
+};
+
+static void cko1_recalc(struct clk *clk)
+{
+ unsigned long rate;
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= MXC_CCM_CCOSR_CKOL_DIV_MASK;
+ reg = reg >> MXC_CCM_CCOSR_CKOL_DIV_OFFSET;
+ rate = clk->parent->rate;
+ clk->rate = rate / (reg + 1);
+}
+
+static int cko1_enable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg |= MXC_CCM_CCOSR_CKOL_EN;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+
+static void cko1_disable(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~MXC_CCM_CCOSR_CKOL_EN;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+}
+
+static int cko1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+
+ div = (clk->parent->rate/rate - 1) & 0x7;
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~MXC_CCM_CCOSR_CKOL_DIV_MASK;
+ reg |= div << MXC_CCM_CCOSR_CKOL_DIV_OFFSET;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+
+static unsigned long cko1_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 div;
+
+ div = clk->parent->rate / rate;
+ div = div < 1 ? 1 : div;
+ div = div > 8 ? 8 : div;
+ return clk->parent->rate / div;
+}
+
+static int cko1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 sel, reg;
+
+ if (parent == &cpu_clk)
+ sel = 0;
+ else if (parent == &pll1_sw_clk)
+ sel = 1;
+ else if (parent == &pll2_sw_clk)
+ sel = 2;
+ else if (parent == &pll3_sw_clk)
+ sel = 3;
+ else if (parent == &emi_core_clk)
+ sel = 4;
+ else if (parent == &nfc_clk)
+ sel = 6;
+ else if (parent == &vpu_clk[1])
+ sel = 7;
+ else if (parent == &ipu_di_clk)
+ sel = 8;
+ else if (parent == &ahb_clk)
+ sel = 11;
+ else if (parent == &ipg_clk)
+ sel = 12;
+ else if (parent == &ipg_perclk)
+ sel = 13;
+ else
+ return -EINVAL;
+
+ reg = __raw_readl(MXC_CCM_CCOSR);
+ reg &= ~MXC_CCM_CCOSR_CKOL_SEL_MASK;
+ reg |= sel << MXC_CCM_CCOSR_CKOL_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CCOSR);
+ return 0;
+}
+static struct clk cko1_clk = {
+ .name = "cko1_clk",
+ .recalc = cko1_recalc,
+ .enable = cko1_enable,
+ .disable = cko1_disable,
+ .set_rate = cko1_set_rate,
+ .round_rate = cko1_round_rate,
+ .set_parent = cko1_set_parent,
+};
+
+static struct clk *mxc_clks[] = {
+ &osc_clk,
+ &ckih_clk,
+ &ckil_clk,
+ &fpm_clk,
+ &fpm_div2_clk,
+ &pll1_main_clk,
+ &pll1_sw_clk,
+ &pll2_sw_clk,
+ &pll3_sw_clk,
+ &gpc_dvfs_clk,
+ &lp_apm_clk,
+ &cpu_clk,
+ &periph_apm_clk,
+ &main_bus_clk,
+ &axi_a_clk,
+ &axi_b_clk,
+ &axi_c_clk,
+ &ahb_clk,
+ &ahb_max_clk,
+ &aips_tz1_clk,
+ &aips_tz2_clk,
+ &ipg_clk,
+ &ipg_perclk,
+ &sdma_clk[0],
+ &sdma_clk[1],
+ &ipu_clk[0],
+ &ipu_clk[1],
+ &ipu_di_clk,
+ &tve_clk,
+ &uart_main_clk,
+ &uart1_clk[0],
+ &uart1_clk[1],
+ &uart2_clk[0],
+ &uart2_clk[1],
+ &uart3_clk[0],
+ &uart3_clk[1],
+ &spba_clk,
+ &i2c_clk[0],
+ &i2c_clk[1],
+ &i2c_clk[2],
+ &gpt_clk[0],
+ &gpt_clk[1],
+ &gpt_clk[2],
+ &cspi_main_clk,
+ &cspi1_clk[0],
+ &cspi1_clk[1],
+ &cspi2_clk[0],
+ &cspi2_clk[1],
+ &cspi3_clk[0],
+ &cspi3_clk[1],
+ &ssi_lp_apm_clk,
+ &ssi1_clk[0],
+ &ssi1_clk[1],
+ &ssi2_clk[0],
+ &ssi2_clk[1],
+ &ssi_ext1_clk,
+ &ssi_ext2_clk,
+ &iim_clk,
+ &tmax1_clk,
+ &tmax2_clk,
+ &ahbmux1_clk,
+ &ahbmux2_clk,
+ &usb_core_clk[0],
+ &usb_core_clk[1],
+ &usb_core_clk[2],
+ &usb_core_clk[3],
+ &usboh2_clk,
+ &usb_phy_clk,
+ &usb_clk,
+ &esdhc1_clk[0],
+ &esdhc1_clk[1],
+ &esdhc1_clk[2],
+ &esdhc2_clk[0],
+ &esdhc2_clk[1],
+ &esdhc2_clk[2],
+ &esdhc3_clk[0],
+ &esdhc3_clk[1],
+ &esdhc3_clk[2],
+ &esdhc_dep_clks,
+ &emi_core_clk,
+ &emi_fast_clk,
+ &emi_slow_clk,
+ &emi_intr_clk,
+ &nfc_clk,
+ &spdif_xtal_clk,
+ &spdif0_clk[0],
+ &spdif0_clk[1],
+ &spdif1_clk[0],
+ &spdif1_clk[1],
+ &ddr_clk,
+ &arm_axi_clk,
+ &vpu_clk[0],
+ &vpu_clk[1],
+ &vpu_clk[2],
+ &lpsr_clk,
+ &pgc_clk,
+ &rtc_clk,
+ &ata_clk,
+ &rng_clk,
+ &scc_clk,
+ &cko1_clk,
+};
+
+static void clk_tree_init(void)
+{
+ u32 reg, dp_ctl;
+
+ ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk);
+
+ /*
+ *Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at
+ * 8MHz, its derived from lp_apm.
+ */
+ reg = __raw_readl(MXC_CCM_CBCDR2);
+ reg &= ~MXC_CCM_CBCDR2_PERCLK_PRED1_MASK;
+ reg &= ~MXC_CCM_CBCDR2_PERCLK_PRED2_MASK;
+ reg &= ~MXC_CCM_CBCDR2_PERCLK_PODF_MASK;
+ reg |= (2 << MXC_CCM_CBCDR2_PERCLK_PRED1_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR2);
+
+ /* set pll1_main_clk parent */
+ pll1_main_clk.parent = &osc_clk;
+ dp_ctl = __raw_readl(pll_base[0] + MXC_PLL_DP_CTL);
+ if ((dp_ctl & MXC_PLL_DP_CTL_REF_CLK_SEL_MASK) == 0)
+ pll1_main_clk.parent = &fpm_clk;
+ /* set pll2_sw_clk parent */
+ pll2_sw_clk.parent = &osc_clk;
+ dp_ctl = __raw_readl(pll_base[1] + MXC_PLL_DP_CTL);
+ if ((dp_ctl & MXC_PLL_DP_CTL_REF_CLK_SEL_MASK) == 0)
+ pll2_sw_clk.parent = &fpm_clk;
+ /* set pll3_clk parent */
+ pll3_sw_clk.parent = &osc_clk;
+ dp_ctl = __raw_readl(pll_base[2] + MXC_PLL_DP_CTL);
+ if ((dp_ctl & MXC_PLL_DP_CTL_REF_CLK_SEL_MASK) == 0)
+ pll3_sw_clk.parent = &fpm_clk;
+
+ /* set emi_core_clk parent */
+ emi_core_clk.parent = &main_bus_clk;
+ reg = __raw_readl(MXC_CCM_CBCDR6);
+ if ((reg & MXC_CCM_CBCDR6_EMI_CLK_SEL) != 0) {
+ emi_core_clk.parent = &ahb_clk;
+ }
+
+ /* set ipg_perclk parent */
+ ipg_perclk.parent = &lp_apm_clk;
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if ((reg & MXC_CCM_CSCMR1_PERCLK_IPG_CLK_SEL) != 0) {
+ ipg_perclk.parent = &ipg_clk;
+ } else {
+ if ((reg & MXC_CCM_CSCMR1_PERCLK_LP_APM_CLK_SEL) == 0)
+ ipg_perclk.parent = &main_bus_clk;
+ }
+
+ /* set DDR clock parent */
+ reg = __raw_readl(MXC_CCM_CAMR) & MXC_CCM_CAMR_DDR_CLK_SEL_MASK;
+ reg >>= MXC_CCM_CAMR_DDR_CLK_SEL_OFFSET;
+ if (reg == 0) {
+ ddr_clk.parent = &axi_a_clk;
+ } else if (reg == 1) {
+ ddr_clk.parent = &axi_b_clk;
+ } else if (reg == 2) {
+ ddr_clk.parent = &axi_c_clk;
+ } else {
+ ddr_clk.parent = &emi_core_clk;
+ }
+}
+
+int __init mxc_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2)
+{
+ struct clk **clkp;
+ u32 reg;
+ int i;
+
+ ckil_clk.rate = ckil;
+ ckih_clk.rate = ckih1;
+ osc_clk.rate = osc;
+
+ clk_tree_init();
+
+ for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++) {
+ clk_register(*clkp);
+ }
+
+ /* Turn off all possible clocks */
+ if (mxc_jtag_enabled) {
+ __raw_writel((1 << MXC_CCM_CCGR0_CG0_OFFSET) |
+ (1 << MXC_CCM_CCGR0_CG1_OFFSET) |
+ (1 << MXC_CCM_CCGR0_CG2_OFFSET) |
+ (1 << MXC_CCM_CCGR0_CG12_OFFSET) |
+ (1 << MXC_CCM_CCGR0_CG13_OFFSET) |
+ (1 << MXC_CCM_CCGR0_CG7_OFFSET) |
+ (1 << MXC_CCM_CCGR0_CG14_OFFSET), MXC_CCM_CCGR0);
+ } else {
+ __raw_writel((1 << MXC_CCM_CCGR0_CG0_OFFSET) |
+ (1 << MXC_CCM_CCGR0_CG1_OFFSET) |
+ (1 << MXC_CCM_CCGR0_CG12_OFFSET) |
+ (1 << MXC_CCM_CCGR0_CG13_OFFSET) |
+ (1 << MXC_CCM_CCGR0_CG7_OFFSET) |
+ (1 << MXC_CCM_CCGR0_CG14_OFFSET), MXC_CCM_CCGR0);
+ }
+ __raw_writel(0, MXC_CCM_CCGR1);
+
+ /* TMAX clocks. */
+ reg = __raw_readl(MXC_CCM_CCGR1);
+ reg |= 1 << MXC_CCM_CCGR1_CG0_OFFSET;
+ reg |= 1 << MXC_CCM_CCGR1_CG1_OFFSET;
+ __raw_writel(reg, MXC_CCM_CCGR1);
+
+ __raw_writel(0, MXC_CCM_CCGR2);
+ __raw_writel(0, MXC_CCM_CCGR3);
+ __raw_writel(0, MXC_CCM_CCGR4);
+ /* Initialise the EMI clocks to be OFF when ARM is in WAIT mode. */
+ __raw_writel((1 << MXC_CCM_CCGR5_CG4_OFFSET) |
+ (1 << MXC_CCM_CCGR5_CG12_OFFSET) |
+ (1 << MXC_CCM_CCGR5_CG13_OFFSET) |
+ (1 << MXC_CCM_CCGR5_CG14_OFFSET) |
+ MXC_CCM_CCGR5_CG11_MASK, MXC_CCM_CCGR5);
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+ /*STEP_CLK - make sure its source is lp_apm */
+ reg &= ~MXC_CCM_CCSR_STEP_SEL_MASK;
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ /* This will propagate to all children and init all the clock rates */
+ propagate_rate(&osc_clk);
+ propagate_rate(&ckih_clk);
+ propagate_rate(&ckil_clk);
+
+ _clk_pll_disable(&pll3_sw_clk);
+
+ clk_enable(&cpu_clk);
+ clk_enable(&main_bus_clk);
+
+ /* Move UART to run from pll2_sw_clk */
+ clk_set_parent(&uart_main_clk, &pll2_sw_clk);
+
+ /* Set the UART dividers to divide by 10, so the UART_CLK is 66.5MHz. */
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ reg &= ~MXC_CCM_CSCDR1_UART_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CSCDR1_UART_CLK_PRED_MASK;
+ reg |= (4 << MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) |
+ (1 << MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET);
+ __raw_writel(reg, MXC_CCM_CSCDR1);
+
+ /* move cspi to 24MHz */
+ clk_set_parent(&cspi_main_clk, &lp_apm_clk);
+ clk_set_rate(&cspi_main_clk, 12000000);
+
+ /*move the spdif0 to spdif_xtal_ckl */
+ clk_set_parent(&spdif0_clk[0], &spdif_xtal_clk);
+ /*set the SPDIF dividers to 1 */
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ reg &= ~MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK;
+ __raw_writel(reg, MXC_CCM_CDCDR);
+
+ /* move the spdif1 to 24MHz */
+ clk_set_parent(&spdif1_clk[0], &spdif_xtal_clk);
+ /* set the spdif1 dividers to 1 */
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ reg &= ~MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK;
+ __raw_writel(reg, MXC_CCM_CDCDR);
+
+ /* Move SSI clocks to SSI_LP_APM clock */
+ clk_set_parent(&ssi_lp_apm_clk, &lp_apm_clk);
+
+ clk_set_parent(&ssi1_clk[0], &ssi_lp_apm_clk);
+ /* set the SSI dividers to divide by 2 */
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ reg &= ~MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK;
+ reg |= 1 << MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CS1CDR);
+
+ clk_set_parent(&ssi2_clk[0], &ssi_lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+ reg &= ~MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK;
+ reg &= ~MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK;
+ reg |= 1 << MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CS2CDR);
+
+ /* Change the SSI_EXT1_CLK to be sourced from SSI1_CLK_ROOT */
+ clk_set_parent(&ssi_ext1_clk, &ssi1_clk[0]);
+ clk_set_parent(&ssi_ext2_clk, &ssi2_clk[0]);
+
+ propagate_rate(&ssi_lp_apm_clk);
+
+ clk_set_parent(&ipu_clk[0], &emi_core_clk);
+ clk_set_parent(&arm_axi_clk, &emi_core_clk);
+ clk_set_parent(&vpu_clk[0], &emi_core_clk);
+ clk_set_parent(&vpu_clk[1], &emi_core_clk);
+ clk_set_parent(&usb_phy_clk, &osc_clk);
+
+ clk_set_parent(&cko1_clk, &ipg_perclk);
+
+ /* Set the current working point. */
+ cpu_wp_tbl = get_cpu_wp(&cpu_wp_nr);
+ for (i = 0; i < cpu_wp_nr; i++) {
+ if (clk_get_rate(&cpu_clk) == cpu_wp_tbl[i].cpu_rate) {
+ cpu_curr_wp = i;
+ break;
+ }
+ }
+ if (i > cpu_wp_nr)
+ BUG();
+
+ propagate_rate(&osc_clk);
+ propagate_rate(&pll1_sw_clk);
+ propagate_rate(&pll2_sw_clk);
+
+ return 0;
+}
+
+/*!
+ * Setup cpu clock based on working point.
+ * @param wp cpu freq working point
+ * @return 0 on success or error code on failure.
+ */
+static int cpu_clk_set_wp(int wp)
+{
+ struct cpu_wp *p;
+ u32 reg;
+ u32 stat;
+
+ if (wp == cpu_curr_wp)
+ return 0;
+
+ p = &cpu_wp_tbl[wp];
+
+ /* Change the ARM clock to requested frequency */
+ /* First move the ARM clock to step clock which is running at 24MHz. */
+
+ /* Change the source of pll1_sw_clk to be the step_clk */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ /* Stop the PLL */
+ reg = __raw_readl(MXC_DPLL1_BASE + MXC_PLL_DP_CTL);
+ reg &= ~MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_CTL);
+
+ /* PDF and MFI */
+ reg = p->pdf | p->mfi << MXC_PLL_DP_OP_MFI_OFFSET;
+ __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_OP);
+
+ /* MFD */
+ __raw_writel(p->mfd, MXC_DPLL1_BASE + MXC_PLL_DP_MFD);
+
+ /* MFI */
+ __raw_writel(p->mfn, MXC_DPLL1_BASE + MXC_PLL_DP_MFN);
+
+ reg = __raw_readl(MXC_DPLL1_BASE + MXC_PLL_DP_CTL);
+ reg |= MXC_PLL_DP_CTL_UPEN;
+ /* Set the UPEN bits */
+ __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_CTL);
+ /* Forcefully restart the PLL */
+ reg |= MXC_PLL_DP_CTL_RST;
+ __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_CTL);
+
+ /* Wait for the PLL to lock */
+ do {
+ stat = __raw_readl(MXC_DPLL1_BASE + MXC_PLL_DP_CTL) &
+ MXC_PLL_DP_CTL_LRF;
+ } while (!stat);
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+ /* Move the PLL1 back to the pll1_main_clk */
+ reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ cpu_curr_wp = wp;
+
+ pll1_sw_clk.rate = cpu_wp_tbl[wp].cpu_rate;
+ pll1_main_clk.rate = pll1_sw_clk.rate;
+ cpu_clk.rate = pll1_sw_clk.rate;
+
+ if (wp == 0)
+ dptc_resume(DPTC_GP_ID);
+ else
+ dptc_suspend(DPTC_GP_ID);
+
+ return 0;
+}
diff --git a/arch/arm/mach-mx37/cpu.c b/arch/arm/mach-mx37/cpu.c
new file mode 100644
index 000000000000..1ca44ae9ed86
--- /dev/null
+++ b/arch/arm/mach-mx37/cpu.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2001 Deep Blue Solutions Ltd.
+ * Copyright 2004-2009 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
+ * published by the Free Software Foundation.
+ *
+ */
+
+/*!
+ * @file mach-mx37/cpu.c
+ *
+ * @brief This file contains the CPU initialization code.
+ *
+ * @ingroup MSL_MX37
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <mach/hardware.h>
+#include <linux/io.h>
+#include <asm/hardware/cache-l2x0.h>
+
+/*!
+ * CPU initialization. It is called by fixup_mxc_board()
+ */
+void __init mxc_cpu_init(void)
+{
+ if (!system_rev) {
+ mxc_set_system_rev(0x37, CHIP_REV_1_0);
+ }
+}
+
+/*!
+ * Post CPU init code
+ *
+ * @return 0 always
+ */
+static int __init post_cpu_init(void)
+{
+ void *l2_base;
+ volatile unsigned long aips_reg;
+
+ /* Initialize L2 cache */
+ l2_base = ioremap(L2CC_BASE_ADDR, SZ_4K);
+ if (l2_base) {
+ l2x0_init(l2_base, 0x0003001B, 0x00000000);
+ }
+
+ __raw_writel(0x0, IO_ADDRESS(AIPS1_BASE_ADDR + 0x40));
+ __raw_writel(0x0, IO_ADDRESS(AIPS1_BASE_ADDR + 0x44));
+ __raw_writel(0x0, IO_ADDRESS(AIPS1_BASE_ADDR + 0x48));
+ __raw_writel(0x0, IO_ADDRESS(AIPS1_BASE_ADDR + 0x4C));
+ aips_reg = __raw_readl(IO_ADDRESS(AIPS1_BASE_ADDR + 0x50));
+ aips_reg &= 0x00FFFFFF;
+ __raw_writel(aips_reg, IO_ADDRESS(AIPS1_BASE_ADDR + 0x50));
+
+ __raw_writel(0x0, IO_ADDRESS(AIPS2_BASE_ADDR + 0x40));
+ __raw_writel(0x0, IO_ADDRESS(AIPS2_BASE_ADDR + 0x44));
+ __raw_writel(0x0, IO_ADDRESS(AIPS2_BASE_ADDR + 0x48));
+ __raw_writel(0x0, IO_ADDRESS(AIPS2_BASE_ADDR + 0x4C));
+ aips_reg = __raw_readl(IO_ADDRESS(AIPS2_BASE_ADDR + 0x50));
+ aips_reg &= 0x00FFFFFF;
+ __raw_writel(aips_reg, IO_ADDRESS(AIPS2_BASE_ADDR + 0x50));
+
+ return 0;
+}
+
+postcore_initcall(post_cpu_init);
diff --git a/arch/arm/mach-mx37/crm_regs.h b/arch/arm/mach-mx37/crm_regs.h
new file mode 100644
index 000000000000..ccc96f02ff68
--- /dev/null
+++ b/arch/arm/mach-mx37/crm_regs.h
@@ -0,0 +1,611 @@
+/*
+ * Copyright 2007-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ARCH_ARM_MACH_MX37_CRM_REGS_H__
+#define __ARCH_ARM_MACH_MX37_CRM_REGS_H__
+
+#define MXC_CCM_BASE ((char *)IO_ADDRESS(CCM_BASE_ADDR))
+#define MXC_DPLL1_BASE IO_ADDRESS(PLL0_BASE_ADDR)
+#define MXC_DPLL2_BASE IO_ADDRESS(PLL1_BASE_ADDR)
+#define MXC_DPLL3_BASE IO_ADDRESS(PLL2_BASE_ADDR)
+
+/* PLL Register Offsets */
+#define MXC_PLL_DP_CTL 0x00
+#define MXC_PLL_DP_CONFIG 0x04
+#define MXC_PLL_DP_OP 0x08
+#define MXC_PLL_DP_MFD 0x0C
+#define MXC_PLL_DP_MFN 0x10
+#define MXC_PLL_DP_MFNMINUS 0x14
+#define MXC_PLL_DP_MFNPLUS 0x18
+#define MXC_PLL_DP_HFS_OP 0x1C
+#define MXC_PLL_DP_HFS_MFD 0x20
+#define MXC_PLL_DP_HFS_MFN 0x24
+#define MXC_PLL_DP_MFN_TOGC 0x28
+#define MXC_PLL_DP_DESTAT 0x2c
+
+/* PLL Register Bit definitions */
+#define MXC_PLL_DP_CTL_MUL_CTRL 0x2000
+#define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000
+#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET 12
+#define MXC_PLL_DP_CTL_ADE 0x800
+#define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK (3 << 8)
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET 8
+#define MXC_PLL_DP_CTL_HFSM 0x80
+#define MXC_PLL_DP_CTL_PRE 0x40
+#define MXC_PLL_DP_CTL_UPEN 0x20
+#define MXC_PLL_DP_CTL_RST 0x10
+#define MXC_PLL_DP_CTL_RCP 0x8
+#define MXC_PLL_DP_CTL_PLM 0x4
+#define MXC_PLL_DP_CTL_BRM0 0x2
+#define MXC_PLL_DP_CTL_LRF 0x1
+
+#define MXC_PLL_DP_CONFIG_BIST 0x8
+#define MXC_PLL_DP_CONFIG_SJC_CE 0x4
+#define MXC_PLL_DP_CONFIG_AREN 0x2
+#define MXC_PLL_DP_CONFIG_LDREQ 0x1
+
+#define MXC_PLL_DP_OP_MFI_OFFSET 4
+#define MXC_PLL_DP_OP_MFI_MASK (0xF << 4)
+#define MXC_PLL_DP_OP_PDF_OFFSET 0
+#define MXC_PLL_DP_OP_PDF_MASK 0xF
+
+#define MXC_PLL_DP_MFD_OFFSET 0
+#define MXC_PLL_DP_MFD_MASK 0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_OFFSET 0x0
+#define MXC_PLL_DP_MFN_MASK 0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_TOGC_TOG_DIS (1 << 17)
+#define MXC_PLL_DP_MFN_TOGC_TOG_EN (1 << 16)
+#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET 0x0
+#define MXC_PLL_DP_MFN_TOGC_CNT_MASK 0xFFFF
+
+#define MXC_PLL_DP_DESTAT_TOG_SEL (1 << 31)
+#define MXC_PLL_DP_DESTAT_MFN 0x07FFFFFF
+
+/* Register addresses of CCM*/
+#define MXC_CCM_CCR (MXC_CCM_BASE + 0x00)
+#define MXC_CCM_CCDR (MXC_CCM_BASE + 0x04)
+#define MXC_CCM_CSR (MXC_CCM_BASE + 0x08)
+#define MXC_CCM_CCSR (MXC_CCM_BASE + 0x0C)
+#define MXC_CCM_CACRR (MXC_CCM_BASE + 0x10)
+#define MXC_CCM_CBCDR2 (MXC_CCM_BASE + 0x18)
+#define MXC_CCM_CBCDR3 (MXC_CCM_BASE + 0x1C)
+#define MXC_CCM_CBCDR4 (MXC_CCM_BASE + 0x20)
+#define MXC_CCM_CBCDR5 (MXC_CCM_BASE + 0x24)
+#define MXC_CCM_CBCDR6 (MXC_CCM_BASE + 0x28)
+#define MXC_CCM_CBCDR7 (MXC_CCM_BASE + 0x2C)
+#define MXC_CCM_CAMR (MXC_CCM_BASE + 0x30)
+#define MXC_CCM_CSCMR1 (MXC_CCM_BASE + 0x34)
+#define MXC_CCM_CSCMR2 (MXC_CCM_BASE + 0x38)
+#define MXC_CCM_CSCDR1 (MXC_CCM_BASE + 0x3C)
+#define MXC_CCM_CS1CDR (MXC_CCM_BASE + 0x40)
+#define MXC_CCM_CS2CDR (MXC_CCM_BASE + 0x44)
+#define MXC_CCM_CSECDR1 (MXC_CCM_BASE + 0x48)
+#define MXC_CCM_CSECDR2 (MXC_CCM_BASE + 0x4C)
+#define MXC_CCM_CECDR (MXC_CCM_BASE + 0x50)
+#define MXC_CCM_CDCDR (MXC_CCM_BASE + 0x54)
+#define MXC_CCM_CH1CDR (MXC_CCM_BASE + 0x58)
+#define MXC_CCM_CH2CDR (MXC_CCM_BASE + 0x5C)
+#define MXC_CCM_CSCDR2 (MXC_CCM_BASE + 0x60)
+#define MXC_CCM_CR2 (MXC_CCM_BASE + 0x64)
+#define MXC_CCM_CDHIPR (MXC_CCM_BASE + 0x68)
+#define MXC_CCM_CDCR (MXC_CCM_BASE + 0x6C)
+#define MXC_CCM_CTOR (MXC_CCM_BASE + 0x70)
+#define MXC_CCM_CLPCR (MXC_CCM_BASE + 0x74)
+#define MXC_CCM_CISR (MXC_CCM_BASE + 0x78)
+#define MXC_CCM_CIMR (MXC_CCM_BASE + 0x7C)
+#define MXC_CCM_CCOSR (MXC_CCM_BASE + 0x80)
+#define MXC_CCM_CGPR (MXC_CCM_BASE + 0x84)
+#define MXC_CCM_CCGR0 (MXC_CCM_BASE + 0x88)
+#define MXC_CCM_CCGR1 (MXC_CCM_BASE + 0x8C)
+#define MXC_CCM_CCGR2 (MXC_CCM_BASE + 0x90)
+#define MXC_CCM_CCGR3 (MXC_CCM_BASE + 0x94)
+#define MXC_CCM_CCGR4 (MXC_CCM_BASE + 0x98)
+#define MXC_CCM_CCGR5 (MXC_CCM_BASE + 0x9C)
+#define MXC_CCM_CMEOR (MXC_CCM_BASE + 0xA0)
+
+/* Define the bits in register CCR */
+#define MXC_CCM_CCR_COSC_EN (1 << 11)
+#define MXC_CCM_CCR_FPM_MULT_MASK (1 << 10)
+#define MXC_CCM_CCR_CAMP_EN (1 << 9)
+#define MXC_CCM_CCR_FPM_EN (1 << 8)
+#define MXC_CCM_CCR_OSCNT_OFFSET (0)
+#define MXC_CCM_CCR_OSCNT_MASK (0xFF)
+
+/* Define the bits in register CCDR */
+#define MXC_CCM_CCDR_IPU_HS_MASK (0x1 << 17)
+#define MXC_CCM_CCDR_EMI_HS_MASK (0x1 << 16)
+#define MXC_CCM_CCDR_LOAD_DIVIDERS (0x1 << 0)
+
+/* Define the bits in register CSR */
+#define MXC_CCM_CSR_COSR_READY (1 << 4)
+#define MXC_CCM_CSR_LVS_VALUE (1 << 3)
+#define MXC_CCM_CSR_CAMP_READY (1 << 2)
+#define MXC_CCM_CSR_FPM_READY (1 << 1)
+#define MXC_CCM_CSR_REF_EN_B (1 << 0)
+
+/* Define the bits in register CCSR */
+#define MXC_CCM_CCSR_LP_APM_SEL (0x1 << 9)
+#define MXC_CCM_CCSR_STEP_SEL_OFFSET (7)
+#define MXC_CCM_CCSR_STEP_SEL_MASK (0x3 << 7)
+#define MXC_CCM_CCSR_PLL2_PODF_OFFSET (5)
+#define MXC_CCM_CCSR_PLL2_PODF_MASK (0x3 << 5)
+#define MXC_CCM_CCSR_PLL3_PODF_OFFSET (3)
+#define MXC_CCM_CCSR_PLL3_PODF_MASK (0x3 << 3)
+#define MXC_CCM_CCSR_PLL1_SW_CLK_SEL (1 << 2)
+#define MXC_CCM_CCSR_PLL2_SW_CLK_SEL (1 << 1)
+#define MXC_CCM_CCSR_PLL3_SW_CLK_SEL (1 << 0)
+
+/* Define the bits in register CACRR */
+#define MXC_CCM_CACRR_ARM_PODF_OFFSET (0)
+#define MXC_CCM_CACRR_ARM_PODF_MASK (0x7)
+
+/* Define the bits in register CBCDR2 */
+#define MXC_CCM_CBCDR2_AHB_PODF_OFFSET (10)
+#define MXC_CCM_CBCDR2_AHB_PODF_MASK (0x7 << 10)
+#define MXC_CCM_CBCDR2_IPG_PODF_OFFSET (8)
+#define MXC_CCM_CBCDR2_IPG_PODF_MASK (0x3 << 8)
+#define MXC_CCM_CBCDR2_PERCLK_PRED1_OFFSET (6)
+#define MXC_CCM_CBCDR2_PERCLK_PRED1_MASK (0x3 << 6)
+#define MXC_CCM_CBCDR2_PERCLK_PRED2_OFFSET (3)
+#define MXC_CCM_CBCDR2_PERCLK_PRED2_MASK (0x7 << 3)
+#define MXC_CCM_CBCDR2_PERCLK_PODF_OFFSET (0)
+#define MXC_CCM_CBCDR2_PERCLK_PODF_MASK (0x7)
+
+/* Define the bits in register CBCDR3 */
+#define MXC_CCM_CBCDR3_AXI_A_PODF_OFFSET (0)
+#define MXC_CCM_CBCDR3_AXI_A_PODF_MASK (0x7)
+
+/* Define the bits in register CBCDR4 */
+#define MXC_CCM_CBCDR4_AXI_B_PODF_OFFSET (0)
+#define MXC_CCM_CBCDR4_AXI_B_PODF_MASK (0x7)
+
+/* Define the bits in register CBCDR5 */
+#define MXC_CCM_CBCDR5_AXI_C_PODF_OFFSET (0)
+#define MXC_CCM_CBCDR5_AXI_C_PODF_MASK (0x7)
+
+/* Define the bits in register CBCDR6 */
+#define MXC_CCM_CBCDR6_EMI_PODF_OFFSET (0)
+#define MXC_CCM_CBCDR6_EMI_PODF_MASK (0x7)
+#define MXC_CCM_CBCDR6_EMI_CLK_SEL (0x1 << 3)
+#define MXC_CCM_CBCDR6_PERIPH_CLK_SEL (0x1 << 4)
+
+/* Define the bits in register CBCDR7 */
+#define MXC_CCM_CBCDR7_IPG_INT_MEM_PODF_OFFSET (3)
+#define MXC_CCM_CBCDR7_IPG_INIT_MEM_PODF_MASK (0x3 << 3)
+#define MXC_CCM_CBCDR7_NFC_PODF_OFFSET (0)
+#define MXC_CCM_CBCDR7_NFC_PODF_MASK (0x7)
+
+/* Define the bits in register CAMR */
+#define MXC_CCM_CAMR_PERIPH_CLK_SEL_OFFSET (12)
+#define MXC_CCM_CAMR_PERIPH_CLK_SEL_MASK (0x3 << 12)
+#define MXC_CCM_CAMR_DDR_CLK_SEL_OFFSET (10)
+#define MXC_CCM_CAMR_DDR_CLK_SEL_MASK (0x3 << 10)
+#define MXC_CCM_CAMR_ARM_AXI_CLK_SEL_OFFSET (8)
+#define MXC_CCM_CAMR_ARM_AXI_CLK_SEL_MASK (0x3 << 8)
+#define MXC_CCM_CAMR_VPU_CLK_SEL_OFFSET (6)
+#define MXC_CCM_CAMR_VPU_CLK_SEL_MASK (0x3 << 6)
+#define MXC_CCM_CAMR_VPU_AXI_CLK_SEL_OFFSET (4)
+#define MXC_CCM_CAMR_VPU_AXI_CLK_SEL_MASK (0x3 << 4)
+#define MXC_CCM_CAMR_IPU_HSP_CLK_SEL_OFFSET (2)
+#define MXC_CCM_CAMR_IPU_HSP_CLK_SEL_MASK (0x3 << 2)
+
+/* Define the bits in register CSCMR1 */
+#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET (30)
+#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK (0x3 << 30)
+#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET (28)
+#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK (0x3 << 28)
+#define MXC_CCM_CSCMR1_DI_CLK_SEL (0x1 << 27)
+#define MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET (26)
+#define MXC_CCM_CSCMR1_USB_PHY_CLK_SEL (0x1 << 26)
+#define MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET (24)
+#define MXC_CCM_CSCMR1_UART_CLK_SEL_MASK (0x3 << 24)
+#define MXC_CCM_CSCMR1_USBOH2_CLK_SEL_OFFSET (22)
+#define MXC_CCM_CSCMR1_USBOH2_CLK_SEL_MASK (0x3 << 22)
+#define MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET (20)
+#define MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK (0x3 << 20)
+#define MXC_CCM_CSCMR1_ESDHC3_CLK_SEL (0x1 << 19)
+#define MXC_CCM_CSCMR1_PERCLK_IPG_CLK_SEL (0x1 << 18)
+#define MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_OFFSET (16)
+#define MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_MASK (0x3 << 16)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET (12)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK (0x3 << 12)
+#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL (0x1 << 9)
+#define MXC_CCM_CSCMR1_SPDIF_CLK_SEL (0x1 << 8)
+#define MXC_CCM_CSCMR1_TVE_CLK_SEL (0x1 << 7)
+#define MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL (0x1 << 6)
+#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET (4)
+#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK (0x3 << 4)
+#define MXC_CCM_CSCMR1_PERCLK_LP_APM_CLK_SEL (0x1 << 2)
+#define MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL (0x1 << 1)
+#define MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL (0x1)
+
+/* Define the bits in register CSCMR2 */
+#define MXC_CCM_CSCMR2_SPDIF1_COM (1 << 5)
+#define MXC_CCM_CSCMR2_SPDIF0_COM (1 << 4)
+#define MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_OFFSET (2)
+#define MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_MASK (0x3 << 2)
+#define MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_OFFSET (0)
+#define MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK (0x3)
+
+/* Define the bits in register CSCDR1 */
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET (22)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK (0x7 << 22)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK (0x7 << 19)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET (14)
+#define MXC_CCM_CSCDR1_PGC_CLK_PODF_MASK (0x3 << 14)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET (11)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK (0x7 << 11)
+#define MXC_CCM_CSCDR1_USBOH2_CLK_PRED_OFFSET (8)
+#define MXC_CCM_CSCDR1_USBOH2_CLK_PRED_MASK (0x7 << 8)
+#define MXC_CCM_CSCDR1_USBOH2_CLK_PODF_OFFSET (6)
+#define MXC_CCM_CSCDR1_USBOH2_CLK_PODF_MASK (0x3 << 6)
+#define MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET (3)
+#define MXC_CCM_CSCDR1_UART_CLK_PRED_MASK (0x7 << 3)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK (0x7)
+
+/* Define the bits in register CS1CDR and CS2CDR */
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK (0x3F)
+
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK (0x3F)
+
+/* Define the bits in register CSECDR1 and CSECDR2 */
+#define MXC_CCM_CSECDR1_SSI_EXT1_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CSECDR1_SSI_EXT1_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CSECDR1_SSI_EXT1_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CSECDR1_SSI_EXT1_CLK_PODF_MASK (0x3F)
+
+#define MXC_CCM_CSECDR2_SSI_EXT2_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CSECDR2_SSI_EXT2_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CSECDR2_SSI_EXT2_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CSECDR2_SSI_EXT2_CLK_PODF_MASK (0x3F)
+
+/* Define the bits in register CDCDR */
+#define MXC_CCM_CDCDR_TVE_CLK_PRED_OFFSET (28)
+#define MXC_CCM_CDCDR_TVE_CLK_PRED_MASK (0x7 << 28)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET (25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK (0x7 << 25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK (0x3F << 19)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET (9)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK (0x3F << 9)
+#define MXC_CCM_CDCDR_USB_PHY_PRED_OFFSET (4)
+#define MXC_CCM_CDCDR_USB_PHY_PRED_MASK (0x7 << 4)
+#define MXC_CCM_CDCDR_USB_PHY_PODF_OFFSET (1)
+#define MXC_CCM_CDCDR_USB_PHY_PODF_MASK (0x7 << 1)
+
+/* Define the bits in register CSCDR2 */
+#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET (25)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK (0x7 << 25)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK (0x3F << 19)
+
+/* Define the bits in register CDHIPR */
+#define MXC_CCM_CDHIPR_ARM_PODF_BUSY (1 << 16)
+#define MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY (1 << 4)
+#define MXC_CCM_CDHIPR_EMI_PODF_BUSY (1 << 3)
+#define MXC_CCM_CDHIPR_AXI_C_PODF_BUSY (1 << 2)
+#define MXC_CCM_CDHIPR_AXI_B_PODF_BUSY (1 << 1)
+#define MXC_CCM_CDHIPR_AXI_A_PODF_BUSY (1 << 0)
+
+/* Define the bits in register CDCR */
+#define MXC_CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER (0x1 << 2)
+#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_OFFSET (0)
+#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_MASK (0x3)
+
+/* Define the bits in register CLPCR */
+#define MXC_CCM_CLPCR_BYPASS_SCC_LPM_HS (0x1 << 22)
+#define MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS (0x1 << 21)
+#define MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS (0x1 << 20)
+#define MXC_CCM_CLPCR_BYPASS_EMI_LPM_HS (0x1 << 19)
+#define MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS (0x1 << 18)
+#define MXC_CCM_CLPCR_BYPASS_RTIC_LPM_HS (0x1 << 17)
+#define MXC_CCM_CLPCR_BYPASS_RNGC_LPM_HS (0x1 << 16)
+#define MXC_CCM_CLPCR_COSC_PWRDOWN (0x1 << 11)
+#define MXC_CCM_CLPCR_STBY_COUNT_OFFSET (9)
+#define MXC_CCM_CLPCR_STBY_COUNT_MASK (0x3 << 9)
+#define MXC_CCM_CLPCR_VSTBY (0x1 << 8)
+#define MXC_CCM_CLPCR_DIS_REF_OSC (0x1 << 7)
+#define MXC_CCM_CLPCR_SBYOS (0x1 << 6)
+#define MXC_CCM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET (3)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK (0x3 << 3)
+#define MXC_CCM_CLPCR_LPM_OFFSET (0)
+#define MXC_CCM_CLPCR_LPM_MASK (0x3)
+
+/* Define the bits in register CISR */
+#define MXC_CCM_CISR_ARM_PODF_LOADED (0x1 << 25)
+#define MXC_CCM_CISR_NFC_IPG_INT_MEM_PODF_LOADED (0x1 << 21)
+#define MXC_CCM_CISR_EMI_PODF_LOADED (0x1 << 20)
+#define MXC_CCM_CISR_AXI_C_PODF_LOADED (0x1 << 19)
+#define MXC_CCM_CISR_AXI_B_PODF_LOADED (0x1 << 18)
+#define MXC_CCM_CISR_AXI_A_PODF_LOADED (0x1 << 17)
+#define MXC_CCM_CISR_DIVIDER_LOADED (0x1 << 16)
+#define MXC_CCM_CISR_COSC_READY (0x1 << 5)
+#define MXC_CCM_CISR_CKIH_READY (0x1 << 4)
+#define MXC_CCM_CISR_FPM_READY (0x1 << 3)
+#define MXC_CCM_CISR_LRF_PLL3 (0x1 << 2)
+#define MXC_CCM_CISR_LRF_PLL2 (0x1 << 1)
+#define MXC_CCM_CISR_LRF_PLL1 (0x1)
+
+/* Define the bits in register CIMR */
+#define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED (0x1 << 25)
+#define MXC_CCM_CIMR_MASK_NFC_IPG_INT_MEM_PODF_LOADED (0x1 << 21)
+#define MXC_CCM_CIMR_MASK_EMI_PODF_LOADED (0x1 << 20)
+#define MXC_CCM_CIMR_MASK_AXI_C_PODF_LOADED (0x1 << 19)
+#define MXC_CCM_CIMR_MASK_AXI_B_PODF_LOADED (0x1 << 18)
+#define MXC_CCM_CIMR_MASK_AXI_A_PODF_LOADED (0x1 << 17)
+#define MXC_CCM_CIMR_MASK_DIVIDER_LOADED (0x1 << 16)
+#define MXC_CCM_CIMR_MASK_COSC_READY (0x1 << 5)
+#define MXC_CCM_CIMR_MASK_CKIH_READY (0x1 << 4)
+#define MXC_CCM_CIMR_MASK_FPM_READY (0x1 << 3)
+#define MXC_CCM_CIMR_MASK_LRF_PLL3 (0x1 << 2)
+#define MXC_CCM_CIMR_MASK_LRF_PLL2 (0x1 << 1)
+#define MXC_CCM_CIMR_MASK_LRF_PLL1 (0x1)
+
+/* Define the bits in register CCOSR */
+#define MXC_CCM_CCOSR_CKO2_EN_OFFSET (0x1 << 24)
+#define MXC_CCM_CCOSR_CKO2_DIV_OFFSET (21)
+#define MXC_CCM_CCOSR_CKO2_DIV_MASK (0x7 << 21)
+#define MXC_CCM_CCOSR_CKO2_SEL_OFFSET (16)
+#define MXC_CCM_CCOSR_CKO2_SEL_MASK (0x1F << 16)
+#define MXC_CCM_CCOSR_CKOL_EN (0x1 << 7)
+#define MXC_CCM_CCOSR_CKOL_DIV_OFFSET (4)
+#define MXC_CCM_CCOSR_CKOL_DIV_MASK (0x7 << 4)
+#define MXC_CCM_CCOSR_CKOL_SEL_OFFSET (0)
+#define MXC_CCM_CCOSR_CKOL_SEL_MASK (0xF)
+
+/* Define the bits in registers CGPR */
+#define MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE (0x1 << 4)
+#define MXC_CCM_CGPR_FPM_SEL (0x1 << 3)
+#define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_OFFSET (0)
+#define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_MASK (0x7)
+
+/* Define the bits in registers CCGRx */
+#define MXC_CCM_CCGR_CG_MASK 0x3
+
+#define MXC_CCM_CCGR0_CG15_OFFSET 30
+#define MXC_CCM_CCGR0_CG14_OFFSET 28
+#define MXC_CCM_CCGR0_CG14_MASK (0x3 << 28)
+#define MXC_CCM_CCGR0_CG13_OFFSET 26
+#define MXC_CCM_CCGR0_CG13_MASK (0x3 << 26)
+#define MXC_CCM_CCGR0_CG12_OFFSET 24
+#define MXC_CCM_CCGR0_CG12_MASK (0x3 << 24)
+#define MXC_CCM_CCGR0_CG11_OFFSET 22
+#define MXC_CCM_CCGR0_CG10_OFFSET 20
+#define MXC_CCM_CCGR0_CG9_OFFSET 18
+#define MXC_CCM_CCGR0_CG8_OFFSET 16
+#define MXC_CCM_CCGR0_CG7_OFFSET 14
+#define MXC_CCM_CCGR0_CG6_OFFSET 12
+#define MXC_CCM_CCGR0_CG5_OFFSET 10
+#define MXC_CCM_CCGR0_CG4_OFFSET 8
+#define MXC_CCM_CCGR0_CG3_OFFSET 6
+#define MXC_CCM_CCGR0_CG2_OFFSET 4
+#define MXC_CCM_CCGR0_CG2_MASK (0x3 << 4)
+#define MXC_CCM_CCGR0_CG1_OFFSET 2
+#define MXC_CCM_CCGR0_CG1_MASK (0x3 << 2)
+#define MXC_CCM_CCGR0_CG0_OFFSET 0
+#define MXC_CCM_CCGR0_CG0_MASK 0x3
+
+#define MXC_CCM_CCGR1_CG15_OFFSET 30
+#define MXC_CCM_CCGR1_CG14_OFFSET 28
+#define MXC_CCM_CCGR1_CG13_OFFSET 26
+#define MXC_CCM_CCGR1_CG12_OFFSET 24
+#define MXC_CCM_CCGR1_CG11_OFFSET 22
+#define MXC_CCM_CCGR1_CG10_OFFSET 20
+#define MXC_CCM_CCGR1_CG9_OFFSET 18
+#define MXC_CCM_CCGR1_CG8_OFFSET 16
+#define MXC_CCM_CCGR1_CG7_OFFSET 14
+#define MXC_CCM_CCGR1_CG6_OFFSET 12
+#define MXC_CCM_CCGR1_CG5_OFFSET 10
+#define MXC_CCM_CCGR1_CG4_OFFSET 8
+#define MXC_CCM_CCGR1_CG3_OFFSET 6
+#define MXC_CCM_CCGR1_CG2_OFFSET 4
+#define MXC_CCM_CCGR1_CG1_OFFSET 2
+#define MXC_CCM_CCGR1_CG0_OFFSET 0
+
+#define MXC_CCM_CCGR2_CG15_OFFSET 30
+#define MXC_CCM_CCGR2_CG14_OFFSET 28
+#define MXC_CCM_CCGR2_CG13_OFFSET 26
+#define MXC_CCM_CCGR2_CG12_OFFSET 24
+#define MXC_CCM_CCGR2_CG11_OFFSET 22
+#define MXC_CCM_CCGR2_CG10_OFFSET 20
+#define MXC_CCM_CCGR2_CG9_OFFSET 18
+#define MXC_CCM_CCGR2_CG8_OFFSET 16
+#define MXC_CCM_CCGR2_CG7_OFFSET 14
+#define MXC_CCM_CCGR2_CG6_OFFSET 12
+#define MXC_CCM_CCGR2_CG5_OFFSET 10
+#define MXC_CCM_CCGR2_CG4_OFFSET 8
+#define MXC_CCM_CCGR2_CG3_OFFSET 6
+#define MXC_CCM_CCGR2_CG2_OFFSET 4
+#define MXC_CCM_CCGR2_CG1_OFFSET 2
+#define MXC_CCM_CCGR2_CG0_OFFSET 0
+
+#define MXC_CCM_CCGR3_CG15_OFFSET 30
+#define MXC_CCM_CCGR3_CG14_OFFSET 28
+#define MXC_CCM_CCGR3_CG13_OFFSET 26
+#define MXC_CCM_CCGR3_CG12_OFFSET 24
+#define MXC_CCM_CCGR3_CG11_OFFSET 22
+#define MXC_CCM_CCGR3_CG10_OFFSET 20
+#define MXC_CCM_CCGR3_CG9_OFFSET 18
+#define MXC_CCM_CCGR3_CG8_OFFSET 16
+#define MXC_CCM_CCGR3_CG7_OFFSET 14
+#define MXC_CCM_CCGR3_CG6_OFFSET 12
+#define MXC_CCM_CCGR3_CG5_OFFSET 10
+#define MXC_CCM_CCGR3_CG4_OFFSET 8
+#define MXC_CCM_CCGR3_CG3_OFFSET 6
+#define MXC_CCM_CCGR3_CG2_OFFSET 4
+#define MXC_CCM_CCGR3_CG1_OFFSET 2
+#define MXC_CCM_CCGR3_CG0_OFFSET 0
+
+#define MXC_CCM_CCGR4_CG15_OFFSET 30
+#define MXC_CCM_CCGR4_CG14_OFFSET 28
+#define MXC_CCM_CCGR4_CG13_OFFSET 26
+#define MXC_CCM_CCGR4_CG12_OFFSET 24
+#define MXC_CCM_CCGR4_CG11_OFFSET 22
+#define MXC_CCM_CCGR4_CG10_OFFSET 20
+#define MXC_CCM_CCGR4_CG9_OFFSET 18
+#define MXC_CCM_CCGR4_CG8_OFFSET 16
+#define MXC_CCM_CCGR4_CG7_OFFSET 14
+#define MXC_CCM_CCGR4_CG6_OFFSET 12
+#define MXC_CCM_CCGR4_CG5_OFFSET 10
+#define MXC_CCM_CCGR4_CG4_OFFSET 8
+#define MXC_CCM_CCGR4_CG3_OFFSET 6
+#define MXC_CCM_CCGR4_CG2_OFFSET 4
+#define MXC_CCM_CCGR4_CG1_OFFSET 2
+#define MXC_CCM_CCGR4_CG0_OFFSET 0
+
+#define MXC_CCM_CCGR5_CG15_OFFSET 30
+#define MXC_CCM_CCGR5_CG14_OFFSET 28
+#define MXC_CCM_CCGR5_CG14_MASK (0x3 << 28)
+#define MXC_CCM_CCGR5_CG13_OFFSET 26
+#define MXC_CCM_CCGR5_CG13_MASK (0x3 << 26)
+#define MXC_CCM_CCGR5_CG12_OFFSET 24
+#define MXC_CCM_CCGR5_CG12_MASK (0x3 << 24)
+#define MXC_CCM_CCGR5_CG11_OFFSET 22
+#define MXC_CCM_CCGR5_CG11_MASK (0x3 << 22)
+#define MXC_CCM_CCGR5_CG10_OFFSET 20
+#define MXC_CCM_CCGR5_CG9_OFFSET 18
+#define MXC_CCM_CCGR5_CG8_OFFSET 16
+#define MXC_CCM_CCGR5_CG7_OFFSET 14
+#define MXC_CCM_CCGR5_CG6_OFFSET 12
+#define MXC_CCM_CCGR5_CG5_OFFSET 10
+#define MXC_CCM_CCGR5_CG4_OFFSET 8
+#define MXC_CCM_CCGR5_CG3_OFFSET 6
+#define MXC_CCM_CCGR5_CG2_OFFSET 4
+#define MXC_CCM_CCGR5_CG1_OFFSET 2
+#define MXC_CCM_CCGR5_CG0_OFFSET 0
+
+#define MXC_ARM1176_BASE IO_ADDRESS(ARM1176_BASE_ADDR)
+#define MXC_GPC_BASE IO_ADDRESS(GPC_BASE_ADDR)
+#define MXC_DPTC_LP_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x80)
+#define MXC_DPTC_GP_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x100)
+#define MXC_DVFS_CORE_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x180)
+#define MXC_DPTC_PER_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x1C0)
+#define MXC_PGC_IPU_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x220)
+#define MXC_PGC_VPU_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x240)
+#define MXC_SRPGC_EMI_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x280)
+#define MXC_SRPGC_ARM_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x2A0)
+#define MXC_EMPGC0_ARM_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x2C0)
+#define MXC_EMPGC1_ARM_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x2D0)
+
+/* ARM1176 platform */
+#define MXC_ARM1176_PLAT_PVID (MXC_ARM1176_BASE + 0x0)
+#define MXC_ARM1176_PLAT_GPC (MXC_ARM1176_BASE + 0x4)
+#define MXC_ARM1176_PLAT_PIC (MXC_ARM1176_BASE + 0x8)
+#define MXC_ARM1176_PLAT_L2SO (MXC_ARM1176_BASE + 0xC)
+#define MXC_ARM1176_PLAT_EMSO (MXC_ARM1176_BASE + 0x10)
+#define MXC_ARM1176_PLAT_LPC (MXC_ARM1176_BASE + 0x14)
+#define MXC_ARM1176_PLAT_ICGC (MXC_ARM1176_BASE + 0x18)
+#define MXC_ARM1176_PLAT_AMC (MXC_ARM1176_BASE + 0x1C)
+
+/* GPC */
+#define MXC_GPC_CNTR (MXC_GPC_BASE + 0x0)
+#define MXC_GPC_PGR (MXC_GPC_BASE + 0x4)
+#define MXC_GPC_VCR (MXC_GPC_BASE + 0x8)
+
+/* DVFS CORE */
+#define MXC_DVFSTHRS (MXC_DVFS_CORE_BASE + 0x00)
+#define MXC_DVFSCOUN (MXC_DVFS_CORE_BASE + 0x04)
+#define MXC_DVFSSIG1 (MXC_DVFS_CORE_BASE + 0x08)
+#define MXC_DVFSSIG0 (MXC_DVFS_CORE_BASE + 0x0C)
+#define MXC_DVFSGPC0 (MXC_DVFS_CORE_BASE + 0x10)
+#define MXC_DVFSGPC1 (MXC_DVFS_CORE_BASE + 0x14)
+#define MXC_DVFSGPBT (MXC_DVFS_CORE_BASE + 0x18)
+#define MXC_DVFSEMAC (MXC_DVFS_CORE_BASE + 0x1C)
+#define MXC_DVFSCNTR (MXC_DVFS_CORE_BASE + 0x20)
+#define MXC_DVFSLTR0_0 (MXC_DVFS_CORE_BASE + 0x24)
+#define MXC_DVFSLTR0_1 (MXC_DVFS_CORE_BASE + 0x28)
+#define MXC_DVFSLTR1_0 (MXC_DVFS_CORE_BASE + 0x2C)
+#define MXC_DVFSLTR1_1 (MXC_DVFS_CORE_BASE + 0x30)
+#define MXC_DVFSPT0 (MXC_DVFS_CORE_BASE + 0x34)
+#define MXC_DVFSPT1 (MXC_DVFS_CORE_BASE + 0x38)
+#define MXC_DVFSPT2 (MXC_DVFS_CORE_BASE + 0x3C)
+#define MXC_DVFSPT3 (MXC_DVFS_CORE_BASE + 0x40)
+
+/* DPTC GP */
+#define MXC_GP_DPTCCR (MXC_DPTC_GP_BASE + 0x00)
+#define MXC_GP_DPTCDBG (MXC_DPTC_GP_BASE + 0x04)
+#define MXC_GP_DCVR0 (MXC_DPTC_GP_BASE + 0x08)
+#define MXC_GP_DCVR1 (MXC_DPTC_GP_BASE + 0x0C)
+#define MXC_GP_DCVR2 (MXC_DPTC_GP_BASE + 0x10)
+#define MXC_GP_DCVR3 (MXC_DPTC_GP_BASE + 0x14)
+
+/* DPTC LP */
+#define MXC_LP_DPTCCR (MXC_DPTC_LP_BASE + 0x00)
+#define MXC_LP_DPTCDBG (MXC_DPTC_LP_BASE + 0x04)
+#define MXC_LP_DCVR0 (MXC_DPTC_LP_BASE + 0x08)
+#define MXC_LP_DCVR1 (MXC_DPTC_LP_BASE + 0x0C)
+#define MXC_LP_DCVR2 (MXC_DPTC_LP_BASE + 0x10)
+#define MXC_LP_DCVR3 (MXC_DPTC_LP_BASE + 0x14)
+
+#define MXC_DPTCCR_DRCE3 0x00400000
+#define MXC_DPTCCR_DRCE2 0x00200000
+#define MXC_DPTCCR_DRCE1 0x00100000
+#define MXC_DPTCCR_DRCE0 0x00080000
+#define MXC_DPTCCR_DCR_256 0x00060000
+#define MXC_DPTCCR_DCR_128 0x00040000
+#define MXC_DPTCCR_DCR_64 0x00020000
+#define MXC_DPTCCR_DCR_32 0x00000000
+#define MXC_DPTCCR_DSMM 0x00000040
+#define MXC_DPTCCR_DPNVCR 0x00000020
+#define MXC_DPTCCR_DPVV 0x00000010
+#define MXC_DPTCCR_VAIM 0x00000008
+#define MXC_DPTCCR_VAI_OFFSET 1
+#define MXC_DPTCCR_VAI_MASK 0x00000006
+#define MXC_DPTCCR_DEN 0x00000001
+
+#define MXC_GPCCNTR_GPCIRQ 0x00100000
+#define MXC_GPCCNTR_DPTC0CR 0x00040000
+#define MXC_GPCCNTR_DPTC1CR 0x00080000
+#define MXC_GPCCNTR_ADU 0x00008000
+
+/* SRPG */
+#define MXC_SRPGC_EMI_SRPGCR (MXC_SRPGC_EMI_BASE + 0x0)
+#define MXC_SRPGC_ARM_SRPGCR (MXC_SRPGC_ARM_BASE + 0x0)
+#define MXC_EMPGC0_ARM_EMPGCR (MXC_EMPGC0_ARM_BASE + 0x0)
+#define MXC_EMPGC1_ARM_EMPGCR (MXC_EMPGC1_ARM_BASE + 0x0)
+
+#define MXC_PGC_IPU_PGCR (MXC_PGC_IPU_BASE + 0x0)
+#define MXC_PGC_IPU_PGSR (MXC_PGC_IPU_BASE + 0xC)
+#define MXC_PGC_VPU_PGCR (MXC_PGC_VPU_BASE + 0x0)
+#define MXC_PGC_VPU_PGSR (MXC_PGC_VPU_BASE + 0xC)
+
+#define MXC_ARM1176_PLAT_LPC_DSM (1 << 16)
+#define MXC_ARM1176_PLAT_LPC_DBG_DSM (1 << 17)
+
+#define MXC_GPC_PGR_ARMPG_OFFSET 8
+#define MXC_GPC_PGR_ARMPG_MASK (3 << 8)
+
+#define MXC_PGCR_PCR 1
+#define MXC_SRPGCR_PCR 1
+#define MXC_EMPGCR_PCR 1
+
+#define MXC_PGSR_PSR 1
+
+#endif /* __ARCH_ARM_MACH_MX37_CRM_REGS_H__ */
diff --git a/arch/arm/mach-mx37/devices.c b/arch/arm/mach-mx37/devices.c
new file mode 100644
index 000000000000..dc0dc5bdd94a
--- /dev/null
+++ b/arch/arm/mach-mx37/devices.c
@@ -0,0 +1,908 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+
+#include <linux/spi/spi.h>
+
+#include <mach/hardware.h>
+#include <mach/spba.h>
+#include <mach/mxc_dptc.h>
+#include <mach/sdma.h>
+#include <mach/mxc_scc2_driver.h>
+#include "sdma_script_code.h"
+#include "iomux.h"
+#include "crm_regs.h"
+
+extern struct dptc_wp dptc_gp_wp_allfreq[DPTC_GP_WP_SUPPORTED];
+extern struct dptc_wp dptc_lp_wp_allfreq[DPTC_LP_WP_SUPPORTED];
+
+void mxc_sdma_get_script_info(sdma_script_start_addrs * sdma_script_addr)
+{
+ sdma_script_addr->mxc_sdma_app_2_mcu_addr = app_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_ap_2_ap_addr = ap_2_ap_ADDR;
+ sdma_script_addr->mxc_sdma_ap_2_bp_addr = -1;
+ sdma_script_addr->mxc_sdma_bp_2_ap_addr = -1;
+ sdma_script_addr->mxc_sdma_loopback_on_dsp_side_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_2_app_addr = mcu_2_app_ADDR;
+ sdma_script_addr->mxc_sdma_mcu_2_shp_addr = mcu_2_shp_ADDR;
+ sdma_script_addr->mxc_sdma_mcu_interrupt_only_addr = -1;
+ sdma_script_addr->mxc_sdma_shp_2_mcu_addr = shp_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_start_addr = (unsigned short *)sdma_code;
+ sdma_script_addr->mxc_sdma_uartsh_2_mcu_addr = uartsh_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_uart_2_mcu_addr = uart_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_ram_code_size = RAM_CODE_SIZE;
+ sdma_script_addr->mxc_sdma_ram_code_start_addr = RAM_CODE_START_ADDR;
+ sdma_script_addr->mxc_sdma_dptc_dvfs_addr = dptc_dvfs_ADDR;
+ sdma_script_addr->mxc_sdma_firi_2_mcu_addr = -1;
+ sdma_script_addr->mxc_sdma_firi_2_per_addr = -1;
+ sdma_script_addr->mxc_sdma_mshc_2_mcu_addr = -1;
+ sdma_script_addr->mxc_sdma_per_2_app_addr = -1;
+ sdma_script_addr->mxc_sdma_per_2_firi_addr = -1;
+ sdma_script_addr->mxc_sdma_per_2_shp_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_2_ata_addr = mcu_2_ata_ADDR;
+ sdma_script_addr->mxc_sdma_mcu_2_firi_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_2_mshc_addr = -1;
+ sdma_script_addr->mxc_sdma_ata_2_mcu_addr = ata_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_uartsh_2_per_addr = -1;
+ sdma_script_addr->mxc_sdma_shp_2_per_addr = -1;
+ sdma_script_addr->mxc_sdma_uart_2_per_addr = -1;
+ sdma_script_addr->mxc_sdma_app_2_per_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_2_spdif_addr = mcu_2_spdif_marley_ADDR;
+}
+
+static void mxc_nop_release(struct device *dev)
+{
+ /* Nothing */
+}
+
+#if defined(CONFIG_W1_MASTER_MXC) || defined(CONFIG_W1_MASTER_MXC_MODULE)
+static struct mxc_w1_config mxc_w1_data = {
+ .search_rom_accelerator = 0,
+};
+
+static struct platform_device mxc_w1_devices = {
+ .name = "mxc_w1",
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_w1_data,
+ },
+ .id = 0
+};
+
+static void mxc_init_owire(void)
+{
+ (void)platform_device_register(&mxc_w1_devices);
+}
+#else
+static inline void mxc_init_owire(void)
+{
+}
+#endif
+
+#if defined(CONFIG_RTC_DRV_MXC_V2) || defined(CONFIG_RTC_DRV_MXC_V2_MODULE)
+static struct mxc_srtc_platform_data srtc_data = {
+ .srtc_sec_mode_addr = 0xC3FAC80C,
+};
+
+static struct resource rtc_resources[] = {
+ {
+ .start = SRTC_BASE_ADDR,
+ .end = SRTC_BASE_ADDR + 0x40,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_INT_SRTC_NTZ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+static struct platform_device mxc_rtc_device = {
+ .name = "mxc_rtc",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &srtc_data,
+ },
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resource = rtc_resources,
+};
+static void mxc_init_rtc(void)
+{
+ (void)platform_device_register(&mxc_rtc_device);
+}
+#else
+static inline void mxc_init_rtc(void)
+{
+}
+#endif
+
+#if defined(CONFIG_MXC_WATCHDOG) || defined(CONFIG_MXC_WATCHDOG_MODULE)
+
+static struct resource wdt_resources[] = {
+ {
+ .start = WDOG1_BASE_ADDR,
+ .end = WDOG1_BASE_ADDR + 0x30,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device mxc_wdt_device = {
+ .name = "mxc_wdt",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+static void mxc_init_wdt(void)
+{
+ (void)platform_device_register(&mxc_wdt_device);
+}
+#else
+static inline void mxc_init_wdt(void)
+{
+}
+#endif
+
+#if defined(CONFIG_MXC_IPU_V3) || defined(CONFIG_MXC_IPU_V3_MODULE)
+static struct mxc_ipu_config mxc_ipu_data = {
+ .rev = 1,
+};
+
+static struct resource ipu_resources[] = {
+ {
+ .start = IPU_CTRL_BASE_ADDR,
+ .end = IPU_CTRL_BASE_ADDR + SZ_512M,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_INT_IPU_SYN,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MXC_INT_IPU_ERR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mxc_ipu_device = {
+ .name = "mxc_ipu",
+ .id = -1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_ipu_data,
+ },
+ .num_resources = ARRAY_SIZE(ipu_resources),
+ .resource = ipu_resources,
+};
+
+static void mxc_init_ipu(void)
+{
+ mxc_ipu_data.di_clk[1] = clk_get(NULL, "ipu_di_clk");
+
+ platform_device_register(&mxc_ipu_device);
+}
+#else
+static inline void mxc_init_ipu(void)
+{
+}
+#endif
+
+/*!
+ * This is platform device structure for adding SCC
+ */
+#if defined(CONFIG_MXC_SECURITY_SCC) || defined(CONFIG_MXC_SECURITY_SCC_MODULE)
+static struct platform_device mxc_scc_device = {
+ .name = "mxc_scc",
+ .id = 0,
+};
+
+static void mxc_init_scc(void)
+{
+ platform_device_register(&mxc_scc_device);
+}
+#else
+static inline void mxc_init_scc(void)
+{
+ uint32_t reg_value;
+ uint8_t *UMID_base;
+ uint32_t *MAP_base;
+ uint8_t i;
+ uint32_t partition_no;
+ uint32_t scc_partno;
+ void *scm_ram_base;
+ void *scc_base;
+
+ scc_base = ioremap((uint32_t) SCC_BASE_ADDR, 0x140);
+ if (scc_base == NULL) {
+ printk(KERN_ERR "FAILED TO MAP IRAM REGS\n");
+ return;
+ }
+ scm_ram_base = ioremap((uint32_t) IRAM_BASE_ADDR, IRAM_SIZE);
+ if (scm_ram_base == NULL) {
+ printk(KERN_ERR "FAILED TO MAP IRAM\n");
+ return;
+ }
+
+ for (partition_no = 0; partition_no < 9; partition_no++) {
+ reg_value = ((partition_no << SCM_ZCMD_PART_SHIFT) &
+ SCM_ZCMD_PART_MASK) | ((0x03 <<
+ SCM_ZCMD_CCMD_SHIFT)
+ & SCM_ZCMD_CCMD_MASK);
+ __raw_writel(reg_value, scc_base + SCM_ZCMD_REG);
+
+ while ((__raw_readl(scc_base + SCM_STATUS_REG) &
+ SCM_STATUS_SRS_READY) != SCM_STATUS_SRS_READY) ;
+
+ __raw_writel(0, scc_base + (SCM_SMID0_REG + 8 * partition_no));
+
+ reg_value = __raw_readl(scc_base + SCM_PART_OWNERS_REG);
+
+ if (((reg_value >> (2 * (partition_no))) & 3) != 3) {
+ printk(KERN_ERR "FAILED TO ACQUIRE IRAM PARTITION\n");
+ iounmap(scm_ram_base);
+ return;
+ }
+
+ MAP_base = scm_ram_base + (partition_no * 0x2000);
+ UMID_base = (uint8_t *) MAP_base + 0x10;
+
+ for (i = 0; i < 16; i++)
+ UMID_base[i] = 0;
+
+ MAP_base[0] = SCM_PERM_NO_ZEROIZE | SCM_PERM_HD_SUP_DISABLE |
+ SCM_PERM_HD_READ | SCM_PERM_HD_WRITE |
+ SCM_PERM_TH_READ | SCM_PERM_TH_WRITE;
+
+ }
+
+ /*Freeing 2 partitions for SCC2 */
+ scc_partno = 9 - (SCC_IRAM_SIZE / SZ_8K);
+ for (partition_no = scc_partno; partition_no < 9; partition_no++) {
+ reg_value = ((partition_no << SCM_ZCMD_PART_SHIFT) &
+ SCM_ZCMD_PART_MASK) | ((0x03 <<
+ SCM_ZCMD_CCMD_SHIFT)
+ & SCM_ZCMD_CCMD_MASK);
+ __raw_writel(reg_value, scc_base + SCM_ZCMD_REG);
+
+ while ((__raw_readl(scc_base + SCM_STATUS_REG) &
+ SCM_STATUS_SRS_READY) != SCM_STATUS_SRS_READY) ;
+ }
+ iounmap(scm_ram_base);
+ iounmap(scc_base);
+ printk(KERN_INFO "IRAM READY\n");
+
+}
+#endif
+
+/* SPI controller and device data */
+#if defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE)
+
+#ifdef CONFIG_SPI_MXC_SELECT1
+/*!
+ * Resource definition for the CSPI1
+ */
+static struct resource mxcspi1_resources[] = {
+ [0] = {
+ .start = CSPI1_BASE_ADDR,
+ .end = CSPI1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_CSPI1,
+ .end = MXC_INT_CSPI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC CSPI1 */
+static struct mxc_spi_master mxcspi1_data = {
+ .maxchipselect = 4,
+ .spi_version = 23,
+};
+
+/*! Device Definition for MXC CSPI1 */
+static struct platform_device mxcspi1_device = {
+ .name = "mxc_spi",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxcspi1_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcspi1_resources),
+ .resource = mxcspi1_resources,
+};
+
+#endif /* CONFIG_SPI_MXC_SELECT1 */
+
+#ifdef CONFIG_SPI_MXC_SELECT2
+/*!
+ * Resource definition for the CSPI2
+ */
+static struct resource mxcspi2_resources[] = {
+ [0] = {
+ .start = CSPI2_BASE_ADDR,
+ .end = CSPI2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_CSPI2,
+ .end = MXC_INT_CSPI2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC CSPI2 */
+static struct mxc_spi_master mxcspi2_data = {
+ .maxchipselect = 4,
+ .spi_version = 23,
+};
+
+/*! Device Definition for MXC CSPI2 */
+static struct platform_device mxcspi2_device = {
+ .name = "mxc_spi",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxcspi2_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcspi2_resources),
+ .resource = mxcspi2_resources,
+};
+#endif /* CONFIG_SPI_MXC_SELECT2 */
+
+#ifdef CONFIG_SPI_MXC_SELECT3
+/*!
+ * Resource definition for the CSPI3
+ */
+static struct resource mxcspi3_resources[] = {
+ [0] = {
+ .start = CSPI3_BASE_ADDR,
+ .end = CSPI3_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_CSPI3,
+ .end = MXC_INT_CSPI3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC CSPI3 */
+static struct mxc_spi_master mxcspi3_data = {
+ .maxchipselect = 4,
+ .spi_version = 23,
+};
+
+/*! Device Definition for MXC CSPI3 */
+static struct platform_device mxcspi3_device = {
+ .name = "mxc_spi",
+ .id = 2,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxcspi3_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcspi3_resources),
+ .resource = mxcspi3_resources,
+};
+#endif /* CONFIG_SPI_MXC_SELECT3 */
+
+void __init mxc_init_spi(void)
+{
+ /* SPBA configuration for CSPI2 - MCU is set */
+ spba_take_ownership(SPBA_CSPI2, SPBA_MASTER_A);
+#ifdef CONFIG_SPI_MXC_SELECT1
+ if (platform_device_register(&mxcspi1_device) < 0)
+ printk("Error: Registering the SPI Controller_1\n");
+#endif /* CONFIG_SPI_MXC_SELECT1 */
+#ifdef CONFIG_SPI_MXC_SELECT2
+ if (platform_device_register(&mxcspi2_device) < 0)
+ printk("Error: Registering the SPI Controller_2\n");
+#endif /* CONFIG_SPI_MXC_SELECT2 */
+#ifdef CONFIG_SPI_MXC_SELECT3
+ if (platform_device_register(&mxcspi3_device) < 0)
+ printk("Error: Registering the SPI Controller_3\n");
+#endif /* CONFIG_SPI_MXC_SELECT3 */
+}
+#else
+void __init mxc_init_spi(void)
+{
+}
+#endif
+
+/* I2C controller and device data */
+#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE)
+
+#ifdef CONFIG_I2C_MXC_SELECT1
+/*!
+ * Resource definition for the I2C1
+ */
+static struct resource mxci2c1_resources[] = {
+ [0] = {
+ .start = I2C_BASE_ADDR,
+ .end = I2C_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_I2C,
+ .end = MXC_INT_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC I2C */
+static struct mxc_i2c_platform_data mxci2c1_data = {
+ .i2c_clk = 100000,
+};
+#endif
+
+#ifdef CONFIG_I2C_MXC_SELECT2
+/*!
+ * Resource definition for the I2C2
+ */
+static struct resource mxci2c2_resources[] = {
+ [0] = {
+ .start = I2C2_BASE_ADDR,
+ .end = I2C2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_I2C2,
+ .end = MXC_INT_I2C2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC I2C */
+static struct mxc_i2c_platform_data mxci2c2_data = {
+ .i2c_clk = 100000,
+};
+#endif
+
+#ifdef CONFIG_I2C_MXC_SELECT3
+/*!
+ * Resource definition for the I2C3
+ */
+static struct resource mxci2c3_resources[] = {
+ [0] = {
+ .start = I2C3_BASE_ADDR,
+ .end = I2C3_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_I2C3,
+ .end = MXC_INT_I2C3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC I2C */
+static struct mxc_i2c_platform_data mxci2c3_data = {
+ .i2c_clk = 100000,
+};
+#endif
+
+/*! Device Definition for MXC I2C1 */
+static struct platform_device mxci2c_devices[] = {
+#ifdef CONFIG_I2C_MXC_SELECT1
+ {
+ .name = "mxc_i2c",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxci2c1_data,
+ },
+ .num_resources = ARRAY_SIZE(mxci2c1_resources),
+ .resource = mxci2c1_resources,},
+#endif
+#ifdef CONFIG_I2C_MXC_SELECT2
+ {
+ .name = "mxc_i2c",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxci2c2_data,
+ },
+ .num_resources = ARRAY_SIZE(mxci2c2_resources),
+ .resource = mxci2c2_resources,},
+#endif
+#ifdef CONFIG_I2C_MXC_SELECT3
+ {
+ .name = "mxc_i2c",
+ .id = 2,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxci2c3_data,
+ },
+ .num_resources = ARRAY_SIZE(mxci2c3_resources),
+ .resource = mxci2c3_resources,},
+#endif
+};
+
+static inline void mxc_init_i2c(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mxci2c_devices); i++) {
+ if (platform_device_register(&mxci2c_devices[i]) < 0)
+ dev_err(&mxci2c_devices[i].dev,
+ "Unable to register I2C device\n");
+ }
+}
+#else
+static inline void mxc_init_i2c(void)
+{
+}
+#endif
+
+struct tve_platform_data tve_data = {
+ .dac_reg = "VVIDEO",
+ .dig_reg = "VDIG",
+};
+
+static struct resource tve_resources[] = {
+ {
+ .start = TVE_BASE_ADDR,
+ .end = TVE_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_INT_TVOUT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mxc_tve_device = {
+ .name = "tve",
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &tve_data,
+ },
+ .num_resources = ARRAY_SIZE(tve_resources),
+ .resource = tve_resources,
+};
+
+void __init mxc_init_tve(void)
+{
+ platform_device_register(&mxc_tve_device);
+}
+
+/*!
+ * Resource definition for the DVFS CORE
+ */
+static struct resource dvfs_core_resources[] = {
+ [0] = {
+ .start = MXC_DVFS_CORE_BASE,
+ .end = MXC_DVFS_CORE_BASE + 4 * SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_GPC1,
+ .end = MXC_INT_GPC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for DVFS CORE */
+struct mxc_dvfs_platform_data dvfs_core_data = {
+ .reg_id = "SW1",
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_reg_addr = MXC_GPC_CNTR,
+ .gpc_vcr_reg_addr = MXC_GPC_VCR,
+ .dvfs_thrs_reg_addr = MXC_DVFSTHRS,
+ .dvfs_coun_reg_addr = MXC_DVFSCOUN,
+ .dvfs_emac_reg_addr = MXC_DVFSEMAC,
+ .dvfs_cntr_reg_addr = MXC_DVFSCNTR,
+ .div3ck_mask = 0x00000006,
+ .div3ck_offset = 1,
+ .div3ck_val = 3,
+ .emac_val = 0x20,
+ .upthr_val = 28,
+ .dnthr_val = 10,
+ .pncthr_val = 33,
+ .upcnt_val = 5,
+ .dncnt_val = 5,
+ .delay_time = 100,
+ .num_wp = 3,
+};
+
+/*! Device Definition for MXC DVFS core */
+static struct platform_device mxc_dvfs_core_device = {
+ .name = "mxc_dvfs_core",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &dvfs_core_data,
+ },
+ .num_resources = ARRAY_SIZE(dvfs_core_resources),
+ .resource = dvfs_core_resources,
+};
+
+static inline void mxc_init_dvfs(void)
+{
+ if (platform_device_register(&mxc_dvfs_core_device) < 0)
+ dev_err(&mxc_dvfs_core_device.dev,
+ "Unable to register DVFS core device\n");
+}
+
+/*!
+ * Resource definition for the DPTC GP
+ */
+static struct resource dptc_gp_resources[] = {
+ [0] = {
+ .start = MXC_DPTC_GP_BASE,
+ .end = MXC_DPTC_GP_BASE + 8 * SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_GPC1,
+ .end = MXC_INT_GPC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for DPTC GP */
+struct mxc_dptc_data dptc_gp_data = {
+ .reg_id = "SW1",
+ .clk_id = "cpu_clk",
+ .dptccr_reg_addr = MXC_GP_DPTCCR,
+ .dcvr0_reg_addr = MXC_GP_DCVR0,
+ .gpc_cntr_reg_addr = MXC_GPC_CNTR,
+ .dptccr = MXC_GPCCNTR_DPTC0CR,
+ .dptc_wp_supported = DPTC_GP_WP_SUPPORTED,
+ .dptc_wp_allfreq = dptc_gp_wp_allfreq,
+ .clk_max_val = 532000000,
+ .gpc_adu = MXC_GPCCNTR_ADU,
+ .vai_mask = MXC_DPTCCR_VAI_MASK,
+ .vai_offset = MXC_DPTCCR_VAI_OFFSET,
+ .dptc_enable_bit = MXC_DPTCCR_DEN,
+ .irq_mask = MXC_DPTCCR_VAIM,
+ .dptc_nvcr_bit = MXC_DPTCCR_DPNVCR,
+ .gpc_irq_bit = MXC_GPCCNTR_GPCIRQ,
+ .init_config =
+ MXC_DPTCCR_DRCE0 | MXC_DPTCCR_DRCE1 | MXC_DPTCCR_DRCE2 |
+ MXC_DPTCCR_DRCE3 | MXC_DPTCCR_DCR_128 | MXC_DPTCCR_DPNVCR |
+ MXC_DPTCCR_DPVV,
+ .enable_config =
+ MXC_DPTCCR_DEN | MXC_DPTCCR_DPNVCR | MXC_DPTCCR_DPVV |
+ MXC_DPTCCR_DSMM,
+ .dcr_mask = MXC_DPTCCR_DCR_256,
+};
+
+/*!
+ * Resource definition for the DPTC LP
+ */
+static struct resource dptc_lp_resources[] = {
+ [0] = {
+ .start = MXC_DPTC_LP_BASE,
+ .end = MXC_DPTC_LP_BASE + 8 * SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_GPC1,
+ .end = MXC_INT_GPC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC DPTC LP */
+struct mxc_dptc_data dptc_lp_data = {
+ .reg_id = "SW2",
+ .clk_id = "ahb_clk",
+ .dptccr_reg_addr = MXC_LP_DPTCCR,
+ .dcvr0_reg_addr = MXC_LP_DCVR0,
+ .gpc_cntr_reg_addr = MXC_GPC_CNTR,
+ .dptccr = MXC_GPCCNTR_DPTC1CR,
+ .dptc_wp_supported = DPTC_LP_WP_SUPPORTED,
+ .dptc_wp_allfreq = dptc_lp_wp_allfreq,
+ .clk_max_val = 133000000,
+ .gpc_adu = 0x0,
+ .vai_mask = MXC_DPTCCR_VAI_MASK,
+ .vai_offset = MXC_DPTCCR_VAI_OFFSET,
+ .dptc_enable_bit = MXC_DPTCCR_DEN,
+ .irq_mask = MXC_DPTCCR_VAIM,
+ .dptc_nvcr_bit = MXC_DPTCCR_DPNVCR,
+ .gpc_irq_bit = MXC_GPCCNTR_GPCIRQ,
+ .init_config =
+ MXC_DPTCCR_DRCE0 | MXC_DPTCCR_DRCE1 | MXC_DPTCCR_DRCE2 |
+ MXC_DPTCCR_DRCE3 | MXC_DPTCCR_DCR_128 | MXC_DPTCCR_DPNVCR |
+ MXC_DPTCCR_DPVV,
+ .enable_config =
+ MXC_DPTCCR_DEN | MXC_DPTCCR_DPNVCR | MXC_DPTCCR_DPVV |
+ MXC_DPTCCR_DSMM,
+ .dcr_mask = MXC_DPTCCR_DCR_256,
+};
+
+/*! Device Definition for MXC DPTC */
+static struct platform_device mxc_dptc_devices[] = {
+ {
+ .name = "mxc_dptc",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &dptc_gp_data,
+ },
+ .num_resources = ARRAY_SIZE(dptc_gp_resources),
+ .resource = dptc_gp_resources,
+ },
+ {
+ .name = "mxc_dptc",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &dptc_lp_data,
+ },
+ .num_resources = ARRAY_SIZE(dptc_lp_resources),
+ .resource = dptc_lp_resources,
+ },
+};
+
+static inline void mxc_init_dptc(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mxc_dptc_devices); i++) {
+ if (platform_device_register(&mxc_dptc_devices[i]) < 0)
+ dev_err(&mxc_dptc_devices[i].dev,
+ "Unable to register DPTC device\n");
+ }
+}
+
+struct mxc_gpio_port mxc_gpio_ports[GPIO_PORT_NUM] = {
+ {
+ .num = 0,
+ .base = IO_ADDRESS(GPIO1_BASE_ADDR),
+ .irq_0_15 = MXC_INT_GPIO1_LOW,
+ .irq_16_31 = MXC_INT_GPIO1_HIGH,
+ .virtual_irq_start = MXC_GPIO_INT_BASE,
+ },
+ {
+ .num = 1,
+ .base = IO_ADDRESS(GPIO2_BASE_ADDR),
+ .irq_0_15 = MXC_INT_GPIO2_LOW,
+ .irq_16_31 = MXC_INT_GPIO2_HIGH,
+ .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 1,
+ },
+ {
+ .num = 2,
+ .base = IO_ADDRESS(GPIO3_BASE_ADDR),
+ .irq_0_15 = MXC_INT_GPIO3_LOW,
+ .irq_16_31 = MXC_INT_GPIO3_HIGH,
+ .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 2,
+ },
+};
+
+#if defined(CONFIG_MXC_VPU) || defined(CONFIG_MXC_VPU_MODULE)
+static struct resource vpu_resources[] = {
+ {
+ .start = VPU_IRAM_BASE_ADDR,
+ .end = VPU_IRAM_BASE_ADDR + VPU_IRAM_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+/*! Platform Data for MXC VPU */
+static struct platform_device mxcvpu_device = {
+ .name = "mxc_vpu",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(vpu_resources),
+ .resource = vpu_resources,
+};
+
+static inline void mxc_init_vpu(void)
+{
+ if (platform_device_register(&mxcvpu_device) < 0)
+ printk(KERN_ERR "Error: Registering the VPU.\n");
+}
+#else
+static inline void mxc_init_vpu(void)
+{
+}
+#endif
+
+static struct platform_device mxc_dma_device = {
+ .name = "mxc_dma",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+};
+
+static inline void mxc_init_dma(void)
+{
+ (void)platform_device_register(&mxc_dma_device);
+}
+
+static struct resource spdif_resources[] = {
+ {
+ .start = SPDIF_BASE_ADDR,
+ .end = SPDIF_BASE_ADDR + 0x50,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct mxc_spdif_platform_data mxc_spdif_data = {
+ .spdif_tx = 1,
+ .spdif_rx = 0,
+ .spdif_clk_44100 = 0,
+ .spdif_clk_48000 = 3,
+ .spdif_clk = NULL,
+ .spdif_core_clk = NULL,
+};
+
+static struct platform_device mxc_alsa_spdif_device = {
+ .name = "mxc_alsa_spdif",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_spdif_data,
+ },
+ .num_resources = ARRAY_SIZE(spdif_resources),
+ .resource = spdif_resources,
+};
+
+static inline void mxc_init_spdif(void)
+{
+ struct clk *ckih_clk;
+ ckih_clk = clk_get(NULL, "ckih");
+ mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk");
+ clk_set_parent(mxc_spdif_data.spdif_core_clk, ckih_clk);
+ clk_put(ckih_clk);
+ clk_put(mxc_spdif_data.spdif_core_clk);
+ platform_device_register(&mxc_alsa_spdif_device);
+}
+
+static struct platform_device mx37_lpmode_device = {
+ .name = "mx37_lpmode",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+};
+
+static inline void mx37_init_lpmode(void)
+{
+ (void)platform_device_register(&mx37_lpmode_device);
+}
+
+int __init mxc_init_devices(void)
+{
+ mxc_init_wdt();
+ mxc_init_ipu();
+ mxc_init_spi();
+ mxc_init_i2c();
+ mxc_init_rtc();
+ mxc_init_owire();
+ mxc_init_scc();
+ mxc_init_dma();
+ mxc_init_vpu();
+ mxc_init_spdif();
+ mxc_init_tve();
+ mx37_init_lpmode();
+ mxc_init_dvfs();
+ mxc_init_dptc();
+ /* SPBA configuration for SSI2 - SDMA and MCU are set */
+ spba_take_ownership(SPBA_SSI2, SPBA_MASTER_C | SPBA_MASTER_A);
+ return 0;
+}
diff --git a/arch/arm/mach-mx37/dma.c b/arch/arm/mach-mx37/dma.c
new file mode 100644
index 000000000000..5732c5803888
--- /dev/null
+++ b/arch/arm/mach-mx37/dma.c
@@ -0,0 +1,666 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/init.h>
+#include <linux/device.h>
+#include <asm/dma.h>
+#include <mach/hardware.h>
+
+#include "serial.h"
+
+#define MXC_MMC_BUFFER_ACCESS 0x20
+#define MXC_SDHC_MMC_WML 512
+#define MXC_SDHC_SD_WML 512
+#define MXC_SSI_TX0_REG 0x0
+#define MXC_SSI_TX1_REG 0x4
+#define MXC_SSI_RX0_REG 0x8
+#define MXC_SSI_RX1_REG 0xC
+#define MXC_SSI_TXFIFO_WML 0x4
+#define MXC_SSI_RXFIFO_WML 0x6
+#define MXC_SPDIF_TXFIFO_WML 0x0
+#define MXC_SPDIF_TX_REG 0x2C
+
+typedef struct mxc_sdma_info_entry_s {
+ mxc_dma_device_t device;
+ mxc_sdma_channel_params_t *chnl_info;
+} mxc_sdma_info_entry_t;
+
+static mxc_sdma_channel_params_t mxc_sdma_uart1_rx_params = {
+ .chnl_params = {
+ .watermark_level = UART1_UFCR_RXTL,
+ .per_address = UART1_BASE_ADDR,
+ .peripheral_type = UART,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_UART1_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART1_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart1_tx_params = {
+ .chnl_params = {
+ .watermark_level = UART1_UFCR_TXTL,
+ .per_address = UART1_BASE_ADDR + MXC_UARTUTXD,
+ .peripheral_type = UART,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_UART1_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART1_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart2_rx_params = {
+ .chnl_params = {
+ .watermark_level = UART2_UFCR_RXTL,
+ .per_address = UART2_BASE_ADDR,
+ .peripheral_type = UART,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_UART2_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART2_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart2_tx_params = {
+ .chnl_params = {
+ .watermark_level = UART2_UFCR_TXTL,
+ .per_address = UART2_BASE_ADDR + MXC_UARTUTXD,
+ .peripheral_type = UART,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_UART2_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART2_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart3_rx_params = {
+ .chnl_params = {
+ .watermark_level = UART3_UFCR_RXTL,
+ .per_address = UART3_BASE_ADDR,
+ .peripheral_type = UART_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_UART3_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART3_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart3_tx_params = {
+ .chnl_params = {
+ .watermark_level = UART3_UFCR_TXTL,
+ .per_address = UART3_BASE_ADDR + MXC_UARTUTXD,
+ .peripheral_type = UART_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_UART3_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART3_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_mmc1_width1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SDHC_MMC_WML,
+ .per_address =
+ MMC_SDHC1_BASE_ADDR + MXC_MMC_BUFFER_ACCESS,
+ .peripheral_type = MMC,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SDHC1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_MMC1,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_mmc1_width4_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SDHC_SD_WML,
+ .per_address =
+ MMC_SDHC1_BASE_ADDR + MXC_MMC_BUFFER_ACCESS,
+ .peripheral_type = MMC,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SDHC1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_MMC1,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_mmc2_width1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SDHC_MMC_WML / 32,
+ .per_address =
+ MMC_SDHC2_BASE_ADDR + MXC_MMC_BUFFER_ACCESS,
+ .peripheral_type = MMC,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SDHC2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_MMC2,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_mmc2_width4_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SDHC_SD_WML / 8,
+ .per_address =
+ MMC_SDHC2_BASE_ADDR + MXC_MMC_BUFFER_ACCESS,
+ .peripheral_type = MMC,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SDHC2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_MMC2,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_memory_params = {
+ .chnl_params = {
+ .peripheral_type = MEMORY,
+ .transfer_type = emi_2_emi,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_MEMORY,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ata_rx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_IDE_DMA_WATERMARK,
+ .per_address = ATA_DMA_BASE_ADDR,
+ .peripheral_type = ATA,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_ATA_TX_END,
+ .event_id2 = DMA_REQ_ATA_RX,
+ .bd_number = MXC_IDE_DMA_BD_NR,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_ATA_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ata_tx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_IDE_DMA_WATERMARK,
+ .per_address = ATA_DMA_BASE_ADDR + 0x18,
+ .peripheral_type = ATA,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_ATA_TX_END,
+ .event_id2 = DMA_REQ_ATA_TX,
+ .bd_number = MXC_IDE_DMA_BD_NR,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_ATA_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_spdif_16bit_tx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SPDIF_TXFIFO_WML,
+ .per_address = SPDIF_BASE_ADDR + MXC_SPDIF_TX_REG,
+ .peripheral_type = SPDIF,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SPDIF_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SPDIF_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_spdif_32bit_tx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SPDIF_TXFIFO_WML,
+ .per_address = SPDIF_BASE_ADDR + MXC_SPDIF_TX_REG,
+ .peripheral_type = SPDIF,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SPDIF_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SPDIF_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_info_entry_t mxc_sdma_active_dma_info[] = {
+ {MXC_DMA_UART1_RX, &mxc_sdma_uart1_rx_params},
+ {MXC_DMA_UART1_TX, &mxc_sdma_uart1_tx_params},
+ {MXC_DMA_UART2_RX, &mxc_sdma_uart2_rx_params},
+ {MXC_DMA_UART2_TX, &mxc_sdma_uart2_tx_params},
+ {MXC_DMA_UART3_RX, &mxc_sdma_uart3_rx_params},
+ {MXC_DMA_UART3_TX, &mxc_sdma_uart3_tx_params},
+ {MXC_DMA_MMC1_WIDTH_1, &mxc_sdma_mmc1_width1_params},
+ {MXC_DMA_MMC1_WIDTH_4, &mxc_sdma_mmc1_width4_params},
+ {MXC_DMA_MMC2_WIDTH_1, &mxc_sdma_mmc2_width1_params},
+ {MXC_DMA_MMC2_WIDTH_4, &mxc_sdma_mmc2_width4_params},
+ {MXC_DMA_SSI1_8BIT_RX0, &mxc_sdma_ssi1_8bit_rx0_params},
+ {MXC_DMA_SSI1_8BIT_TX0, &mxc_sdma_ssi1_8bit_tx0_params},
+ {MXC_DMA_SSI1_16BIT_RX0, &mxc_sdma_ssi1_16bit_rx0_params},
+ {MXC_DMA_SSI1_16BIT_TX0, &mxc_sdma_ssi1_16bit_tx0_params},
+ {MXC_DMA_SSI1_24BIT_RX0, &mxc_sdma_ssi1_24bit_rx0_params},
+ {MXC_DMA_SSI1_24BIT_TX0, &mxc_sdma_ssi1_24bit_tx0_params},
+ {MXC_DMA_SSI1_8BIT_RX1, &mxc_sdma_ssi1_8bit_rx1_params},
+ {MXC_DMA_SSI1_8BIT_TX1, &mxc_sdma_ssi1_8bit_tx1_params},
+ {MXC_DMA_SSI1_16BIT_RX1, &mxc_sdma_ssi1_16bit_rx1_params},
+ {MXC_DMA_SSI1_16BIT_TX1, &mxc_sdma_ssi1_16bit_tx1_params},
+ {MXC_DMA_SSI1_24BIT_RX1, &mxc_sdma_ssi1_24bit_rx1_params},
+ {MXC_DMA_SSI1_24BIT_TX1, &mxc_sdma_ssi1_24bit_tx1_params},
+ {MXC_DMA_SSI2_8BIT_RX0, &mxc_sdma_ssi2_8bit_rx0_params},
+ {MXC_DMA_SSI2_8BIT_TX0, &mxc_sdma_ssi2_8bit_tx0_params},
+ {MXC_DMA_SSI2_16BIT_RX0, &mxc_sdma_ssi2_16bit_rx0_params},
+ {MXC_DMA_SSI2_16BIT_TX0, &mxc_sdma_ssi2_16bit_tx0_params},
+ {MXC_DMA_SSI2_24BIT_RX0, &mxc_sdma_ssi2_24bit_rx0_params},
+ {MXC_DMA_SSI2_24BIT_TX0, &mxc_sdma_ssi2_24bit_tx0_params},
+ {MXC_DMA_SSI2_8BIT_RX1, &mxc_sdma_ssi2_8bit_rx1_params},
+ {MXC_DMA_SSI2_8BIT_TX1, &mxc_sdma_ssi2_8bit_tx1_params},
+ {MXC_DMA_SSI2_16BIT_RX1, &mxc_sdma_ssi2_16bit_rx1_params},
+ {MXC_DMA_SSI2_16BIT_TX1, &mxc_sdma_ssi2_16bit_tx1_params},
+ {MXC_DMA_SSI2_24BIT_RX1, &mxc_sdma_ssi2_24bit_rx1_params},
+ {MXC_DMA_SSI2_24BIT_TX1, &mxc_sdma_ssi2_24bit_tx1_params},
+ {MXC_DMA_MEMORY, &mxc_sdma_memory_params},
+ {MXC_DMA_ATA_RX, &mxc_sdma_ata_rx_params},
+ {MXC_DMA_ATA_TX, &mxc_sdma_ata_tx_params},
+ {MXC_DMA_SPDIF_16BIT_TX, &mxc_sdma_spdif_16bit_tx_params},
+ {MXC_DMA_SPDIF_32BIT_TX, &mxc_sdma_spdif_32bit_tx_params},
+};
+
+static int mxc_sdma_info_entrys =
+ sizeof(mxc_sdma_active_dma_info) / sizeof(mxc_sdma_active_dma_info[0]);
+
+/*!
+ * This functions Returns the SDMA paramaters associated for a module
+ *
+ * @param channel_id the ID of the module requesting DMA
+ * @return returns the sdma parameters structure for the device
+ */
+mxc_sdma_channel_params_t *mxc_sdma_get_channel_params(mxc_dma_device_t
+ channel_id)
+{
+ mxc_sdma_info_entry_t *p = mxc_sdma_active_dma_info;
+ int i;
+
+ for (i = 0; i < mxc_sdma_info_entrys; i++, p++) {
+ if (p->device == channel_id) {
+ return p->chnl_info;
+ }
+ }
+ return NULL;
+}
+
+/*!
+ * This functions marks the SDMA channels that are statically allocated
+ *
+ * @param chnl the channel array used to store channel information
+ */
+void mxc_get_static_channels(mxc_dma_channel_t * chnl)
+{
+#ifdef CONFIG_SDMA_IRAM
+ int i;
+ for (i = MXC_DMA_CHANNEL_IRAM; i < MAX_DMA_CHANNELS; i++)
+ chnl[i].dynamic = 0;
+#endif
+}
+
+EXPORT_SYMBOL(mxc_sdma_get_channel_params);
+EXPORT_SYMBOL(mxc_get_static_channels);
diff --git a/arch/arm/mach-mx37/dptc.c b/arch/arm/mach-mx37/dptc.c
new file mode 100644
index 000000000000..4585423c0036
--- /dev/null
+++ b/arch/arm/mach-mx37/dptc.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file dptc_gp.c
+ *
+ * @brief DPTC table for the Freescale Semiconductor MXC DPTC module.
+ *
+ * @ingroup PM
+ */
+
+#include <mach/hardware.h>
+#include <mach/mxc_dptc.h>
+
+struct dptc_wp dptc_gp_wp_allfreq[DPTC_GP_WP_SUPPORTED] = {
+ /* 532MHz */
+ /* dcvr0 dcvr1 dcvr2
+ dcvr3 voltage */
+ /* wp0 */
+ {DCVR(107, 108, 112), DCVR(122, 123, 127), DCVR(133, 134, 139),
+ DCVR(115, 116, 121), 1000},
+ {DCVR(107, 108, 113), DCVR(122, 123, 127), DCVR(133, 134, 139),
+ DCVR(115, 117, 122), 975},
+ {DCVR(107, 109, 113), DCVR(122, 123, 127), DCVR(133, 134, 139),
+ DCVR(115, 117, 122), 950},
+ {DCVR(107, 109, 114), DCVR(122, 123, 127), DCVR(133, 135, 140),
+ DCVR(115, 117, 122), 925},
+ {DCVR(108, 109, 115), DCVR(122, 123, 127), DCVR(133, 136, 142),
+ DCVR(115, 117, 123), 900},
+ {DCVR(108, 110, 115), DCVR(122, 123, 127), DCVR(133, 136, 142),
+ DCVR(115, 117, 123), 875},
+ {DCVR(108, 110, 115), DCVR(122, 124, 128), DCVR(133, 136, 143),
+ DCVR(115, 118, 124), 850},
+};
+
+struct dptc_wp dptc_lp_wp_allfreq[DPTC_LP_WP_SUPPORTED] = {
+ /* 532MHz */
+ /* dcvr0 dcvr1 dcvr2
+ dcvr3 regulator voltage */
+ /* wp0 */
+ {DCVR(141, 143, 149), DCVR(155, 157, 162), DCVR(106, 108, 112),
+ DCVR(124, 126, 130), 1200},
+ {DCVR(141, 143, 149), DCVR(155, 157, 162), DCVR(106, 108, 113),
+ DCVR(124, 126, 131), 1175},
+ {DCVR(141, 144, 150), DCVR(155, 157, 163), DCVR(106, 108, 113),
+ DCVR(124, 126, 131), 1150},
+ {DCVR(141, 144, 151), DCVR(155, 157, 163), DCVR(106, 108, 114),
+ DCVR(124, 126, 131), 1125},
+ {DCVR(142, 144, 152), DCVR(155, 157, 163), DCVR(107, 109, 114),
+ DCVR(125, 127, 132), 1100},
+ {DCVR(142, 145, 153), DCVR(155, 157, 164), DCVR(107, 109, 115),
+ DCVR(125, 127, 133), 1075},
+ {DCVR(142, 145, 153), DCVR(155, 158, 164), DCVR(107, 109, 116),
+ DCVR(125, 127, 133), 1050},
+ {DCVR(142, 145, 154), DCVR(155, 158, 165), DCVR(107, 110, 117),
+ DCVR(125, 127, 134), 1025},
+ {DCVR(142, 146, 156), DCVR(155, 158, 165), DCVR(107, 110, 117),
+ DCVR(125, 128, 135), 1000},
+};
diff --git a/arch/arm/mach-mx37/iomux.c b/arch/arm/mach-mx37/iomux.c
new file mode 100644
index 000000000000..03b23047670c
--- /dev/null
+++ b/arch/arm/mach-mx37/iomux.c
@@ -0,0 +1,205 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup GPIO_MX37 Board GPIO and Muxing Setup
+ * @ingroup MSL_MX37
+ */
+/*!
+ * @file mach-mx37/iomux.c
+ *
+ * @brief I/O Muxing control functions
+ *
+ * @ingroup GPIO_MX37
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include "iomux.h"
+
+/*!
+ * IOMUX register (base) addresses
+ */
+enum iomux_reg_addr {
+ IOMUXGPR0 = IO_ADDRESS(IOMUXC_BASE_ADDR), /*!< General purpose 0 */
+ IOMUXGPR1 = IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x004, /*!< General purpose 1 */
+ IOMUXSW_MUX_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR) + MUX_I_START, /*!< MUX control */
+ IOMUXSW_MUX_END = IO_ADDRESS(IOMUXC_BASE_ADDR) + PAD_I_END, /*!< last MUX control register */
+ IOMUXSW_PAD_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR) + PAD_I_START, /*!< Pad control */
+ IOMUXSW_PAD_END = IO_ADDRESS(IOMUXC_BASE_ADDR) + PAD_I_END, /*!< last Pad control register */
+ IOMUXSW_INPUT_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR) + INPUT_CTL_START, /*!< input select register */
+ IOMUXSW_INPUT_END = IO_ADDRESS(IOMUXC_BASE_ADDR) + INPUT_CTL_END, /*!< last input select register */
+};
+
+#define MUX_PIN_NUM_MAX (((IOMUXSW_MUX_END - IOMUXSW_MUX_CTL) >> 2) + 1)
+#define MUX_INPUT_NUM_MUX (((IOMUXSW_INPUT_END - IOMUXSW_INPUT_CTL) >> 2) + 1)
+
+static u8 iomux_pin_res_table[MUX_PIN_NUM_MAX];
+static DEFINE_SPINLOCK(gpio_mux_lock);
+
+/*!
+ * This function is used to configure a pin through the IOMUX module.
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param config a configuration as defined in \b #iomux_pin_cfg_t
+ *
+ * @return 0 if successful; Non-zero otherwise
+ */
+static int iomux_config_mux(iomux_pin_name_t pin, iomux_pin_cfg_t config)
+{
+ u32 ret = 0;
+ u32 pin_index = PIN_TO_IOMUX_INDEX(pin);
+ u32 mux_reg = IOMUXSW_MUX_CTL + PIN_TO_IOMUX_MUX(pin);
+ u32 mux_data = 0;
+ u8 *rp;
+
+ BUG_ON((mux_reg > IOMUXSW_MUX_END) || (mux_reg < IOMUXSW_MUX_CTL));
+ spin_lock(&gpio_mux_lock);
+
+ if (config == IOMUX_CONFIG_GPIO) {
+ mux_data = PIN_TO_ALT_GPIO(pin);
+ } else {
+ mux_data = config;
+ }
+
+ __raw_writel(mux_data, mux_reg);
+
+ /*
+ * Log a warning if a pin changes ownership
+ */
+ rp = iomux_pin_res_table + pin_index;
+ if ((mux_data & *rp) && (*rp != mux_data)) {
+ /*
+ * Don't call printk if we're tweaking the console uart or
+ * we'll deadlock.
+ */
+ printk(KERN_ERR "iomux_config_mux: Warning: iomux pin"
+ " config changed, pin=%d, "
+ " prev=0x%x new=0x%x\n", mux_reg, *rp, mux_data);
+ ret = -EINVAL;
+ }
+ *rp = mux_data;
+ spin_unlock(&gpio_mux_lock);
+ return ret;
+}
+
+/*!
+ * Request ownership for an IO pin. This function has to be the first one
+ * being called before that pin is used. The caller has to check the
+ * return value to make sure it returns 0.
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param config a configuration as defined in \b #iomux_pin_cfg_t
+ *
+ * @return 0 if successful; Non-zero otherwise
+ */
+int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t config)
+{
+ int ret = iomux_config_mux(pin, config);
+ int gpio_port = GPIO_TO_PORT(IOMUX_TO_GPIO(pin));
+
+ if (!ret && (gpio_port != NON_GPIO_PORT)
+ && ((config == IOMUX_CONFIG_GPIO)
+ || (config == PIN_TO_ALT_GPIO(pin)))) {
+ ret |= mxc_request_gpio(pin);
+ }
+ return ret;
+}
+
+/*!
+ * Release ownership for an IO pin
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param config config as defined in \b #iomux_pin_ocfg_t
+ */
+void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t config)
+{
+ u32 pin_index = PIN_TO_IOMUX_INDEX(pin);
+ u8 *rp = iomux_pin_res_table + pin_index;
+ int gpio_port = GPIO_TO_PORT(IOMUX_TO_GPIO(pin));
+
+ BUG_ON(pin_index > MUX_PIN_NUM_MAX);
+ *rp = 0;
+ if ((gpio_port != NON_GPIO_PORT)
+ && ((config == IOMUX_CONFIG_GPIO)
+ || (config == PIN_TO_ALT_GPIO(pin)))) {
+ mxc_free_gpio(pin);
+ }
+}
+
+/*!
+ * This function configures the pad value for a IOMUX pin.
+ *
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param config the ORed value of elements defined in \b #iomux_pad_config_t
+ */
+void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config)
+{
+ u32 pad_reg = IOMUXSW_PAD_CTL + PIN_TO_IOMUX_PAD(pin);
+
+ BUG_ON((pad_reg > IOMUXSW_PAD_END) || (pad_reg < IOMUXSW_PAD_CTL));
+ spin_lock(&gpio_mux_lock);
+ __raw_writel(config, pad_reg);
+ spin_unlock(&gpio_mux_lock);
+}
+
+unsigned int mxc_iomux_get_pad(iomux_pin_name_t pin)
+{
+ volatile u32 pad_reg = IOMUXSW_PAD_CTL + PIN_TO_IOMUX_PAD(pin);
+ return __raw_readl(pad_reg);
+}
+
+/*!
+ * This function enables/disables the general purpose function for a particular
+ * signal.
+ *
+ * @param gp one signal as defined in \b #iomux_gp_func_t
+ * @param en \b #true to enable; \b #false to disable
+ * @param index 0 for GPR0 and 1 for GPR1
+ */
+void mxc_iomux_set_gpr(iomux_gp_func_t gp, bool en, u8 index)
+{
+ volatile u32 l;
+
+ spin_lock(&gpio_mux_lock);
+ l = __raw_readl(IOMUXGPR0 + (index << 2));
+ if (en) {
+ l |= gp;
+ } else {
+ l &= ~gp;
+ }
+ __raw_writel(l, IOMUXGPR0 + (index << 2));
+ spin_unlock(&gpio_mux_lock);
+}
+
+/*!
+ * This function configures input path.
+ *
+ * @param input index of input select register as defined in \b #iomux_input_select_t
+ * @param config the binary value of elements defined in \b #iomux_input_config_t
+ * */
+void mxc_iomux_set_input(iomux_input_select_t input, u32 config)
+{
+ u32 reg = IOMUXSW_INPUT_CTL + (input << 2);
+
+ BUG_ON(input >= MUX_INPUT_NUM_MUX);
+ __raw_writel(config, reg);
+}
+
+EXPORT_SYMBOL(mxc_request_iomux);
+EXPORT_SYMBOL(mxc_free_iomux);
+EXPORT_SYMBOL(mxc_iomux_set_input);
+EXPORT_SYMBOL(mxc_iomux_set_pad);
+EXPORT_SYMBOL(mxc_iomux_set_gpr);
diff --git a/arch/arm/mach-mx37/iomux.h b/arch/arm/mach-mx37/iomux.h
new file mode 100644
index 000000000000..1780086bafe1
--- /dev/null
+++ b/arch/arm/mach-mx37/iomux.h
@@ -0,0 +1,226 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __MACH_MX37_IOMUX_H__
+#define __MACH_MX37_IOMUX_H__
+
+#include <linux/types.h>
+#include <mach/gpio.h>
+#include "mx37_pins.h"
+
+/*!
+ * @file mach-mx37/iomux.h
+ *
+ * @brief I/O Muxing control definitions and functions
+ *
+ * @ingroup GPIO_MX37
+ */
+
+/*!
+ * various IOMUX output functions
+ */
+typedef enum iomux_config {
+ IOMUX_CONFIG_ALT0, /*!< used as alternate function 0 */
+ IOMUX_CONFIG_ALT1, /*!< used as alternate function 1 */
+ IOMUX_CONFIG_ALT2, /*!< used as alternate function 2 */
+ IOMUX_CONFIG_ALT3, /*!< used as alternate function 3 */
+ IOMUX_CONFIG_ALT4, /*!< used as alternate function 4 */
+ IOMUX_CONFIG_ALT5, /*!< used as alternate function 5 */
+ IOMUX_CONFIG_ALT6, /*!< used as alternate function 6 */
+ IOMUX_CONFIG_ALT7, /*!< used as alternate function 7 */
+ IOMUX_CONFIG_GPIO, /*!< added to help user use GPIO mode */
+ IOMUX_CONFIG_SION = 0x1 << 4, /*!< used as LOOPBACK:MUX SION bit */
+} iomux_pin_cfg_t;
+
+/*!
+ * various IOMUX pad functions
+ */
+typedef enum iomux_pad_config {
+ PAD_CTL_SRE_SLOW = 0x0 << 0,
+ PAD_CTL_SRE_FAST = 0x1 << 0,
+ PAD_CTL_DRV_LOW = 0x0 << 1,
+ PAD_CTL_DRV_MEDIUM = 0x1 << 1,
+ PAD_CTL_DRV_HIGH = 0x2 << 1,
+ PAD_CTL_DRV_MAX = 0x3 << 1,
+ PAD_CTL_ODE_OPENDRAIN_NONE = 0x0 << 3,
+ PAD_CTL_ODE_OPENDRAIN_ENABLE = 0x1 << 3,
+ PAD_CTL_100K_PD = 0x0 << 4,
+ PAD_CTL_47K_PU = 0x1 << 4,
+ PAD_CTL_100K_PU = 0x2 << 4,
+ PAD_CTL_22K_PU = 0x3 << 4,
+ PAD_CTL_PUE_KEEPER = 0x0 << 6,
+ PAD_CTL_PUE_PULL = 0x1 << 6,
+ PAD_CTL_PKE_NONE = 0x0 << 7,
+ PAD_CTL_PKE_ENABLE = 0x1 << 7,
+ PAD_CTL_HYS_NONE = 0x0 << 8,
+ PAD_CTL_HYS_ENABLE = 0x1 << 8,
+ PAD_CTL_DDR_INPUT_CMOS = 0x0 << 9,
+ PAD_CTL_DDR_INPUT_DDR = 0x1 << 9,
+ PAD_CTL_DRV_VOT_LOW = 0x0 << 13,
+ PAD_CTL_DRV_VOT_HIGH = 0x1 << 13,
+} iomux_pad_config_t;
+
+/*!
+ * various IOMUX general purpose functions
+ */
+typedef enum iomux_gp_func {
+ MUX_IPD_ESDHC_DREQ_B = 0x0 << 0,
+ MUX_XDRQ = 0x1 << 0,
+ MUX_EMI_DMA_ACCESS_1 = 0x0 << 4,
+ MUX_KEY_COL2 = 0x1 << 4,
+ MUX_TAMPER_DETECT_EN = 0x1 << 8,
+ MUX_IPUv3D_TVE = 0x0 << 12,
+ MUX_IPUv3D_CAMP = 0x1 << 12,
+} iomux_gp_func_t;
+
+/*!
+ * various IOMUX input select register index
+ */
+typedef enum iomux_input_select {
+ MUX_IN_CCM_PLL1_BYPASS_CLK = 0,
+ MUX_IN_CCM_PLL2_BYPASS_CLK,
+ MUX_IN_CCM_PLL3_BYPASS_CLK,
+ MUX_IN_CSPI3_CSPI_CLK,
+ MUX_IN_CSPI3_MISO,
+ MUX_IN_CSPI3_MOSI,
+ MUX_IN_EMI_READ_MADDR_DATA_0,
+ MUX_IN_EMI_READ_MADDR_DATA_10,
+ MUX_IN_EMI_READ_MADDR_DATA_11,
+ MUX_IN_EMI_READ_MADDR_DATA_12,
+ MUX_IN_EMI_READ_MADDR_DATA_13,
+ MUX_IN_EMI_READ_MADDR_DATA_14,
+ MUX_IN_EMI_READ_MADDR_DATA_15,
+ MUX_IN_EMI_READ_MADDR_DATA_1,
+ MUX_IN_EMI_READ_MADDR_DATA_2,
+ MUX_IN_EMI_READ_MADDR_DATA_3,
+ MUX_IN_EMI_READ_MADDR_DATA_4,
+ MUX_IN_EMI_READ_MADDR_DATA_5,
+ MUX_IN_EMI_READ_MADDR_DATA_6,
+ MUX_IN_EMI_READ_MADDR_DATA_7,
+ MUX_IN_EMI_READ_MADDR_DATA_8,
+ MUX_IN_EMI_READ_MADDR_DATA_9,
+ MUX_IN_EMI_NFC_READ_DATA_IN_0,
+ MUX_IN_EMI_NFC_READ_DATA_IN_10,
+ MUX_IN_EMI_NFC_READ_DATA_IN_11,
+ MUX_IN_EMI_NFC_READ_DATA_IN_12,
+ MUX_IN_EMI_NFC_READ_DATA_IN_13,
+ MUX_IN_EMI_NFC_READ_DATA_IN_14,
+ MUX_IN_EMI_NFC_READ_DATA_IN_15,
+ MUX_IN_EMI_NFC_READ_DATA_IN_1,
+ MUX_IN_EMI_NFC_READ_DATA_IN_2,
+ MUX_IN_EMI_NFC_READ_DATA_IN_3,
+ MUX_IN_EMI_NFC_READ_DATA_IN_4,
+ MUX_IN_EMI_NFC_READ_DATA_IN_5,
+ MUX_IN_EMI_NFC_READ_DATA_IN_6,
+ MUX_IN_EMI_NFC_READ_DATA_IN_7,
+ MUX_IN_EMI_NFC_READ_DATA_IN_8,
+ MUX_IN_EMI_NFC_READ_DATA_IN_9,
+ MUX_IN_FEC_FEC_COL,
+ MUX_IN_FEC_FEC_CRS, MUX_IN_FEC_FEC_MDI,
+ MUX_IN_FEC_FEC_RDATA_0,
+ MUX_IN_FEC_FEC_RX_CLK,
+ MUX_IN_FEC_FEC_RX_DV,
+ MUX_IN_FEC_FEC_RX_ER,
+ MUX_IN_FEC_FEC_TX_CLK,
+ MUX_IN_I2C1_SCL,
+ MUX_IN_I2C1_SDA,
+ MUX_IN_I2C2_SCL,
+ MUX_IN_I2C2_SDA,
+ MUX_IN_I2C3_SCL,
+ MUX_IN_I2C3_SDA,
+ MUX_IN_IPU_DI_0_IND_DISPB_D0_VSYNC,
+ MUX_IN__IPU_DI_0_IND_DISPB_SD_D,
+ MUX_IN_KPP_ROW_0,
+ MUX_IN_KPP_ROW_1,
+ MUX_IN_KPP_ROW_2,
+ MUX_IN_KPP_ROW_3,
+ MUX_IN_KPP_ROW_4,
+ MUX_IN_KPP_ROW_5,
+ MUX_IN_KPP_ROW_6,
+ MUX_IN_KPP_ROW_7,
+ MUX_IN_UART1_UART_RTS_B,
+ MUX_IN_UART1_UART_RXD_MUX,
+ MUX_IN_UART2_UART_RTS_B,
+ MUX_IN_UART2_UART_RXD_MUX,
+ MUX_IN_UART3_UART_RTS_B,
+ MUX_IN_UART3_UART_RXD_MUX,
+} iomux_input_select_t;
+
+/*!
+ * various IOMUX input functions
+ */
+typedef enum iomux_input_config {
+ INPUT_CTL_PATH0 = 0x0,
+ INPUT_CTL_PATH1,
+ INPUT_CTL_PATH2,
+ INPUT_CTL_PATH3,
+ INPUT_CTL_PATH4,
+ INPUT_CTL_PATH5,
+ INPUT_CTL_PATH6,
+ INPUT_CTL_PATH7,
+} iomux_input_config_t;
+
+/*!
+ * Request ownership for an IO pin. This function has to be the first one
+ * being called before that pin is used. The caller has to check the
+ * return value to make sure it returns 0.
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param config config as defined in \b #iomux_pin_ocfg_t
+ *
+ * @return 0 if successful; Non-zero otherwise
+ */
+int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t config);
+
+/*!
+ * Release ownership for an IO pin
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param config config as defined in \b #iomux_pin_ocfg_t
+ */
+void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t config);
+
+/*!
+ * This function enables/disables the general purpose function for a particular
+ * signal.
+ *
+ * @param gp one signal as defined in \b #iomux_gp_func_t
+ * @param en \b #true to enable; \b #false to disable
+ * @param index 0 for GPR0 and 1 for GPR1
+ */
+void mxc_iomux_set_gpr(iomux_gp_func_t gp, bool en, u8 index);
+
+/*!
+ * This function configures the pad value for a IOMUX pin.
+ *
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param config the ORed value of elements defined in \b #iomux_pad_config_t
+ */
+void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config);
+
+/*!
+ * This function gets the current pad value for a IOMUX pin.
+ *
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @return current pad value
+ */
+unsigned int mxc_iomux_get_pad(iomux_pin_name_t pin);
+
+/*!
+ * This function configures input path.
+ *
+ * @param input index of input select register as defined in \b #iomux_input_select_t
+ * @param config the binary value of elements defined in \b #iomux_input_config_t
+ */
+void mxc_iomux_set_input(iomux_input_select_t input, u32 config);
+
+#endif /* __MACH_MX37_IOMUX_H__ */
diff --git a/arch/arm/mach-mx37/lpmodes.c b/arch/arm/mach-mx37/lpmodes.c
new file mode 100644
index 000000000000..6328b78a0530
--- /dev/null
+++ b/arch/arm/mach-mx37/lpmodes.c
@@ -0,0 +1,408 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file mx37_lpmodes.c
+ *
+ * @brief Driver for the Freescale Semiconductor MXC low power modes setup.
+ *
+ * MX37 is designed to play and video with minimal power consumption.
+ * This driver enables the platform to enter and exit audio and video low
+ * power modes.
+ *
+ * @ingroup PM
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <linux/regulator/regulator-platform.h>
+#include "crm_regs.h"
+
+#define ARM_LP_CLK 200000000
+#define GP_LPM_VOLTAGE 850000
+#define LP_LPM_VOLTAGE 1000000
+#define GP_NORMAL_VOLTAGE 1000000
+#define LP_NORMAL_VOLTAGE 1200000
+
+static int org_cpu_rate;
+int lp_video_mode;
+int lp_audio_mode;
+static struct device *lpmode_dev;
+
+void enter_lp_video_mode(void)
+{
+ int ret = 0;
+
+ struct clk *p_clk;
+ struct clk *tclk;
+ struct clk *vmode_parent_clk;
+ struct regulator *gp_core;
+
+ tclk = clk_get(NULL, "main_bus_clk");
+ vmode_parent_clk = clk_get(NULL, "pll2");
+ p_clk = clk_get_parent(tclk);
+
+ if (p_clk != vmode_parent_clk) {
+ clk_set_parent(tclk, vmode_parent_clk);
+
+ clk_set_rate(clk_get(NULL, "axi_a_clk"), 133000000);
+ clk_set_rate(clk_get(NULL, "axi_b_clk"), 66500000);
+ clk_set_rate(clk_get(NULL, "axi_c_clk"), 166000000);
+ clk_set_rate(clk_get(NULL, "emi_core_clk"), 133000000);
+ clk_set_rate(clk_get(NULL, "nfc_clk"), 26600000);
+ clk_set_rate(clk_get(NULL, "ahb_clk"), 133000000);
+ }
+
+ /* move VPU clock to source from the emi_core_clk */
+ tclk = clk_get(NULL, "vpu_clk");
+ vmode_parent_clk = clk_get(NULL, "emi_core_clk");
+ if (clk_get_parent(tclk) != vmode_parent_clk)
+ clk_set_parent(tclk, vmode_parent_clk);
+
+ tclk = clk_get(NULL, "vpu_core_clk");
+ if (clk_get_parent(tclk) != vmode_parent_clk)
+ clk_set_parent(tclk, vmode_parent_clk);
+
+ tclk = clk_get(NULL, "arm_axi_clk");
+ if (clk_get_parent(tclk) != vmode_parent_clk)
+ clk_set_parent(tclk, vmode_parent_clk);
+
+ tclk = clk_get(NULL, "ddr_clk");
+ vmode_parent_clk = clk_get(NULL, "axi_c_clk");
+ if (clk_get_parent(tclk) != vmode_parent_clk)
+ clk_set_parent(tclk, vmode_parent_clk);
+
+ /* disable PLL3 */
+ tclk = clk_get(NULL, "pll3");
+ if (tclk->usecount == 1)
+ clk_disable(tclk);
+
+ tclk = clk_get(NULL, "cpu_clk");
+ org_cpu_rate = clk_get_rate(tclk);
+
+ ret = clk_set_rate(tclk, ARM_LP_CLK);
+ if (ret != 0)
+ printk(KERN_DEBUG "cannot set CPU clock rate\n");
+
+ /* Set the voltage to 0.8v for the GP domain. */
+
+ if (!board_is_mx37(BOARD_REV_2))
+ gp_core = regulator_get(NULL, "DCDC1");
+ else
+ gp_core = regulator_get(NULL, "SW1");
+
+ ret = regulator_set_voltage(gp_core, GP_LPM_VOLTAGE);
+ if (ret < 0)
+ printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!\n");
+
+ lp_video_mode = 1;
+}
+
+void exit_lp_video_mode(void)
+{
+ int ret = 0;
+ static struct clk *tclk;
+ struct regulator *gp_core;
+
+ /*Set the voltage to 0.8v for the GP domain. */
+ if (!board_is_mx37(BOARD_REV_2))
+ gp_core = regulator_get(NULL, "DCDC1");
+ else
+ gp_core = regulator_get(NULL, "SW1");
+
+ ret = regulator_set_voltage(gp_core, GP_NORMAL_VOLTAGE);
+ if (ret < 0)
+ printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!\n");
+
+ tclk = clk_get(NULL, "cpu_clk");
+
+ ret = clk_set_rate(tclk, org_cpu_rate);
+ if (ret != 0)
+ printk(KERN_DEBUG "cannot set CPU clock rate\n");
+
+ lp_video_mode = 0;
+}
+
+void enter_lp_audio_mode(void)
+{
+ int ret = 0;
+
+ struct clk *p_clk;
+ struct clk *tclk;
+ struct clk *amode_parent_clk;
+ struct regulator *gp_core;
+ struct regulator *lp_core;
+
+ tclk = clk_get(NULL, "ipu_clk");
+ if (clk_get_usecount(tclk) != 0) {
+ printk(KERN_INFO
+ "Cannot enter AUDIO LPM mode - display is still active\n");
+ return;
+ }
+
+ tclk = clk_get(NULL, "periph_apm_clk");
+ amode_parent_clk = clk_get(NULL, "lp_apm");
+ p_clk = clk_get_parent(tclk);
+
+ /* Make sure osc_clk is the parent of lp_apm. */
+ clk_set_parent(amode_parent_clk, clk_get(NULL, "osc"));
+
+ /* Set the parent of periph_apm_clk to be lp_apm */
+ clk_set_parent(tclk, amode_parent_clk);
+ amode_parent_clk = tclk;
+
+ tclk = clk_get(NULL, "main_bus_clk");
+ p_clk = clk_get_parent(tclk);
+ /* Set the parent of main_bus_clk to be periph_apm_clk */
+ clk_set_parent(tclk, amode_parent_clk);
+
+ clk_set_rate(clk_get(NULL, "axi_a_clk"), 24000000);
+ clk_set_rate(clk_get(NULL, "axi_b_clk"), 24000000);
+ clk_set_rate(clk_get(NULL, "axi_c_clk"), 24000000);
+ clk_set_rate(clk_get(NULL, "emi_core_clk"), 24000000);
+ clk_set_rate(clk_get(NULL, "nfc_clk"), 4800000);
+ clk_set_rate(clk_get(NULL, "ahb_clk"), 24000000);
+
+ amode_parent_clk = clk_get(NULL, "emi_core_clk");
+
+ tclk = clk_get(NULL, "arm_axi_clk");
+ p_clk = clk_get_parent(tclk);
+ if (p_clk != amode_parent_clk) {
+ clk_set_parent(tclk, amode_parent_clk);
+ }
+
+ tclk = clk_get(NULL, "vpu_clk");
+ p_clk = clk_get_parent(tclk);
+ if (p_clk != amode_parent_clk) {
+ clk_set_parent(tclk, amode_parent_clk);
+ }
+
+ tclk = clk_get(NULL, "vpu_core_clk");
+ p_clk = clk_get_parent(tclk);
+ if (p_clk != amode_parent_clk) {
+ clk_set_parent(tclk, amode_parent_clk);
+ }
+
+ /* disable PLL3 */
+ tclk = clk_get(NULL, "pll3");
+ if (tclk->usecount == 1)
+ clk_disable(tclk);
+
+ /* disable PLL2 */
+ tclk = clk_get(NULL, "pll2");
+ if (tclk->usecount == 1)
+ clk_disable(tclk);
+
+ /* Set the voltage to 1.0v for the LP domain. */
+ if (!board_is_mx37(BOARD_REV_2))
+ lp_core = regulator_get(NULL, "DCDC4");
+ else
+ lp_core = regulator_get(NULL, "SW2");
+
+ if (lp_core != NULL) {
+ ret = regulator_set_voltage(lp_core, LP_LPM_VOLTAGE);
+ if (ret < 0)
+ printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!!!\n");
+ }
+
+ tclk = clk_get(NULL, "cpu_clk");
+ org_cpu_rate = clk_get_rate(tclk);
+
+ ret = clk_set_rate(tclk, ARM_LP_CLK);
+ if (ret != 0)
+ printk(KERN_DEBUG "cannot set CPU clock rate\n");
+
+ /* Set the voltage to 0.8v for the GP domain. */
+ if (!board_is_mx37(BOARD_REV_2))
+ gp_core = regulator_get(NULL, "DCDC1");
+ else
+ gp_core = regulator_get(NULL, "SW1");
+
+ if (gp_core != NULL) {
+ ret = regulator_set_voltage(gp_core, GP_LPM_VOLTAGE);
+ if (ret < 0)
+ printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!!\n");
+ }
+ lp_audio_mode = 1;
+}
+
+void exit_lp_audio_mode(void)
+{
+ struct regulator *gp_core;
+ struct regulator *lp_core;
+ struct clk *tclk;
+ struct clk *p_clk;
+ struct clk *rmode_parent_clk;
+ int ret;
+
+ lp_audio_mode = 0;
+ /* Set the voltage to 1.2v for the LP domain. */
+ if (!board_is_mx37(BOARD_REV_2))
+ lp_core = regulator_get(NULL, "DCDC4");
+ else
+ lp_core = regulator_get(NULL, "SW2");
+
+ if (lp_core != NULL) {
+ ret = regulator_set_voltage(lp_core, LP_NORMAL_VOLTAGE);
+ if (ret < 0)
+ printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!!!\n");
+ }
+
+ /* Set the voltage to 1.0v for the GP domain. */
+ if (!board_is_mx37(BOARD_REV_2))
+ gp_core = regulator_get(NULL, "DCDC1");
+ else
+ gp_core = regulator_get(NULL, "SW1");
+
+ ret = regulator_set_voltage(gp_core, GP_NORMAL_VOLTAGE);
+ if (ret < 0)
+ printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!\n");
+
+ tclk = clk_get(NULL, "cpu_clk");
+
+ ret = clk_set_rate(tclk, org_cpu_rate);
+ if (ret != 0)
+ printk(KERN_DEBUG "cannot set CPU clock rate\n");
+
+ rmode_parent_clk = clk_get(NULL, "pll2");
+ clk_enable(rmode_parent_clk);
+
+ tclk = clk_get(NULL, "main_bus_clk");
+ p_clk = clk_get_parent(tclk);
+
+ /* Set the dividers before setting the parent clock. */
+ clk_set_rate(clk_get(NULL, "axi_a_clk"), 4800000);
+ clk_set_rate(clk_get(NULL, "axi_b_clk"), 4000000);
+ clk_set_rate(clk_get(NULL, "axi_c_clk"), 6000000);
+ clk_set_rate(clk_get(NULL, "emi_core_clk"), 4800000);
+ clk_set_rate(clk_get(NULL, "ahb_clk"), 4800000);
+
+ /* Set the parent of main_bus_clk to be pll2 */
+ clk_set_parent(tclk, rmode_parent_clk);
+ udelay(5);
+}
+
+static ssize_t lp_curr_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (lp_video_mode)
+ return sprintf(buf, "in lp_video_mode\n");
+ else if (lp_audio_mode)
+ return sprintf(buf, "in lp_audio_mode\n");
+ else
+ return sprintf(buf, "in normal mode\n");
+}
+
+static ssize_t set_lp_mode(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ printk(KERN_DEBUG "In set_lp_mode() \n");
+
+ if (strstr(buf, "enable_lp_video") != NULL) {
+ if (!lp_video_mode)
+ enter_lp_video_mode();
+ } else if (strstr(buf, "disable_lp_video") != NULL) {
+ if (lp_video_mode)
+ exit_lp_video_mode();
+ } else if (strstr(buf, "enable_lp_audio") != NULL) {
+ if (!lp_audio_mode)
+ enter_lp_audio_mode();
+ } else if (strstr(buf, "disable_lp_audio") != NULL) {
+ if (lp_audio_mode)
+ exit_lp_audio_mode();
+ }
+ return size;
+}
+
+static DEVICE_ATTR(lp_modes, 0644, lp_curr_mode, set_lp_mode);
+
+/*!
+ * This is the probe routine for the lp_mode driver.
+ *
+ * @param pdev The platform device structure
+ *
+ * @return The function returns 0 on success
+ *
+ */
+static int __devinit mx37_lpmode_probe(struct platform_device *pdev)
+{
+ u32 res = 0;
+ lpmode_dev = &pdev->dev;
+
+ res = sysfs_create_file(&lpmode_dev->kobj, &dev_attr_lp_modes.attr);
+ if (res) {
+ printk(KERN_ERR
+ "lpmode_dev: Unable to register sysdev entry for lpmode_dev");
+ return res;
+ }
+
+ if (res != 0) {
+ printk(KERN_ERR "lpmode_dev: Unable to start");
+ return res;
+ }
+ lp_video_mode = 0;
+ lp_audio_mode = 0;
+
+ return 0;
+}
+
+static struct platform_driver mx37_lpmode_driver = {
+ .driver = {
+ .name = "mx37_lpmode",
+ },
+ .probe = mx37_lpmode_probe,
+};
+
+/*!
+ * Initialise the mx37_lpmode_driver.
+ *
+ * @return The function always returns 0.
+ */
+
+static int __init lpmode_init(void)
+{
+ if (platform_driver_register(&mx37_lpmode_driver) != 0) {
+ printk(KERN_ERR "mx37_lpmode_driver register failed\n");
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "LPMode driver module loaded\n");
+ return 0;
+}
+
+static void __exit lpmode_cleanup(void)
+{
+ sysfs_remove_file(&lpmode_dev->kobj, &dev_attr_lp_modes.attr);
+
+ /* Unregister the device structure */
+ platform_driver_unregister(&mx37_lpmode_driver);
+}
+
+module_init(lpmode_init);
+module_exit(lpmode_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("LPMode driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-mx37/mm.c b/arch/arm/mach-mx37/mm.c
new file mode 100644
index 000000000000..64a4df695219
--- /dev/null
+++ b/arch/arm/mach-mx37/mm.c
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <mach/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+/*!
+ * @file mach-mx37/mm.c
+ *
+ * @brief This file creates static mapping between physical to virtual memory.
+ *
+ * @ingroup Memory_MX37
+ */
+
+/*!
+ * This structure defines the MX37 memory map.
+ */
+static struct map_desc mxc_io_desc[] __initdata = {
+ {
+ .virtual = IRAM_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(IRAM_BASE_ADDR),
+ .length = IRAM_SIZE,
+ .type = MT_DEVICE_NONSHARED},
+ {
+ .virtual = PLATFORM_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(PLATFORM_BASE_ADDR),
+ .length = PLATFORM_SIZE,
+ .type = MT_DEVICE},
+ {
+ .virtual = DEBUG_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(DEBUG_BASE_ADDR),
+ .length = DEBUG_SIZE,
+ .type = MT_DEVICE_NONSHARED},
+ {
+ .virtual = TZIC_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(TZIC_BASE_ADDR),
+ .length = TZIC_SIZE,
+ .type = MT_DEVICE_NONSHARED},
+ {
+ .virtual = AIPS1_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
+ .length = AIPS1_SIZE,
+ .type = MT_DEVICE_NONSHARED},
+ {
+ .virtual = SPBA0_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
+ .length = SPBA0_SIZE,
+ .type = MT_DEVICE_NONSHARED},
+ {
+ .virtual = AIPS2_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
+ .length = AIPS2_SIZE,
+ .type = MT_DEVICE_NONSHARED},
+ {
+ .virtual = NFC_BASE_ADDR_AXI_VIRT,
+ .pfn = __phys_to_pfn(NFC_BASE_ADDR_AXI),
+ .length = NFC_AXI_SIZE,
+ .type = MT_DEVICE},
+};
+
+/*!
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory map for
+ * the IO modules.
+ */
+void __init mxc_map_io(void)
+{
+ iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
+}
diff --git a/arch/arm/mach-mx37/mx37_3stack.c b/arch/arm/mach-mx37/mx37_3stack.c
new file mode 100644
index 000000000000..9b7700cf443e
--- /dev/null
+++ b/arch/arm/mach-mx37/mx37_3stack.c
@@ -0,0 +1,907 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/ata.h>
+#include <linux/regulator/regulator.h>
+#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE)
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/flash.h>
+#endif
+
+#include <mach/hardware.h>
+#include <mach/spba.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+#include <mach/memory.h>
+#include <mach/gpio.h>
+#include <mach/mmc.h>
+#include "board-mx37_3stack.h"
+#include "iomux.h"
+#include "crm_regs.h"
+
+/*!
+ * @file mach-mx37/mx37_3stack.c
+ *
+ * @brief This file contains the board specific initialization routines.
+ *
+ * @ingroup MSL_MX37
+ */
+extern void gpio_lcd_active(void);
+
+/* working point(wp): 0 - 532MHz; 1 - 200MHz; */
+static struct cpu_wp cpu_wp_auto[] = {
+ {
+ .pll_rate = 532000000,
+ .cpu_rate = 532000000,
+ .pdf = 0,
+ .mfi = 5,
+ .mfd = 23,
+ .mfn = 13,
+ .cpu_voltage = 1000000,},
+ {
+ .pll_rate = 400000000,
+ .cpu_rate = 400000000,
+ .pdf = 1,
+ .mfi = 8,
+ .mfd = 2,
+ .mfn = 1,
+ .cpu_voltage = 900000,},
+ {
+ .pll_rate = 200000000,
+ .cpu_rate = 200000000,
+ .pdf = 3,
+ .mfi = 8,
+ .mfd = 2,
+ .mfn = 1,
+ .cpu_voltage = 850000,},
+ {
+ .pll_rate = 600000000,
+ .cpu_rate = 600000000,
+ .pdf = 0,
+ .mfi = 6,
+ .mfd = 3,
+ .mfn = 1,
+ .cpu_voltage = 1200000,},
+};
+
+struct cpu_wp *get_cpu_wp(int *wp)
+{
+ *wp = 3;
+ return cpu_wp_auto;
+}
+
+static void mc13892_reg_int(void)
+{
+ int i = 0;
+ struct regulator *regulator;
+ struct cpu_wp *cpu_wp_tbl1;
+ int cpu_wp_nr1;
+ char *reg_name[] = {
+ "SW1",
+ "SW2",
+ "SW3",
+ "SW4",
+ "SW1_STBY",
+ "SW2_STBY",
+ "SW3_STBY",
+ "SW4_STBY",
+ "SW1_DVS",
+ "SW2_DVS",
+ "SWBST",
+ "VIOHI",
+ "VPLL",
+ "VDIG",
+ "VSD",
+ "VUSB2",
+ "VVIDEO",
+ "VAUDIO",
+ "VCAM",
+ "VGEN1",
+ "VGEN2",
+ "VGEN3",
+ "USB",
+ "GPO1",
+ "GPO2",
+ "GPO3",
+ "GPO4",
+ };
+
+ /* for board v1.1 do nothing*/
+ if (!board_is_mx37(BOARD_REV_2))
+ return;
+
+ for (i = 0; i < ARRAY_SIZE(reg_name); i++) {
+ regulator = regulator_get(NULL, reg_name[i]);
+ if (regulator != ERR_PTR(-ENOENT)) {
+ regulator_enable(regulator);
+ regulator_put(regulator, NULL);
+ }
+ }
+ for (i = 0; i < ARRAY_SIZE(reg_name); i++) {
+ if ((strcmp(reg_name[i], "VIOHI") == 0) ||
+ (strcmp(reg_name[i], "VPLL") == 0) ||
+ (strcmp(reg_name[i], "VDIG") == 0) ||
+ (strcmp(reg_name[i], "VGEN2") == 0))
+ continue;
+ regulator = regulator_get(NULL, reg_name[i]);
+ if (regulator != ERR_PTR(-ENOENT)) {
+ regulator_disable(regulator);
+ regulator_put(regulator, NULL);
+ }
+ }
+
+ /* Set the current working point. */
+ cpu_wp_tbl1 = get_cpu_wp(&cpu_wp_nr1);
+ for (i = 0; i < cpu_wp_nr1; i++)
+ cpu_wp_tbl1[i].cpu_voltage += 50000;
+}
+
+late_initcall(mc13892_reg_int);
+
+static void mxc_nop_release(struct device *dev)
+{
+ /* Nothing */
+}
+
+/* MTD NAND flash */
+#if defined(CONFIG_MTD_NAND_MXC) || defined(CONFIG_MTD_NAND_MXC_MODULE) \
+ || defined(CONFIG_MTD_NAND_MXC_V2) || defined(CONFIG_MTD_NAND_MXC_V2_MODULE) \
+ || defined(CONFIG_MTD_NAND_MXC_V3)
+
+static struct mtd_partition mxc_nand_partitions[] = {
+ {
+ .name = "nand.bootloader",
+ .offset = 0,
+ .size = 2 * 1024 * 1024},
+ {
+ .name = "nand.kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 4 * 1024 * 1024},
+ {
+ .name = "nand.rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 128 * 1024 * 1024},
+ {
+ .name = "nand.userfs1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 256 * 1024 * 1024},
+ {
+ .name = "nand.userfs2",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 512 * 1024 * 1024},
+ {
+ .name = "nand.userfs3",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 1024 * 1024 * 1024},
+};
+
+static struct flash_platform_data mxc_nand_data = {
+ .parts = mxc_nand_partitions,
+ .nr_parts = ARRAY_SIZE(mxc_nand_partitions),
+ .width = 1,
+};
+
+static struct platform_device mxc_nandv2_mtd_device = {
+ .name = "mxc_nandv2_flash",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_nand_data,
+ },
+};
+
+static void mxc_init_nand_mtd(void)
+{
+// if (__raw_readl(MXC_CCM_RCSR) & MXC_CCM_RCSR_NF16B) {
+// mxc_nand_data.width = 2;
+// }
+ (void)platform_device_register(&mxc_nandv2_mtd_device);
+}
+#else
+static inline void mxc_init_nand_mtd(void)
+{
+}
+#endif
+
+static void lcd_reset(void)
+{
+ static int first;
+
+ /* ensure that LCDIO(1.8V) has been turn on */
+ /* active reset line GPIO */
+ if (!first) {
+ mxc_request_iomux(MX37_PIN_GPIO1_5, IOMUX_CONFIG_GPIO);
+ first = 1;
+ }
+ mxc_set_gpio_dataout(MX37_PIN_GPIO1_5, 0);
+ mxc_set_gpio_direction(MX37_PIN_GPIO1_5, 0);
+ /* do reset */
+ msleep(10); /* tRES >= 100us */
+ mxc_set_gpio_dataout(MX37_PIN_GPIO1_5, 1);
+ msleep(60);
+}
+
+static struct mxc_lcd_platform_data lcd_data = {
+ .core_reg = "VVIDEO",
+ .io_reg = "SW4",
+ .reset = lcd_reset,
+};
+
+#if defined(CONFIG_KEYBOARD_MPR084) || defined(CONFIG_KEYBOARD_MPR084_MODULE)
+/*!
+ * These functions are used to configure and the GPIO pins for keypad to
+ * activate and deactivate it.
+ */
+extern void gpio_keypad_active(void);
+
+extern void gpio_keypad_inactive(void);
+
+static u16 keymap[] = {
+ KEY_DOWN, KEY_LEFT, KEY_ENTER,
+ KEY_RIGHT, KEY_UP, KEY_LEFTALT,
+ KEY_TAB, KEY_ESC,
+};
+
+static struct mxc_keyp_platform_data keypad_data = {
+ .matrix = keymap,
+ .active = gpio_keypad_active,
+ .inactive = gpio_keypad_inactive,
+ .vdd_reg = "VGEN2",
+};
+#else
+
+static struct mxc_keyp_platform_data keypad_data = {};
+
+#endif
+
+static struct mxc_lightsensor_platform_data ls_data = {
+ .vdd_reg = "VGEN2",
+ .rext = 100,
+};
+static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
+ {
+ .type = "tsc2007",
+ .addr = 0x48,
+ .irq = IOMUX_TO_IRQ(MX37_PIN_AUD5_RXFS),
+ },
+ {
+ .type = "mpr084",
+ .addr = 0x5D,
+ .platform_data = &keypad_data,
+ .irq = IOMUX_TO_IRQ(MX37_PIN_GPIO1_3),
+ },
+ {
+ .type = "isl29003",
+ .addr = 0x44,
+ .platform_data = &ls_data,
+ },
+};
+
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+ {
+ .type = "mc13892",
+ .addr = 0x08,
+ .platform_data = (void *)MX37_PIN_OWIRE_LINE,
+ },
+ {
+ .type = "sgtl5000-i2c",
+ .addr = 0x0a,
+ },
+};
+
+static struct spi_board_info mxc_spi_board_info[] __initdata = {
+ {
+ .modalias = "cpld_spi",
+ .max_speed_hz = 27000000,
+ .bus_num = 2,
+ .chip_select = 0,
+ },
+ {
+ .modalias = "lcd_spi",
+ .max_speed_hz = 5000000,
+ .bus_num = 2,
+ .platform_data = &lcd_data,
+ .chip_select = 1,},
+};
+
+#if defined(CONFIG_FB_MXC_SYNC_PANEL) || defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE)
+static struct platform_device mxc_fb_device[] = {
+ {
+ .name = "mxc_sdc_fb",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+ },
+ {
+ .name = "mxc_sdc_fb",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+ },
+ {
+ .name = "mxc_sdc_fb",
+ .id = 2,
+ .dev = {
+ .release = mxc_nop_release,
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+ },
+};
+
+static void mxc_init_fb(void)
+{
+ (void)platform_device_register(&mxc_fb_device[0]);
+ (void)platform_device_register(&mxc_fb_device[1]);
+ (void)platform_device_register(&mxc_fb_device[2]);
+ gpio_lcd_active();
+}
+#else
+static inline void mxc_init_fb(void)
+{
+}
+#endif
+
+static struct platform_device mxcbl_device = {
+ .name = "mxc_mc13892_bl",
+};
+
+static inline void mxc_init_bl(void)
+{
+ platform_device_register(&mxcbl_device);
+}
+
+#if defined(CONFIG_TOUCHSCREEN_TSC2007) || defined(CONFIG_TOUCHSCREEN_TSC2007_MODULE)
+
+static int __init mxc_init_touchscreen(void)
+{
+ int pad_val;
+
+ mxc_request_iomux(MX37_PIN_AUD5_RXFS, IOMUX_CONFIG_GPIO);
+ pad_val = PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU;
+ mxc_iomux_set_pad(MX37_PIN_AUD5_RXFS, pad_val);
+ mxc_set_gpio_direction(MX37_PIN_AUD5_RXFS, 1);
+
+ return 0;
+}
+#else
+static int __init mxc_init_touchscreen(void)
+{
+ return 0;
+}
+#endif
+
+/*lan9217 device*/
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+static struct resource smsc911x_resources[] = {
+ {
+ .start = LAN9217_BASE_ADDR,
+ .end = LAN9217_BASE_ADDR + 255,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_EXP_IO_BASE,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+static struct platform_device smsc_lan9217_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+};
+
+static int __init mxc_init_enet(void)
+{
+ (void)platform_device_register(&smsc_lan9217_device);
+ return 0;
+}
+#else
+static int __init mxc_init_enet(void)
+{
+ return 0;
+}
+#endif
+
+late_initcall(mxc_init_enet);
+
+#if defined(CONFIG_PATA_FSL) || defined(CONFIG_PATA_FSL_MODULE)
+extern void gpio_ata_active(void);
+extern void gpio_ata_inactive(void);
+
+static int ata_init(struct platform_device *pdev)
+{
+ /* Configure the pins */
+ gpio_ata_active();
+
+ return 0;
+}
+
+static void ata_exit(void)
+{
+ /* Free the pins */
+ gpio_ata_inactive();
+}
+
+static struct fsl_ata_platform_data ata_data = {
+ .udma_mask = ATA_UDMA3, /* board can handle up to UDMA3 */
+ .mwdma_mask = ATA_MWDMA2,
+ .pio_mask = ATA_PIO4,
+ .fifo_alarm = MXC_IDE_DMA_WATERMARK / 2,
+ .max_sg = MXC_IDE_DMA_BD_NR,
+ .init = ata_init,
+ .exit = ata_exit,
+ .core_reg = NULL, /*"LDO2", */
+ .io_reg = NULL, /*"LDO3", */
+};
+
+static struct resource pata_fsl_resources[] = {
+ [0] = { /* I/O */
+ .start = ATA_BASE_ADDR,
+ .end = ATA_BASE_ADDR + 0x000000C8,
+ .flags = IORESOURCE_MEM,
+ },
+ [2] = { /* IRQ */
+ .start = MXC_INT_ATA,
+ .end = MXC_INT_ATA,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device pata_fsl_device = {
+ .name = "pata_fsl",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pata_fsl_resources),
+ .resource = pata_fsl_resources,
+ .dev = {
+ .platform_data = &ata_data,
+ .coherent_dma_mask = ~0,
+ },
+};
+
+static void __init mxc_init_pata(void)
+{
+ (void)platform_device_register(&pata_fsl_device);
+}
+#else /* CONFIG_PATA_FSL */
+static void __init mxc_init_pata(void)
+{
+}
+#endif /* CONFIG_PATA_FSL */
+
+/*!
+ * Board specific fixup function. It is called by \b setup_arch() in
+ * setup.c file very early on during kernel starts. It allows the user to
+ * statically fill in the proper values for the passed-in parameters. None of
+ * the parameters is used currently.
+ *
+ * @param desc pointer to \b struct \b machine_desc
+ * @param tags pointer to \b struct \b tag
+ * @param cmdline pointer to the command line
+ * @param mi pointer to \b struct \b meminfo
+ */
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ mxc_cpu_init();
+
+#ifdef CONFIG_DISCONTIGMEM
+ do {
+ int nid;
+ mi->nr_banks = MXC_NUMNODES;
+ for (nid = 0; nid < mi->nr_banks; nid++) {
+ SET_NODE(mi, nid);
+ }
+ } while (0);
+#endif
+}
+
+#if defined(CONFIG_SDIO_UNIFI_FS) || defined(CONFIG_SDIO_UNIFI_FS_MODULE)
+static void mxc_unifi_hardreset(void)
+{
+ struct regulator *gpo4;
+
+ if (board_is_mx37(BOARD_REV_2)) {
+ gpo4 = regulator_get(NULL, "GPO4");
+ if (!IS_ERR(gpo4))
+ regulator_enable(gpo4);
+ regulator_put(gpo4, NULL);
+ } else {
+ mxc_request_iomux(MX37_PIN_AUD5_RXC, IOMUX_CONFIG_GPIO);
+ mxc_set_gpio_dataout(MX37_PIN_AUD5_RXC, 1);
+ mxc_set_gpio_direction(MX37_PIN_AUD5_RXC, 0);
+ mxc_free_iomux(MX37_PIN_AUD5_RXC, IOMUX_CONFIG_GPIO);
+ }
+}
+
+static struct mxc_unifi_platform_data unifi_data = {
+ .hardreset = mxc_unifi_hardreset,
+ .enable = NULL,
+ .reg_1v5_ana_bb = "VGEN1",
+ .reg_vdd_vpa = "VCAM",
+ .reg_1v5_dd = "VGEN1",
+ .host_id = 1,
+};
+
+struct mxc_unifi_platform_data *get_unifi_plat_data(void)
+{
+ return &unifi_data;
+}
+#else
+struct mxc_unifi_platform_data *get_unifi_plat_data(void)
+{
+ return NULL;
+}
+#endif
+
+EXPORT_SYMBOL(get_unifi_plat_data);
+
+#if defined(CONFIG_MMC_IMX_ESDHCI) || defined(CONFIG_MMC_IMX_ESDHCI_MODULE)
+static struct mxc_mmc_platform_data mmc_data = {
+ .ocr_mask = MMC_VDD_32_33,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .min_clk = 400000,
+ .max_clk = 52000000,
+ .card_inserted_state = 0,
+ .status = sdhc_get_card_det_status,
+ .wp_status = sdhc_write_protect,
+ .clock_mmc = "esdhc_clk",
+};
+
+/*!
+ * Resource definition for the SDHC1
+ */
+static struct resource mxcsdhc1_resources[] = {
+ [0] = {
+ .start = MMC_SDHC1_BASE_ADDR,
+ .end = MMC_SDHC1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_MMC_SDHC1,
+ .end = MXC_INT_MMC_SDHC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Device Definition for MXC SDHC1 */
+static struct platform_device mxcsdhc1_device = {
+ .name = "mxsdhci",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mmc_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcsdhc1_resources),
+ .resource = mxcsdhc1_resources,
+};
+
+#if defined(CONFIG_SDIO_UNIFI_FS) || defined(CONFIG_SDIO_UNIFI_FS_MODULE)
+static struct mxc_mmc_platform_data mmc1_data = {
+ .ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29 | MMC_VDD_29_30 |
+ MMC_VDD_31_32,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .min_clk = 150000,
+ .max_clk = 50000000,
+ .card_inserted_state = 0,
+ .status = sdhc_get_card_det_status,
+ .wp_status = sdhc_write_protect,
+ .clock_mmc = "esdhc_clk",
+};
+
+static struct resource mxcsdhc2_resources[] = {
+ [0] = {
+ .start = MMC_SDHC2_BASE_ADDR,
+ .end = MMC_SDHC2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_MMC_SDHC2,
+ .end = MXC_INT_MMC_SDHC2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mxcsdhc2_device = {
+ .name = "mxsdhci",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mmc1_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcsdhc2_resources),
+ .resource = mxcsdhc2_resources,
+};
+#endif
+
+static inline void mxc_init_mmc(void)
+{
+ int cd_irq;
+
+ cd_irq = sdhc_init_card_det(0);
+ if (cd_irq) {
+ mxcsdhc1_device.resource[2].start = cd_irq;
+ mxcsdhc1_device.resource[2].end = cd_irq;
+ }
+
+ spba_take_ownership(SPBA_SDHC1, SPBA_MASTER_A | SPBA_MASTER_C);
+ (void)platform_device_register(&mxcsdhc1_device);
+#if defined(CONFIG_SDIO_UNIFI_FS) || defined(CONFIG_SDIO_UNIFI_FS_MODULE)
+ cd_irq = sdhc_init_card_det(1);
+ if (cd_irq) {
+ mxcsdhc2_device.resource[2].start = cd_irq;
+ mxcsdhc2_device.resource[2].end = cd_irq;
+ }
+ spba_take_ownership(SPBA_SDHC2, SPBA_MASTER_A | SPBA_MASTER_C);
+ (void)platform_device_register(&mxcsdhc2_device);
+#endif
+}
+#else
+static inline void mxc_init_mmc(void)
+{
+}
+#endif
+
+static void bt_reset(void)
+{
+ struct regulator *gpo4;
+ if (board_is_mx37(BOARD_REV_2)) {
+ gpo4 = regulator_get(NULL, "GPO4");
+ if (!IS_ERR(gpo4))
+ regulator_enable(gpo4);
+ regulator_put(gpo4, NULL);
+ } else {
+ mxc_request_iomux(MX37_PIN_AUD5_RXC, IOMUX_CONFIG_GPIO);
+ mxc_set_gpio_dataout(MX37_PIN_AUD5_RXC, 1);
+ mxc_set_gpio_direction(MX37_PIN_AUD5_RXC, 0);
+ }
+}
+
+static struct mxc_bt_platform_data mxc_bt_data = {
+ .bt_vdd = "VGEN2",
+ .bt_vdd_parent = NULL,
+ .bt_vusb = "SW4",
+ .bt_vusb_parent = NULL,
+ .bt_reset = bt_reset,
+};
+
+static struct platform_device mxc_bt_device = {
+ .name = "mxc_bt",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_bt_data,
+ },
+};
+
+static void mxc_init_bluetooth(void)
+{
+ (void)platform_device_register(&mxc_bt_device);
+}
+
+#if defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000) \
+ || defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000_MODULE)
+static struct mxc_sgtl5000_platform_data sgtl5000_data = {
+ .ssi_num = 1,
+ .src_port = 2,
+ .ext_port = 5,
+ .hp_irq = IOMUX_TO_IRQ(MX37_PIN_AUD5_RXFS),
+ .hp_status = headphone_det_status,
+ .vddio_reg = "SW3",
+ .vdda_reg = "VAUDIO",
+ .amp_gpo = "GPO2",
+ .vddio = 1850000,
+ .vdda = 2775000,
+ .vddd = 0,
+ .sysclk = 8300000,
+};
+
+static struct platform_device sgtl5000_device = {
+ .name = "sgtl5000-imx",
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &sgtl5000_data,
+ },
+};
+
+static void mxc_sgtl5000_init(void)
+{
+ int err, pin;
+ struct clk *cko1, *parent;
+ unsigned long rate;
+
+ /* for board v1.1 do nothing*/
+ if (!board_is_mx37(BOARD_REV_2))
+ return;
+
+ pin = MX37_PIN_AUD5_RXFS;
+ err = mxc_request_iomux(pin, IOMUX_CONFIG_GPIO);
+ if (err) {
+ sgtl5000_data.hp_irq = -1;
+ printk(KERN_ERR "Error: sgtl5000_init request gpio failed!\n");
+ return;
+ }
+ mxc_iomux_set_pad(pin, PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU);
+ mxc_set_gpio_direction(pin, 1);
+
+ /* cko1 clock */
+ mxc_request_iomux(MX37_PIN_GPIO1_6, IOMUX_CONFIG_ALT2);
+
+ cko1 = clk_get(NULL, "cko1_clk");
+ if (IS_ERR(cko1))
+ return;
+ parent = clk_get(NULL, "ipg_perclk");
+ if (IS_ERR(parent))
+ return;
+ clk_set_parent(cko1, parent);
+ rate = clk_round_rate(cko1, 13000000);
+ if (rate < 8000000 || rate > 27000000) {
+ printk(KERN_ERR "Error: SGTL5000 mclk freq %d out of range!\n",
+ rate);
+ clk_put(parent);
+ clk_put(cko1);
+ return;
+ }
+ clk_set_rate(cko1, rate);
+ clk_enable(cko1);
+ sgtl5000_data.sysclk = rate;
+ platform_device_register(&sgtl5000_device);
+}
+#else
+static inline void mxc_sgtl5000_init(void)
+{
+}
+#endif
+
+/*!
+ * fixup for mx37 3stack board v1.1(wm8350)
+ */
+static void mx37_3stack_fixup_for_board_v1(void)
+{
+ dptc_gp_data.reg_id = "DCDC1";
+ dptc_lp_data.reg_id = "DCDC4";
+ gp_reg_id = "DCDC1";
+ lp_reg_id = "DCDC4";
+ tve_data.dac_reg = "LDO2";
+ tve_data.dig_reg = "LDO3";
+ lcd_data.core_reg = "LDO1";
+ lcd_data.io_reg = "DCDC6";
+ dvfs_core_data.reg_id = "DCDC1";
+ ls_data.vdd_reg = "DCDC3";
+ mxc_bt_data.bt_vdd = "DCDC3";
+ mxc_bt_data.bt_vusb = "DCDC6";
+ mxc_init_touchscreen();
+#if defined(CONFIG_SDIO_UNIFI_FS) || defined(CONFIG_SDIO_UNIFI_FS_MODULE)
+ unifi_data.reg_1v5_ana_bb = NULL; /* VMAIN is used on v1 board */
+ unifi_data.reg_vdd_vpa = NULL;
+ unifi_data.reg_1v5_dd = NULL;
+#endif
+#if defined(CONFIG_KEYBOARD_MPR084) || defined(CONFIG_KEYBOARD_MPR084_MODULE)
+ keypad_data.vdd_reg = "DCDC3";
+#endif
+}
+
+#if defined(CONFIG_GPS_IOCTRL) || defined(CONFIG_GPS_IOCTRL_MODULE)
+static struct mxc_gps_platform_data gps_data = {
+ .core_reg = "VIOHI",
+ .analog_reg = "SW3",
+};
+
+static struct platform_device mxc_gps_device = {
+ .name = "gps_ioctrl",
+ .id = 0,
+ .dev = {
+ .platform_data = &gps_data,
+ },
+};
+
+static void __init mxc_init_gps(void)
+{
+ (void)platform_device_register(&mxc_gps_device);
+}
+#else
+static void __init mxc_init_gps(void)
+{
+}
+#endif
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ mxc_cpu_common_init();
+ mxc_gpio_init();
+ early_console_setup(saved_command_line);
+ mxc_init_devices();
+ if (!board_is_mx37(BOARD_REV_2))
+ mx37_3stack_fixup_for_board_v1();
+ 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));
+
+ spi_register_board_info(mxc_spi_board_info,
+ ARRAY_SIZE(mxc_spi_board_info));
+ mxc_init_nand_mtd();
+ mxc_init_mmc();
+ mxc_init_pata();
+ mxc_init_fb();
+ mxc_init_bl();
+ mxc_init_bluetooth();
+ mxc_init_gps();
+ mxc_sgtl5000_init();
+}
+
+static void __init mx37_3stack_timer_init(void)
+{
+ mxc_clocks_init(32768, 24000000, 22579200, 0);
+ mxc_timer_init("gpt_clk");
+}
+
+static struct sys_timer mxc_timer = {
+ .init = mx37_3stack_timer_init,
+};
+
+/*
+ * The following uses standard kernel macros define in arch.h in order to
+ * initialize __mach_desc_MX37_3STACK data structure.
+ */
+/* *INDENT-OFF* */
+MACHINE_START(MX37_3DS, "Freescale MX37 3-Stack Board")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .phys_io = AIPS1_BASE_ADDR,
+ .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = PHYS_OFFSET + 0x100,
+ .fixup = fixup_mxc_board,
+ .map_io = mxc_map_io,
+ .init_irq = mxc_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &mxc_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx37/mx37_3stack_cpld.c b/arch/arm/mach-mx37/mx37_3stack_cpld.c
new file mode 100644
index 000000000000..e09d6022aeb9
--- /dev/null
+++ b/arch/arm/mach-mx37/mx37_3stack_cpld.c
@@ -0,0 +1,231 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <mach/hardware.h>
+#include <asm/mach/irq.h>
+#include <mach/gpio.h>
+#include "board-mx37_3stack.h"
+#include "iomux.h"
+
+/*!
+ * @file mach-mx37/mx37_3stack_cpld.c
+ *
+ * @brief This file contains the board specific initialization routines.
+ *
+ * @ingroup MSL_MX37
+ */
+
+extern int mxc_spi_poll_transfer(struct spi_device *spi,
+ struct spi_transfer *t);
+
+struct spi_device *cpld_spi;
+
+/*!
+ * This function is used to tranfer data to CPLD regs over CSPI
+ */
+static inline int mx37_3ds_cpld_rw(u8 * buf, size_t len)
+{
+ struct spi_transfer t = {
+ .tx_buf = (const void *)buf,
+ .rx_buf = buf,
+ .len = len,
+ .cs_change = 0,
+ .delay_usecs = 0,
+ };
+ mxc_spi_poll_transfer(cpld_spi, &t);
+ return 0;
+}
+
+/*!
+ * This function is called to read a CPLD register over CSPI.
+ *
+ * @param offset number of the cpld register to be read
+ *
+ * @return Returns 0 on success -1 on failure.
+ */
+unsigned int spi_cpld_read(unsigned int offset)
+{
+ unsigned int frame[2];
+ unsigned int reg_num = offset >> 1;
+ unsigned int data = 0;
+
+ frame[0] = (1 << 13) | ((reg_num & 0x0001FFFF) >> 5) | 0x00001000;
+ frame[1] = (((reg_num & 0x0000001F) << 27) | 0x0200001f);
+ mx37_3ds_cpld_rw((u8 *) frame, 2);
+ data = (frame[1] >> 6) & 0xFFFF;
+
+ reg_num = (offset + 2) >> 1;
+ frame[0] = (1 << 13) | ((reg_num & 0x0001FFFF) >> 5) | 0x00001000;
+ frame[1] = (((reg_num & 0x0000001F) << 27) | 0x0200001f);
+ mx37_3ds_cpld_rw((u8 *) frame, 2);
+
+ data |= (((frame[1] >> 6) & 0xFFFF) << 16);
+ return data;
+}
+EXPORT_SYMBOL(spi_cpld_read);
+
+/*!
+ * This function is called to write to a CPLD register over CSPI.
+ *
+ * @param offset number of the cpld register to be written
+ * @param reg_val value to be written
+ *
+ * @return Returns 0 on success -1 on failure.
+ */
+unsigned int spi_cpld_write(unsigned int offset, unsigned int reg_val)
+{
+ unsigned int frame[2] = { 0, 0 };
+ unsigned int reg_num = offset >> 1;
+ unsigned int data = reg_val;
+
+ frame[0] = ((reg_num & 0x0001FFFF) >> 5) | 0x00001000;
+ frame[1] = (((reg_num & 0x0000001F) << 27) |
+ ((data & 0x0000FFFF) << 6) | 0x03C00027);
+ mx37_3ds_cpld_rw((u8 *) frame, 2);
+
+ reg_num = (offset + 2) >> 1;
+ data = reg_val >> 16;
+ frame[0] = 0;
+ frame[1] = 0;
+ frame[0] = ((reg_num & 0x0001FFFF) >> 5) | 0x00001000;
+ frame[1] = (((reg_num & 0x0000001F) << 27) |
+ ((data & 0x0000FFFF) << 6) | 0x03C00027);
+
+ mx37_3ds_cpld_rw((u8 *) frame, 2);
+
+ return 0;
+}
+EXPORT_SYMBOL(spi_cpld_write);
+
+static int __devinit mx37_3ds_cpld_probe(struct spi_device *spi)
+{
+ unsigned int i = 0;
+
+ spi->bits_per_word = 46;
+ cpld_spi = spi;
+
+ spi_setup(spi);
+ i = spi_cpld_read(CPLD_CODE_VER_REG);
+ pr_info("3-Stack Debug board detected, rev = 0x%04X\n", i);
+ spi_cpld_write(LED_SWITCH_REG, 0xFF);
+
+ /* disable the interrupt and clear the status */
+ spi_cpld_write(INTR_MASK_REG, 0);
+ spi_cpld_write(INTR_RESET_REG, 0xFFFF);
+ spi_cpld_write(INTR_RESET_REG, 0);
+ spi_cpld_write(INTR_MASK_REG, 0x1E);
+ return 0;
+}
+
+/*!
+ * This structure contains pointers to the CPLD callback functions.
+ */
+static struct spi_driver mx37_3ds_cpld_driver = {
+ .driver = {
+ .name = "cpld_spi",
+ .bus = &spi_bus_type,
+ .owner = THIS_MODULE,
+ },
+ .probe = mx37_3ds_cpld_probe,
+};
+
+static int __init mx37_3ds_cpld_init(void)
+{
+ pr_debug("Registering the CPLD Driver\n");
+ return spi_register_driver(&mx37_3ds_cpld_driver);
+}
+
+device_initcall(mx37_3ds_cpld_init);
+
+static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 expio_irq;
+ struct irq_desc *d;
+
+ desc->chip->mask(irq); /* irq = gpio irq number */
+
+ expio_irq = MXC_EXP_IO_BASE;
+
+ d = irq_desc + expio_irq;
+ if (unlikely(!(d->handle_irq))) {
+ printk(KERN_ERR "\nEXPIO irq: %d unhandled\n", expio_irq);
+ BUG(); /* oops */
+ }
+ d->handle_irq(expio_irq, d);
+
+ desc->chip->ack(irq);
+ desc->chip->unmask(irq);
+}
+
+/*
+ * Disable an expio pin's interrupt by setting the bit in the imr.
+ * @param irq an expio virtual irq number
+ */
+static void expio_mask_irq(u32 irq)
+{
+}
+
+/*
+ * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
+ * @param irq an expanded io virtual irq number
+ */
+static void expio_ack_irq(u32 irq)
+{
+ /* clear the interrupt status */
+ spi_cpld_write(INTR_RESET_REG, 1);
+ spi_cpld_write(INTR_RESET_REG, 0);
+}
+
+/*
+ * Enable a expio pin's interrupt by clearing the bit in the imr.
+ * @param irq a expio virtual irq number
+ */
+static void expio_unmask_irq(u32 irq)
+{
+}
+
+static struct irq_chip expio_irq_chip = {
+ .ack = expio_ack_irq,
+ .mask = expio_mask_irq,
+ .unmask = expio_unmask_irq,
+};
+
+static int __init mxc_expio_init(void)
+{
+ int i;
+ int pad_val;
+
+ /*
+ * Configure INT line as GPIO input
+ */
+ mxc_request_iomux(MX37_PIN_GPIO1_2, IOMUX_CONFIG_GPIO);
+ pad_val = mxc_iomux_get_pad(MX37_PIN_GPIO1_2);
+ pad_val |= PAD_CTL_PUE_PULL;
+ mxc_iomux_set_pad(MX37_PIN_GPIO1_2, pad_val);
+ mxc_set_gpio_direction(MX37_PIN_GPIO1_2, 1);
+
+ for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
+ i++) {
+ set_irq_chip(i, &expio_irq_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+ set_irq_type(IOMUX_TO_IRQ(MX37_PIN_GPIO1_2), IRQF_TRIGGER_LOW);
+ set_irq_chained_handler(IOMUX_TO_IRQ(MX37_PIN_GPIO1_2),
+ mxc_expio_irq_handler);
+ return 0;
+}
+
+arch_initcall(mxc_expio_init);
diff --git a/arch/arm/mach-mx37/mx37_3stack_gpio.c b/arch/arm/mach-mx37/mx37_3stack_gpio.c
new file mode 100644
index 000000000000..0c05df89df10
--- /dev/null
+++ b/arch/arm/mach-mx37/mx37_3stack_gpio.c
@@ -0,0 +1,1016 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/clock.h>
+#include <mach/gpio.h>
+
+#include "iomux.h"
+
+/*!
+ * @file mx37_3stack_gpio.c
+ *
+ * @brief This file contains all the GPIO setup functions for the board.
+ *
+ * @ingroup GPIO
+ */
+
+void gpio_activate_audio_ports(void);
+
+/*!
+ * Setup GPIO for a UART port to be active
+ *
+ * @param port a UART port
+ * @param no_irda indicates if the port is used for SIR
+ */
+void gpio_uart_active(int port, int no_irda)
+{
+ /*
+ * Configure the IOMUX control registers for the UART signals
+ * and enable the UART transceivers
+ */
+ switch (port) {
+ /* UART 1 IOMUX Configs */
+ case 0:
+ mxc_request_iomux(MX37_PIN_UART1_RXD, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX37_PIN_UART1_RXD, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_input(MUX_IN_UART1_UART_RXD_MUX, INPUT_CTL_PATH4);
+ mxc_request_iomux(MX37_PIN_UART1_TXD, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX37_PIN_UART1_TXD, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ mxc_request_iomux(MX37_PIN_UART1_RTS, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX37_PIN_UART1_RTS, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH);
+ mxc_iomux_set_input(MUX_IN_UART1_UART_RTS_B, INPUT_CTL_PATH4);
+ mxc_request_iomux(MX37_PIN_UART1_CTS, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX37_PIN_UART1_CTS, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH);
+ break;
+ case 1:
+ mxc_request_iomux(MX37_PIN_UART1_DCD, IOMUX_CONFIG_ALT3);
+ mxc_iomux_set_pad(MX37_PIN_UART1_DCD, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_input(MUX_IN_UART2_UART_RXD_MUX, INPUT_CTL_PATH1);
+ mxc_request_iomux(MX37_PIN_UART1_RI, IOMUX_CONFIG_ALT3);
+ mxc_iomux_set_pad(MX37_PIN_UART1_RI, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ mxc_request_iomux(MX37_PIN_UART1_DSR, IOMUX_CONFIG_ALT3);
+ mxc_iomux_set_pad(MX37_PIN_UART1_DSR, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH);
+ mxc_iomux_set_input(MUX_IN_UART2_UART_RTS_B, INPUT_CTL_PATH1);
+ mxc_request_iomux(MX37_PIN_UART1_DTR, IOMUX_CONFIG_ALT3);
+ mxc_iomux_set_pad(MX37_PIN_UART1_DTR, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH);
+ break;
+ case 2:
+ mxc_request_iomux(MX37_PIN_AUD3_BB_TXD, IOMUX_CONFIG_ALT3);
+ mxc_iomux_set_pad(MX37_PIN_AUD3_BB_TXD, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_input(MUX_IN_UART3_UART_RXD_MUX, INPUT_CTL_PATH0);
+ mxc_request_iomux(MX37_PIN_AUD3_BB_RXD, IOMUX_CONFIG_ALT3);
+ mxc_iomux_set_pad(MX37_PIN_AUD3_BB_RXD, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ mxc_request_iomux(MX37_PIN_AUD3_BB_CK, IOMUX_CONFIG_ALT3);
+ mxc_iomux_set_pad(MX37_PIN_AUD3_BB_CK, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH);
+ mxc_iomux_set_input(MUX_IN_UART3_UART_RTS_B, INPUT_CTL_PATH0);
+ mxc_request_iomux(MX37_PIN_AUD3_BB_FS, IOMUX_CONFIG_ALT3);
+ mxc_iomux_set_pad(MX37_PIN_AUD3_BB_FS, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * Setup GPIO for a UART port to be inactive
+ *
+ * @param port a UART port
+ * @param no_irda indicates if the port is used for SIR
+ */
+void gpio_uart_inactive(int port, int no_irda)
+{
+ /*
+ * Configure the IOMUX control registers for the UART signals
+ * and disable the UART transceivers
+ */
+ switch (port) {
+ case 0:
+ mxc_request_iomux(MX37_PIN_UART1_RXD, IOMUX_CONFIG_GPIO);
+ mxc_request_iomux(MX37_PIN_UART1_TXD, IOMUX_CONFIG_GPIO);
+ mxc_request_iomux(MX37_PIN_UART1_RTS, IOMUX_CONFIG_GPIO);
+ mxc_request_iomux(MX37_PIN_UART1_CTS, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX37_PIN_UART1_RXD, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX37_PIN_UART1_TXD, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX37_PIN_UART1_RTS, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX37_PIN_UART1_CTS, IOMUX_CONFIG_GPIO);
+ break;
+ case 1:
+ mxc_request_iomux(MX37_PIN_UART1_DCD, IOMUX_CONFIG_GPIO);
+ mxc_request_iomux(MX37_PIN_UART1_RI, IOMUX_CONFIG_GPIO);
+ mxc_request_iomux(MX37_PIN_UART1_DSR, IOMUX_CONFIG_GPIO);
+ mxc_request_iomux(MX37_PIN_UART1_DTR, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX37_PIN_UART1_DCD, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX37_PIN_UART1_RI, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX37_PIN_UART1_DSR, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX37_PIN_UART1_DTR, IOMUX_CONFIG_GPIO);
+ break;
+ /* UART 3 IOMUX Configs */
+ case 2:
+ mxc_request_iomux(MX37_PIN_AUD3_BB_TXD, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX37_PIN_AUD3_BB_TXD, IOMUX_CONFIG_GPIO);
+ mxc_request_iomux(MX37_PIN_AUD3_BB_RXD, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX37_PIN_AUD3_BB_RXD, IOMUX_CONFIG_GPIO);
+ mxc_request_iomux(MX37_PIN_AUD3_BB_CK, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX37_PIN_AUD3_BB_CK, IOMUX_CONFIG_GPIO);
+ mxc_request_iomux(MX37_PIN_AUD3_BB_FS, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX37_PIN_AUD3_BB_FS, IOMUX_CONFIG_GPIO);
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * Configure the IOMUX GPR register to receive shared SDMA UART events
+ *
+ * @param port a UART port
+ */
+void config_uartdma_event(int port)
+{
+
+}
+
+EXPORT_SYMBOL(gpio_uart_active);
+EXPORT_SYMBOL(gpio_uart_inactive);
+EXPORT_SYMBOL(config_uartdma_event);
+
+/*!
+ * Setup GPIO for a CSPI device to be active
+ *
+ * @param cspi_mod an CSPI device
+ */
+void gpio_spi_active(int cspi_mod)
+{
+ switch (cspi_mod) {
+ case 0:
+ break;
+ case 1:
+ /* SPI2 */
+ mxc_request_iomux(MX37_PIN_CSPI2_MISO, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX37_PIN_CSPI2_MISO, PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX37_PIN_GRP_H9, PAD_CTL_HYS_ENABLE);
+
+ mxc_request_iomux(MX37_PIN_CSPI2_MOSI, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX37_PIN_CSPI2_MOSI, PAD_CTL_SRE_FAST);
+
+ mxc_request_iomux(MX37_PIN_UART1_CTS, IOMUX_CONFIG_ALT3);
+ mxc_iomux_set_pad(MX37_PIN_UART1_CTS, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE);
+
+ mxc_request_iomux(MX37_PIN_CSPI2_SCLK, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX37_PIN_CSPI2_SCLK, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_SRE_FAST);
+
+ mxc_request_iomux(MX37_PIN_CSPI2_SS1, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX37_PIN_CSPI2_SS1, PAD_CTL_SRE_FAST);
+
+ mxc_request_iomux(MX37_PIN_CSPI2_SS0, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX37_PIN_CSPI2_SS0, PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX37_PIN_GRP_H10, PAD_CTL_HYS_ENABLE);
+ break;
+ case 2:
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * Setup GPIO for a CSPI device to be inactive
+ *
+ * @param cspi_mod a CSPI device
+ */
+void gpio_spi_inactive(int cspi_mod)
+{
+}
+
+/*!
+ * Setup 1-Wire to be active
+ */
+void gpio_owire_active(void)
+{
+ /*TODO*/}
+
+/*!
+ * Setup 1-Wire to be active
+ */
+void gpio_owire_inactive(void)
+{
+ /*TODO*/}
+
+EXPORT_SYMBOL(gpio_owire_active);
+EXPORT_SYMBOL(gpio_owire_inactive);
+
+/*!
+ * Setup GPIO for an I2C device to be active
+ *
+ * @param i2c_num an I2C device
+ */
+void gpio_i2c_active(int i2c_num)
+{
+ iomux_pad_config_t regval = 0;
+
+ switch (i2c_num) {
+ case 0:
+ /* Touch */
+ /* select I2C1_SCK as daisy chain input */
+ mxc_request_iomux(MX37_PIN_I2C1_CLK, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_input(MUX_IN_I2C1_SCL, INPUT_CTL_PATH1);
+ /* OpenDrain enabled, 100k PU enabled */
+ regval =
+ PAD_CTL_ODE_OPENDRAIN_ENABLE | PAD_CTL_100K_PU |
+ PAD_CTL_PKE_ENABLE;
+ mxc_iomux_set_pad(MX37_PIN_I2C1_CLK, regval);
+
+ /*select I2C1_SDA as daisy chain input */
+ mxc_request_iomux(MX37_PIN_I2C1_DAT, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_input(MUX_IN_I2C1_SDA, INPUT_CTL_PATH1);
+ mxc_iomux_set_pad(MX37_PIN_I2C1_DAT, regval);
+ mxc_iomux_set_pad(MX37_PIN_GRP_H3, PAD_CTL_HYS_ENABLE);
+ break;
+ case 1:
+ /* PMIC */
+ /*select I2C2_SCL as daisy chain input */
+ mxc_iomux_set_input(MUX_IN_I2C2_SCL, INPUT_CTL_PATH1);
+ regval = PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PULL | PAD_CTL_100K_PU |
+ PAD_CTL_ODE_OPENDRAIN_ENABLE | PAD_CTL_DRV_HIGH;
+ mxc_iomux_set_pad(MX37_PIN_GPIO1_0, regval);
+ mxc_request_iomux(MX37_PIN_GPIO1_0,
+ (IOMUX_CONFIG_SION | IOMUX_CONFIG_ALT2));
+
+ /*select I2C2_SDA as daisy chain input */
+ mxc_iomux_set_input(MUX_IN_I2C2_SDA, INPUT_CTL_PATH1);
+ mxc_iomux_set_pad(MX37_PIN_GPIO1_1, regval);
+ mxc_request_iomux(MX37_PIN_GPIO1_1,
+ (IOMUX_CONFIG_SION | IOMUX_CONFIG_ALT2));
+ break;
+ case 2:
+ break;
+ default:
+ break;
+ }
+}
+
+/*!
+ * Setup GPIO for an I2C device to be inactive
+ *
+ * @param i2c_num an I2C device
+ */
+void gpio_i2c_inactive(int i2c_num)
+{
+ /*TODO*/}
+
+/*!
+ * This function activates DAM ports 4 & 5 to enable
+ * audio I/O.
+ */
+void gpio_activate_audio_ports(void)
+{
+ unsigned int pad_val;
+
+ /* AUD4_TXD */
+ mxc_request_iomux(MX37_PIN_DISP1_DAT20, IOMUX_CONFIG_ALT5);
+ /* AUD4_RXD */
+ mxc_request_iomux(MX37_PIN_DISP1_DAT21, IOMUX_CONFIG_ALT5);
+ /* AUD4_TXC */
+ mxc_request_iomux(MX37_PIN_DISP1_DAT22, IOMUX_CONFIG_ALT5);
+ /* AUD4_TXFS */
+ mxc_request_iomux(MX37_PIN_DISP1_DAT23, IOMUX_CONFIG_ALT5);
+
+ pad_val = PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST;
+ mxc_iomux_set_pad(MX37_PIN_AUD5_WB_CK, PAD_CTL_100K_PU | pad_val);
+ mxc_request_iomux(MX37_PIN_AUD5_WB_CK, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX37_PIN_AUD5_WB_RXD, pad_val);
+ mxc_request_iomux(MX37_PIN_AUD5_WB_RXD, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX37_PIN_AUD5_WB_TXD, pad_val);
+ mxc_request_iomux(MX37_PIN_AUD5_WB_TXD, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX37_PIN_AUD5_WB_FS, PAD_CTL_100K_PU | pad_val);
+ mxc_request_iomux(MX37_PIN_AUD5_WB_FS, IOMUX_CONFIG_ALT0);
+
+ /* Enable hysteresis for AUD5_WB_CK, AUD5_WB_RXD, AUD5_WB_TXD, AUD5_WB_FS */
+ mxc_iomux_set_pad(MX37_PIN_GRP_H5, PAD_CTL_HYS_ENABLE);
+}
+
+EXPORT_SYMBOL(gpio_activate_audio_ports);
+
+/*!
+ * Setup GPIO for SDHC to be active
+ *
+ * @param module SDHC module number
+ */
+void gpio_sdhc_active(int module)
+{
+ switch (module) {
+ case 0:
+ mxc_request_iomux(MX37_PIN_SD1_CLK,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_request_iomux(MX37_PIN_SD1_CMD,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_request_iomux(MX37_PIN_SD1_DATA0,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_request_iomux(MX37_PIN_SD1_DATA1,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_request_iomux(MX37_PIN_SD1_DATA2,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_request_iomux(MX37_PIN_SD1_DATA3,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+
+ mxc_iomux_set_pad(MX37_PIN_SD1_CMD,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_NONE | PAD_CTL_PUE_PULL |
+ PAD_CTL_47K_PU |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX37_PIN_SD1_CLK,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_NONE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_47K_PU |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX37_PIN_SD1_DATA0,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_NONE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_47K_PU |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX37_PIN_SD1_DATA1,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_NONE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_47K_PU |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX37_PIN_SD1_DATA2,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_NONE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_47K_PU |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX37_PIN_SD1_DATA3,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_NONE | PAD_CTL_PUE_PULL |
+ PAD_CTL_47K_PU |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+
+ /* Write Protected Pin */
+ mxc_request_iomux(MX37_PIN_CSPI1_SS0,
+ IOMUX_CONFIG_SION | IOMUX_CONFIG_ALT4);
+ mxc_iomux_set_pad(MX37_PIN_CSPI1_SS0,
+ PAD_CTL_DRV_HIGH | PAD_CTL_HYS_NONE |
+ PAD_CTL_SRE_FAST);
+ /*
+ * SW workaround for the eSDHC1 Write Protected feature
+ * The PSR of CSPI1_SS0 (GPIO3_2) should be read.
+ */
+ mxc_set_gpio_direction(MX37_PIN_CSPI1_SS0, 0);
+ mxc_set_gpio_dataout(MX37_PIN_CSPI1_SS0, 1);
+ break;
+ case 1:
+ mxc_request_iomux(MX37_PIN_SD2_CLK,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_request_iomux(MX37_PIN_SD2_CMD,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_request_iomux(MX37_PIN_SD2_DATA0,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_request_iomux(MX37_PIN_SD2_DATA1,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_request_iomux(MX37_PIN_SD2_DATA2,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_request_iomux(MX37_PIN_SD2_DATA3,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+
+ mxc_iomux_set_pad(MX37_PIN_SD2_CMD,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_NONE | PAD_CTL_PUE_PULL |
+ PAD_CTL_47K_PU |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX37_PIN_SD2_CLK,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_NONE | PAD_CTL_PUE_PULL |
+ PAD_CTL_47K_PU |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX37_PIN_SD2_DATA0,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_NONE | PAD_CTL_PUE_PULL |
+ PAD_CTL_47K_PU |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX37_PIN_SD2_DATA1,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_NONE | PAD_CTL_PUE_PULL |
+ PAD_CTL_47K_PU |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX37_PIN_SD2_DATA2,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_NONE | PAD_CTL_PUE_PULL |
+ PAD_CTL_47K_PU |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX37_PIN_SD2_DATA3,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_NONE | PAD_CTL_PUE_PULL |
+ PAD_CTL_47K_PU |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_sdhc_active);
+
+/*!
+ * Setup GPIO for SDHC1 to be inactive
+ *
+ * @param module SDHC module number
+ */
+void gpio_sdhc_inactive(int module)
+{
+ switch (module) {
+ case 0:
+ mxc_free_iomux(MX37_PIN_SD1_CLK,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX37_PIN_SD1_CMD,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX37_PIN_SD1_DATA0,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX37_PIN_SD1_DATA1,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX37_PIN_SD1_DATA2,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX37_PIN_SD1_DATA3,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+
+ mxc_iomux_set_pad(MX37_PIN_SD1_CLK,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX37_PIN_SD1_CMD,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX37_PIN_SD1_DATA0,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX37_PIN_SD1_DATA1,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX37_PIN_SD1_DATA2,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX37_PIN_SD1_DATA3,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+
+ /* Free Write Protected Pin */
+ mxc_free_iomux(MX37_PIN_CSPI1_SS0,
+ IOMUX_CONFIG_SION | IOMUX_CONFIG_ALT4);
+ mxc_iomux_set_pad(MX37_PIN_CSPI1_SS0,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ break;
+ case 1:
+ mxc_free_iomux(MX37_PIN_SD2_CLK,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX37_PIN_SD2_CMD,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX37_PIN_SD2_DATA0,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX37_PIN_SD2_DATA1,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX37_PIN_SD2_DATA2,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX37_PIN_SD2_DATA3,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+
+ mxc_iomux_set_pad(MX37_PIN_SD2_CLK,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX37_PIN_SD2_CMD,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX37_PIN_SD2_DATA0,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX37_PIN_SD2_DATA1,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX37_PIN_SD2_DATA2,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX37_PIN_SD2_DATA3,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_sdhc_inactive);
+
+/*
+ * Probe for the card. If present the GPIO data would be set.
+ */
+int sdhc_get_card_det_status(struct device *dev)
+{
+ int ret;
+
+ if (to_platform_device(dev)->id == 0) {
+ if (board_is_mx37(BOARD_REV_2))
+ ret = mxc_get_gpio_datain(MX37_PIN_GPIO1_4);
+ else
+ ret = mxc_get_gpio_datain(MX37_PIN_OWIRE_LINE);
+ return ret;
+ } else { /* config the det pin for SDHC2 */
+ return 0;
+ }
+}
+
+EXPORT_SYMBOL(sdhc_get_card_det_status);
+
+/*
+ * Return the card detect pin.
+ */
+int sdhc_init_card_det(int id)
+{
+ if (id == 0) {
+ if (board_is_mx37(BOARD_REV_2)) {
+ mxc_request_iomux(MX37_PIN_GPIO1_4, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX37_PIN_GPIO1_4,
+ PAD_CTL_DRV_HIGH |
+ PAD_CTL_HYS_NONE |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_NONE | PAD_CTL_SRE_FAST);
+ mxc_set_gpio_direction(MX37_PIN_GPIO1_4, 1);
+ return IOMUX_TO_IRQ(MX37_PIN_GPIO1_4);
+ } else {
+ mxc_request_iomux(MX37_PIN_OWIRE_LINE,
+ IOMUX_CONFIG_ALT4);
+ mxc_iomux_set_pad(MX37_PIN_OWIRE_LINE,
+ PAD_CTL_DRV_HIGH |
+ PAD_CTL_HYS_NONE |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_NONE | PAD_CTL_SRE_FAST);
+ mxc_set_gpio_direction(MX37_PIN_OWIRE_LINE, 1);
+ return IOMUX_TO_IRQ(MX37_PIN_OWIRE_LINE);
+ }
+ } else { /* config the det pin for SDHC2 */
+ return 0;
+
+ }
+}
+
+EXPORT_SYMBOL(sdhc_init_card_det);
+
+/*!
+ * Get CSPI1_SS0 pin value to detect write protection
+ */
+int sdhc_write_protect(struct device *dev)
+{
+ unsigned short rc = 0;
+
+ rc = mxc_get_gpio_datain(MX37_PIN_CSPI1_SS0);
+ if (rc > 0)
+ return 1;
+ else
+ return 0;
+}
+
+EXPORT_SYMBOL(sdhc_write_protect);
+
+/*!
+ * Setup GPIO for LCD to be active
+ *
+ */
+void gpio_lcd_active(void)
+{
+ mxc_request_iomux(MX37_PIN_DI1_PIN2, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_PAD_DI1_PIN3, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_DISP_CLK, IOMUX_CONFIG_ALT0);
+}
+
+/*!
+ * Setup GPIO for LCD to be inactive
+ *
+ */
+void gpio_lcd_inactive(void)
+{
+ /*TODO*/}
+
+/*!
+ * Setup pins for SLCD to be active
+ *
+ */
+void slcd_gpio_config(void)
+{
+ /*TODO*/}
+
+/*!
+ * Switch to the specified sensor - MX33 ADS has two
+ *
+ */
+void gpio_sensor_select(int sensor)
+{
+ /*TODO*/}
+
+/*!
+ * Setup GPIO for sensor to be active
+ *
+ */
+void gpio_sensor_active(void)
+{
+ /*TODO*/}
+
+EXPORT_SYMBOL(gpio_sensor_active);
+
+/*!
+ * Setup GPIO for sensor to be inactive
+ *
+ */
+void gpio_sensor_inactive(void)
+{
+ /*TODO*/}
+
+EXPORT_SYMBOL(gpio_sensor_inactive);
+
+/*!
+ * Setup GPIO for ATA interface
+ *
+ */
+void gpio_ata_active(void)
+{
+ /*IOMUX Settings */
+ /*PATA_DMARQ_B */
+ mxc_request_iomux(MX37_PIN_NANDF_RE_B, IOMUX_CONFIG_ALT1);
+ /*PATA_DIOR */
+ mxc_request_iomux(MX37_PIN_NANDF_ALE, IOMUX_CONFIG_ALT1);
+ /*PATA_DIOW */
+ mxc_request_iomux(MX37_PIN_NANDF_CLE, IOMUX_CONFIG_ALT1);
+ /*PATA_DMACK */
+ mxc_request_iomux(MX37_PIN_NANDF_WP_B, IOMUX_CONFIG_ALT1);
+ /*PATA_RESET_B */
+ mxc_request_iomux(MX37_PIN_NANDF_RB, IOMUX_CONFIG_ALT1);
+ /*PATA_IORDY */
+ mxc_request_iomux(MX37_PIN_NANDF_CS0, IOMUX_CONFIG_ALT1);
+ /*PATA_INTRQ_B */
+ mxc_request_iomux(MX37_PIN_NANDF_CS1, IOMUX_CONFIG_ALT1);
+ /*PATA_CS_0 */
+ mxc_request_iomux(MX37_PIN_NANDF_CS2, IOMUX_CONFIG_ALT1);
+ /*PATA_CS_1 */
+ mxc_request_iomux(MX37_PIN_NANDF_CS3, IOMUX_CONFIG_ALT1);
+
+ /*PATA_D0 */
+ mxc_request_iomux(MX37_PIN_EIM_D0, IOMUX_CONFIG_ALT1);
+ /*PATA_D1 */
+ mxc_request_iomux(MX37_PIN_EIM_D1, IOMUX_CONFIG_ALT1);
+ /*PATA_D2 */
+ mxc_request_iomux(MX37_PIN_EIM_D2, IOMUX_CONFIG_ALT1);
+ /*PATA_D3 */
+ mxc_request_iomux(MX37_PIN_EIM_D3, IOMUX_CONFIG_ALT1);
+ /*PATA_D4 */
+ mxc_request_iomux(MX37_PIN_EIM_D4, IOMUX_CONFIG_ALT1);
+ /*PATA_D5 */
+ mxc_request_iomux(MX37_PIN_EIM_D5, IOMUX_CONFIG_ALT1);
+ /*PATA_D6 */
+ mxc_request_iomux(MX37_PIN_EIM_D6, IOMUX_CONFIG_ALT1);
+ /*PATA_D7 */
+ mxc_request_iomux(MX37_PIN_EIM_D7, IOMUX_CONFIG_ALT1);
+ /*PATA_D8 */
+ mxc_request_iomux(MX37_PIN_EIM_D8, IOMUX_CONFIG_ALT1);
+ /*PATA_D9 */
+ mxc_request_iomux(MX37_PIN_EIM_D9, IOMUX_CONFIG_ALT1);
+ /*PATA_D10 */
+ mxc_request_iomux(MX37_PIN_EIM_D10, IOMUX_CONFIG_ALT1);
+ /*PATA_D11 */
+ mxc_request_iomux(MX37_PIN_EIM_D11, IOMUX_CONFIG_ALT1);
+ /*PATA_D12 */
+ mxc_request_iomux(MX37_PIN_EIM_D12, IOMUX_CONFIG_ALT1);
+ /*PATA_D13 */
+ mxc_request_iomux(MX37_PIN_EIM_D13, IOMUX_CONFIG_ALT1);
+ /*PATA_D14 */
+ mxc_request_iomux(MX37_PIN_EIM_D14, IOMUX_CONFIG_ALT1);
+ /*PATA_D15 */
+ mxc_request_iomux(MX37_PIN_EIM_D15, IOMUX_CONFIG_ALT1);
+ /*PATA_DA0 */
+ mxc_request_iomux(MX37_PIN_SD2_DATA3, IOMUX_CONFIG_ALT1);
+ /*PATA_DA1 */
+ mxc_request_iomux(MX37_PIN_SD2_DATA2, IOMUX_CONFIG_ALT1);
+ /*PATA_DA2 */
+ mxc_request_iomux(MX37_PIN_SD2_DATA1, IOMUX_CONFIG_ALT1);
+
+ /* BUFFER_ENABLE - HDD_ENABLE_B */
+ mxc_request_iomux(MX37_PIN_NANDF_WE_B, IOMUX_CONFIG_ALT1);
+
+ /* IOMUX Pad Settings */
+ mxc_iomux_set_pad(MX37_PIN_EIM_D0, 0xc0);
+ mxc_iomux_set_pad(MX37_PIN_EIM_D1, 0xc0);
+ mxc_iomux_set_pad(MX37_PIN_EIM_D2, 0xc0);
+ mxc_iomux_set_pad(MX37_PIN_EIM_D3, 0xc0);
+ mxc_iomux_set_pad(MX37_PIN_EIM_D4, 0xc0);
+ mxc_iomux_set_pad(MX37_PIN_EIM_D5, 0xc0);
+ mxc_iomux_set_pad(MX37_PIN_EIM_D6, 0xc0);
+ mxc_iomux_set_pad(MX37_PIN_EIM_D7, 0xc0);
+ mxc_iomux_set_pad(MX37_PIN_EIM_D8, 0xc0);
+ mxc_iomux_set_pad(MX37_PIN_EIM_D9, 0xc0);
+ mxc_iomux_set_pad(MX37_PIN_EIM_D10, 0xc0);
+ mxc_iomux_set_pad(MX37_PIN_EIM_D11, 0xc0);
+ mxc_iomux_set_pad(MX37_PIN_EIM_D12, 0xc0);
+ mxc_iomux_set_pad(MX37_PIN_EIM_D13, 0xc0);
+ mxc_iomux_set_pad(MX37_PIN_EIM_D14, 0xc0);
+ mxc_iomux_set_pad(MX37_PIN_EIM_D15, 0xc0);
+
+ mxc_iomux_set_pad(MX37_PIN_NANDF_RE_B, 0x0080);
+ mxc_iomux_set_pad(MX37_PIN_NANDF_CS1, 0x0020);
+ mxc_iomux_set_pad(MX37_PIN_SD2_DATA3, 0x00);
+ mxc_iomux_set_pad(MX37_PIN_SD2_DATA2, 0x00);
+ mxc_iomux_set_pad(MX37_PIN_SD2_DATA1, 0x00);
+ mxc_iomux_set_pad(MX37_PIN_NANDF_ALE, 0x00);
+ mxc_iomux_set_pad(MX37_PIN_NANDF_CS2, 0x00);
+ mxc_iomux_set_pad(MX37_PIN_NANDF_CS3, 0x00);
+ mxc_iomux_set_pad(MX37_PIN_NANDF_WE_B, 0x00);
+ mxc_iomux_set_pad(MX37_PIN_NANDF_CLE, 0x00);
+ mxc_iomux_set_pad(MX37_PIN_NANDF_WP_B, 0x00);
+ mxc_iomux_set_pad(MX37_PIN_NANDF_RB, 0x00);
+ mxc_iomux_set_pad(MX37_PIN_NANDF_CS0, 0x0020);
+
+}
+
+EXPORT_SYMBOL(gpio_ata_active);
+
+/*!
+ * Restore ATA interface pins to reset values
+ *
+ */
+void gpio_ata_inactive(void)
+{
+ /*Turn off the IOMUX for ATA group B signals */
+ mxc_request_iomux(MX37_PIN_EIM_D0, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_EIM_D1, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_EIM_D2, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_EIM_D3, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_EIM_D4, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_EIM_D5, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_EIM_D6, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_EIM_D7, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_EIM_D8, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_EIM_D9, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_EIM_D10, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_EIM_D11, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_EIM_D12, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_EIM_D13, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_EIM_D14, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_EIM_D15, IOMUX_CONFIG_ALT0);
+
+ /* Config the multiplex pin of ATA interface DIR, DA0-2, INTRQ, DMARQ */
+ mxc_request_iomux(MX37_PIN_NANDF_RE_B, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_NANDF_CS1, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_SD2_DATA3, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_SD2_DATA2, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_SD2_DATA1, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_NANDF_ALE, IOMUX_CONFIG_ALT0);
+
+ /* HDD_BUFF_EN (H:A->B, L:B->A) and HDD_ENABLE_B(H:Disable,L:Enable) */
+ mxc_free_iomux(MX37_PIN_NANDF_WE_B, IOMUX_CONFIG_ALT0);
+
+ /* These ATA pins are common to Group A and Group B */
+ mxc_request_iomux(MX37_PIN_NANDF_CS2, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_NANDF_CS3, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_NANDF_ALE, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_NANDF_CLE, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_NANDF_WP_B, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_NANDF_RB, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX37_PIN_NANDF_CS0, IOMUX_CONFIG_ALT0);
+
+}
+
+EXPORT_SYMBOL(gpio_ata_inactive);
+
+/*!
+ * Setup GPIO for Keypad to be active
+ *
+ */
+void gpio_keypad_active(void)
+{
+ int pad_val;
+
+ /*
+ * Configure the IOMUX control register for keypad signals.
+ */
+ /*KEY_INT */
+ mxc_request_iomux(MX37_PIN_GPIO1_3, IOMUX_CONFIG_ALT0);
+ /*KEY_WAKE */
+ mxc_request_iomux(MX37_PIN_DISP1_DAT18, IOMUX_CONFIG_ALT4);
+
+ /* fast slew rate */
+ pad_val = (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_22K_PU | \
+ PAD_CTL_ODE_OPENDRAIN_ENABLE | PAD_CTL_HYS_NONE | \
+ PAD_CTL_DDR_INPUT_CMOS | PAD_CTL_DRV_VOT_LOW);
+ /*KEY_INT */
+ mxc_iomux_set_pad(MX37_PIN_GPIO1_3, pad_val);
+
+ /* fast slew rate */
+ pad_val = (PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | \
+ PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_HYS_NONE | \
+ PAD_CTL_DDR_INPUT_CMOS | PAD_CTL_DRV_VOT_LOW);
+ /*KEY_WAKE */
+ mxc_iomux_set_pad(MX37_PIN_DISP1_DAT18, pad_val);
+
+ mxc_set_gpio_direction(MX37_PIN_DISP1_DAT18, 0);
+ mxc_set_gpio_direction(MX37_PIN_GPIO1_3, 1);
+
+ /* drive initial value */
+ mxc_set_gpio_dataout(MX37_PIN_DISP1_DAT18, 1);
+}
+
+EXPORT_SYMBOL(gpio_keypad_active);
+
+/*!
+ * Setup GPIO for Keypad to be inactive
+ *
+ */
+void gpio_keypad_inactive(void)
+{
+ /*KEY_INT */
+ mxc_request_iomux(MX37_PIN_GPIO1_3, IOMUX_CONFIG_ALT0);
+ /*KEY_WAKE */
+ mxc_request_iomux(MX37_PIN_DISP1_DAT18, IOMUX_CONFIG_ALT0);
+}
+
+EXPORT_SYMBOL(gpio_keypad_inactive);
+
+/*
+ * USB OTG HS port
+ */
+int gpio_usbotg_hs_active(void)
+{
+ /*TODO*/ return 0;
+}
+
+EXPORT_SYMBOL(gpio_usbotg_hs_active);
+
+void gpio_usbotg_hs_inactive(void)
+{
+ /*TODO*/}
+
+EXPORT_SYMBOL(gpio_usbotg_hs_inactive);
+
+/*!
+ * Setup GPIO for PCMCIA interface
+ *
+ */
+void gpio_pcmcia_active(void)
+{
+ /*TODO*/}
+
+EXPORT_SYMBOL(gpio_pcmcia_active);
+
+/*!
+ * Setup GPIO for pcmcia to be inactive
+ */
+void gpio_pcmcia_inactive(void)
+{
+ /*TODO*/}
+
+EXPORT_SYMBOL(gpio_pcmcia_inactive);
+
+/*!
+ * Setup GPIO for fec to be active
+ */
+void gpio_fec_active(void)
+{
+ /*TODO*/}
+
+EXPORT_SYMBOL(gpio_fec_active);
+/*!
+ * Setup GPIO for fec to be inactive
+ */
+void gpio_fec_inactive(void)
+{
+ /*TODO*/}
+
+EXPORT_SYMBOL(gpio_fec_inactive);
+
+void gpio_spdif_active(void)
+{
+ iomux_pad_config_t regval = 0;
+ regval =
+ PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_100K_PU;
+ mxc_iomux_set_pad(MX37_PIN_AUD3_BB_RXD, regval);
+ mxc_request_iomux(MX37_PIN_AUD3_BB_RXD, IOMUX_CONFIG_ALT1);
+}
+
+EXPORT_SYMBOL(gpio_spdif_active);
+
+void gpio_spdif_inactive(void)
+{
+ mxc_free_iomux(MX37_PIN_AUD3_BB_RXD, IOMUX_CONFIG_ALT1);
+}
+
+EXPORT_SYMBOL(gpio_spdif_inactive);
+
+void gpio_pmic_active(void)
+{
+ mxc_request_iomux(MX37_PIN_OWIRE_LINE, IOMUX_CONFIG_GPIO);
+ mxc_iomux_set_pad(MX37_PIN_OWIRE_LINE, PAD_CTL_SRE_SLOW |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_DRV_MEDIUM |
+ PAD_CTL_100K_PU |
+ PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_VOT_HIGH | PAD_CTL_DDR_INPUT_CMOS);
+ mxc_set_gpio_direction(MX37_PIN_OWIRE_LINE, 1);
+}
+
+EXPORT_SYMBOL(gpio_pmic_active);
+
+void gpio_gps_active(void)
+{
+ /* PWR_EN */
+ mxc_request_iomux(MX37_PIN_EIM_OE, IOMUX_CONFIG_GPIO);
+ mxc_iomux_set_pad(MX37_PIN_EIM_OE, PAD_CTL_100K_PU |
+ PAD_CTL_DRV_HIGH | PAD_CTL_HYS_NONE |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_set_gpio_direction(MX37_PIN_EIM_OE, 0);
+
+ /* RESET */
+ mxc_request_iomux(MX37_PIN_EIM_BCLK, IOMUX_CONFIG_GPIO);
+ mxc_iomux_set_pad(MX37_PIN_EIM_BCLK, PAD_CTL_DRV_HIGH |
+ PAD_CTL_HYS_NONE | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_set_gpio_direction(MX37_PIN_EIM_BCLK, 0);
+
+ mxc_set_gpio_dataout(MX37_PIN_EIM_OE, 0);
+ mxc_set_gpio_dataout(MX37_PIN_EIM_BCLK, 0);
+
+ msleep(5);
+ mxc_set_gpio_dataout(MX37_PIN_EIM_BCLK, 1);
+
+ msleep(5);
+}
+
+EXPORT_SYMBOL(gpio_gps_active);
+
+int gpio_gps_access(int para)
+{
+ iomux_pin_name_t pin;
+ pin = (para & 0x1) ? MX37_PIN_EIM_OE : MX37_PIN_EIM_BCLK;
+
+ if (para & 0x4)
+ return mxc_get_gpio_datain(pin);
+ else if (para & 0x2)
+ mxc_set_gpio_dataout(pin, 1);
+ else
+ mxc_set_gpio_dataout(pin, 0);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(gpio_gps_access);
+
+void gpio_gps_inactive(void)
+{
+ mxc_free_iomux(MX37_PIN_EIM_BCLK, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX37_PIN_EIM_OE, IOMUX_CONFIG_GPIO);
+}
+
+EXPORT_SYMBOL(gpio_gps_inactive);
+
+int headphone_det_status(void)
+{
+ return mxc_get_gpio_datain(MX37_PIN_AUD5_RXFS);
+}
+
+EXPORT_SYMBOL(headphone_det_status);
diff --git a/arch/arm/mach-mx37/mx37_3stack_pmic_wm8350.c b/arch/arm/mach-mx37/mx37_3stack_pmic_wm8350.c
new file mode 100644
index 000000000000..0026b63d05fb
--- /dev/null
+++ b/arch/arm/mach-mx37/mx37_3stack_pmic_wm8350.c
@@ -0,0 +1,394 @@
+/*
+ * mx37-3stack-pmic-wm8350.c -- i.MX37 3STACK Driver for Wolfson WM8350 PMIC
+ *
+ * Copyright 2007 Wolfson Microelectronics PLC.
+ * Copyright 2008-2009 Freescale Semiconductor Inc.
+ *
+ * Author: Liam Girdwood
+ * liam.girdwood@wolfsonmicro.com or linux@wolfsonmicro.com
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/pm.h>
+#include <linux/bitops.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+#include <linux/regulator/regulator.h>
+#include <linux/regulator/regulator-platform.h>
+#include <linux/regulator/wm8350/wm8350.h>
+#include <linux/regulator/wm8350/wm8350-pmic.h>
+#include <linux/regulator/wm8350/wm8350-gpio.h>
+#include <linux/regulator/wm8350/wm8350-bus.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/leds.h>
+#include <linux/fb.h>
+
+#include <mach/dma.h>
+#include <mach/spba.h>
+#include <mach/clock.h>
+#include <mach/mxc.h>
+#include "board-mx37_3stack.h"
+
+static void wm8350_regulator_init(void)
+{
+ int i = 0;
+ struct regulator *regulator;
+ char *wm8350_global_regulator[] = {
+ "DCDC1",
+ "DCDC3",
+ "DCDC4",
+ "DCDC6",
+ "LDO3",
+ };
+
+ /* for board v2.0 later, do nothing here*/
+ if (board_is_mx37(BOARD_REV_2))
+ return;
+ while (!IS_ERR_VALUE((unsigned long)(regulator = regulator_get(NULL,
+ wm8350_global_regulator[i])))) {
+ regulator_enable(regulator);
+ i++;
+ }
+}
+late_initcall(wm8350_regulator_init);
+
+/*
+ * Set to 1 when testing battery that is connected otherwise spuriuos debug
+ */
+#define BATTERY 0
+
+/* extern const char imx_3stack_audio[32]; */
+
+struct mxc_audio_platform_data imx_3stack_audio_platform_data = {
+ .ssi_num = 2,
+ .src_port = 2,
+ .ext_port = 5,
+ .regulator1 = "DCDC6",
+ .regulator2 = "DCDC3"
+};
+
+#ifdef NOT_PORTED_TO_IMX37_3STACK_YET
+
+static void imx37_3stack_switch_handler(struct wm8350 *wm8350, int irq)
+{
+ printk("switch pressed %d\n", irq);
+}
+#endif
+static struct platform_device *imx_snd_device;
+
+void wm8350_free(struct wm8350 *wm8350)
+{
+#if BATTERY
+ struct wm8350_power *power = &wm8350->power;
+#endif
+
+ wm8350_mask_irq(wm8350, WM8350_IRQ_GPIO(7));
+ wm8350_free_irq(wm8350, WM8350_IRQ_GPIO(7));
+ wm8350_mask_irq(wm8350, WM8350_IRQ_WKUP_ONKEY);
+ wm8350_free_irq(wm8350, WM8350_IRQ_WKUP_ONKEY);
+
+#if BATTERY
+ wm8350_charger_enable(power, 0);
+ wm8350_fast_charger_enable(power, 0);
+#endif
+ if (wm8350->nirq)
+ free_irq(wm8350->nirq, wm8350);
+
+ flush_scheduled_work();
+
+ if (device_is_registered(&wm8350->pmic.dev))
+ device_unregister(&wm8350->pmic.dev);
+ if (device_is_registered(&wm8350->rtc.dev))
+ device_unregister(&wm8350->rtc.dev);
+ if (device_is_registered(&wm8350->wdg.dev))
+ device_unregister(&wm8350->wdg.dev);
+ if (device_is_registered(&wm8350->power.dev))
+ device_unregister(&wm8350->power.dev);
+
+ platform_device_unregister(imx_snd_device);
+}
+
+#if BATTERY
+static int wm8350_init_battery(struct wm8350 *wm8350)
+{
+ struct wm8350_power *power = &wm8350->power;
+ struct wm8350_charger_policy *policy = &power->policy;
+
+ policy->eoc_mA = WM8350_CHG_EOC_mA(10);
+ policy->charge_mV = WM8350_CHG_4_05V;
+ policy->fast_limit_mA = WM8350_CHG_FAST_LIMIT_mA(400);
+ policy->charge_timeout = WM8350_CHG_TIME_MIN(60);
+ policy->trickle_start_mV = WM8350_CHG_TRICKLE_3_1V;
+ policy->trickle_charge_mA = WM8350_CHG_TRICKLE_50mA;
+
+ wm8350_charger_enable(power, 1);
+ wm8350_fast_charger_enable(power, 1);
+ return 0;
+}
+#endif
+
+#ifdef NOT_PORTED_TO_IMX37_3STACK_YET
+static int config_gpios(struct wm8350 *wm8350)
+{
+ /* power on */
+ wm8350_gpio_config(wm8350, 0, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO0_PWR_ON_IN, WM8350_GPIO_ACTIVE_LOW,
+ WM8350_GPIO_PULL_UP, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_ON);
+
+ /* Sw3 --> PWR_OFF_GPIO3 */
+ /* lg - TODO: GPIO1_0 to be pulled down */
+ wm8350_gpio_config(wm8350, 3, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO3_PWR_OFF_IN, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_ON);
+
+ /* MR or MEMRST ????? */
+ wm8350_gpio_config(wm8350, 4, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO4_MR_IN, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ /* Hibernate -- GPIO 7 */
+ wm8350_gpio_config(wm8350, 7, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO7_HIBERNATE_IN, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_DOWN, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ /* SDOUT */
+ wm8350_gpio_config(wm8350, 6, WM8350_GPIO_DIR_OUT,
+ WM8350_GPIO6_SDOUT_OUT, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ /* GPIO switch SW2 */
+ wm8350_gpio_config(wm8350, 7, WM8350_GPIO_DIR_IN, WM8350_GPIO7_GPIO_IN,
+ WM8350_GPIO_ACTIVE_HIGH, WM8350_GPIO_PULL_DOWN,
+ WM8350_GPIO_INVERT_OFF, WM8350_GPIO_DEBOUNCE_ON);
+ wm8350_register_irq(wm8350, WM8350_IRQ_GPIO(7),
+ imx37_3stack_switch_handler, NULL);
+ wm8350_unmask_irq(wm8350, WM8350_IRQ_GPIO(7));
+
+ /* PWR_FAIL */
+ wm8350_gpio_config(wm8350, 8, WM8350_GPIO_DIR_OUT,
+ WM8350_GPIO8_VCC_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW,
+ WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ /* BATT Fault */
+ wm8350_gpio_config(wm8350, 9, WM8350_GPIO_DIR_OUT,
+ WM8350_GPIO9_BATT_FAULT_OUT, WM8350_GPIO_ACTIVE_LOW,
+ WM8350_GPIO_PULL_NONE, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+
+ return 0;
+}
+
+static int config_hibernate(struct wm8350 *wm8350)
+{
+ struct wm8350_pmic *pmic = &wm8350->pmic;
+
+ /* dont assert RTS when hibernating */
+ wm8350_set_bits(wm8350, WM8350_SYSTEM_HIBERNATE, WM8350_RST_HIB_MODE);
+
+ /* set up hibernate voltages -- needs refining */
+ wm8350_dcdc_set_image_voltage(pmic, WM8350_DCDC_1, 1400, /*1200, *//* 1.0v for mx32 */
+ WM8350_DCDC_HIB_MODE_IMAGE,
+ WM8350_DCDC_HIB_SIG_REG);
+ wm8350_dcdc_set_image_voltage(pmic, WM8350_DCDC_3, 2800,
+ WM8350_DCDC_HIB_MODE_IMAGE,
+ WM8350_DCDC_HIB_SIG_REG);
+ wm8350_dcdc_set_image_voltage(pmic, WM8350_DCDC_4, 1800,
+ WM8350_DCDC_HIB_MODE_IMAGE,
+ WM8350_DCDC_HIB_SIG_REG);
+ wm8350_dcdc_set_image_voltage(pmic, WM8350_DCDC_6, 1800,
+ WM8350_DCDC_HIB_MODE_IMAGE,
+ WM8350_DCDC_HIB_SIG_REG);
+ wm8350_ldo_set_image_voltage(pmic, WM8350_LDO_1, 2800,
+ WM8350_LDO_HIB_MODE_IMAGE,
+ WM8350_LDO_HIB_SIG_REG);
+ wm8350_ldo_set_image_voltage(pmic, WM8350_LDO_2, 3300,
+ WM8350_LDO_HIB_MODE_IMAGE,
+ WM8350_LDO_HIB_SIG_REG);
+ wm8350_ldo_set_image_voltage(pmic, WM8350_LDO_3, 1500,
+ WM8350_LDO_HIB_MODE_IMAGE,
+ WM8350_LDO_HIB_SIG_REG);
+ wm8350_ldo_set_image_voltage(pmic, WM8350_LDO_4, 2500,
+ WM8350_LDO_HIB_MODE_IMAGE,
+ WM8350_LDO_HIB_MODE_DIS);
+ return 0;
+}
+#endif
+
+struct regulation_constraints led_regulation_constraints = {
+ .min_uA = 0,
+ .max_uA = 230000,
+ .valid_ops_mask = REGULATOR_CHANGE_CURRENT,
+};
+struct regulation_constraints dcdc1_regulation_constraints = {
+ .min_uV = mV_to_uV(850),
+ .max_uV = mV_to_uV(1200),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+};
+struct regulation_constraints dcdc4_regulation_constraints = {
+ .min_uV = mV_to_uV(1000),
+ .max_uV = mV_to_uV(1200),
+ .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | REGULATOR_CHANGE_MODE,
+};
+
+static void set_regulator_constraints(struct wm8350 *wm8350)
+{
+ regulator_set_platform_constraints("DCDC1",
+ &dcdc1_regulation_constraints);
+ regulator_set_platform_constraints("DCDC4",
+ &dcdc4_regulation_constraints);
+ regulator_set_platform_constraints("ISINKA",
+ &led_regulation_constraints);
+}
+
+static void wm8350_nop_release(struct device *dev)
+{
+ /* Nothing */
+}
+
+static int wm8350_check_fb(struct fb_info *info)
+{
+ return (to_platform_device(info->device)->id == 0);
+}
+
+struct wm8350_bl_platform_data wm8350_bl_data = {
+ .isink = WM8350_ISINK_A,
+ .dcdc = WM8350_DCDC_5,
+ .voltage_ramp = WM8350_DC5_RMP_20V,
+ .retries = 5,
+ .max_brightness = 63,
+ .power = FB_BLANK_UNBLANK,
+ .brightness = 50,
+ .check_fb = wm8350_check_fb,
+};
+
+static struct platform_device mxc_wm8350_devices[] = {
+ {
+ .name = "wm8350-bl",
+ .id = 2,
+ .dev = {
+ .release = wm8350_nop_release,
+ .platform_data = &wm8350_bl_data,
+ },
+ },
+};
+
+static inline void mxc_init_wm8350(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mxc_wm8350_devices); i++) {
+ if (platform_device_register(&mxc_wm8350_devices[i]) < 0)
+ dev_err(&mxc_wm8350_devices[i].dev,
+ "Unable to register WM8350 device\n");
+ }
+}
+
+int wm8350_init(struct wm8350 *wm8350)
+{
+ int ret = 0;
+
+ /* register regulator and set constraints */
+ wm8350_device_register_pmic(wm8350);
+ set_regulator_constraints(wm8350);
+#ifdef NOT_PORTED_TO_IMX37
+ wm8350_device_register_rtc(wm8350);
+ wm8350_device_register_wdg(wm8350);
+ wm8350_device_register_power(wm8350);
+#endif
+ mxc_init_wm8350();
+
+ /*Note: Needs to be moved into a regulator function. */
+ /* Configuring -- GPIO 7 pin */
+ if (wm8350_gpio_config(wm8350, 7, WM8350_GPIO_DIR_OUT, 0,
+ WM8350_GPIO_ACTIVE_LOW, WM8350_GPIO_PULL_NONE,
+ WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF) == 0)
+ wm8350_gpio_set_status(wm8350, 7, 1);
+ else
+ printk(KERN_ERR "Error in setting Wolfson GPIO pin 7 \n");
+ /* enable gpio4:USB_VBUS_EN */
+ ret =
+ wm8350_gpio_config(wm8350, 4, WM8350_GPIO_DIR_IN,
+ WM8350_GPIO4_MR_IN, WM8350_GPIO_ACTIVE_HIGH,
+ WM8350_GPIO_PULL_UP, WM8350_GPIO_INVERT_OFF,
+ WM8350_GPIO_DEBOUNCE_OFF);
+ if (ret)
+ printk(KERN_ERR "Error in setting USB VBUS enable pin\n");
+
+ /* register sound */
+ printk("Registering imx37_snd_device");
+ imx_snd_device = platform_device_alloc("wm8350-imx-3stack-audio", -1);
+ if (!imx_snd_device) {
+ ret = -ENOMEM;
+ goto err;
+ }
+ imx_snd_device->dev.platform_data = &imx_3stack_audio_platform_data;
+ platform_set_drvdata(imx_snd_device, &wm8350->audio);
+ ret = platform_device_add(imx_snd_device);
+ if (ret)
+ goto snd_err;
+
+ /* set up PMIC IRQ (active high) to i.MX32ADS */
+#ifdef NOT_PORTED_TO_IMX37
+ printk("Registering PMIC INT");
+ INIT_WORK(&wm8350->work, wm8350_irq_work);
+ wm8350_reg_unlock(wm8350);
+ wm8350_set_bits(wm8350, WM8350_SYSTEM_CONTROL_1, WM8350_IRQ_POL);
+ wm8350_reg_lock(wm8350);
+ set_irq_type(MXC_PMIC_INT_LINE, IRQF_TRIGGER_RISING);
+ ret = request_irq(MXC_PMIC_INT_LINE, wm8350_irq_handler,
+ IRQF_DISABLED, "wm8350-pmic", wm8350);
+ if (ret != 0) {
+ printk(KERN_ERR "wm8350: cant request irq %d\n",
+ MXC_PMIC_INT_LINE);
+ goto err;
+ }
+ wm8350->nirq = MXC_PMIC_INT_LINE;
+ printk("Configuring WM8350 GPIOS");
+ config_gpios(wm8350);
+ config_hibernate(wm8350);
+
+ /* Sw1 --> PWR_ON */
+ printk("Registering and unmasking the WM8350 wakeup key");
+ wm8350_register_irq(wm8350, WM8350_IRQ_WKUP_ONKEY,
+ imx37_3stack_switch_handler);
+ wm8350_unmask_irq(wm8350, WM8350_IRQ_WKUP_ONKEY);
+
+ /* unmask all & clear sticky */
+ printk("Unmasking WM8350 local interrupts");
+ wm8350_reg_write(wm8350, WM8350_SYSTEM_INTERRUPTS_MASK, 0x0);
+ schedule_work(&wm8350->work);
+#endif
+
+#if BATTERY
+ /* not much use without a battery atm */
+ wm8350_init_battery(wm8350);
+#endif
+
+ printk("Exiting normally from wm8350_init()");
+ return ret;
+ snd_err:
+ platform_device_put(imx_snd_device);
+
+ err:
+ printk("wm8350_init() FAILED");
+ kfree(wm8350->reg_cache);
+ return ret;
+}
diff --git a/arch/arm/mach-mx37/mx37_pins.h b/arch/arm/mach-mx37/mx37_pins.h
new file mode 100644
index 000000000000..10dcbf3c8d8b
--- /dev/null
+++ b/arch/arm/mach-mx37/mx37_pins.h
@@ -0,0 +1,256 @@
+/*
+ * Copyright 2007-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_MXC_MX37_PINS_H__
+#define __ASM_ARCH_MXC_MX37_PINS_H__
+
+/*!
+ * @file arch-mxc/mx37_pins.h
+ *
+ * @brief MX37 I/O Pin List
+ *
+ * @ingroup GPIO_MX37
+ */
+
+#ifndef __ASSEMBLY__
+
+/*!
+ * @name IOMUX/PAD Bit field definitions
+ */
+
+/*! @{ */
+
+/*!
+ * In order to identify pins more effectively, each mux-controlled pin's
+ * enumerated value is constructed in the following way:
+ *
+ * -------------------------------------------------------------------
+ * 31-29 | 28 - 24 | 23 | 22 - 20 | 19 - 10| 9 - 0
+ * -------------------------------------------------------------------
+ * IO_P | IO_I | RSVD_I | GPIO_I | PAD_I | MUX_I
+ * -------------------------------------------------------------------
+ *
+ * Bit 0 to 9 contains MUX_I used to identify the register
+ * offset (0-based. base is IOMUX_module_base) defined in the Section
+ * "sw_pad_ctl & sw_mux_ctl details" of the IC Spec. The
+ * similar field definitions are used for the pad control register.
+ * For example, the MX37_PIN_ETM_D0 is defined in the enumeration:
+ * ( (0x28 - MUX_I_START) << MUX_I)|( (0x250 - PAD_I_START) << PAD_I)
+ * It means the mux control register is at register offset 0x28. The pad control
+ * register offset is: 0x250 and also occupy the least significant bits
+ * within the register.
+ */
+
+/*!
+ * Starting bit position within each entry of \b iomux_pins to represent the
+ * MUX control register offset
+ */
+#define MUX_I 0
+/*!
+ * Starting bit position within each entry of \b iomux_pins to represent the
+ * PAD control register offset
+ */
+#define PAD_I 10
+/*!
+ * Starting bit position within each entry of \b iomux_pins to represent which
+ * mux mode is for GPIO (0-based)
+ */
+#define GPIO_I 20
+/*!
+ * Starting bit position which is reserved.
+ */
+#define RSVD_I 23
+
+#define NON_GPIO_PORT 0x7
+#define PIN_TO_MUX_MASK ((1 << (PAD_I - MUX_I)) -1)
+#define PIN_TO_PAD_MASK ((1 << (GPIO_I - PAD_I)) - 1)
+#define PIN_TO_ALT_GPIO_MASK ((1 << (RSVD_I - GPIO_I)) - 1)
+
+#define NON_MUX_I PIN_TO_MUX_MASK
+#define MUX_I_START 0x0008
+#define MUX_I_END (PAD_I_START - 4)
+#define PAD_I_START 0x230
+#define PAD_I_END (INPUT_CTL_START - 4)
+#define INPUT_CTL_START 0x508
+#define INPUT_CTL_END 0x614
+
+#define _MXC_BUILD_PIN(gp, gi, ga, mi, pi) \
+ (((gp) << MUX_IO_P) | ((gi) << MUX_IO_I) | \
+ ((mi - MUX_I_START) << MUX_I) | \
+ ((pi - PAD_I_START) << PAD_I) | \
+ ((ga) << GPIO_I))
+
+#define _MXC_BUILD_GPIO_PIN(gp, gi, ga, mi, pi) \
+ _MXC_BUILD_PIN(gp, gi, ga, mi, pi)
+
+#define _MXC_BUILD_NON_GPIO_PIN(mi, pi) \
+ _MXC_BUILD_PIN(NON_GPIO_PORT, 0, 0, mi, pi)
+
+#define PIN_TO_IOMUX_MUX(pin) ((pin >> MUX_I) & PIN_TO_MUX_MASK)
+#define PIN_TO_IOMUX_PAD(pin) ((pin >> PAD_I) & PIN_TO_PAD_MASK)
+#define PIN_TO_ALT_GPIO(pin) ((pin >> GPIO_I) & PIN_TO_ALT_GPIO_MASK)
+#define PIN_TO_IOMUX_INDEX(pin) (PIN_TO_IOMUX_MUX(pin) >> 2)
+
+/*! @} End IOMUX/PAD Bit field definitions */
+
+/*!
+ * This enumeration is constructed based on the Section
+ * "sw_pad_ctl & sw_mux_ctl details" of the MX37 IC Spec. Each enumerated
+ * value is constructed based on the rules described above.
+ */
+enum iomux_pins {
+ MX37_PIN_KEY_ROW0 = _MXC_BUILD_NON_GPIO_PIN(0x8, 0x230),
+ MX37_PIN_KEY_ROW1 = _MXC_BUILD_NON_GPIO_PIN(0xC, 0x234),
+ MX37_PIN_KEY_ROW2 = _MXC_BUILD_NON_GPIO_PIN(0x10, 0x238),
+ MX37_PIN_KEY_ROW3 = _MXC_BUILD_NON_GPIO_PIN(0x14, 0x23C),
+ MX37_PIN_KEY_ROW4 = _MXC_BUILD_NON_GPIO_PIN(0x18, 0x240),
+ MX37_PIN_KEY_ROW5 = _MXC_BUILD_NON_GPIO_PIN(0x1C, 0x244),
+ MX37_PIN_KEY_ROW6 = _MXC_BUILD_NON_GPIO_PIN(0x20, 0x248),
+ MX37_PIN_KEY_ROW7 = _MXC_BUILD_NON_GPIO_PIN(0x24, 0x24C),
+ MX37_PIN_ETM_D0 = _MXC_BUILD_NON_GPIO_PIN(0x28, 0x250),
+ MX37_PIN_ETM_D1 = _MXC_BUILD_NON_GPIO_PIN(0x2C, 0x254),
+ MX37_PIN_ETM_D2 = _MXC_BUILD_NON_GPIO_PIN(0x30, 0x258),
+ MX37_PIN_ETM_D3 = _MXC_BUILD_NON_GPIO_PIN(0x34, 0x25C),
+ MX37_PIN_ETM_D4 = _MXC_BUILD_NON_GPIO_PIN(0x38, 0x260),
+ MX37_PIN_ETM_D5 = _MXC_BUILD_NON_GPIO_PIN(0x3C, 0x264),
+ MX37_PIN_ETM_D6 = _MXC_BUILD_NON_GPIO_PIN(0x40, 0x268),
+ MX37_PIN_ETM_D7 = _MXC_BUILD_NON_GPIO_PIN(0x44, 0x26C),
+ MX37_PIN_EIM_EB0 = _MXC_BUILD_GPIO_PIN(0, 15, 3, 0x48, 0x2A8),
+ MX37_PIN_EIM_EB1 = _MXC_BUILD_GPIO_PIN(0, 14, 3, 0x4C, 0x2AC),
+ MX37_PIN_EIM_OE = _MXC_BUILD_GPIO_PIN(0, 13, 3, 0x50, 0x2B0),
+ MX37_PIN_EIM_CS0 = _MXC_BUILD_GPIO_PIN(1, 0, 1, 0x54, 0x2B4),
+ MX37_PIN_EIM_CS1 = _MXC_BUILD_GPIO_PIN(1, 1, 1, 0x58, 0x2B8),
+ MX37_PIN_EIM_ECB = _MXC_BUILD_GPIO_PIN(0, 12, 3, 0x5C, 0x2BC),
+ MX37_PIN_EIM_LBA = _MXC_BUILD_GPIO_PIN(0, 11, 3, 0x60, 0x2C0),
+ MX37_PIN_EIM_BCLK = _MXC_BUILD_GPIO_PIN(0, 10, 3, 0x64, 0x2C4),
+ MX37_PIN_EIM_RW = _MXC_BUILD_GPIO_PIN(0, 9, 3, 0x68, 0x2C8),
+ MX37_PIN_NANDF_WE_B = _MXC_BUILD_GPIO_PIN(1, 2, 4, 0x6C, 0x2CC),
+ MX37_PIN_NANDF_RE_B = _MXC_BUILD_GPIO_PIN(1, 3, 4, 0x70, 0x2D0),
+ MX37_PIN_NANDF_ALE = _MXC_BUILD_GPIO_PIN(1, 4, 4, 0x74, 0x2D4),
+ MX37_PIN_NANDF_CLE = _MXC_BUILD_GPIO_PIN(1, 5, 4, 0x78, 0x2D8),
+ MX37_PIN_NANDF_WP_B = _MXC_BUILD_GPIO_PIN(1, 6, 4, 0x7C, 0x2DC),
+ MX37_PIN_NANDF_RB = _MXC_BUILD_GPIO_PIN(1, 7, 4, 0x80, 0x2E0),
+ MX37_PIN_NANDF_CS0 = _MXC_BUILD_GPIO_PIN(1, 8, 4, 0x84, 0x2E4),
+ MX37_PIN_NANDF_CS1 = _MXC_BUILD_GPIO_PIN(1, 9, 4, 0x88, 0x2E8),
+ MX37_PIN_NANDF_CS2 = _MXC_BUILD_GPIO_PIN(1, 10, 4, 0x8C, 0x2EC),
+ MX37_PIN_NANDF_CS3 = _MXC_BUILD_GPIO_PIN(1, 11, 4, 0x90, 0x2F0),
+ MX37_PIN_EIM_D15 = _MXC_BUILD_NON_GPIO_PIN(0x94, 0x2F4),
+ MX37_PIN_EIM_D14 = _MXC_BUILD_NON_GPIO_PIN(0x98, 0x2F8),
+ MX37_PIN_EIM_D13 = _MXC_BUILD_NON_GPIO_PIN(0x9C, 0x2FC),
+ MX37_PIN_EIM_D12 = _MXC_BUILD_NON_GPIO_PIN(0xA0, 0x300),
+ MX37_PIN_EIM_D11 = _MXC_BUILD_NON_GPIO_PIN(0xA4, 0x304),
+ MX37_PIN_EIM_D10 = _MXC_BUILD_NON_GPIO_PIN(0xA8, 0x308),
+ MX37_PIN_EIM_D9 = _MXC_BUILD_NON_GPIO_PIN(0xAC, 0x30C),
+ MX37_PIN_EIM_D8 = _MXC_BUILD_GPIO_PIN(0, 8, 3, 0xB0, 0x310),
+ MX37_PIN_EIM_D7 = _MXC_BUILD_GPIO_PIN(2, 27, 3, 0xB4, 0x314),
+ MX37_PIN_EIM_D6 = _MXC_BUILD_GPIO_PIN(2, 26, 3, 0xB8, 0x318),
+ MX37_PIN_EIM_D5 = _MXC_BUILD_GPIO_PIN(2, 25, 3, 0xBC, 0x31C),
+ MX37_PIN_EIM_D4 = _MXC_BUILD_GPIO_PIN(2, 24, 3, 0xC0, 0x320),
+ MX37_PIN_EIM_D3 = _MXC_BUILD_GPIO_PIN(2, 23, 3, 0xC4, 0x324),
+ MX37_PIN_EIM_D2 = _MXC_BUILD_GPIO_PIN(2, 22, 3, 0xC8, 0x328),
+ MX37_PIN_EIM_D1 = _MXC_BUILD_GPIO_PIN(2, 21, 3, 0xCC, 0x32C),
+ MX37_PIN_EIM_D0 = _MXC_BUILD_GPIO_PIN(2, 20, 3, 0xD0, 0x330),
+ MX37_PIN_SD1_CMD = _MXC_BUILD_GPIO_PIN(0, 16, 3, 0xD4, 0x334),
+ MX37_PIN_SD1_CLK = _MXC_BUILD_GPIO_PIN(0, 17, 3, 0xD8, 0x338),
+ MX37_PIN_SD1_DATA0 = _MXC_BUILD_GPIO_PIN(0, 18, 3, 0xDC, 0x33C),
+ MX37_PIN_SD1_DATA1 = _MXC_BUILD_GPIO_PIN(0, 19, 3, 0xE0, 0x340),
+ MX37_PIN_SD1_DATA2 = _MXC_BUILD_GPIO_PIN(0, 20, 3, 0xE4, 0x344),
+ MX37_PIN_SD1_DATA3 = _MXC_BUILD_GPIO_PIN(0, 21, 3, 0xE8, 0x348),
+ MX37_PIN_SD2_CMD = _MXC_BUILD_GPIO_PIN(0, 22, 3, 0xEC, 0x34C),
+ MX37_PIN_SD2_CLK = _MXC_BUILD_GPIO_PIN(0, 23, 3, 0xF0, 0x350),
+ MX37_PIN_SD2_DATA0 = _MXC_BUILD_GPIO_PIN(0, 24, 3, 0xF4, 0x354),
+ MX37_PIN_SD2_DATA1 = _MXC_BUILD_GPIO_PIN(0, 25, 3, 0xF8, 0x358),
+ MX37_PIN_SD2_DATA2 = _MXC_BUILD_GPIO_PIN(0, 26, 3, 0xFC, 0x35C),
+ MX37_PIN_SD2_DATA3 = _MXC_BUILD_GPIO_PIN(0, 27, 3, 0x100, 0x360),
+ MX37_PIN_I2C1_CLK = _MXC_BUILD_GPIO_PIN(1, 12, 4, 0x104, 0x364),
+ MX37_PIN_I2C1_DAT = _MXC_BUILD_GPIO_PIN(1, 13, 4, 0x108, 0x368),
+ MX37_PIN_AUD3_BB_TXD = _MXC_BUILD_GPIO_PIN(1, 14, 4, 0x10C, 0x36C),
+ MX37_PIN_AUD3_BB_RXD = _MXC_BUILD_GPIO_PIN(1, 15, 4, 0x110, 0x370),
+ MX37_PIN_AUD3_BB_CK = _MXC_BUILD_GPIO_PIN(1, 16, 4, 0x114, 0x374),
+ MX37_PIN_AUD3_BB_FS = _MXC_BUILD_GPIO_PIN(1, 17, 4, 0x118, 0x378),
+ MX37_PIN_AUD5_RXFS = _MXC_BUILD_GPIO_PIN(1, 18, 4, 0x11C, 0x37C),
+ MX37_PIN_AUD5_RXC = _MXC_BUILD_GPIO_PIN(1, 19, 4, 0x120, 0x380),
+ MX37_PIN_AUD5_WB_TXD = _MXC_BUILD_GPIO_PIN(1, 20, 4, 0x124, 0x384),
+ MX37_PIN_AUD5_WB_RXD = _MXC_BUILD_GPIO_PIN(1, 21, 4, 0x128, 0x388),
+ MX37_PIN_AUD5_WB_CK = _MXC_BUILD_GPIO_PIN(1, 22, 4, 0x12C, 0x38C),
+ MX37_PIN_AUD5_WB_FS = _MXC_BUILD_GPIO_PIN(1, 23, 4, 0x130, 0x390),
+ MX37_PIN_CSPI1_MOSI = _MXC_BUILD_GPIO_PIN(2, 0, 4, 0x134, 0x394),
+ MX37_PIN_CSPI1_MISO = _MXC_BUILD_GPIO_PIN(2, 1, 4, 0x138, 0x398),
+ MX37_PIN_CSPI1_SS0 = _MXC_BUILD_GPIO_PIN(2, 2, 4, 0x13C, 0x39C),
+ MX37_PIN_CSPI1_SS1 = _MXC_BUILD_GPIO_PIN(2, 3, 4, 0x140, 0x3A0),
+ MX37_PIN_CSPI1_SCLK = _MXC_BUILD_GPIO_PIN(2, 4, 4, 0x144, 0x3A4),
+ MX37_PIN_CSPI2_MOSI = _MXC_BUILD_GPIO_PIN(2, 5, 4, 0x148, 0x3A8),
+ MX37_PIN_CSPI2_MISO = _MXC_BUILD_GPIO_PIN(2, 6, 4, 0x14C, 0x3AC),
+ MX37_PIN_CSPI2_SS0 = _MXC_BUILD_GPIO_PIN(2, 7, 4, 0x150, 0x3B0),
+ MX37_PIN_CSPI2_SS1 = _MXC_BUILD_GPIO_PIN(2, 8, 4, 0x154, 0x3B4),
+ MX37_PIN_CSPI2_SCLK = _MXC_BUILD_GPIO_PIN(2, 9, 4, 0x158, 0x3B8),
+ MX37_PIN_UART1_RXD = _MXC_BUILD_GPIO_PIN(1, 24, 4, 0x15C, 0x3BC),
+ MX37_PIN_UART1_TXD = _MXC_BUILD_GPIO_PIN(1, 25, 4, 0x160, 0x3C0),
+ MX37_PIN_UART1_RTS = _MXC_BUILD_GPIO_PIN(1, 26, 4, 0x164, 0x3C4),
+ MX37_PIN_UART1_CTS = _MXC_BUILD_GPIO_PIN(1, 27, 4, 0x168, 0x3C8),
+ MX37_PIN_UART1_DTR = _MXC_BUILD_GPIO_PIN(1, 28, 4, 0x16C, 0x3CC),
+ MX37_PIN_UART1_DSR = _MXC_BUILD_GPIO_PIN(1, 29, 4, 0x170, 0x3D0),
+ MX37_PIN_UART1_RI = _MXC_BUILD_GPIO_PIN(1, 30, 4, 0x174, 0x3D4),
+ MX37_PIN_UART1_DCD = _MXC_BUILD_GPIO_PIN(1, 31, 4, 0x178, 0x3D8),
+ MX37_PIN_OWIRE_LINE = _MXC_BUILD_GPIO_PIN(0, 31, 4, 0x17C, 0x3DC),
+ MX37_PIN_JTAG_DE_B = _MXC_BUILD_NON_GPIO_PIN(0x180, 0x3E0),
+ MX37_PIN_DI1_PIN11 = _MXC_BUILD_GPIO_PIN(2, 10, 4, 0x184, 0x3E4),
+ MX37_PIN_DI1_PIN12 = _MXC_BUILD_GPIO_PIN(2, 11, 4, 0x188, 0x3E8),
+ MX37_PIN_DI1_PIN13 = _MXC_BUILD_GPIO_PIN(2, 12, 4, 0x18C, 0x3EC),
+ MX37_PIN_DI1_D0_CS = _MXC_BUILD_GPIO_PIN(2, 13, 4, 0x190, 0x3F0),
+ MX37_PIN_DI1_PIN15 = _MXC_BUILD_GPIO_PIN(0, 30, 4, 0x194, 0),
+ MX37_PIN_DISP1_DAT0 = _MXC_BUILD_NON_GPIO_PIN(0x198, 0x3F4),
+ MX37_PIN_DISP1_DAT1 = _MXC_BUILD_NON_GPIO_PIN(0x19C, 0x3F8),
+ MX37_PIN_DISP1_DAT2 = _MXC_BUILD_NON_GPIO_PIN(0x1A0, 0x3FC),
+ MX37_PIN_DISP1_DAT3 = _MXC_BUILD_NON_GPIO_PIN(0x1A4, 0x400),
+ MX37_PIN_DISP1_DAT4 = _MXC_BUILD_NON_GPIO_PIN(0x1A8, 0x404),
+ MX37_PIN_DISP1_DAT5 = _MXC_BUILD_NON_GPIO_PIN(0x1AC, 0x408),
+ MX37_PIN_DISP1_DAT6 = _MXC_BUILD_NON_GPIO_PIN(0x1B0, 0x40C),
+ MX37_PIN_DISP1_DAT7 = _MXC_BUILD_NON_GPIO_PIN(0x1B4, 0x410),
+ MX37_PIN_DISP1_DAT8 = _MXC_BUILD_NON_GPIO_PIN(0x1B8, 0x414),
+ MX37_PIN_DISP1_DAT9 = _MXC_BUILD_NON_GPIO_PIN(0x1BC, 0x418),
+ MX37_PIN_DISP1_DAT10 = _MXC_BUILD_NON_GPIO_PIN(0x1C0, 0x41C),
+ MX37_PIN_DISP1_DAT11 = _MXC_BUILD_NON_GPIO_PIN(0x1C4, 0x420),
+ MX37_PIN_DISP1_DAT12 = _MXC_BUILD_NON_GPIO_PIN(0x1C8, 0x424),
+ MX37_PIN_DISP1_DAT13 = _MXC_BUILD_NON_GPIO_PIN(0x1CC, 0x428),
+ MX37_PIN_DISP1_DAT14 = _MXC_BUILD_NON_GPIO_PIN(0x1D0, 0x42C),
+ MX37_PIN_DISP1_DAT15 = _MXC_BUILD_NON_GPIO_PIN(0x1D4, 0x430),
+ MX37_PIN_DISP1_DAT16 = _MXC_BUILD_GPIO_PIN(0, 28, 4, 0x1D8, 0x434),
+ MX37_PIN_DISP1_DAT17 = _MXC_BUILD_GPIO_PIN(0, 29, 4, 0x1DC, 0x438),
+ MX37_PIN_DISP1_DAT18 = _MXC_BUILD_GPIO_PIN(2, 14, 4, 0x1E0, 0x43C),
+ MX37_PIN_DISP1_DAT19 = _MXC_BUILD_GPIO_PIN(2, 15, 4, 0x1E4, 0x440),
+ MX37_PIN_DISP1_DAT20 = _MXC_BUILD_GPIO_PIN(2, 16, 4, 0x1E8, 0x444),
+ MX37_PIN_DISP1_DAT21 = _MXC_BUILD_GPIO_PIN(2, 17, 4, 0x1EC, 0x448),
+ MX37_PIN_DISP1_DAT22 = _MXC_BUILD_GPIO_PIN(2, 18, 4, 0x1F0, 0x44C),
+ MX37_PIN_DISP1_DAT23 = _MXC_BUILD_GPIO_PIN(2, 18, 4, 0x1F4, 0x450),
+ MX37_PIN_PAD_DI1_PIN3 = _MXC_BUILD_GPIO_PIN(2, 29, 4, 0x1F8, 0),
+ MX37_PIN_DISP_CLK = _MXC_BUILD_GPIO_PIN(2, 30, 4, 0x1FC, 0),
+ MX37_PIN_DI1_PIN2 = _MXC_BUILD_GPIO_PIN(2, 31, 4, 0x200, 0),
+ MX37_PIN_BOOT_MODE1 = _MXC_BUILD_NON_GPIO_PIN(0x204, 0x454),
+ MX37_PIN_BOOT_MODE0 = _MXC_BUILD_NON_GPIO_PIN(0x208, 0x458),
+ MX37_PIN_WDOG_RST = _MXC_BUILD_GPIO_PIN(2, 28, 1, 0x20C, 0x464),
+ MX37_PIN_GPIO1_0 = _MXC_BUILD_GPIO_PIN(0, 0, 0, 0x210, 0x468),
+ MX37_PIN_GPIO1_1 = _MXC_BUILD_GPIO_PIN(0, 1, 0, 0x214, 0x46C),
+ MX37_PIN_GPIO1_2 = _MXC_BUILD_GPIO_PIN(0, 2, 1, 0x218, 0x470),
+ MX37_PIN_GPIO1_3 = _MXC_BUILD_GPIO_PIN(0, 3, 0, 0x21C, 0x474),
+ MX37_PIN_GPIO1_4 = _MXC_BUILD_GPIO_PIN(0, 4, 0, 0x220, 0x478),
+ MX37_PIN_GPIO1_5 = _MXC_BUILD_GPIO_PIN(0, 5, 0, 0x224, 0x47C),
+ MX37_PIN_GPIO1_6 = _MXC_BUILD_GPIO_PIN(0, 6, 0, 0x228, 0x480),
+ MX37_PIN_GPIO1_7 = _MXC_BUILD_GPIO_PIN(0, 7, 0, 0x22C, 0x484),
+ MX37_PIN_GRP_H10 = _MXC_BUILD_NON_GPIO_PIN(0x230, 0x490),
+ MX37_PIN_GRP_H9 = _MXC_BUILD_NON_GPIO_PIN(0x230, 0x494),
+ MX37_PIN_GRP_H3 = _MXC_BUILD_NON_GPIO_PIN(0x230, 0x4D0),
+ MX37_PIN_GRP_H5 = _MXC_BUILD_NON_GPIO_PIN(0x230, 0x4EC),
+};
+
+#endif /* */
+#endif /* */
diff --git a/arch/arm/mach-mx37/pm.c b/arch/arm/mach-mx37/pm.c
new file mode 100644
index 000000000000..d8318d57e05b
--- /dev/null
+++ b/arch/arm/mach-mx37/pm.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+
+static int mx37_suspend_enter(suspend_state_t state)
+{
+ if (tzic_enable_wake(0) != 0)
+ return -EAGAIN;
+
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ mxc_cpu_lp_set(STOP_POWER_OFF);
+ break;
+ case PM_SUSPEND_STANDBY:
+ mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+ break;
+ default:
+ return -EINVAL;
+ }
+ cpu_do_idle();
+
+ return 0;
+}
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int mx37_suspend_prepare(void)
+{
+ return 0;
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+static void mx37_suspend_finish(void)
+{
+}
+
+static int mx37_pm_valid(suspend_state_t state)
+{
+ return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX);
+}
+
+struct platform_suspend_ops mx37_suspend_ops = {
+ .valid = mx37_pm_valid,
+ .prepare = mx37_suspend_prepare,
+ .enter = mx37_suspend_enter,
+ .finish = mx37_suspend_finish,
+};
+
+static int __init mx37_pm_init(void)
+{
+ pr_info("Static Power Management for Freescale i.MX37\n");
+ suspend_set_ops(&mx37_suspend_ops);
+
+ return 0;
+}
+
+late_initcall(mx37_pm_init);
diff --git a/arch/arm/mach-mx37/sdma_script_code.h b/arch/arm/mach-mx37/sdma_script_code.h
new file mode 100644
index 000000000000..f3b7d509ffb5
--- /dev/null
+++ b/arch/arm/mach-mx37/sdma_script_code.h
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2008 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 */
+
+/*!
+ * @file sdma_script_code.h
+ * @brief This file contains functions of SDMA scripts code initialization
+ *
+ * The file was generated automatically. Based on sdma scripts library.
+ *
+ * @ingroup SDMA
+ */
+/*******************************************************************************
+
+ SDMA RELEASE LABEL: "SS15_MARLEY"
+
+*******************************************************************************/
+
+#ifndef __SDMA_SCRIPT_CODE_H__
+#define __SDMA_SCRIPT_CODE_H__
+
+/*!
+* SDMA ROM scripts start addresses and sizes
+*/
+
+#define start_ADDR 0
+#define start_SIZE 20
+
+#define core_ADDR 80
+#define core_SIZE 232
+
+#define common_ADDR 312
+#define common_SIZE 330
+
+#define ap_2_ap_ADDR 642
+#define ap_2_ap_SIZE 41
+
+#define app_2_mcu_ADDR 683
+#define app_2_mcu_SIZE 64
+
+#define mcu_2_app_ADDR 747
+#define mcu_2_app_SIZE 70
+
+#define uart_2_mcu_ADDR 817
+#define uart_2_mcu_SIZE 75
+
+#define shp_2_mcu_ADDR 892
+#define shp_2_mcu_SIZE 69
+
+#define mcu_2_shp_ADDR 961
+#define mcu_2_shp_SIZE 72
+
+#define uartsh_2_mcu_ADDR 1033
+#define uartsh_2_mcu_SIZE 69
+
+#define mcu_2_ata_ADDR 1102
+#define mcu_2_ata_SIZE 81
+
+#define ata_2_mcu_ADDR 1183
+#define ata_2_mcu_SIZE 96
+
+#define burstDMA__2__burstDMA_routine_ADDR 1279
+#define burstDMA__2__burstDMA_routine_SIZE 227
+
+#define test_ADDR 1506
+#define test_SIZE 63
+
+#define signature_ADDR 1023
+#define signature_SIZE 1
+
+/*!
+* SDMA RAM scripts start addresses and sizes
+*/
+
+#define dptc_dvfs_ADDR 6144
+#define dptc_dvfs_SIZE 270
+
+#define ext_mem__ipu_ram_ADDR 6414
+#define ext_mem__ipu_ram_SIZE 123
+
+#define mcu_2_mshc_ADDR 6537
+#define mcu_2_mshc_SIZE 54
+
+#define mcu_2_spdif_marley_ADDR 6591
+#define mcu_2_spdif_marley_SIZE 161
+
+#define mshc_2_mcu_ADDR 6752
+#define mshc_2_mcu_SIZE 54
+
+/*!
+* SDMA RAM image start address and size
+*/
+
+#define RAM_CODE_START_ADDR 6144
+#define RAM_CODE_SIZE 662
+
+/*!
+* Buffer that holds the SDMA RAM image
+*/
+__attribute__ ((__aligned__(4)))
+#ifndef CONFIG_XIP_KERNEL
+const
+#endif
+static const short sdma_code[] = {
+ 0xc13c, 0x7d70, 0x0800, 0x0970, 0x0111, 0x5111, 0x5ac1, 0x5bc9,
+ 0x028e, 0xc14e, 0x068a, 0x7c66, 0x5dd9, 0x5ce1, 0x0bff, 0x0311,
+ 0x1bff, 0x03bc, 0x5bd1, 0x1a5c, 0x6ac3, 0x63c8, 0x0363, 0x7c05,
+ 0x036f, 0x7d27, 0x0374, 0x7c76, 0x9874, 0xd907, 0x3c06, 0x4c00,
+ 0x7df7, 0x028f, 0x1a04, 0x6a20, 0x620b, 0x6f20, 0x301f, 0x00aa,
+ 0x0462, 0x7c04, 0x4a00, 0x7d0b, 0x2001, 0x9837, 0x048a, 0x620b,
+ 0x2201, 0x1c01, 0x1801, 0x02dc, 0x7d02, 0x301f, 0x00aa, 0x048f,
+ 0x1c04, 0x6c04, 0x0488, 0x3c1f, 0x6c2b, 0x0045, 0x028e, 0x1a5c,
+ 0x9818, 0x058f, 0x1d0c, 0x6d20, 0x650b, 0x007d, 0x7c01, 0x1d08,
+ 0x007c, 0x7c01, 0x1d04, 0x6d20, 0x650b, 0x0488, 0x3c1f, 0x0417,
+ 0x0417, 0x0417, 0x0417, 0x059c, 0x6d20, 0x028e, 0x1a34, 0x6ad7,
+ 0x0488, 0x0804, 0x7802, 0x650b, 0x6dc8, 0x008c, 0x1a28, 0x6ad7,
+ 0x63c8, 0x034c, 0x6bc8, 0x54d1, 0x4c00, 0x7d06, 0x0065, 0x7c02,
+ 0x0101, 0x0025, 0x0400, 0x9814, 0x52c1, 0x53c9, 0x54e1, 0x0453,
+ 0xc159, 0x7d95, 0x0200, 0x9800, 0x55d9, 0x6d04, 0x54d1, 0x058a,
+ 0x2508, 0x6dc7, 0x0373, 0x7c03, 0x65c8, 0x6d0b, 0x2408, 0x0372,
+ 0x7c04, 0x65c8, 0x6d0b, 0x2408, 0x9889, 0x6cce, 0x65c8, 0x6d0a,
+ 0x2404, 0x6d28, 0x6504, 0x5dd9, 0x5cd1, 0x6ad7, 0x6ae3, 0x63c8,
+ 0x0334, 0x6bc8, 0x0370, 0x7cad, 0x0c60, 0x0411, 0x04bb, 0x4c00,
+ 0x7da8, 0x0410, 0x1c30, 0x0410, 0x04bb, 0x046d, 0x7d0a, 0x047d,
+ 0x7c03, 0x047c, 0x7c01, 0x9841, 0x003b, 0x003a, 0x0039, 0x0058,
+ 0x98b8, 0x047d, 0x7d03, 0x047c, 0x7d01, 0x9841, 0x005b, 0xd8fc,
+ 0x1d18, 0x6d20, 0x650b, 0x0510, 0x003a, 0x0039, 0x0038, 0x00ad,
+ 0xd907, 0x0c30, 0x0410, 0x04bb, 0x003c, 0x003d, 0x00ac, 0xd8fc,
+ 0x007b, 0x7c04, 0x003d, 0x003c, 0x1d0c, 0x98d9, 0x048f, 0x1c14,
+ 0x6c20, 0x640b, 0x4401, 0x7d04, 0x005d, 0x005c, 0x1d0c, 0x98d9,
+ 0x0310, 0x3b30, 0x4b30, 0x7d01, 0x1b10, 0x0310, 0x003d, 0x003c,
+ 0x00ab, 0x6ad7, 0x63c8, 0x6d20, 0x650b, 0x0560, 0x7d03, 0x005e,
+ 0xd8f0, 0x9841, 0x003e, 0x0c80, 0x0410, 0x0394, 0xd8f0, 0x640b,
+ 0x037f, 0x7d02, 0x1a14, 0x98ed, 0x1a0c, 0x6ad7, 0x6cc8, 0x9841,
+ 0x0c7f, 0x0410, 0x03b4, 0x04b8, 0x03ac, 0x640b, 0x6bc8, 0x028e,
+ 0x1a04, 0x6ad7, 0x6cc8, 0x0006, 0x058f, 0x1d08, 0x6d20, 0x650b,
+ 0x007d, 0x7c01, 0x1d38, 0x007c, 0x7c01, 0x1d1c, 0x0006, 0x048b,
+ 0x042c, 0x0454, 0x042b, 0x6ad7, 0x6cc8, 0x0006, 0x0e70, 0x0611,
+ 0x5616, 0xc13c, 0x7d2a, 0x5ade, 0x008e, 0xc14e, 0x7c26, 0x5be0,
+ 0x5ef0, 0x5ce8, 0x0688, 0x08ff, 0x0011, 0x28ff, 0x00bc, 0x53f6,
+ 0x05df, 0x7d0b, 0x6dc5, 0x03df, 0x7d03, 0x6bd5, 0xd95d, 0x9939,
+ 0x6b05, 0xc55f, 0x7e27, 0x7f29, 0x9939, 0x6d01, 0x03df, 0x7d05,
+ 0x6bd5, 0xc589, 0x7e18, 0x7f1a, 0x9939, 0x6b05, 0xc4ff, 0x7e07,
+ 0x7f06, 0x52de, 0x53e6, 0xc159, 0x7dd7, 0x0200, 0x9911, 0x0007,
+ 0x6004, 0x680c, 0x53f6, 0x028e, 0x00a3, 0xc256, 0x048b, 0x0498,
+ 0x0454, 0x068a, 0x9939, 0x0207, 0x680c, 0x6ddf, 0x0107, 0x68ff,
+ 0x60d0, 0x9942, 0x0207, 0x68ff, 0x6d28, 0x0107, 0x6004, 0x680c,
+ 0x9942, 0x0007, 0x68ff, 0x60d0, 0x9942, 0x0288, 0x03a5, 0x3b03,
+ 0x3d03, 0x4d00, 0x7d0a, 0x0804, 0x00a5, 0x00da, 0x7d1a, 0x02a0,
+ 0x7b01, 0x65d8, 0x7eee, 0x65ff, 0x7eec, 0x0804, 0x02d0, 0x7d11,
+ 0x4b00, 0x7c0f, 0x008a, 0x3003, 0x6dcf, 0x6bdf, 0x0015, 0x0015,
+ 0x7b02, 0x65d8, 0x0000, 0x7edd, 0x63ff, 0x7edb, 0x3a03, 0x6dcd,
+ 0x6bdd, 0x008a, 0x7b02, 0x65d8, 0x0000, 0x7ed3, 0x65ff, 0x7ed1,
+ 0x0006, 0xc1d9, 0x0b70, 0x0311, 0x5313, 0x58d3, 0x008b, 0x5efb,
+ 0xc13c, 0x7d2b, 0x5ac0, 0x5bc8, 0xc14e, 0x7c27, 0x6d01, 0x0388,
+ 0x0dff, 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d1a, 0x0e70, 0x0611,
+ 0x522e, 0x02b9, 0x4a00, 0x7c07, 0x52fe, 0x50d3, 0x02b8, 0x4a00,
+ 0x7c02, 0x0400, 0x999e, 0x56fb, 0x620b, 0x7e06, 0x5a06, 0x7f06,
+ 0x0000, 0x2504, 0x7d05, 0x999e, 0x0007, 0x680c, 0x0007, 0x0454,
+ 0x008b, 0x52c0, 0x53c8, 0xc159, 0x7dd6, 0x0200, 0x9990, 0xc1d9,
+ 0xc1e3, 0x0800, 0x005f, 0x00ac, 0x58e3, 0x0478, 0x7d5c, 0x0479,
+ 0x7d01, 0x0515, 0x0515, 0xda38, 0xda57, 0x0479, 0x7d26, 0x54e3,
+ 0x047f, 0x7d12, 0x50eb, 0x56fb, 0x0015, 0x52db, 0x7806, 0x5402,
+ 0x5c06, 0x1a01, 0x5402, 0x5c26, 0x1a01, 0x54e3, 0x043f, 0x5ce3,
+ 0x4d00, 0x7d4e, 0x0479, 0x7d14, 0x047f, 0x7d01, 0xda57, 0x52f3,
+ 0x6a21, 0x56db, 0x7803, 0x620b, 0x5a06, 0x1e01, 0x7f34, 0x7e33,
+ 0x6200, 0x5af3, 0x047f, 0x7dde, 0x9a20, 0x54e3, 0x047f, 0x7cda,
+ 0x54e3, 0x047f, 0x7d01, 0xda57, 0x54eb, 0x0fff, 0x0711, 0x1fff,
+ 0x56db, 0x52f3, 0x6a21, 0x630b, 0x028b, 0x03bf, 0xda32, 0x5b06,
+ 0x2401, 0x4c00, 0x7d0b, 0x1e01, 0x038a, 0x03b7, 0x0312, 0x0312,
+ 0xda32, 0x5b06, 0x1e01, 0x2401, 0x4c00, 0x7ced, 0x0b70, 0x0311,
+ 0x5313, 0x7f09, 0x7e08, 0x6200, 0x5af3, 0x54e3, 0x047f, 0x7db2,
+ 0x57db, 0xc1fa, 0x99cd, 0x0007, 0x680c, 0x54e3, 0x0478, 0x7c02,
+ 0x0800, 0x9a2e, 0x0479, 0x7d01, 0x0517, 0x0517, 0x5deb, 0xc213,
+ 0xc20a, 0x99c1, 0x0808, 0x7801, 0x0317, 0x0006, 0x020a, 0x0006,
+ 0x070a, 0xda36, 0x1a05, 0x0215, 0x5adb, 0x0708, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
+ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x080c,
+ 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x4800, 0x7dd2, 0x58eb, 0x0006,
+ 0xc1d9, 0x0b70, 0x0311, 0x5313, 0x58d3, 0x008b, 0x5efb, 0xc13c,
+ 0x7d2b, 0x5ac0, 0x5bc8, 0xc14e, 0x7c27, 0x0388, 0x6d05, 0x0dff,
+ 0x0511, 0x1dff, 0x05bc, 0x4d00, 0x7d1a, 0x0e70, 0x0611, 0x522e,
+ 0x02b9, 0x4a00, 0x7c07, 0x52fe, 0x50d3, 0x02b8, 0x4a00, 0x7c02,
+ 0x0400, 0x9a75, 0x56fb, 0x5206, 0x7e08, 0x6a0b, 0x6a28, 0x7f04,
+ 0x0000, 0x2504, 0x7d04, 0x9a75, 0x680c, 0x0007, 0x0454, 0x008b,
+ 0x52c0, 0x53c8, 0xc159, 0x7dd6, 0x0200, 0x9a67
+};
+#endif
diff --git a/arch/arm/mach-mx37/serial.c b/arch/arm/mach-mx37/serial.c
new file mode 100644
index 000000000000..aaa5171eb177
--- /dev/null
+++ b/arch/arm/mach-mx37/serial.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/*!
+ * @file mach-mx37/serial.c
+ *
+ * @brief This file contains the UART initiliazation.
+ *
+ * @ingroup MSL_MX37
+ */
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <mach/hardware.h>
+#include <mach/mxc_uart.h>
+#include <mach/spba.h>
+#include "serial.h"
+#include "board-mx37_3stack.h"
+
+#if defined(CONFIG_SERIAL_MXC) || defined(CONFIG_SERIAL_MXC_MODULE)
+
+/*!
+ * This is an array where each element holds information about a UART port,
+ * like base address of the UART, interrupt numbers etc. This structure is
+ * passed to the serial_core.c file. Based on which UART is used, the core file
+ * passes back the appropriate port structure as an argument to the control
+ * functions.
+ */
+static uart_mxc_port mxc_ports[] = {
+ [0] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART1_BASE_ADDR),
+ .mapbase = UART1_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART1_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 0,
+ },
+ .ints_muxed = UART1_MUX_INTS,
+ .irqs = {UART1_INT2, UART1_INT3},
+ .mode = UART1_MODE,
+ .ir_mode = UART1_IR,
+ .enabled = UART1_ENABLED,
+ .hardware_flow = UART1_HW_FLOW,
+ .cts_threshold = UART1_UCR4_CTSTL,
+ .dma_enabled = UART1_DMA_ENABLE,
+ .dma_rxbuf_size = UART1_DMA_RXBUFSIZE,
+ .rx_threshold = UART1_UFCR_RXTL,
+ .tx_threshold = UART1_UFCR_TXTL,
+ .shared = UART1_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART1_TX,
+ .dma_rx_id = MXC_DMA_UART1_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ },
+ [1] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART2_BASE_ADDR),
+ .mapbase = UART2_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART2_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 1,
+ },
+ .ints_muxed = UART2_MUX_INTS,
+ .irqs = {UART2_INT2, UART2_INT3},
+ .mode = UART2_MODE,
+ .ir_mode = UART2_IR,
+ .enabled = UART2_ENABLED,
+ .hardware_flow = UART2_HW_FLOW,
+ .cts_threshold = UART2_UCR4_CTSTL,
+ .dma_enabled = UART2_DMA_ENABLE,
+ .dma_rxbuf_size = UART2_DMA_RXBUFSIZE,
+ .rx_threshold = UART2_UFCR_RXTL,
+ .tx_threshold = UART2_UFCR_TXTL,
+ .shared = UART2_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART2_TX,
+ .dma_rx_id = MXC_DMA_UART2_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ },
+ [2] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART3_BASE_ADDR),
+ .mapbase = UART3_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART3_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 2,
+ },
+ .ints_muxed = UART3_MUX_INTS,
+ .irqs = {UART3_INT2, UART3_INT3},
+ .mode = UART3_MODE,
+ .ir_mode = UART3_IR,
+ .enabled = UART3_ENABLED,
+ .hardware_flow = UART3_HW_FLOW,
+ .cts_threshold = UART3_UCR4_CTSTL,
+ .dma_enabled = UART3_DMA_ENABLE,
+ .dma_rxbuf_size = UART3_DMA_RXBUFSIZE,
+ .rx_threshold = UART3_UFCR_RXTL,
+ .tx_threshold = UART3_UFCR_TXTL,
+ .shared = UART3_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART3_TX,
+ .dma_rx_id = MXC_DMA_UART3_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ },
+};
+
+static struct platform_device mxc_uart_device1 = {
+ .name = "mxcintuart",
+ .id = 0,
+ .dev = {
+ .platform_data = &mxc_ports[0],
+ },
+};
+
+static struct platform_device mxc_uart_device2 = {
+ .name = "mxcintuart",
+ .id = 1,
+ .dev = {
+ .platform_data = &mxc_ports[1],
+ },
+};
+
+static struct platform_device mxc_uart_device3 = {
+ .name = "mxcintuart",
+ .id = 2,
+ .dev = {
+ .platform_data = &mxc_ports[2],
+ },
+};
+
+static int __init mxc_init_uart(void)
+{
+ /* Register all the MXC UART platform device structures */
+ platform_device_register(&mxc_uart_device1);
+ platform_device_register(&mxc_uart_device2);
+
+ /* Grab ownership of shared UARTs 3 and 4, only when enabled */
+#if UART3_ENABLED == 1
+#if UART3_DMA_ENABLE == 1
+ spba_take_ownership(UART3_SHARED_PERI, (SPBA_MASTER_A | SPBA_MASTER_C));
+#else
+ spba_take_ownership(UART3_SHARED_PERI, SPBA_MASTER_A);
+#endif /* UART3_DMA_ENABLE */
+ platform_device_register(&mxc_uart_device3);
+#endif /* UART3_ENABLED */
+
+ return 0;
+}
+
+#else
+static int __init mxc_init_uart(void)
+{
+ return 0;
+}
+#endif
+
+arch_initcall(mxc_init_uart);
diff --git a/arch/arm/mach-mx37/serial.h b/arch/arm/mach-mx37/serial.h
new file mode 100644
index 000000000000..b8b8403e2698
--- /dev/null
+++ b/arch/arm/mach-mx37/serial.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ARCH_ARM_MACH_MX37_SERIAL_H__
+#define __ARCH_ARM_MACH_MX37_SERIAL_H__
+
+#include <mach/mxc_uart.h>
+
+/* UART 1 configuration */
+/*!
+ * This option allows to choose either an interrupt-driven software controlled
+ * hardware flow control (set this option to 0) or hardware-driven hardware
+ * flow control (set this option to 1).
+ */
+/* UART used as wakeup source */
+#define UART1_HW_FLOW 0
+/*!
+ * This specifies the threshold at which the CTS pin is deasserted by the
+ * RXFIFO. Set this value in Decimal to anything from 0 to 32 for
+ * hardware-driven hardware flow control. Read the HW spec while specifying
+ * this value. When using interrupt-driven software controlled hardware
+ * flow control set this option to -1.
+ */
+#define UART1_UCR4_CTSTL 16
+/*!
+ * This is option to enable (set this option to 1) or disable DMA data transfer
+ */
+#define UART1_DMA_ENABLE 0
+/*!
+ * Specify the size of the DMA receive buffer. The minimum buffer size is 512
+ * bytes. The buffer size should be a multiple of 256.
+ */
+#define UART1_DMA_RXBUFSIZE 1024
+/*!
+ * Specify the MXC UART's Receive Trigger Level. This controls the threshold at
+ * which a maskable interrupt is generated by the RxFIFO. Set this value in
+ * Decimal to anything from 0 to 32. Read the HW spec while specifying this
+ * value.
+ */
+#define UART1_UFCR_RXTL 16
+/*!
+ * Specify the MXC UART's Transmit Trigger Level. This controls the threshold at
+ * which a maskable interrupt is generated by the TxFIFO. Set this value in
+ * Decimal to anything from 0 to 32. Read the HW spec while specifying this
+ * value.
+ */
+#define UART1_UFCR_TXTL 16
+/* UART 2 configuration */
+#define UART2_HW_FLOW 0
+#define UART2_UCR4_CTSTL -1
+#define UART2_DMA_ENABLE 0
+#define UART2_DMA_RXBUFSIZE 512
+#define UART2_UFCR_RXTL 16
+#define UART2_UFCR_TXTL 16
+/* UART 3 configuration */
+#define UART3_HW_FLOW 1
+#define UART3_UCR4_CTSTL 16
+#define UART3_DMA_ENABLE 0
+#define UART3_DMA_RXBUFSIZE 1024
+#define UART3_UFCR_RXTL 16
+#define UART3_UFCR_TXTL 16
+/*
+ * UART Chip level Configuration that a user may not have to edit. These
+ * configuration vary depending on how the UART module is integrated with
+ * the ARM core
+ */
+/*
+ * Is the MUXED interrupt output sent to the ARM core
+ */
+#define INTS_NOTMUXED 0
+#define INTS_MUXED 1
+/* UART 1 configuration */
+/*!
+ * This define specifies whether the muxed ANDed interrupt line or the
+ * individual interrupts from the UART port is integrated with the ARM core.
+ * There exists a define like this for each UART port. Valid values that can
+ * be used are \b INTS_NOTMUXED or \b INTS_MUXED.
+ */
+#define UART1_MUX_INTS INTS_MUXED
+/*!
+ * This define specifies the transmitter interrupt number or the interrupt
+ * number of the ANDed interrupt in case the interrupts are muxed. There exists
+ * a define like this for each UART port.
+ */
+#define UART1_INT1 MXC_INT_UART1
+/*!
+ * This define specifies the receiver interrupt number. If the interrupts of
+ * the UART are muxed, then we specify here a dummy value -1. There exists a
+ * define like this for each UART port.
+ */
+#define UART1_INT2 -1
+/*!
+ * This specifies the master interrupt number. If the interrupts of the UART
+ * are muxed, then we specify here a dummy value of -1. There exists a define
+ * like this for each UART port.
+ */
+#define UART1_INT3 -1
+/*!
+ * This specifies if the UART is a shared peripheral. It holds the shared
+ * peripheral number if it is shared or -1 if it is not shared. There exists
+ * a define like this for each UART port.
+ */
+#define UART1_SHARED_PERI -1
+/* UART 2 configuration */
+#define UART2_MUX_INTS INTS_MUXED
+#define UART2_INT1 MXC_INT_UART2
+#define UART2_INT2 -1
+#define UART2_INT3 -1
+#define UART2_SHARED_PERI -1
+/* UART 3 configuration */
+#define UART3_MUX_INTS INTS_MUXED
+#define UART3_INT1 MXC_INT_UART3
+#define UART3_INT2 -1
+#define UART3_INT3 -1
+#define UART3_SHARED_PERI SPBA_UART3
+
+#endif /* __ARCH_ARM_MACH_MX37_SERIAL_H__ */
diff --git a/arch/arm/mach-mx37/system.c b/arch/arm/mach-mx37/system.c
new file mode 100644
index 000000000000..d40549b29ddc
--- /dev/null
+++ b/arch/arm/mach-mx37/system.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#define DEBUG
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+#include <asm/cacheflush.h>
+#include <mach/clock.h>
+#include "crm_regs.h"
+
+/*!
+ * @defgroup MSL_MX37 i.MX37 Machine Specific Layer (MSL)
+ */
+
+/*!
+ * @file mach-mx37/system.c
+ * @brief This file contains idle and reset functions.
+ *
+ * @ingroup MSL_MX37
+ */
+
+extern int mxc_jtag_enabled;
+extern int low_bus_freq_mode;
+
+static struct clk *pll1_main;
+static struct clk *pll1_sw_clk;
+static struct clk *lp_apm_clk;
+static struct clk *gpc_dvfs_clk;
+
+/* set cpu low power mode before WFI instruction */
+void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
+{
+ u32 plat_lpc, gpc_pgr, arm_srpgcr, empgcr0, empgcr1, ccm_clpcr;
+ /* always allow platform to issue a deep sleep mode request */
+ plat_lpc = __raw_readl(MXC_ARM1176_PLAT_LPC) &
+ ~(MXC_ARM1176_PLAT_LPC_DSM);
+
+ ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK);
+ gpc_pgr = __raw_readl(MXC_GPC_PGR) & ~(MXC_GPC_PGR_ARMPG_MASK);
+ arm_srpgcr = __raw_readl(MXC_SRPGC_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR);
+ empgcr0 = __raw_readl(MXC_EMPGC0_ARM_EMPGCR) & ~(MXC_EMPGCR_PCR);
+ empgcr1 = __raw_readl(MXC_EMPGC1_ARM_EMPGCR) & ~(MXC_EMPGCR_PCR);
+
+ switch (mode) {
+ case WAIT_CLOCKED:
+ break;
+ case WAIT_UNCLOCKED:
+ ccm_clpcr |= (0x1 << MXC_CCM_CLPCR_LPM_OFFSET);
+ break;
+ case WAIT_UNCLOCKED_POWER_OFF:
+ case STOP_POWER_OFF:
+ plat_lpc |= MXC_ARM1176_PLAT_LPC_DSM;
+ if (mode == WAIT_UNCLOCKED_POWER_OFF)
+ ccm_clpcr |= (0x1 << MXC_CCM_CLPCR_LPM_OFFSET);
+ else {
+ ccm_clpcr |= (0x2 << MXC_CCM_CLPCR_LPM_OFFSET);
+ ccm_clpcr |= (0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET);
+ ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
+ ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
+ }
+
+ gpc_pgr |= (0x1 << MXC_GPC_PGR_ARMPG_OFFSET);
+ arm_srpgcr |= MXC_SRPGCR_PCR;
+ empgcr0 |= MXC_EMPGCR_PCR;
+ empgcr1 |= MXC_EMPGCR_PCR;
+
+ if (tzic_enable_wake(1) != 0)
+ return;
+ break;
+ case STOP_POWER_ON:
+ ccm_clpcr |= (0x2 << MXC_CCM_CLPCR_LPM_OFFSET);
+ break;
+ default:
+ printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode);
+ return;
+ }
+
+ __raw_writel(plat_lpc, MXC_ARM1176_PLAT_LPC);
+ __raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
+ __raw_writel(gpc_pgr, MXC_GPC_PGR);
+ __raw_writel(arm_srpgcr, MXC_SRPGC_ARM_SRPGCR);
+ if ((mxc_cpu_is_rev(CHIP_REV_1_0)) != 1)
+ __raw_writel(empgcr0, MXC_EMPGC0_ARM_EMPGCR);
+
+ __raw_writel(empgcr1, MXC_EMPGC1_ARM_EMPGCR);
+
+ flush_cache_all();
+
+ if (gpc_dvfs_clk == NULL)
+ gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs_clk");
+
+ /* gpc clock is needed for SRPG */
+ clk_enable(gpc_dvfs_clk);
+ if (low_bus_freq_mode) {
+ if (pll1_sw_clk == NULL)
+ pll1_sw_clk = clk_get(NULL, "pll1_sw_clk");
+ if (lp_apm_clk == NULL)
+ lp_apm_clk = clk_get(NULL, "lp_apm");
+ if (pll1_main == NULL)
+ pll1_main = clk_get(NULL, "pll1_main_clk");
+
+ /* Move the ARM to run off the 24MHz clock. Shutdown the PLL1 */
+ /* Change the source of pll1_sw_clk to be the step_clk */
+ clk_set_parent(pll1_sw_clk, lp_apm_clk);
+ }
+}
+
+void mxc_pg_enable(struct platform_device *pdev)
+{
+ if (pdev == NULL)
+ return;
+
+ if (strcmp(pdev->name, "mxc_ipu") == 0) {
+ __raw_writel(MXC_PGCR_PCR, MXC_PGC_IPU_PGCR);
+ __raw_writel(MXC_PGSR_PSR, MXC_PGC_IPU_PGSR);
+ } else if (strcmp(pdev->name, "mxc_vpu") == 0) {
+ __raw_writel(MXC_PGCR_PCR, MXC_PGC_VPU_PGCR);
+ __raw_writel(MXC_PGSR_PSR, MXC_PGC_VPU_PGSR);
+ }
+}
+
+EXPORT_SYMBOL(mxc_pg_enable);
+
+void mxc_pg_disable(struct platform_device *pdev)
+{
+ if (pdev == NULL)
+ return;
+
+ if (strcmp(pdev->name, "mxc_ipu") == 0) {
+ __raw_writel(0x0, MXC_PGC_IPU_PGCR);
+ if (__raw_readl(MXC_PGC_IPU_PGSR) & MXC_PGSR_PSR)
+ dev_dbg(&pdev->dev, "power gating successful\n");
+ __raw_writel(MXC_PGSR_PSR, MXC_PGC_IPU_PGSR);
+ } else if (strcmp(pdev->name, "mxc_vpu") == 0) {
+ __raw_writel(0x0, MXC_PGC_VPU_PGCR);
+ if (__raw_readl(MXC_PGC_VPU_PGSR) & MXC_PGSR_PSR)
+ dev_dbg(&pdev->dev, "power gating successful\n");
+ __raw_writel(MXC_PGSR_PSR, MXC_PGC_VPU_PGSR);
+ }
+}
+
+EXPORT_SYMBOL(mxc_pg_disable);
+
+/* To change the idle power mode, need to set arch_idle_mode to a different
+ * power mode as in enum mxc_cpu_pwr_mode.
+ * May allow dynamically changing the idle mode.
+ */
+static int arch_idle_mode = WAIT_UNCLOCKED_POWER_OFF;
+
+/*!
+ * This function puts the CPU into idle mode. It is called by default_idle()
+ * in process.c file.
+ */
+void arch_idle(void)
+{
+ if (likely(!mxc_jtag_enabled)) {
+ mxc_cpu_lp_set(arch_idle_mode);
+ cpu_do_idle();
+ /* gpc clock is needed for SRPG */
+ clk_disable(gpc_dvfs_clk);
+ if (low_bus_freq_mode) {
+ /* Move ARM back to PLL from step clk. */
+ /* Move the PLL1 back to the pll1_main_clk */
+ clk_set_parent(pll1_sw_clk, pll1_main);
+ }
+ }
+}
+
+/*
+ * This function resets the system. It is called by machine_restart().
+ *
+ * @param mode indicates different kinds of resets
+ */
+void arch_reset(char mode)
+{
+ /* Assert SRS signal */
+ mxc_wd_reset();
+}
diff --git a/arch/arm/mach-mx37/usb.h b/arch/arm/mach-mx37/usb.h
new file mode 100644
index 000000000000..3542866ada0b
--- /dev/null
+++ b/arch/arm/mach-mx37/usb.h
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2005-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+
+extern int usbotg_init(struct platform_device *pdev);
+extern void usbotg_uninit(struct fsl_usb2_platform_data *pdata);
+extern int gpio_usbotg_hs_active(void);
+extern void gpio_usbotg_hs_inactive(void);
+extern struct platform_device *host_pdev_register(struct resource *res,
+ int n_res, struct fsl_usb2_platform_data *config);
+
+extern int gpio_usbotg_utmi_active(void);
+extern void gpio_usbotg_utmi_inactive(void);
+static int usbotg_init_ext(struct platform_device *pdev);
+static void usbotg_uninit_ext(struct fsl_usb2_platform_data *pdata);
+
+/*
+ * Determine which platform_data struct to use for the DR controller,
+ * based on which transceiver is configured.
+ * PDATA is a pointer to it.
+ */
+#if defined(CONFIG_ISP1301_MXC)
+static struct fsl_usb2_platform_data __maybe_unused dr_1301_config;
+#define PDATA (&dr_1301_config)
+#elif defined(CONFIG_MC13783_MXC)
+static struct fsl_usb2_platform_data __maybe_unused dr_13783_config;
+#define PDATA (&dr_13783_config)
+#elif defined(CONFIG_UTMI_MXC)
+static struct fsl_usb2_platform_data __maybe_unused dr_utmi_config;
+#define PDATA (&dr_utmi_config)
+#endif
+
+
+/*
+ * Used to set pdata->operating_mode before registering the platform_device.
+ * If OTG is configured, the controller operates in OTG mode,
+ * otherwise it's either host or device.
+ */
+#ifdef CONFIG_USB_OTG
+#define DR_UDC_MODE FSL_USB2_DR_OTG
+#define DR_HOST_MODE FSL_USB2_DR_OTG
+#else
+#define DR_UDC_MODE FSL_USB2_DR_DEVICE
+#define DR_HOST_MODE FSL_USB2_DR_HOST
+#endif
+
+
+#ifdef CONFIG_USB_EHCI_ARC_OTG
+static inline void dr_register_host(struct resource *r, int rs)
+{
+ PDATA->operating_mode = DR_HOST_MODE;
+ host_pdev_register(r, rs, PDATA);
+}
+#else
+static inline void dr_register_host(struct resource *r, int rs)
+{
+}
+#endif
+
+#ifdef CONFIG_USB_GADGET_ARC
+static struct platform_device dr_udc_device;
+
+static inline void dr_register_udc(void)
+{
+ PDATA->operating_mode = DR_UDC_MODE;
+ dr_udc_device.dev.platform_data = PDATA;
+
+ if (platform_device_register(&dr_udc_device))
+ printk(KERN_ERR "usb: can't register DR gadget\n");
+ else
+ printk(KERN_INFO "usb: DR gadget (%s) registered\n",
+ PDATA->transceiver);
+}
+#else
+static inline void dr_register_udc(void)
+{
+}
+#endif
+
+#ifdef CONFIG_USB_OTG
+static struct platform_device dr_otg_device;
+
+/*
+ * set the proper operating_mode and
+ * platform_data pointer, then register the
+ * device.
+ */
+static inline void dr_register_otg(void)
+{
+ PDATA->operating_mode = FSL_USB2_DR_OTG;
+ dr_otg_device.dev.platform_data = PDATA;
+
+ if (platform_device_register(&dr_otg_device))
+ printk(KERN_ERR "usb: can't register otg device\n");
+ else
+ printk(KERN_INFO "usb: DR OTG registered\n");
+}
+#else
+static inline void dr_register_otg(void)
+{
+}
+#endif
diff --git a/arch/arm/mach-mx37/usb_dr.c b/arch/arm/mach-mx37/usb_dr.c
new file mode 100644
index 000000000000..0a1b03fdcabd
--- /dev/null
+++ b/arch/arm/mach-mx37/usb_dr.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <mach/arc_otg.h>
+#include "usb.h"
+
+/*
+ * platform data structs
+ * - Which one to use is determined by CONFIG options in usb.h
+ * - operating_mode plugged at run time
+ */
+static struct fsl_usb2_platform_data __maybe_unused dr_utmi_config = {
+ .name = "DR",
+ .platform_init = usbotg_init_ext,
+ .platform_uninit = usbotg_uninit_ext,
+ .phy_mode = FSL_USB2_PHY_UTMI_WIDE,
+ .power_budget = 500, /* 500 mA max power */
+ .gpio_usb_active = gpio_usbotg_hs_active,
+ .gpio_usb_inactive = gpio_usbotg_hs_inactive,
+ .transceiver = "utmi",
+};
+
+
+/*
+ * resources
+ */
+static struct resource otg_resources[] = {
+ [0] = {
+ .start = (u32)(OTG_BASE_ADDR),
+ .end = (u32)(OTG_BASE_ADDR + 0x1ff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_USB_OTG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+static u64 dr_udc_dmamask = ~(u32) 0;
+static void dr_udc_release(struct device *dev)
+{
+}
+
+/*
+ * platform device structs
+ * dev.platform_data field plugged at run time
+ */
+static struct platform_device dr_udc_device = {
+ .name = "fsl-usb2-udc",
+ .id = -1,
+ .dev = {
+ .release = dr_udc_release,
+ .dma_mask = &dr_udc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .resource = otg_resources,
+ .num_resources = ARRAY_SIZE(otg_resources),
+};
+
+/* Notes: configure USB clock*/
+static int usbotg_init_ext(struct platform_device *pdev)
+{
+ struct clk *usb_clk, *usboh2_clk;
+ int ret;
+
+ usboh2_clk = clk_get(NULL, "usboh2_clk");
+ clk_enable(usboh2_clk);
+
+ usb_clk = clk_get(NULL, "usb_phy_clk");
+ clk_enable(usb_clk);
+ clk_put(usb_clk);
+
+ ret = usbotg_init(pdev);
+
+ /* this clock is no use after set portsc PTS bit */
+ clk_disable(usboh2_clk);
+ clk_put(usboh2_clk);
+
+ return ret;
+}
+
+static void usbotg_uninit_ext(struct fsl_usb2_platform_data *pdata)
+{
+ struct clk *usb_clk;
+
+ usb_clk = clk_get(NULL, "usb_phy_clk");
+ clk_disable(usb_clk);
+ clk_put(usb_clk);
+
+ usbotg_uninit(pdata);
+}
+
+static int __init usb_dr_init(void)
+{
+ pr_debug("%s: \n", __func__);
+
+ /* dr_register_otg(); */
+ dr_register_host(otg_resources, ARRAY_SIZE(otg_resources));
+ dr_register_udc();
+
+ return 0;
+}
+
+module_init(usb_dr_init);
diff --git a/arch/arm/mach-mx51/Kconfig b/arch/arm/mach-mx51/Kconfig
new file mode 100644
index 000000000000..7655de1c514b
--- /dev/null
+++ b/arch/arm/mach-mx51/Kconfig
@@ -0,0 +1,85 @@
+menu "MX51 Options"
+ depends on ARCH_MX51
+
+config MX51_OPTIONS
+ bool
+ default y
+ select CPU_V7
+ select USB_ARCH_HAS_EHCI
+ select MXC_TZIC
+
+config MACH_MX51_3DS
+ bool "Support MX51 3-Stack platforms"
+ default y
+ help
+ Include support for MX51 3-Stack platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MXC_SDMA_API
+ bool "Use SDMA API"
+ default y
+ help
+ This selects the Freescale MXC SDMA API.
+ If unsure, say N.
+
+config ARCH_MXC_HAS_NFC_V3
+ bool "MXC NFC Hardware Version 3"
+ depends on ARCH_MX51
+ default y
+ help
+ This selects the Freescale MXC Nand Flash Controller Hardware Version 3
+ If unsure, say N.
+
+config ARCH_MXC_HAS_NFC_V3_2
+ bool "MXC NFC Hardware Version 3.2"
+ depends on ARCH_MXC_HAS_NFC_V3
+ default y
+ help
+ This selects the Freescale MXC Nand Flash Controller Hardware Version 3.1
+ If unsure, say N.
+
+menu "SDMA options"
+ depends on MXC_SDMA_API
+
+config SDMA_IRAM
+ bool "Use Internal RAM for SDMA transfer"
+ default n
+ help
+ Support Internal RAM as SDMA buffer or control structures
+
+config SDMA_IRAM_SIZE
+ hex "Reserved bytes of IRAM for SDMA (0x800-0x1000)"
+ range 0x800 0x1000
+ depends on SDMA_IRAM
+ default "0x1000"
+ help
+ Set the size of IRAM for SDMA. It must be a multiple of 512bytes.
+endmenu
+
+menu "Device options"
+
+config I2C_MXC_SELECT1
+ bool "Enable I2C1 module"
+ default y
+ depends on I2C_MXC
+ help
+ Enable MX51 I2C1 module.
+
+config I2C_MXC_SELECT2
+ bool "Enable I2C2 module"
+ default n
+ depends on I2C_MXC
+ help
+ Enable MX51 I2C2 module.
+
+config I2C_MXC_SELECT3
+ bool "Enable I2C3 module"
+ default n
+ depends on I2C_MXC
+ help
+ Enable MX51 I2C3 module.
+
+endmenu
+
+endmenu
+
diff --git a/arch/arm/mach-mx51/Makefile b/arch/arm/mach-mx51/Makefile
new file mode 100644
index 000000000000..31495e3ee993
--- /dev/null
+++ b/arch/arm/mach-mx51/Makefile
@@ -0,0 +1,19 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Object file lists.
+
+
+obj-y := system.o iomux.o cpu.o mm.o clock.o devices.o serial.o dma.o lpmodes.o pm.o
+
+obj-$(CONFIG_CPU_V7) += wfi.o suspend.o
+
+obj-$(CONFIG_MACH_MX51_3DS) += mx51_3stack.o mx51_3stack_gpio.o
+
+obj-$(CONFIG_USB_EHCI_ARC_H1) += usb_h1.o
+
+ifneq ($(strip $(CONFIG_USB_GADGET_ARC) $(CONFIG_USB_EHCI_ARC_OTG)),)
+ obj-y += usb_dr.o
+endif
+
diff --git a/arch/arm/mach-mx51/Makefile.boot b/arch/arm/mach-mx51/Makefile.boot
new file mode 100644
index 000000000000..9939a19d99a1
--- /dev/null
+++ b/arch/arm/mach-mx51/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x90008000
+params_phys-y := 0x90000100
+initrd_phys-y := 0x90800000
diff --git a/arch/arm/mach-mx51/board-mx51_3stack.h b/arch/arm/mach-mx51/board-mx51_3stack.h
new file mode 100644
index 000000000000..33aef2a944a7
--- /dev/null
+++ b/arch/arm/mach-mx51/board-mx51_3stack.h
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_BOARD_MX51_3STACK_H__
+#define __ASM_ARCH_MXC_BOARD_MX51_3STACK_H__
+
+/*!
+ * @defgroup BRDCFG_MX51 Board Configuration Options
+ * @ingroup MSL_MX51
+ */
+
+/*!
+ * @file mach-mx51/board-mx51_3stack.h
+ *
+ * @brief This file contains all the board level configuration options.
+ *
+ * It currently hold the options defined for MX51 3Stack Platform.
+ *
+ * @ingroup BRDCFG_MX51
+ */
+
+/*
+ * Include Files
+ */
+#include <mach/mxc_uart.h>
+
+/*!
+ * @name MXC UART board level configurations
+ */
+/*! @{ */
+/*!
+ * Specifies if the Irda transmit path is inverting
+ */
+#define MXC_IRDA_TX_INV 0
+/*!
+ * Specifies if the Irda receive path is inverting
+ */
+#define MXC_IRDA_RX_INV 0
+
+/* UART 1 configuration */
+/*!
+ * This define specifies if the UART port is configured to be in DTE or
+ * DCE mode. There exists a define like this for each UART port. Valid
+ * values that can be used are \b MODE_DTE or \b MODE_DCE.
+ */
+#define UART1_MODE MODE_DCE
+/*!
+ * This define specifies if the UART is to be used for IRDA. There exists a
+ * define like this for each UART port. Valid values that can be used are
+ * \b IRDA or \b NO_IRDA.
+ */
+#define UART1_IR NO_IRDA
+/*!
+ * This define is used to enable or disable a particular UART port. If
+ * disabled, the UART will not be registered in the file system and the user
+ * will not be able to access it. There exists a define like this for each UART
+ * port. Specify a value of 1 to enable the UART and 0 to disable it.
+ */
+#define UART1_ENABLED 1
+/*! @} */
+/* UART 2 configuration */
+#define UART2_MODE MODE_DCE
+#define UART2_IR NO_IRDA
+#define UART2_ENABLED 1
+/* UART 3 configuration */
+#define UART3_MODE MODE_DTE
+#define UART3_IR NO_IRDA
+#define UART3_ENABLED 1
+
+#define MXC_LL_UART_PADDR UART1_BASE_ADDR
+#define MXC_LL_UART_VADDR AIPS1_IO_ADDRESS(UART1_BASE_ADDR)
+
+#define DEBUG_BOARD_BASE_ADDRESS(n) (n)
+/* LAN9217 ethernet base address */
+#define LAN9217_BASE_ADDR(n) (DEBUG_BOARD_BASE_ADDRESS(n))
+/* External UART */
+#define UARTA_BASE_ADDR(n) (DEBUG_BOARD_BASE_ADDRESS(n) + 0x8000)
+#define UARTB_BASE_ADDR(n) (DEBUG_BOARD_BASE_ADDRESS(n) + 0x10000)
+
+#define BOARD_IO_ADDR(n) (DEBUG_BOARD_BASE_ADDRESS(n) + 0x20000)
+/* LED switchs */
+#define LED_SWITCH_REG 0x00
+/* buttons */
+#define SWITCH_BUTTONS_REG 0x08
+/* status, interrupt */
+#define INTR_STATUS_REG 0x10
+#define INTR_MASK_REG 0x38
+#define INTR_RESET_REG 0x20
+/* magic word for debug CPLD */
+#define MAGIC_NUMBER1_REG 0x40
+#define MAGIC_NUMBER2_REG 0x48
+/* CPLD code version */
+#define CPLD_CODE_VER_REG 0x50
+/* magic word for debug CPLD */
+#define MAGIC_NUMBER3_REG 0x58
+/* module reset register*/
+#define MODULE_RESET_REG 0x60
+/* CPU ID and Personality ID */
+#define MCU_BOARD_ID_REG 0x68
+
+/* interrupts like external uart , external ethernet etc*/
+#define EXPIO_PARENT_INT IOMUX_TO_IRQ(MX51_PIN_GPIO1_6)
+
+#define EXPIO_INT_ENET (MXC_EXP_IO_BASE + 0)
+#define EXPIO_INT_XUART_A (MXC_EXP_IO_BASE + 1)
+#define EXPIO_INT_XUART_B (MXC_EXP_IO_BASE + 2)
+#define EXPIO_INT_BUTTON_A (MXC_EXP_IO_BASE + 3)
+#define EXPIO_INT_BUTTON_B (MXC_EXP_IO_BASE + 4)
+
+/*! This is System IRQ used by LAN9217 */
+#define LAN9217_IRQ EXPIO_INT_ENET
+
+extern unsigned int sdhc_get_card_det_status(struct device *dev);
+extern int sdhc_write_protect(struct device *dev);
+extern int sdhc_init_card_det(int id);
+extern int headphone_det_status(void);
+
+#endif /* __ASM_ARCH_MXC_BOARD_MX51_3STACK_H__ */
diff --git a/arch/arm/mach-mx51/clock.c b/arch/arm/mach-mx51/clock.c
new file mode 100644
index 000000000000..69d106df0534
--- /dev/null
+++ b/arch/arm/mach-mx51/clock.c
@@ -0,0 +1,3048 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <asm/io.h>
+#include <asm/div64.h>
+#include <mach/hardware.h>
+#include <mach/clock.h>
+#include <mach/spba.h>
+
+#include "crm_regs.h"
+
+static unsigned long pll_base[] = {
+ (unsigned long)MXC_DPLL1_BASE,
+ (unsigned long)MXC_DPLL2_BASE,
+ (unsigned long)MXC_DPLL3_BASE,
+};
+
+static struct clk pll1_main_clk;
+static struct clk pll1_sw_clk;
+static struct clk pll2_sw_clk;
+static struct clk pll3_sw_clk;
+static struct clk lp_apm_clk;
+static struct clk tve_clk;
+static struct clk emi_fast_clk;
+static struct clk emi_slow_clk;
+static struct clk emi_intr_clk;
+static struct clk ddr_clk;
+static struct clk ipu_clk[];
+static struct clk axi_a_clk;
+static struct clk axi_b_clk;
+static struct clk ddr_hf_clk;
+static int cpu_curr_wp;
+static struct cpu_wp *cpu_wp_tbl;
+
+int cpu_wp_nr;
+
+extern int mxc_jtag_enabled;
+
+static int cpu_clk_set_wp(int wp);
+extern void propagate_rate(struct clk *tclk);
+
+static void __calc_pre_post_dividers(u32 div, u32 *pre, u32 *post)
+{
+ u32 min_pre, temp_pre, old_err, err;
+
+ if (div >= 512) {
+ *pre = 8;
+ *post = 64;
+ } else if (div >= 8) {
+ min_pre = (div - 1) / 64 + 1;
+ old_err = 8;
+ for (temp_pre = 8; temp_pre >= min_pre; temp_pre--) {
+ err = div % temp_pre;
+ if (err == 0) {
+ *pre = temp_pre;
+ break;
+ }
+ err = temp_pre - err;
+ if (err < old_err) {
+ old_err = err;
+ *pre = temp_pre;
+ }
+ }
+ *post = (div + *pre - 1) / *pre;
+ } else if (div < 8) {
+ *pre = div;
+ *post = 1;
+ }
+}
+
+static int _clk_enable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg |= MXC_CCM_CCGR_CG_MASK << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+
+ return 0;
+}
+
+static void _clk_disable(struct clk *clk)
+{
+ u32 reg;
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGR_CG_MASK << clk->enable_shift);
+ __raw_writel(reg, clk->enable_reg);
+}
+
+static void _clk_disable_inwait(struct clk *clk)
+{
+ u32 reg;
+
+ reg = __raw_readl(clk->enable_reg);
+ reg &= ~(MXC_CCM_CCGR_CG_MASK << clk->enable_shift);
+ reg |= 1 << clk->enable_shift;
+ __raw_writel(reg, clk->enable_reg);
+}
+
+/*
+ * For the 4-to-1 muxed input clock
+ */
+static inline u32 _get_mux(struct clk *parent, struct clk *m0,
+ struct clk *m1, struct clk *m2, struct clk *m3)
+{
+ if (parent == m0)
+ return 0;
+ else if (parent == m1)
+ return 1;
+ else if (parent == m2)
+ return 2;
+ else if (parent == m3)
+ return 3;
+ else
+ BUG();
+
+ return 0;
+}
+
+/*
+ * For the ddr muxed input clock
+ */
+static inline u32 _get_mux_ddr(struct clk *parent, struct clk *m0,
+ struct clk *m1, struct clk *m2, struct clk *m3, struct clk *m4)
+{
+ if (parent == m0)
+ return 0;
+ else if (parent == m1)
+ return 1;
+ else if (parent == m2)
+ return 2;
+ else if (parent == m3)
+ return 3;
+ else if (parent == m4)
+ return 4;
+ else
+ BUG();
+
+ return 0;
+}
+
+static inline unsigned long _get_pll_base(struct clk *pll)
+{
+ if (pll == &pll1_main_clk)
+ return pll_base[0];
+ else if (pll == &pll2_sw_clk)
+ return pll_base[1];
+ else if (pll == &pll3_sw_clk)
+ return pll_base[2];
+ else
+ BUG();
+
+ return 0;
+}
+
+static struct clk ckih_clk = {
+ .name = "ckih",
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk ckih2_clk = {
+ .name = "ckih2",
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk osc_clk = {
+ .name = "osc",
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk ckil_clk = {
+ .name = "ckil",
+ .flags = RATE_PROPAGATES,
+};
+
+static void _fpm_recalc(struct clk *clk)
+{
+ clk->rate = ckil_clk.rate * 512;
+ if ((__raw_readl(MXC_CCM_CCR) & MXC_CCM_CCR_FPM_MULT_MASK) != 0)
+ clk->rate *= 2;
+
+}
+
+static int _fpm_enable(struct clk *clk)
+{
+ u32 reg = __raw_readl(MXC_CCM_CCR);
+ reg |= MXC_CCM_CCR_FPM_EN;
+ __raw_writel(reg, MXC_CCM_CCR);
+ return 0;
+}
+
+static void _fpm_disable(struct clk *clk)
+{
+ u32 reg = __raw_readl(MXC_CCM_CCR);
+ reg &= ~MXC_CCM_CCR_FPM_EN;
+ __raw_writel(reg, MXC_CCM_CCR);
+}
+
+static struct clk fpm_clk = {
+ .name = "fpm_clk",
+ .parent = &ckil_clk,
+ .recalc = _fpm_recalc,
+ .enable = _fpm_enable,
+ .disable = _fpm_disable,
+ .flags = RATE_PROPAGATES,
+};
+
+static void _fpm_div2_recalc(struct clk *clk)
+{
+ clk->rate = clk->parent->rate / 2;
+}
+
+static struct clk fpm_div2_clk = {
+ .name = "fpm_div2_clk",
+ .parent = &fpm_clk,
+ .recalc = _fpm_div2_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static void _clk_pll_recalc(struct clk *clk)
+{
+ long mfi, mfn, mfd, pdf, ref_clk, mfn_abs;
+ unsigned long dp_op, dp_mfd, dp_mfn, dp_ctl, pll_hfsm, dbl;
+ unsigned long pllbase;
+ s64 temp;
+
+ pllbase = _get_pll_base(clk);
+
+ dp_ctl = __raw_readl(pllbase + MXC_PLL_DP_CTL);
+ pll_hfsm = dp_ctl & MXC_PLL_DP_CTL_HFSM;
+ dbl = dp_ctl & MXC_PLL_DP_CTL_DPDCK0_2_EN;
+
+ if (pll_hfsm == 0) {
+ dp_op = __raw_readl(pllbase + MXC_PLL_DP_OP);
+ dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_MFD);
+ dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_MFN);
+ } else {
+ dp_op = __raw_readl(pllbase + MXC_PLL_DP_HFS_OP);
+ dp_mfd = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFD);
+ dp_mfn = __raw_readl(pllbase + MXC_PLL_DP_HFS_MFN);
+ }
+ pdf = dp_op & MXC_PLL_DP_OP_PDF_MASK;
+ mfi = (dp_op & MXC_PLL_DP_OP_MFI_MASK) >> MXC_PLL_DP_OP_MFI_OFFSET;
+ mfi = (mfi <= 5) ? 5 : mfi;
+ mfd = dp_mfd & MXC_PLL_DP_MFD_MASK;
+ mfn = mfn_abs = dp_mfn & MXC_PLL_DP_MFN_MASK;
+ /* Sign extend to 32-bits */
+ if (mfn >= 0x04000000) {
+ mfn |= 0xFC000000;
+ mfn_abs = -mfn;
+ }
+
+ ref_clk = 2 * clk->parent->rate;
+ if (dbl != 0)
+ ref_clk *= 2;
+
+ ref_clk /= (pdf + 1);
+ temp = (u64) ref_clk * mfn_abs;
+ do_div(temp, mfd + 1);
+ if (mfn < 0)
+ temp = -temp;
+ temp = (ref_clk * mfi) + temp;
+
+ clk->rate = temp;
+}
+
+static int _clk_pll_enable(struct clk *clk)
+{
+ u32 reg;
+ u32 pllbase;
+
+ pllbase = _get_pll_base(clk);
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) | MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+
+ /* Wait for lock */
+ while (!(__raw_readl(pllbase + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_LRF)) ;
+
+ return 0;
+}
+
+static void _clk_pll_disable(struct clk *clk)
+{
+ u32 reg;
+ u32 pllbase;
+
+ pllbase = _get_pll_base(clk);
+ reg = __raw_readl(pllbase + MXC_PLL_DP_CTL) & ~MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, pllbase + MXC_PLL_DP_CTL);
+}
+
+static struct clk pll1_main_clk = {
+ .name = "pll1_main_clk",
+ .parent = &osc_clk,
+ .recalc = _clk_pll_recalc,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .flags = RATE_PROPAGATES,
+};
+
+static int _clk_pll1_sw_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ if (parent == &pll1_main_clk) {
+ reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ } else {
+ if (parent == &lp_apm_clk) {
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ reg = __raw_readl(MXC_CCM_CCSR);
+ mux = _get_mux(parent, &lp_apm_clk, NULL, &pll2_sw_clk,
+ &pll3_sw_clk);
+ reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
+ (mux << MXC_CCM_CCSR_STEP_SEL_OFFSET);
+ } else {
+ mux = _get_mux(parent, &lp_apm_clk, NULL, &pll2_sw_clk,
+ &pll3_sw_clk);
+ reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) |
+ (mux << MXC_CCM_CCSR_STEP_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CCSR);
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+
+ }
+ }
+ __raw_writel(reg, MXC_CCM_CCSR);
+ return 0;
+}
+
+static void _clk_pll1_sw_recalc(struct clk *clk)
+{
+ u32 reg, div;
+ div = 1;
+ reg = __raw_readl(MXC_CCM_CCSR);
+
+ if (clk->parent == &pll2_sw_clk) {
+ div = ((reg & MXC_CCM_CCSR_PLL2_PODF_MASK) >>
+ MXC_CCM_CCSR_PLL2_PODF_OFFSET) + 1;
+ } else if (clk->parent == &pll3_sw_clk) {
+ div = ((reg & MXC_CCM_CCSR_PLL3_PODF_MASK) >>
+ MXC_CCM_CCSR_PLL3_PODF_OFFSET) + 1;
+ }
+ clk->rate = clk->parent->rate / div;
+}
+
+/* pll1 switch clock */
+static struct clk pll1_sw_clk = {
+ .name = "pll1_sw_clk",
+ .parent = &pll1_main_clk,
+ .set_parent = _clk_pll1_sw_set_parent,
+ .recalc = _clk_pll1_sw_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+/* same as pll2_main_clk. These two clocks should always be the same */
+static struct clk pll2_sw_clk = {
+ .name = "pll2",
+ .parent = &osc_clk,
+ .recalc = _clk_pll_recalc,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .flags = RATE_PROPAGATES,
+};
+
+/* same as pll3_main_clk. These two clocks should always be the same */
+static struct clk pll3_sw_clk = {
+ .name = "pll3",
+ .parent = &osc_clk,
+ .recalc = _clk_pll_recalc,
+ .enable = _clk_pll_enable,
+ .disable = _clk_pll_disable,
+ .flags = RATE_PROPAGATES,
+};
+
+static int _clk_lp_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ if (parent == &osc_clk)
+ reg = __raw_readl(MXC_CCM_CCSR) & ~MXC_CCM_CCSR_LP_APM_SEL;
+ else if (parent == &fpm_clk)
+ reg = __raw_readl(MXC_CCM_CCSR) | MXC_CCM_CCSR_LP_APM_SEL;
+ else
+ return -EINVAL;
+
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ return 0;
+}
+
+static struct clk lp_apm_clk = {
+ .name = "lp_apm",
+ .parent = &osc_clk,
+ .set_parent = _clk_lp_apm_set_parent,
+ .flags = RATE_PROPAGATES,
+};
+
+static void _clk_arm_recalc(struct clk *clk)
+{
+ u32 cacrr, div;
+
+ cacrr = __raw_readl(MXC_CCM_CACRR);
+ div = (cacrr & MXC_CCM_CACRR_ARM_PODF_MASK) + 1;
+ clk->rate = clk->parent->rate / div;
+}
+
+static int _clk_cpu_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 i;
+ for (i = 0; i < cpu_wp_nr; i++) {
+ if (rate == cpu_wp_tbl[i].cpu_rate)
+ break;
+ }
+ if (i > cpu_wp_nr)
+ return -EINVAL;
+ cpu_clk_set_wp(i);
+
+ return 0;
+}
+
+static unsigned long _clk_cpu_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 i;
+ u32 wp;
+
+ for (i = 0; i < cpu_wp_nr; i++) {
+ if (rate == cpu_wp_tbl[i].cpu_rate)
+ break;
+ }
+
+ if (i > cpu_wp_nr)
+ wp = 0;
+
+ return cpu_wp_tbl[wp].cpu_rate;
+}
+
+
+static struct clk cpu_clk = {
+ .name = "cpu_clk",
+ .parent = &pll1_sw_clk,
+ .recalc = _clk_arm_recalc,
+ .set_rate = _clk_cpu_set_rate,
+ .round_rate = _clk_cpu_round_rate,
+};
+
+static int _clk_periph_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll3_sw_clk, &lp_apm_clk, NULL);
+
+ reg = __raw_readl(MXC_CCM_CBCMR) & ~MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk periph_apm_clk = {
+ .name = "periph_apm_clk",
+ .parent = &pll1_sw_clk,
+ .set_parent = _clk_periph_apm_set_parent,
+ .flags = RATE_PROPAGATES,
+};
+
+/* TODO: Need to sync with GPC to determine if DVFS is in place so that
+ * the DVFS_PODF divider can be applied in CDCR register.
+ */
+static void _clk_main_bus_recalc(struct clk *clk)
+{
+ clk->rate = clk->parent->rate;
+}
+
+static int _clk_main_bus_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.enable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.enable(&emi_slow_clk);
+ if (emi_intr_clk.usecount == 0)
+ emi_intr_clk.enable(&emi_intr_clk);
+
+ if (parent == &pll2_sw_clk) {
+ reg = __raw_readl(MXC_CCM_CBCDR) &
+ ~MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+ } else if (parent == &periph_apm_clk) {
+ reg = __raw_readl(MXC_CCM_CBCDR) | MXC_CCM_CBCDR_PERIPH_CLK_SEL;
+ } else {
+ return -EINVAL;
+ }
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.disable(&emi_fast_clk);
+ if (emi_slow_clk.usecount == 0)
+ emi_slow_clk.disable(&emi_slow_clk);
+ if (emi_intr_clk.usecount == 0)
+ emi_intr_clk.disable(&emi_intr_clk);
+
+ return 0;
+}
+
+static struct clk main_bus_clk = {
+ .name = "main_bus_clk",
+ .parent = &pll2_sw_clk,
+ .set_parent = _clk_main_bus_set_parent,
+ .recalc = _clk_main_bus_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static void _clk_axi_a_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_AXI_A_PODF_MASK) >>
+ MXC_CCM_CBCDR_AXI_A_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+}
+
+static struct clk axi_a_clk = {
+ .name = "axi_a_clk",
+ .parent = &main_bus_clk,
+ .recalc = _clk_axi_a_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static void _clk_ddr_hf_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_DDR_PODF_MASK) >>
+ MXC_CCM_CBCDR_DDR_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+}
+
+static struct clk ddr_hf_clk = {
+ .name = "ddr_hf_clk",
+ .parent = &pll1_sw_clk,
+ .recalc = _clk_ddr_hf_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static void _clk_axi_b_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_AXI_B_PODF_MASK) >>
+ MXC_CCM_CBCDR_AXI_B_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+}
+
+static struct clk axi_b_clk = {
+ .name = "axi_b_clk",
+ .parent = &main_bus_clk,
+ .recalc = _clk_axi_b_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static void _clk_ahb_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
+ MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+}
+
+static struct clk ahb_clk = {
+ .name = "ahb_clk",
+ .parent = &main_bus_clk,
+ .recalc = _clk_ahb_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static int _clk_max_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_enable(clk);
+
+ /* Handshake with MAX when LPM is entered. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg &= ~MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+
+static void _clk_max_disable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_disable_inwait(clk);
+
+ /* No Handshake with MAX when LPM is entered as its disabled. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg |= MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+
+static struct clk ahb_max_clk = {
+ .name = "max_clk",
+ .parent = &ahb_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGR0_CG14_OFFSET,
+ .enable = _clk_max_enable,
+ .disable = _clk_max_disable,
+};
+
+static int _clk_emi_slow_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ if (parent == &ahb_clk) {
+ reg |= MXC_CCM_CBCDR_EMI_CLK_SEL;
+ } else if (parent == &main_bus_clk) {
+ reg &= ~MXC_CCM_CBCDR_EMI_CLK_SEL;
+ } else {
+ BUG();
+ }
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ return 0;
+}
+
+static void _clk_emi_slow_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_EMI_PODF_MASK) >>
+ MXC_CCM_CBCDR_EMI_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+}
+
+static int _clk_emi_slow_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+
+ div = clk->parent->rate / rate;
+ if (div == 0)
+ div++;
+ if (((clk->parent->rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.enable(&emi_fast_clk);
+ if (emi_intr_clk.usecount == 0)
+ emi_intr_clk.enable(&emi_intr_clk);
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_EMI_PODF_MASK;
+ reg |= (div - 1) << MXC_CCM_CBCDR_EMI_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ clk->rate = rate;
+
+ if (emi_fast_clk.usecount == 0)
+ emi_fast_clk.disable(&emi_fast_clk);
+ if (emi_intr_clk.usecount == 0)
+ emi_intr_clk.disable(&emi_intr_clk);
+
+ return 0;
+}
+
+static unsigned long _clk_emi_slow_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 div;
+
+ div = clk->parent->rate / rate;
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+ return clk->parent->rate / div;
+}
+
+
+static struct clk emi_slow_clk = {
+ .name = "emi_slow_clk",
+ .parent = &main_bus_clk,
+ .set_parent = _clk_emi_slow_set_parent,
+ .recalc = _clk_emi_slow_recalc,
+ .set_rate = _clk_emi_slow_set_rate,
+ .round_rate = _clk_emi_slow_round_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG8_OFFSET,
+ .disable = _clk_disable_inwait,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk ahbmux1_clk = {
+ .name = "ahbmux1_clk",
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGR0_CG8_OFFSET,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk ahbmux2_clk = {
+ .name = "ahbmux2_clk",
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &emi_intr_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGR0_CG9_OFFSET,
+ .disable = _clk_disable_inwait,
+};
+
+
+static struct clk emi_fast_clk = {
+ .name = "emi_fast_clk",
+ .parent = &ddr_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG7_OFFSET,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk emi_intr_clk = {
+ .name = "emi_intr_clk",
+ .parent = &ahb_clk,
+ .secondary = &ahbmux2_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG9_OFFSET,
+ .disable = _clk_disable_inwait,
+};
+
+static void _clk_ipg_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
+ MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+}
+
+static struct clk ipg_clk = {
+ .name = "ipg_clk",
+ .parent = &ahb_clk,
+ .recalc = _clk_ipg_recalc,
+ .flags = RATE_PROPAGATES,
+};
+
+static void _clk_ipg_per_recalc(struct clk *clk)
+{
+ u32 reg, prediv1, prediv2, podf;
+
+ if (clk->parent == &main_bus_clk || clk->parent == &lp_apm_clk) {
+ /* the main_bus_clk is the one before the DVFS engine */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ prediv1 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET) + 1;
+ prediv2 = ((reg & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >>
+ MXC_CCM_CBCDR_PERCLK_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / (prediv1 * prediv2 * podf);
+ } else if (clk->parent == &ipg_clk) {
+ clk->rate = ipg_clk.rate;
+ } else {
+ BUG();
+ }
+}
+
+static int _clk_ipg_per_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ mux = _get_mux(parent, &main_bus_clk, &lp_apm_clk, &ipg_clk, NULL);
+ if (mux == 2) {
+ reg |= MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
+ } else {
+ reg &= ~MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL;
+ if (mux == 0)
+ reg &= ~MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
+ else
+ reg |= MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL;
+ }
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk ipg_perclk = {
+ .name = "ipg_perclk",
+ .parent = &lp_apm_clk,
+ .recalc = _clk_ipg_per_recalc,
+ .set_parent = _clk_ipg_per_set_parent,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk aips_tz1_clk = {
+ .name = "aips_tz1_clk",
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGR0_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk aips_tz2_clk = {
+ .name = "aips_tz2_clk",
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGR0_CG13_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable_inwait,
+};
+
+static struct clk gpc_dvfs_clk = {
+ .name = "gpc_dvfs_clk",
+ .parent = &aips_tz1_clk,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static int _clk_sdma_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_enable(clk);
+
+ /* Handshake with SDMA when LPM is entered. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg &= ~MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+static void _clk_sdma_disable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_disable(clk);
+ /* No handshake with SDMA as its not enabled. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg |= MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+
+static struct clk sdma_clk[] = {
+ {
+ .name = "sdma_ahb_clk",
+ .parent = &ahb_clk,
+ .secondary = &emi_fast_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG15_OFFSET,
+ .enable = _clk_sdma_enable,
+ .disable = _clk_sdma_disable,
+ },
+ {
+ .name = "sdma_ipg_clk",
+ .parent = &ipg_clk,
+#ifdef CONFIG_SDMA_IRAM
+ .secondary = &emi_intr_clk,
+#endif
+ },
+};
+
+static int _clk_ipu_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_enable(clk);
+ /* Handshake with IPU when certain clock rates are changed. */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg &= ~MXC_CCM_CCDR_IPU_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ /* Handshake with IPU when LPM is entered as its enabled. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg &= ~MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+
+ return 0;
+}
+
+static void _clk_ipu_disable(struct clk *clk)
+{
+ u32 reg;
+ _clk_disable(clk);
+
+ /* No handshake with IPU whe dividers are changed
+ * as its not enabled. */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg |= MXC_CCM_CCDR_IPU_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ /* No handshake with IPU when LPM is entered as its not enabled. */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg |= MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+}
+
+
+static struct clk ipu_clk[] = {
+ {
+ .name = "ipu_clk",
+ .parent = &ahb_clk,
+ .secondary = &ipu_clk[1],
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG5_OFFSET,
+ .enable = _clk_ipu_enable,
+ .disable = _clk_ipu_disable,
+ },
+ {
+ .name = "ipu_sec_clk",
+ .parent = &emi_fast_clk,
+ .secondary = &ahbmux1_clk,
+ }
+};
+
+static int _clk_ipu_di_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ reg &= ~MXC_CCM_CSCMR2_DI_CLK_SEL_MASK;
+ if (parent == &pll3_sw_clk)
+ ;
+ else if (parent == &osc_clk)
+ reg |= 1 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET;
+ else if (parent == &ckih_clk)
+ reg |= 2 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET;
+ else if (parent == &tve_clk)
+ reg |= 3 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET;
+ else /* Assume any other clock is external clock pin */
+ reg |= 4 << MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static void _clk_ipu_di_recalc(struct clk *clk)
+{
+ u32 reg, div, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ mux = (reg & MXC_CCM_CSCMR2_DI_CLK_SEL_MASK) >>
+ MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET;
+ if (mux == 0) {
+ reg = __raw_readl(MXC_CCM_CDCDR) &
+ MXC_CCM_CDCDR_DI_CLK_PRED_MASK;
+ div = (reg >> MXC_CCM_CDCDR_DI_CLK_PRED_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+ } else if (mux == 3) {
+ clk->rate = clk->parent->rate / 8;
+ } else {
+ clk->rate = clk->parent->rate;
+ }
+}
+
+static struct clk ipu_di_clk = {
+ .name = "ipu_di_clk",
+ .parent = &pll3_sw_clk,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG6_OFFSET,
+ .recalc = _clk_ipu_di_recalc,
+ .set_parent = _clk_ipu_di_set_parent,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static int _clk_csi0_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, NULL);
+ reg = (reg & ~MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static void _clk_csi0_recalc(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR4);
+ pred = ((reg & MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / (pred * podf);
+}
+
+static unsigned long _clk_csi0_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 pre, post;
+ u32 div = clk->parent->rate / rate;
+ if (clk->parent->rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ return clk->parent->rate / (pre * post);
+}
+
+static int _clk_csi0_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 pre, post;
+
+ div = clk->parent->rate / rate;
+
+ if ((clk->parent->rate / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ /* Set CSI clock divider */
+ reg = __raw_readl(MXC_CCM_CSCDR4) &
+ ~(MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_MASK |
+ MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR4);
+
+ clk->rate = rate;
+ return 0;
+}
+
+static struct clk csi0_clk = {
+ .name = "csi_mclk1",
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_csi0_set_parent,
+ .recalc = _clk_csi0_recalc,
+ .round_rate = _clk_csi0_round_rate,
+ .set_rate = _clk_csi0_set_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGR6_CG2_OFFSET,
+ .disable = _clk_disable,
+};
+
+static int _clk_csi1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk, NULL);
+ reg = (reg & ~MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static void _clk_csi1_recalc(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR4);
+ pred = ((reg & MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / (pred * podf);
+}
+
+static unsigned long _clk_csi1_round_rate(struct clk *clk, unsigned long rate)
+{
+ u32 pre, post;
+ u32 div = clk->parent->rate / rate;
+ if (clk->parent->rate % rate)
+ div++;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ return clk->parent->rate / (pre * post);
+}
+
+static int _clk_csi1_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg;
+ u32 div;
+ u32 pre, post;
+
+ div = clk->parent->rate / rate;
+
+ if ((clk->parent->rate / div) != rate)
+ return -EINVAL;
+
+ __calc_pre_post_dividers(div, &pre, &post);
+
+ /* Set CSI clock divider */
+ reg = __raw_readl(MXC_CCM_CSCDR4) &
+ ~(MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_MASK |
+ MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_MASK);
+ reg |= (post - 1) << MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_OFFSET;
+ reg |= (pre - 1) << MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCDR4);
+
+ clk->rate = rate;
+ return 0;
+}
+
+static struct clk csi1_clk = {
+ .name = "csi_mclk2",
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_csi1_set_parent,
+ .recalc = _clk_csi1_recalc,
+ .round_rate = _clk_csi1_round_rate,
+ .set_rate = _clk_csi1_set_rate,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGR6_CG3_OFFSET,
+ .disable = _clk_disable,
+};
+
+
+static int _clk_hsc_enable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_enable(clk);
+ /* Handshake with IPU when certain clock rates are changed. */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg &= ~MXC_CCM_CCDR_HSC_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg &= ~MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+static void _clk_hsc_disable(struct clk *clk)
+{
+ u32 reg;
+
+ _clk_disable(clk);
+ /* No handshake with HSC as its not enabled. */
+ reg = __raw_readl(MXC_CCM_CCDR);
+ reg |= MXC_CCM_CCDR_IPU_HS_MASK;
+ __raw_writel(reg, MXC_CCM_CCDR);
+
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+}
+
+static struct clk mipi_esc_clk = {
+ .name = "mipi_esc_clk",
+ .parent = &pll2_sw_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG5_OFFSET,
+};
+
+static struct clk mipi_hsc2_clk = {
+ .name = "mipi_hsc2_clk",
+ .parent = &pll2_sw_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG4_OFFSET,
+ .secondary = &mipi_esc_clk,
+};
+
+static struct clk mipi_hsc1_clk = {
+ .name = "mipi_hsc1_clk",
+ .parent = &pll2_sw_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG3_OFFSET,
+ .secondary = &mipi_hsc2_clk,
+};
+
+static struct clk mipi_hsp_clk = {
+ .name = "mipi_hsp_clk",
+ .parent = &ipu_clk[0],
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG6_OFFSET,
+ .enable = _clk_hsc_enable,
+ .disable = _clk_hsc_disable,
+ .secondary = &mipi_hsc1_clk,
+};
+
+static int _clk_tve_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+
+ if (parent == &pll3_sw_clk) {
+ reg &= ~(MXC_CCM_CSCMR1_TVE_CLK_SEL);
+ } else if (parent == &osc_clk) {
+ reg |= MXC_CCM_CSCMR1_TVE_CLK_SEL;
+ reg &= MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL;
+ } else if (parent == &ckih_clk) {
+ reg |= MXC_CCM_CSCMR1_TVE_CLK_SEL;
+ reg |= MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL;
+ } else {
+ BUG();
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+ return 0;
+}
+
+static void _clk_tve_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if ((reg & MXC_CCM_CSCMR1_TVE_CLK_SEL) == 0) {
+ reg = __raw_readl(MXC_CCM_CDCDR) &
+ MXC_CCM_CDCDR_TVE_CLK_PRED_MASK;
+ div = (reg >> MXC_CCM_CDCDR_TVE_CLK_PRED_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+ } else {
+ clk->rate = clk->parent->rate;
+ }
+}
+
+static unsigned long _clk_tve_round_rate(struct clk *clk,
+ unsigned long rate)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (reg & MXC_CCM_CSCMR1_TVE_CLK_SEL)
+ return -EINVAL;
+
+ div = clk->parent->rate / rate;
+ if (div > 8)
+ div = 8;
+ else if (div == 0)
+ div++;
+ return clk->parent->rate / div;
+}
+
+static int _clk_tve_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (reg & MXC_CCM_CSCMR1_TVE_CLK_SEL)
+ return -EINVAL;
+
+ div = clk->parent->rate / rate;
+ if (div == 0)
+ div++;
+ if (((clk->parent->rate / div) != rate) || (div > 8))
+ return -EINVAL;
+
+ div--;
+ reg = __raw_readl(MXC_CCM_CDCDR) & ~MXC_CCM_CDCDR_TVE_CLK_PRED_MASK;
+ reg |= div << MXC_CCM_CDCDR_TVE_CLK_PRED_OFFSET;
+ __raw_writel(reg, MXC_CCM_CDCDR);
+ clk->rate = rate;
+ return 0;
+}
+
+static struct clk tve_clk = {
+ .name = "tve_clk",
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_tve_set_parent,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG15_OFFSET,
+ .recalc = _clk_tve_recalc,
+ .round_rate = _clk_tve_round_rate,
+ .set_rate = _clk_tve_set_rate,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static struct clk spba_clk = {
+ .name = "spba_clk",
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG0_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static void _clk_uart_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+}
+
+static int _clk_uart_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_UART_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk uart_main_clk = {
+ .name = "uart_main_clk",
+ .parent = &pll2_sw_clk,
+ .recalc = _clk_uart_recalc,
+ .set_parent = _clk_uart_set_parent,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk uart1_clk[] = {
+ {
+ .name = "uart_clk",
+ .id = 0,
+ .parent = &uart_main_clk,
+ .secondary = &uart1_clk[1],
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG4_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "uart_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &aips_tz1_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG3_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk uart2_clk[] = {
+ {
+ .name = "uart_clk",
+ .id = 1,
+ .parent = &uart_main_clk,
+ .secondary = &uart2_clk[1],
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "uart_ipg_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .secondary = &aips_tz1_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG5_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk uart3_clk[] = {
+ {
+ .name = "uart_clk",
+ .id = 2,
+ .parent = &uart_main_clk,
+ .secondary = &uart3_clk[1],
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "uart_ipg_clk",
+ .id = 2,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk gpt_clk[] = {
+ {
+ .name = "gpt_clk",
+ .parent = &ipg_perclk,
+ .id = 0,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &gpt_clk[1],
+ },
+ {
+ .name = "gpt_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "gpt_32k_clk",
+ .id = 0,
+ .parent = &ckil_clk,
+ },
+};
+
+static struct clk pwm1_clk[] = {
+ {
+ .name = "pwm_clk",
+ .parent = &ipg_perclk,
+ .id = 0,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG6_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &pwm1_clk[1],
+ },
+ {
+ .name = "pwm_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG5_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "pwm_32k_clk",
+ .id = 0,
+ .parent = &ckil_clk,
+ },
+};
+
+static struct clk pwm2_clk[] = {
+ {
+ .name = "pwm_clk",
+ .parent = &ipg_perclk,
+ .id = 1,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &pwm2_clk[1],
+ },
+ {
+ .name = "pwm_ipg_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "pwm_32k_clk",
+ .id = 1,
+ .parent = &ckil_clk,
+ },
+};
+
+static struct clk i2c_clk[] = {
+ {
+ .name = "i2c_clk",
+ .id = 0,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "i2c_clk",
+ .id = 1,
+ .parent = &ipg_perclk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static void _clk_hsi2c_serial_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR3);
+ prediv = ((reg & MXC_CCM_CSCDR3_HSI2C_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR3_HSI2C_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR3_HSI2C_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR3_HSI2C_CLK_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+}
+
+static struct clk hsi2c_serial_clk = {
+ .name = "hsi2c_serial_clk",
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG11_OFFSET,
+ .recalc = _clk_hsi2c_serial_recalc,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static struct clk hsi2c_clk = {
+ .name = "hsi2c_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static void _clk_cspi_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR2);
+ prediv = ((reg & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+}
+
+static int _clk_cspi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk cspi_main_clk = {
+ .name = "cspi_main_clk",
+ .parent = &pll3_sw_clk,
+ .recalc = _clk_cspi_recalc,
+ .set_parent = _clk_cspi_set_parent,
+ .flags = RATE_PROPAGATES,
+};
+
+static struct clk cspi1_clk[] = {
+ {
+ .name = "cspi_clk",
+ .id = 0,
+ .parent = &cspi_main_clk,
+ .secondary = &cspi1_clk[1],
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "cspi_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk cspi2_clk[] = {
+ {
+ .name = "cspi_clk",
+ .id = 1,
+ .parent = &cspi_main_clk,
+ .secondary = &cspi2_clk[1],
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG12_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "cspi_ipg_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .secondary = &aips_tz2_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG11_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+};
+
+static struct clk cspi3_clk[] = {
+ {
+ .name = "cspi_clk",
+ .id = 2,
+ .parent = &cspi_main_clk,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG13_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ .secondary = &cspi3_clk[1],
+ },
+ {
+ .name = "cspi_ipg_clk",
+ .id = 2,
+ .parent = &ipg_clk,
+ .secondary = &aips_tz2_clk,
+ },
+};
+
+static int _clk_ssi_lp_apm_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &ckih_clk, &lp_apm_clk, &ckih2_clk, NULL);
+ reg = __raw_readl(MXC_CCM_CSCMR1) &
+ ~MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi_lp_apm_clk = {
+ .name = "ssi_lp_apm_clk",
+ .parent = &ckih_clk,
+ .set_parent = _clk_ssi_lp_apm_set_parent,
+};
+
+static void _clk_ssi1_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ prediv = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK) >>
+ MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK) >>
+ MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+}
+static int _clk_ssi1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk,
+ &pll3_sw_clk, &ssi_lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi1_clk[] = {
+ {
+ .name = "ssi_clk",
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ssi1_set_parent,
+ .secondary = &ssi1_clk[1],
+ .recalc = _clk_ssi1_recalc,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG9_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "ssi_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &ssi1_clk[2],
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG8_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "ssi_dep_clk",
+ .id = 0,
+ .parent = &aips_tz2_clk,
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+ .secondary = &emi_intr_clk,
+#else
+ .secondary = &emi_fast_clk,
+#endif
+ },
+};
+
+static void _clk_ssi2_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+ prediv = ((reg & MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK) >>
+ MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK) >>
+ MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+}
+
+static int _clk_ssi2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk,
+ &pll3_sw_clk, &ssi_lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi2_clk[] = {
+ {
+ .name = "ssi_clk",
+ .id = 1,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ssi2_set_parent,
+ .secondary = &ssi2_clk[1],
+ .recalc = _clk_ssi2_recalc,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG11_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "ssi_ipg_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .secondary = &ssi2_clk[2],
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG10_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "ssi_dep_clk",
+ .id = 1,
+ .parent = &spba_clk,
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+ .secondary = &emi_intr_clk,
+#else
+ .secondary = &emi_fast_clk,
+#endif
+ },
+};
+
+static void _clk_ssi_ext1_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ clk->rate = clk->parent->rate;
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if ((reg & MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL) == 0) {
+ reg = __raw_readl(MXC_CCM_CS1CDR);
+ prediv = ((reg & MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK) >>
+ MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK) >>
+ MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / (prediv * podf);
+ }
+}
+
+static int _clk_ssi_ext1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &ssi1_clk[0]) {
+ reg |= MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL;
+ } else {
+ reg &= ~MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL;
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &ssi_lp_apm_clk);
+ reg = (reg & ~MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET);
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi_ext1_clk = {
+ .name = "ssi_ext1_clk",
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ssi_ext1_set_parent,
+ .recalc = _clk_ssi_ext1_recalc,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG14_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static void _clk_ssi_ext2_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ clk->rate = clk->parent->rate;
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if ((reg & MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL) == 0) {
+ reg = __raw_readl(MXC_CCM_CS2CDR);
+ prediv = ((reg & MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_MASK) >>
+ MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_MASK) >>
+ MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / (prediv * podf);
+ }
+}
+
+static int _clk_ssi_ext2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &ssi2_clk[0]) {
+ reg |= MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL;
+ } else {
+ reg &= ~MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL;
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &ssi_lp_apm_clk);
+ reg = (reg & ~MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET);
+ }
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk ssi_ext2_clk = {
+ .name = "ssi_ext2_clk",
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_ssi_ext2_set_parent,
+ .recalc = _clk_ssi_ext2_recalc,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG15_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+};
+
+static struct clk iim_clk = {
+ .name = "iim_clk",
+ .parent = &ipg_clk,
+ .secondary = &aips_tz2_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGR0_CG15_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk tmax1_clk = {
+ .name = "tmax1_clk",
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG0_OFFSET,
+ .disable = _clk_disable,
+ };
+
+static struct clk tmax2_clk = {
+ .name = "tmax2_clk",
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG1_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk tmax3_clk = {
+ .name = "tmax3_clk",
+ .id = 0,
+ .parent = &ahb_clk,
+ .secondary = &ahb_max_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR1,
+ .enable_shift = MXC_CCM_CCGR1_CG2_OFFSET,
+ .disable = _clk_disable,
+};
+
+static void _clk_usboh3_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET) + 1;
+ if (prediv == 1)
+ BUG();
+ podf = ((reg & MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+}
+
+static int _clk_usboh3_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk usboh3_clk[] = {
+ {
+ .name = "usboh3_clk",
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_usboh3_set_parent,
+ .recalc = _clk_usboh3_recalc,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG14_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &usboh3_clk[1],
+ },
+ {
+ .name = "usb_ahb_clk",
+ .parent = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG13_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &usboh3_clk[2],
+ },
+ {
+ .name = "usb_sec_clk",
+ .parent = &tmax2_clk,
+ .secondary = &emi_fast_clk,
+ },
+};
+
+static void _clk_usb_phy_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ if (clk->parent == &pll3_sw_clk) {
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ prediv = ((reg & MXC_CCM_CDCDR_USB_PHY_PRED_MASK) >>
+ MXC_CCM_CDCDR_USB_PHY_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CDCDR_USB_PHY_PODF_MASK) >>
+ MXC_CCM_CDCDR_USB_PHY_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+ } else
+ clk->rate = clk->parent->rate;
+}
+
+static int _clk_usb_phy_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &osc_clk)
+ reg &= ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL;
+ else if (parent == &pll3_sw_clk)
+ reg |= MXC_CCM_CSCMR1_USB_PHY_CLK_SEL;
+ else
+ BUG();
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+ return 0;
+}
+
+static struct clk usb_phy_clk = {
+ .name = "usb_phy_clk",
+ .parent = &pll3_sw_clk,
+ .secondary = &tmax3_clk,
+ .set_parent = _clk_usb_phy_set_parent,
+ .recalc = _clk_usb_phy_recalc,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG0_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk esdhc_dep_clks = {
+ .name = "sd_dep_clk",
+ .parent = &spba_clk,
+ .secondary = &emi_fast_clk,
+};
+
+
+static void _clk_esdhc1_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+}
+
+static int _clk_esdhc1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) &
+ ~MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk esdhc1_clk[] = {
+ {
+ .name = "esdhc_clk",
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_esdhc1_set_parent,
+ .recalc = _clk_esdhc1_recalc,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG1_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc1_clk[1],
+ },
+ {
+ .name = "esdhc_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &esdhc1_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG0_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "esdhc_sec_clk",
+ .id = 0,
+ .parent = &tmax3_clk,
+ .secondary = &esdhc_dep_clks,
+ },
+
+};
+
+static void _clk_esdhc2_recalc(struct clk *clk)
+{
+ u32 reg, prediv, podf;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ prediv = ((reg & MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET) + 1;
+
+ clk->rate = clk->parent->rate / (prediv * podf);
+}
+
+static int _clk_esdhc2_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &lp_apm_clk);
+ reg = __raw_readl(MXC_CCM_CSCMR1) &
+ ~MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk esdhc2_clk[] = {
+ {
+ .name = "esdhc_clk",
+ .id = 1,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_esdhc2_set_parent,
+ .recalc = _clk_esdhc2_recalc,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG3_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc2_clk[1],
+ },
+ {
+ .name = "esdhc_ipg_clk",
+ .id = 1,
+ .parent = &ipg_clk,
+ .secondary = &esdhc2_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG2_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "esdhc_sec_clk",
+ .id = 0,
+ .parent = &tmax2_clk,
+ .secondary = &esdhc_dep_clks,
+ },
+};
+
+static int _clk_esdhc3_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk[0])
+ reg &= ~MXC_CCM_CSCMR1_ESDHC3_CLK_SEL;
+ else if (parent == &esdhc2_clk[0])
+ reg |= MXC_CCM_CSCMR1_ESDHC3_CLK_SEL;
+ else
+ BUG();
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk esdhc3_clk[] = {
+ {
+ .name = "esdhc_clk",
+ .id = 2,
+ .parent = &esdhc1_clk[0],
+ .set_parent = _clk_esdhc3_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG5_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc3_clk[1],
+ },
+ {
+ .name = "esdhc_ipg_clk",
+ .id = 2,
+ .parent = &ipg_clk,
+ .secondary = &esdhc3_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG4_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "esdhc_sec_clk",
+ .id = 0,
+ .parent = &ahb_max_clk,
+ .secondary = &esdhc_dep_clks,
+ },
+};
+
+
+static int _clk_esdhc4_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg;
+
+ reg = __raw_readl(MXC_CCM_CSCMR1);
+ if (parent == &esdhc1_clk[0])
+ reg &= ~MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ else if (parent == &esdhc2_clk[0])
+ reg |= MXC_CCM_CSCMR1_ESDHC4_CLK_SEL;
+ else
+ BUG();
+
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk esdhc4_clk[] = {
+ {
+ .name = "esdhc_clk",
+ .id = 3,
+ .parent = &esdhc1_clk[0],
+ .set_parent = _clk_esdhc4_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG7_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &esdhc3_clk[1],
+ },
+ {
+ .name = "esdhc_ipg_clk",
+ .id = 3,
+ .parent = &ipg_clk,
+ .secondary = &esdhc3_clk[2],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR3,
+ .enable_shift = MXC_CCM_CCGR3_CG6_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "esdhc_sec_clk",
+ .id = 0,
+ .parent = &tmax3_clk,
+ .secondary = &esdhc_dep_clks,
+ },
+};
+
+static void _clk_nfc_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ div = ((reg & MXC_CCM_CBCDR_NFC_PODF_MASK) >>
+ MXC_CCM_CBCDR_NFC_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / div;
+}
+
+static struct clk emi_enfc_clk = {
+ .name = "nfc_clk",
+ .parent = &emi_slow_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG10_OFFSET,
+ .disable = _clk_disable_inwait,
+ .recalc = _clk_nfc_recalc,
+};
+
+static int _clk_spdif_xtal_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ mux = _get_mux(parent, &osc_clk, &ckih_clk, &ckih2_clk, NULL);
+ reg = __raw_readl(MXC_CCM_CSCMR1) & ~MXC_CCM_CSCMR1_SPDIF_CLK_SEL_MASK;
+ reg |= mux << MXC_CCM_CSCMR1_SPDIF_CLK_SEL_OFFSET;
+ __raw_writel(reg, MXC_CCM_CSCMR1);
+
+ return 0;
+}
+
+static struct clk spdif_xtal_clk = {
+ .name = "spdif_xtal_clk",
+ .parent = &osc_clk,
+ .set_parent = _clk_spdif_xtal_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG15_OFFSET,
+ .disable = _clk_disable,
+};
+
+static int _clk_spdif0_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ reg |= MXC_CCM_CSCMR2_SPDIF0_COM;
+ if (parent != &ssi1_clk[0]) {
+ reg &= ~MXC_CCM_CSCMR2_SPDIF0_COM;
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &spdif_xtal_clk);
+ reg = (reg & ~MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_OFFSET);
+ }
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static void _clk_spdif0_recalc(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ if (clk->parent == &ssi1_clk[0]) {
+ clk->rate = clk->parent->rate;
+ } else {
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ pred = ((reg & MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK) >>
+ MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK) >>
+ MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / (pred * podf);
+ }
+}
+
+static struct clk spdif0_clk[] = {
+ {
+ .name = "spdif_clk",
+ .id = 0,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_spdif0_set_parent,
+ .recalc = _clk_spdif0_recalc,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG13_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "spdif_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG15_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static int _clk_spdif1_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CSCMR2);
+ reg |= MXC_CCM_CSCMR2_SPDIF1_COM;
+ if (parent != &ssi2_clk[0]) {
+ reg &= ~MXC_CCM_CSCMR2_SPDIF1_COM;
+ mux = _get_mux(parent, &pll1_sw_clk, &pll2_sw_clk, &pll3_sw_clk,
+ &spdif_xtal_clk);
+ reg = (reg & ~MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_OFFSET);
+ }
+ __raw_writel(reg, MXC_CCM_CSCMR2);
+
+ return 0;
+}
+
+static void _clk_spdif1_recalc(struct clk *clk)
+{
+ u32 reg, pred, podf;
+
+ if (clk->parent == &ssi2_clk[0]) {
+ clk->rate = clk->parent->rate;
+ } else {
+ reg = __raw_readl(MXC_CCM_CDCDR);
+ pred = ((reg & MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK) >>
+ MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET) + 1;
+ podf = ((reg & MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK) >>
+ MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET) + 1;
+ clk->rate = clk->parent->rate / (pred * podf);
+ }
+}
+
+static struct clk spdif1_clk[] = {
+ {
+ .name = "spdif_clk",
+ .id = 1,
+ .parent = &pll3_sw_clk,
+ .set_parent = _clk_spdif1_set_parent,
+ .recalc = _clk_spdif1_recalc,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG14_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "spdif_ipg_clk",
+ .id = 0,
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG15_OFFSET,
+ .disable = _clk_disable,
+ },
+};
+
+static int _clk_ddr_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, reg2, mux;
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ reg2 = __raw_readl(MXC_CCM_CBCDR);
+ mux = _get_mux_ddr(parent, &axi_a_clk, &axi_b_clk, &emi_slow_clk, &ahb_clk, &ddr_hf_clk);
+ if (mux < 4) {
+ reg = (reg & ~MXC_CCM_CBCMR_DDR_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+ } else {
+ reg2 = (reg2 & ~MXC_CCM_CBCDR_DDR_HF_SEL) |
+ (MXC_CCM_CBCDR_DDR_HF_SEL);
+ __raw_writel(reg2, MXC_CCM_CBCDR);
+ }
+
+ return 0;
+}
+
+static struct clk ddr_clk = {
+ .name = "ddr_clk",
+ .parent = &ddr_hf_clk,
+ .set_parent = _clk_ddr_set_parent,
+ .flags = RATE_PROPAGATES,
+};
+
+static int _clk_arm_axi_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &emi_slow_clk, &ahb_clk);
+ reg = (reg & ~MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk arm_axi_clk = {
+ .name = "arm_axi_clk",
+ .parent = &axi_a_clk,
+ .set_parent = _clk_arm_axi_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR0,
+ .enable_shift = MXC_CCM_CCGR0_CG1_OFFSET,
+ .disable = _clk_disable,
+};
+
+static int _clk_vpu_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &emi_slow_clk, &ahb_clk);
+ reg = (reg & ~MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk vpu_clk[] = {
+ {
+ .name = "vpu_clk",
+ .set_parent = _clk_vpu_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG4_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &vpu_clk[1],
+ },
+ {
+ .name = "vpu_core_clk",
+ .set_parent = _clk_vpu_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG3_OFFSET,
+ .disable = _clk_disable,
+ .secondary = &vpu_clk[2],
+ },
+ {
+ .name = "vpu_emi_clk",
+ .parent = &emi_fast_clk,
+#ifdef CONFIG_MXC_VPU_IRAM
+ .secondary = &emi_intr_clk,
+#endif
+ }
+};
+
+static int _clk_lpsr_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ mux = _get_mux(parent, &ckil_clk, &fpm_clk, &fpm_div2_clk, NULL);
+ reg = (reg & ~MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ return 0;
+}
+
+static struct clk lpsr_clk = {
+ .name = "lpsr_clk",
+ .parent = &ckil_clk,
+ .set_parent = _clk_lpsr_set_parent,
+};
+
+static void _clk_pgc_recalc(struct clk *clk)
+{
+ u32 reg, div;
+
+ reg = __raw_readl(MXC_CCM_CSCDR1);
+ div = (reg & MXC_CCM_CSCDR1_PGC_CLK_PODF_MASK) >>
+ MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET;
+ div = 1 >> div;
+ clk->rate = clk->parent->rate / div;
+}
+
+static struct clk pgc_clk = {
+ .name = "pgc_clk",
+ .parent = &ipg_clk,
+ .recalc = _clk_pgc_recalc,
+};
+
+/*usb OTG clock */
+
+static struct clk usb_clk = {
+ .name = "usb_clk",
+ .rate = 60000000,
+};
+
+static struct clk usb_utmi_clk = {
+ .name = "usb_utmi_clk",
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CSCMR1,
+ .enable_shift = MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk rtc_clk = {
+ .name = "rtc_clk",
+ .parent = &ckil_clk,
+ .secondary = &ipg_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG14_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk ata_clk = {
+ .name = "ata_clk",
+ .parent = &ipg_clk,
+ .secondary = &spba_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG0_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk owire_clk = {
+ .name = "owire_clk",
+ .parent = &ipg_perclk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG11_OFFSET,
+ .disable = _clk_disable,
+};
+
+
+static struct clk fec_clk[] = {
+ {
+ .name = "fec_clk",
+ .parent = &ipg_clk,
+ .secondary = &fec_clk[1],
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR2,
+ .enable_shift = MXC_CCM_CCGR2_CG12_OFFSET,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "fec_sec1_clk",
+ .parent = &tmax2_clk,
+ .secondary = &fec_clk[2],
+ },
+ {
+ .name = "fec_sec2_clk",
+ .parent = &aips_tz2_clk,
+ .secondary = &emi_fast_clk,
+ },
+};
+
+static struct clk sahara_clk[] = {
+ {
+ .name = "sahara_clk",
+ .parent = &ahb_clk,
+ .secondary = &sahara_clk[1],
+ .enable_reg = MXC_CCM_CCGR4,
+ .enable_shift = MXC_CCM_CCGR4_CG7_OFFSET,
+ .enable = _clk_enable,
+ .disable = _clk_disable,
+ },
+ {
+ .name = "sahara_sec_clk",
+ .parent = &tmax1_clk,
+ .secondary = &emi_fast_clk,
+ }
+};
+
+static int _clk_gpu3d_set_parent(struct clk *clk, struct clk *parent)
+{
+ u32 reg, mux;
+
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ mux = _get_mux(parent, &axi_a_clk, &axi_b_clk, &emi_slow_clk, &ahb_clk);
+ reg = (reg & ~MXC_CCM_CBCMR_GPU_CLK_SEL_MASK) |
+ (mux << MXC_CCM_CBCMR_GPU_CLK_SEL_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCMR);
+
+ return 0;
+}
+
+static struct clk gpu3d_clk = {
+ .name = "gpu3d_clk",
+ .parent = &axi_a_clk,
+ .set_parent = _clk_gpu3d_set_parent,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG1_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk garb_clk = {
+ .name = "garb_clk",
+ .parent = &axi_a_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR5,
+ .enable_shift = MXC_CCM_CCGR5_CG2_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk emi_garb_clk = {
+ .name = "emi_garb_clk",
+ .parent = &axi_a_clk,
+ .enable = _clk_enable,
+ .enable_reg = MXC_CCM_CCGR6,
+ .enable_shift = MXC_CCM_CCGR6_CG4_OFFSET,
+ .disable = _clk_disable,
+};
+
+static struct clk *mxc_clks[] = {
+ &osc_clk,
+ &ckih_clk,
+ &ckih2_clk,
+ &ckil_clk,
+ &fpm_clk,
+ &fpm_div2_clk,
+ &pll1_main_clk,
+ &pll1_sw_clk,
+ &pll2_sw_clk,
+ &pll3_sw_clk,
+ &gpc_dvfs_clk,
+ &lp_apm_clk,
+ &cpu_clk,
+ &periph_apm_clk,
+ &main_bus_clk,
+ &axi_a_clk,
+ &axi_b_clk,
+ &ahb_clk,
+ &ahb_max_clk,
+ &ipg_clk,
+ &ipg_perclk,
+ &ahbmux1_clk,
+ &ahbmux2_clk,
+ &aips_tz1_clk,
+ &aips_tz2_clk,
+ &sdma_clk[0],
+ &sdma_clk[1],
+ &ipu_clk[0],
+ &ipu_clk[1],
+ &ipu_di_clk,
+ &tve_clk,
+ &csi0_clk,
+ &csi1_clk,
+ &uart_main_clk,
+ &uart1_clk[0],
+ &uart1_clk[1],
+ &uart2_clk[0],
+ &uart2_clk[1],
+ &uart3_clk[0],
+ &uart3_clk[1],
+ &spba_clk,
+ &i2c_clk[0],
+ &i2c_clk[1],
+ &hsi2c_clk,
+ &hsi2c_serial_clk,
+ &gpt_clk[0],
+ &gpt_clk[1],
+ &gpt_clk[2],
+ &pwm1_clk[0],
+ &pwm1_clk[1],
+ &pwm1_clk[2],
+ &pwm2_clk[0],
+ &pwm2_clk[1],
+ &pwm2_clk[2],
+ &cspi_main_clk,
+ &cspi1_clk[0],
+ &cspi1_clk[1],
+ &cspi2_clk[0],
+ &cspi2_clk[1],
+ &cspi3_clk[0],
+ &cspi3_clk[1],
+ &ssi_lp_apm_clk,
+ &ssi1_clk[0],
+ &ssi1_clk[1],
+ &ssi1_clk[2],
+ &ssi2_clk[0],
+ &ssi2_clk[1],
+ &ssi2_clk[2],
+ &ssi_ext1_clk,
+ &ssi_ext2_clk,
+ &iim_clk,
+ &tmax1_clk,
+ &tmax2_clk,
+ &tmax3_clk,
+ &usboh3_clk[0],
+ &usboh3_clk[1],
+ &usboh3_clk[2],
+ &usb_phy_clk,
+ &usb_utmi_clk,
+ &usb_clk,
+ &esdhc1_clk[0],
+ &esdhc1_clk[1],
+ &esdhc2_clk[0],
+ &esdhc2_clk[1],
+ &esdhc3_clk[0],
+ &esdhc3_clk[1],
+ &esdhc4_clk[0],
+ &esdhc4_clk[1],
+ &esdhc_dep_clks,
+ &emi_slow_clk,
+ &ddr_clk,
+ &emi_enfc_clk,
+ &emi_fast_clk,
+ &emi_intr_clk,
+ &spdif_xtal_clk,
+ &spdif0_clk[0],
+ &spdif0_clk[1],
+ &spdif1_clk[0],
+ &spdif1_clk[1],
+ &arm_axi_clk,
+ &vpu_clk[0],
+ &vpu_clk[1],
+ &vpu_clk[2],
+ &lpsr_clk,
+ &pgc_clk,
+ &rtc_clk,
+ &ata_clk,
+ &owire_clk,
+ &fec_clk[0],
+ &fec_clk[1],
+ &fec_clk[2],
+ &mipi_hsc1_clk,
+ &mipi_hsc2_clk,
+ &mipi_esc_clk,
+ &mipi_hsp_clk,
+ &sahara_clk[0],
+ &sahara_clk[1],
+ &gpu3d_clk,
+ &garb_clk,
+ &emi_garb_clk,
+ &ddr_hf_clk,
+};
+
+static void clk_tree_init(void)
+{
+ u32 reg, reg2, dp_ctl;
+
+ ipg_perclk.set_parent(&ipg_perclk, &lp_apm_clk);
+
+ /*
+ *Initialise the IPG PER CLK dividers to 3. IPG_PER_CLK should be at
+ * 8MHz, its derived from lp_apm.
+ */
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ reg &= ~MXC_CCM_CBCDR_PERCLK_PRED1_MASK;
+ reg &= ~MXC_CCM_CBCDR_PERCLK_PRED2_MASK;
+ reg &= ~MXC_CCM_CBCDR_PERCLK_PODF_MASK;
+ reg |= (2 << MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET);
+ __raw_writel(reg, MXC_CCM_CBCDR);
+
+ /* set pll1_main_clk parent */
+ pll1_main_clk.parent = &osc_clk;
+ dp_ctl = __raw_readl(pll_base[0] + MXC_PLL_DP_CTL);
+ if ((dp_ctl & MXC_PLL_DP_CTL_REF_CLK_SEL_MASK) == 0)
+ pll1_main_clk.parent = &fpm_clk;
+ /* set pll2_sw_clk parent */
+ pll2_sw_clk.parent = &osc_clk;
+ dp_ctl = __raw_readl(pll_base[1] + MXC_PLL_DP_CTL);
+ if ((dp_ctl & MXC_PLL_DP_CTL_REF_CLK_SEL_MASK) == 0)
+ pll2_sw_clk.parent = &fpm_clk;
+ /* set pll3_clk parent */
+ pll3_sw_clk.parent = &osc_clk;
+ dp_ctl = __raw_readl(pll_base[2] + MXC_PLL_DP_CTL);
+ if ((dp_ctl & MXC_PLL_DP_CTL_REF_CLK_SEL_MASK) == 0)
+ pll3_sw_clk.parent = &fpm_clk;
+
+ /* set emi_slow_clk parent */
+ emi_slow_clk.parent = &main_bus_clk;
+ reg = __raw_readl(MXC_CCM_CBCDR);
+ if ((reg & MXC_CCM_CBCDR_EMI_CLK_SEL) != 0)
+ emi_slow_clk.parent = &ahb_clk;
+
+ /* set ipg_perclk parent */
+ ipg_perclk.parent = &lp_apm_clk;
+ reg = __raw_readl(MXC_CCM_CBCMR);
+ if ((reg & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) != 0) {
+ ipg_perclk.parent = &ipg_clk;
+ } else {
+ if ((reg & MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL) == 0)
+ ipg_perclk.parent = &main_bus_clk;
+ }
+
+ /* set DDR clock parent */
+ reg = __raw_readl(MXC_CCM_CBCMR) & MXC_CCM_CBCMR_DDR_CLK_SEL_MASK;
+ reg >>= MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET;
+ reg2 = __raw_readl(MXC_CCM_CBCDR) & MXC_CCM_CBCDR_DDR_HF_SEL;
+ reg2 >>= MXC_CCM_CBCDR_DDR_HF_SEL_OFFSET;
+
+ if (reg2) {
+ ddr_clk.parent = &ddr_hf_clk;
+ } else {
+ if (reg == 0) {
+ ddr_clk.parent = &axi_a_clk;
+ } else if (reg == 1) {
+ ddr_clk.parent = &axi_b_clk;
+ } else if (reg == 2) {
+ ddr_clk.parent = &emi_slow_clk;
+ } else {
+ ddr_clk.parent = &ahb_clk;
+ }
+ }
+}
+
+int __init mxc_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2)
+{
+ struct clk **clkp;
+ int i, reg;
+
+ ckil_clk.rate = ckil;
+ osc_clk.rate = osc;
+ ckih_clk.rate = ckih1;
+ ckih2_clk.rate = ckih2;
+
+ clk_tree_init();
+
+ for (clkp = mxc_clks; clkp < mxc_clks + ARRAY_SIZE(mxc_clks); clkp++)
+ clk_register(*clkp);
+
+ /* Turn off all possible clocks */
+ if (mxc_jtag_enabled) {
+ __raw_writel(1 << MXC_CCM_CCGR0_CG0_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG1_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG2_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG3_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG4_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG8_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG9_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG12_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG13_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG14_OFFSET, MXC_CCM_CCGR0);
+ } else {
+ __raw_writel(1 << MXC_CCM_CCGR0_CG0_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG1_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG2_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG3_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG8_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG9_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG12_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG13_OFFSET |
+ 1 << MXC_CCM_CCGR0_CG14_OFFSET, MXC_CCM_CCGR0);
+ }
+ __raw_writel(0, MXC_CCM_CCGR1);
+ __raw_writel(0, MXC_CCM_CCGR2);
+ __raw_writel(0, MXC_CCM_CCGR3);
+ __raw_writel(3 << MXC_CCM_CCGR4_CG8_OFFSET, MXC_CCM_CCGR4);
+ __raw_writel(1 << MXC_CCM_CCGR5_CG2_OFFSET |
+ 1 << MXC_CCM_CCGR5_CG7_OFFSET |
+ 1 << MXC_CCM_CCGR5_CG8_OFFSET |
+ 1 << MXC_CCM_CCGR5_CG9_OFFSET |
+ 1 << MXC_CCM_CCGR5_CG10_OFFSET |
+ 3 << MXC_CCM_CCGR5_CG11_OFFSET, MXC_CCM_CCGR5);
+ __raw_writel(1 << MXC_CCM_CCGR6_CG4_OFFSET, MXC_CCM_CCGR6);
+
+ /*Setup the LPM bypass bits */
+ reg = __raw_readl(MXC_CCM_CLPCR);
+ reg |= MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS
+ | MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS
+ | MXC_CCM_CLPCR_BYPASS_RTIC_LPM_HS
+ | MXC_CCM_CLPCR_BYPASS_SCC_LPM_HS
+ | MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS;
+ __raw_writel(reg, MXC_CCM_CLPCR);
+
+ /* This will propagate to all children and init all the clock rates */
+ propagate_rate(&osc_clk);
+ propagate_rate(&ckih_clk);
+ propagate_rate(&ckih2_clk);
+ propagate_rate(&ckil_clk);
+ propagate_rate(&pll1_sw_clk);
+ propagate_rate(&pll2_sw_clk);
+
+ clk_enable(&cpu_clk);
+ clk_enable(&main_bus_clk);
+
+ reg = __raw_readl(MXC_CCM_CBCDR) & MXC_CCM_CBCDR_DDR_HF_SEL;
+ reg >>= MXC_CCM_CBCDR_DDR_HF_SEL_OFFSET;
+
+ if (reg)
+ clk_set_parent(&ddr_clk, &ddr_hf_clk);
+ else
+ clk_set_parent(&ddr_clk, &axi_a_clk);
+
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) {
+ clk_set_parent(&vpu_clk[0], &ahb_clk);
+ clk_set_parent(&vpu_clk[1], &ahb_clk);
+ } else {
+ clk_set_parent(&vpu_clk[0], &axi_a_clk);
+ clk_set_parent(&vpu_clk[1], &axi_a_clk);
+ }
+
+ /* Set the current working point. */
+ cpu_wp_tbl = get_cpu_wp(&cpu_wp_nr);
+ for (i = 0; i < cpu_wp_nr; i++) {
+ if (clk_get_rate(&cpu_clk) == cpu_wp_tbl[i].cpu_rate) {
+ cpu_curr_wp = i;
+ break;
+ }
+ }
+ if (i > cpu_wp_nr)
+ BUG();
+
+ return 0;
+}
+
+/*!
+ * Setup cpu clock based on working point.
+ * @param wp cpu freq working point
+ * @return 0 on success or error code on failure.
+ */
+static int cpu_clk_set_wp(int wp)
+{
+ struct cpu_wp *p;
+ u32 reg;
+ u32 stat;
+
+ if (wp == cpu_curr_wp)
+ return 0;
+
+ p = &cpu_wp_tbl[wp];
+
+ /*
+ * If DDR clock is sourced from PLL1, we cannot drop PLL1 freq.
+ * Use the ARM_PODF to change the freq of the core, leave the PLL1
+ * freq unchanged.
+ */
+ if (ddr_clk.parent == &ddr_hf_clk) {
+ reg = __raw_readl(MXC_CCM_CACRR);
+ reg &= ~MXC_CCM_CACRR_ARM_PODF_MASK;
+ reg |= cpu_wp_tbl[wp].cpu_podf << MXC_CCM_CACRR_ARM_PODF_OFFSET;
+ __raw_writel(reg, MXC_CCM_CACRR);
+ cpu_curr_wp = wp;
+ cpu_clk.rate = cpu_wp_tbl[wp].cpu_rate;
+ } else {
+ /* Change the ARM clock to requested frequency */
+ /* First move the ARM clock to step clock which is running
+ * at 24MHz.
+ */
+
+ /* Change the source of pll1_sw_clk to be the step_clk */
+ reg = __raw_readl(MXC_CCM_CCSR);
+ reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ /* Stop the PLL */
+ reg = __raw_readl(MXC_DPLL1_BASE + MXC_PLL_DP_CTL);
+ reg &= ~MXC_PLL_DP_CTL_UPEN;
+ __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_CTL);
+
+ /* PDF and MFI */
+ reg = p->pdf | p->mfi << MXC_PLL_DP_OP_MFI_OFFSET;
+ __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_OP);
+
+ /* MFD */
+ __raw_writel(p->mfd, MXC_DPLL1_BASE + MXC_PLL_DP_MFD);
+
+ /* MFI */
+ __raw_writel(p->mfn, MXC_DPLL1_BASE + MXC_PLL_DP_MFN);
+
+ reg = __raw_readl(MXC_DPLL1_BASE + MXC_PLL_DP_CTL);
+ reg |= MXC_PLL_DP_CTL_UPEN;
+ /* Set the UPEN bits */
+ __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_CTL);
+ /* Forcefully restart the PLL */
+ reg |= MXC_PLL_DP_CTL_RST;
+ __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_CTL);
+
+ /* Wait for the PLL to lock */
+ do {
+ stat = __raw_readl(MXC_DPLL1_BASE + MXC_PLL_DP_CTL) &
+ MXC_PLL_DP_CTL_LRF;
+ } while (!stat);
+
+ reg = __raw_readl(MXC_CCM_CCSR);
+ /* Move the PLL1 back to the pll1_main_clk */
+ reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL;
+ __raw_writel(reg, MXC_CCM_CCSR);
+
+ cpu_curr_wp = wp;
+
+ pll1_sw_clk.rate = cpu_wp_tbl[wp].cpu_rate;
+ pll1_main_clk.rate = pll1_sw_clk.rate;
+ cpu_clk.rate = pll1_sw_clk.rate;
+ }
+ return 0;
+}
+
diff --git a/arch/arm/mach-mx51/cpu.c b/arch/arm/mach-mx51/cpu.c
new file mode 100644
index 000000000000..81d0a4fcdb11
--- /dev/null
+++ b/arch/arm/mach-mx51/cpu.c
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file mach-mx51/cpu.c
+ *
+ * @brief This file contains the CPU initialization code.
+ *
+ * @ingroup MSL_MX51
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <mach/hardware.h>
+#include <asm/io.h>
+
+/*!
+ * CPU initialization. It is called by fixup_mxc_board()
+ */
+void __init mxc_cpu_init(void)
+{
+ if (!system_rev)
+ mxc_set_system_rev(0x51, CHIP_REV_1_0);
+}
+
+static int __init post_cpu_init(void)
+{
+ unsigned int base, reg;
+
+ base = IO_ADDRESS(AIPS1_BASE_ADDR);
+ __raw_writel(0x0, base + 0x40);
+ __raw_writel(0x0, base + 0x44);
+ __raw_writel(0x0, base + 0x48);
+ __raw_writel(0x0, base + 0x4C);
+ reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
+ __raw_writel(reg, base + 0x50);
+
+ base = IO_ADDRESS(AIPS2_BASE_ADDR);
+ __raw_writel(0x0, base + 0x40);
+ __raw_writel(0x0, base + 0x44);
+ __raw_writel(0x0, base + 0x48);
+ __raw_writel(0x0, base + 0x4C);
+ reg = __raw_readl(base + 0x50) & 0x00FFFFFF;
+ __raw_writel(reg, base + 0x50);
+
+ return 0;
+}
+
+postcore_initcall(post_cpu_init);
diff --git a/arch/arm/mach-mx51/crm_regs.h b/arch/arm/mach-mx51/crm_regs.h
new file mode 100644
index 000000000000..c570b8a3b18b
--- /dev/null
+++ b/arch/arm/mach-mx51/crm_regs.h
@@ -0,0 +1,673 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ARCH_ARM_MACH_MX51_CRM_REGS_H__
+#define __ARCH_ARM_MACH_MX51_CRM_REGS_H__
+
+#define MXC_CCM_BASE ((char *)IO_ADDRESS(CCM_BASE_ADDR))
+#define MXC_DPLL1_BASE IO_ADDRESS(PLL1_BASE_ADDR)
+#define MXC_DPLL2_BASE IO_ADDRESS(PLL2_BASE_ADDR)
+#define MXC_DPLL3_BASE IO_ADDRESS(PLL3_BASE_ADDR)
+
+/* PLL Register Offsets */
+#define MXC_PLL_DP_CTL 0x00
+#define MXC_PLL_DP_CONFIG 0x04
+#define MXC_PLL_DP_OP 0x08
+#define MXC_PLL_DP_MFD 0x0C
+#define MXC_PLL_DP_MFN 0x10
+#define MXC_PLL_DP_MFNMINUS 0x14
+#define MXC_PLL_DP_MFNPLUS 0x18
+#define MXC_PLL_DP_HFS_OP 0x1C
+#define MXC_PLL_DP_HFS_MFD 0x20
+#define MXC_PLL_DP_HFS_MFN 0x24
+#define MXC_PLL_DP_MFN_TOGC 0x28
+#define MXC_PLL_DP_DESTAT 0x2c
+
+/* PLL Register Bit definitions */
+#define MXC_PLL_DP_CTL_MUL_CTRL 0x2000
+#define MXC_PLL_DP_CTL_DPDCK0_2_EN 0x1000
+#define MXC_PLL_DP_CTL_DPDCK0_2_OFFSET 12
+#define MXC_PLL_DP_CTL_ADE 0x800
+#define MXC_PLL_DP_CTL_REF_CLK_DIV 0x400
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_MASK (3 << 8)
+#define MXC_PLL_DP_CTL_REF_CLK_SEL_OFFSET 8
+#define MXC_PLL_DP_CTL_HFSM 0x80
+#define MXC_PLL_DP_CTL_PRE 0x40
+#define MXC_PLL_DP_CTL_UPEN 0x20
+#define MXC_PLL_DP_CTL_RST 0x10
+#define MXC_PLL_DP_CTL_RCP 0x8
+#define MXC_PLL_DP_CTL_PLM 0x4
+#define MXC_PLL_DP_CTL_BRM0 0x2
+#define MXC_PLL_DP_CTL_LRF 0x1
+
+#define MXC_PLL_DP_CONFIG_BIST 0x8
+#define MXC_PLL_DP_CONFIG_SJC_CE 0x4
+#define MXC_PLL_DP_CONFIG_AREN 0x2
+#define MXC_PLL_DP_CONFIG_LDREQ 0x1
+
+#define MXC_PLL_DP_OP_MFI_OFFSET 4
+#define MXC_PLL_DP_OP_MFI_MASK (0xF << 4)
+#define MXC_PLL_DP_OP_PDF_OFFSET 0
+#define MXC_PLL_DP_OP_PDF_MASK 0xF
+
+#define MXC_PLL_DP_MFD_OFFSET 0
+#define MXC_PLL_DP_MFD_MASK 0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_OFFSET 0x0
+#define MXC_PLL_DP_MFN_MASK 0x07FFFFFF
+
+#define MXC_PLL_DP_MFN_TOGC_TOG_DIS (1 << 17)
+#define MXC_PLL_DP_MFN_TOGC_TOG_EN (1 << 16)
+#define MXC_PLL_DP_MFN_TOGC_CNT_OFFSET 0x0
+#define MXC_PLL_DP_MFN_TOGC_CNT_MASK 0xFFFF
+
+#define MXC_PLL_DP_DESTAT_TOG_SEL (1 << 31)
+#define MXC_PLL_DP_DESTAT_MFN 0x07FFFFFF
+
+/* Register addresses of CCM*/
+#define MXC_CCM_CCR (MXC_CCM_BASE + 0x00)
+#define MXC_CCM_CCDR (MXC_CCM_BASE + 0x04)
+#define MXC_CCM_CSR (MXC_CCM_BASE + 0x08)
+#define MXC_CCM_CCSR (MXC_CCM_BASE + 0x0C)
+#define MXC_CCM_CACRR (MXC_CCM_BASE + 0x10)
+#define MXC_CCM_CBCDR (MXC_CCM_BASE + 0x14)
+#define MXC_CCM_CBCMR (MXC_CCM_BASE + 0x18)
+#define MXC_CCM_CSCMR1 (MXC_CCM_BASE + 0x1C)
+#define MXC_CCM_CSCMR2 (MXC_CCM_BASE + 0x20)
+#define MXC_CCM_CSCDR1 (MXC_CCM_BASE + 0x24)
+#define MXC_CCM_CS1CDR (MXC_CCM_BASE + 0x28)
+#define MXC_CCM_CS2CDR (MXC_CCM_BASE + 0x2C)
+#define MXC_CCM_CDCDR (MXC_CCM_BASE + 0x30)
+#define MXC_CCM_CHSCDR (MXC_CCM_BASE + 0x34)
+#define MXC_CCM_CSCDR2 (MXC_CCM_BASE + 0x38)
+#define MXC_CCM_CSCDR3 (MXC_CCM_BASE + 0x3C)
+#define MXC_CCM_CSCDR4 (MXC_CCM_BASE + 0x40)
+#define MXC_CCM_CWDR (MXC_CCM_BASE + 0x44)
+#define MXC_CCM_CDHIPR (MXC_CCM_BASE + 0x48)
+#define MXC_CCM_CDCR (MXC_CCM_BASE + 0x4C)
+#define MXC_CCM_CTOR (MXC_CCM_BASE + 0x50)
+#define MXC_CCM_CLPCR (MXC_CCM_BASE + 0x54)
+#define MXC_CCM_CISR (MXC_CCM_BASE + 0x58)
+#define MXC_CCM_CIMR (MXC_CCM_BASE + 0x5C)
+#define MXC_CCM_CCOSR (MXC_CCM_BASE + 0x60)
+#define MXC_CCM_CGPR (MXC_CCM_BASE + 0x64)
+#define MXC_CCM_CCGR0 (MXC_CCM_BASE + 0x68)
+#define MXC_CCM_CCGR1 (MXC_CCM_BASE + 0x6C)
+#define MXC_CCM_CCGR2 (MXC_CCM_BASE + 0x70)
+#define MXC_CCM_CCGR3 (MXC_CCM_BASE + 0x74)
+#define MXC_CCM_CCGR4 (MXC_CCM_BASE + 0x78)
+#define MXC_CCM_CCGR5 (MXC_CCM_BASE + 0x7C)
+#define MXC_CCM_CCGR6 (MXC_CCM_BASE + 0x80)
+#define MXC_CCM_CMEOR (MXC_CCM_BASE + 0x84)
+
+/* Define the bits in register CCR */
+#define MXC_CCM_CCR_COSC_EN (1 << 12)
+#define MXC_CCM_CCR_FPM_MULT_MASK (1 << 11)
+#define MXC_CCM_CCR_CAMP2_EN (1 << 10)
+#define MXC_CCM_CCR_CAMP1_EN (1 << 9)
+#define MXC_CCM_CCR_FPM_EN (1 << 8)
+#define MXC_CCM_CCR_OSCNT_OFFSET (0)
+#define MXC_CCM_CCR_OSCNT_MASK (0xFF)
+
+/* Define the bits in register CCDR */
+#define MXC_CCM_CCDR_HSC_HS_MASK (0x1 << 18)
+#define MXC_CCM_CCDR_IPU_HS_MASK (0x1 << 17)
+#define MXC_CCM_CCDR_EMI_HS_MASK (0x1 << 16)
+
+/* Define the bits in register CSR */
+#define MXC_CCM_CSR_COSR_READY (1 << 5)
+#define MXC_CCM_CSR_LVS_VALUE (1 << 4)
+#define MXC_CCM_CSR_CAMP2_READY (1 << 3)
+#define MXC_CCM_CSR_CAMP1_READY (1 << 2)
+#define MXC_CCM_CSR_FPM_READY (1 << 1)
+#define MXC_CCM_CSR_REF_EN_B (1 << 0)
+
+/* Define the bits in register CCSR */
+#define MXC_CCM_CCSR_LP_APM_SEL (0x1 << 9)
+#define MXC_CCM_CCSR_STEP_SEL_OFFSET (7)
+#define MXC_CCM_CCSR_STEP_SEL_MASK (0x3 << 7)
+#define MXC_CCM_CCSR_PLL2_PODF_OFFSET (5)
+#define MXC_CCM_CCSR_PLL2_PODF_MASK (0x3 << 5)
+#define MXC_CCM_CCSR_PLL3_PODF_OFFSET (3)
+#define MXC_CCM_CCSR_PLL3_PODF_MASK (0x3 << 3)
+#define MXC_CCM_CCSR_PLL1_SW_CLK_SEL (1 << 2)
+#define MXC_CCM_CCSR_PLL2_SW_CLK_SEL (1 << 1)
+#define MXC_CCM_CCSR_PLL3_SW_CLK_SEL (1 << 0)
+
+/* Define the bits in register CACRR */
+#define MXC_CCM_CACRR_ARM_PODF_OFFSET (0)
+#define MXC_CCM_CACRR_ARM_PODF_MASK (0x7)
+
+/* Define the bits in register CBCDR */
+#define MXC_CCM_CBCDR_EMI_CLK_SEL (0x1 << 26)
+#define MXC_CCM_CBCDR_PERIPH_CLK_SEL (0x1 << 25)
+#define MXC_CCM_CBCDR_DDR_HF_SEL_OFFSET (30)
+#define MXC_CCM_CBCDR_DDR_HF_SEL (0x1 << 30)
+#define MXC_CCM_CBCDR_DDR_PODF_OFFSET (27)
+#define MXC_CCM_CBCDR_DDR_PODF_MASK (0x7 << 27)
+#define MXC_CCM_CBCDR_EMI_PODF_OFFSET (22)
+#define MXC_CCM_CBCDR_EMI_PODF_MASK (0x7 << 22)
+#define MXC_CCM_CBCDR_AXI_B_PODF_OFFSET (19)
+#define MXC_CCM_CBCDR_AXI_B_PODF_MASK (0x7 << 19)
+#define MXC_CCM_CBCDR_AXI_A_PODF_OFFSET (16)
+#define MXC_CCM_CBCDR_AXI_A_PODF_MASK (0x7 << 16)
+#define MXC_CCM_CBCDR_NFC_PODF_OFFSET (13)
+#define MXC_CCM_CBCDR_NFC_PODF_MASK (0x7 << 13)
+#define MXC_CCM_CBCDR_AHB_PODF_OFFSET (10)
+#define MXC_CCM_CBCDR_AHB_PODF_MASK (0x7 << 10)
+#define MXC_CCM_CBCDR_IPG_PODF_OFFSET (8)
+#define MXC_CCM_CBCDR_IPG_PODF_MASK (0x3 << 8)
+#define MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET (6)
+#define MXC_CCM_CBCDR_PERCLK_PRED1_MASK (0x3 << 6)
+#define MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET (3)
+#define MXC_CCM_CBCDR_PERCLK_PRED2_MASK (0x7 << 3)
+#define MXC_CCM_CBCDR_PERCLK_PODF_OFFSET (0)
+#define MXC_CCM_CBCDR_PERCLK_PODF_MASK (0x7)
+
+/* Define the bits in register CBCMR */
+#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CBCMR_VPU_AXI_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET (12)
+#define MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK (0x3 << 12)
+#define MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET (10)
+#define MXC_CCM_CBCMR_DDR_CLK_SEL_MASK (0x3 << 10)
+#define MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_OFFSET (8)
+#define MXC_CCM_CBCMR_ARM_AXI_CLK_SEL_MASK (0x3 << 8)
+#define MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_OFFSET (6)
+#define MXC_CCM_CBCMR_IPU_HSP_CLK_SEL_MASK (0x3 << 6)
+#define MXC_CCM_CBCMR_GPU_CLK_SEL_OFFSET (4)
+#define MXC_CCM_CBCMR_GPU_CLK_SEL_MASK (0x3 << 4)
+#define MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL (0x1 << 1)
+#define MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL (0x1 << 0)
+
+/* Define the bits in register CSCMR1 */
+#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_OFFSET (30)
+#define MXC_CCM_CSCMR1_SSI_EXT2_CLK_SEL_MASK (0x3 << 30)
+#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_OFFSET (28)
+#define MXC_CCM_CSCMR1_SSI_EXT1_CLK_SEL_MASK (0x3 << 28)
+#define MXC_CCM_CSCMR1_USB_PHY_CLK_SEL_OFFSET (26)
+#define MXC_CCM_CSCMR1_USB_PHY_CLK_SEL (0x1 << 26)
+#define MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET (24)
+#define MXC_CCM_CSCMR1_UART_CLK_SEL_MASK (0x3 << 24)
+#define MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET (22)
+#define MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK (0x3 << 22)
+#define MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_OFFSET (20)
+#define MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_MASK (0x3 << 20)
+#define MXC_CCM_CSCMR1_ESDHC3_CLK_SEL (0x1 << 19)
+#define MXC_CCM_CSCMR1_ESDHC4_CLK_SEL (0x1 << 18)
+#define MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_OFFSET (16)
+#define MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_MASK (0x3 << 16)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CSCMR1_SSI1_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_OFFSET (12)
+#define MXC_CCM_CSCMR1_SSI2_CLK_SEL_MASK (0x3 << 12)
+#define MXC_CCM_CSCMR1_SSI3_CLK_SEL (0x1 << 11)
+#define MXC_CCM_CSCMR1_VPU_RCLK_SEL (0x1 << 10)
+#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_OFFSET (8)
+#define MXC_CCM_CSCMR1_SSI_APM_CLK_SEL_MASK (0x3 << 8)
+#define MXC_CCM_CSCMR1_TVE_CLK_SEL (0x1 << 7)
+#define MXC_CCM_CSCMR1_TVE_EXT_CLK_SEL (0x1 << 6)
+#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET (4)
+#define MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK (0x3 << 4)
+#define MXC_CCM_CSCMR1_SPDIF_CLK_SEL_OFFSET (2)
+#define MXC_CCM_CSCMR1_SPDIF_CLK_SEL_MASK (0x3 << 2)
+#define MXC_CCM_CSCMR1_SSI_EXT2_COM_CLK_SEL (0x1 << 1)
+#define MXC_CCM_CSCMR1_SSI_EXT1_COM_CLK_SEL (0x1)
+
+/* Define the bits in register CSCMR2 */
+#define MXC_CCM_CSCMR2_DI_CLK_SEL_OFFSET (26)
+#define MXC_CCM_CSCMR2_DI_CLK_SEL_MASK (0x7 << 26)
+#define MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_OFFSET (24)
+#define MXC_CCM_CSCMR2_CSI_MCLK2_CLK_SEL_MASK (0x3 << 24)
+#define MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_OFFSET (22)
+#define MXC_CCM_CSCMR2_CSI_MCLK1_CLK_SEL_MASK (0x3 << 22)
+#define MXC_CCM_CSCMR2_ESC_CLK_SEL_OFFSET (20)
+#define MXC_CCM_CSCMR2_ESC_CLK_SEL_MASK (0x3 << 20)
+#define MXC_CCM_CSCMR2_HSC2_CLK_SEL_OFFSET (18)
+#define MXC_CCM_CSCMR2_HSC2_CLK_SEL_MASK (0x3 << 18)
+#define MXC_CCM_CSCMR2_HSC1_CLK_SEL_OFFSET (16)
+#define MXC_CCM_CSCMR2_HSC1_CLK_SEL_MASK (0x3 << 16)
+#define MXC_CCM_CSCMR2_HSI2C_CLK_SEL_OFFSET (14)
+#define MXC_CCM_CSCMR2_HSI2C_CLK_SEL_MASK (0x3 << 14)
+#define MXC_CCM_CSCMR2_FIRI_CLK_SEL_OFFSET (12)
+#define MXC_CCM_CSCMR2_FIRI_CLK_SEL_MASK (0x3 << 12)
+#define MXC_CCM_CSCMR2_SIM_CLK_SEL_OFFSET (10)
+#define MXC_CCM_CSCMR2_SIM_CLK_SEL_MASK (0x3 << 10)
+#define MXC_CCM_CSCMR2_SLIMBUS_COM (0x1 << 9)
+#define MXC_CCM_CSCMR2_SLIMBUS_CLK_SEL_OFFSET (6)
+#define MXC_CCM_CSCMR2_SLIMBUS_CLK_SEL_MASK (0x7 << 6)
+#define MXC_CCM_CSCMR2_SPDIF1_COM (1 << 5)
+#define MXC_CCM_CSCMR2_SPDIF0_COM (1 << 4)
+#define MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_OFFSET (2)
+#define MXC_CCM_CSCMR2_SPDIF1_CLK_SEL_MASK (0x3 << 2)
+#define MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_OFFSET (0)
+#define MXC_CCM_CSCMR2_SPDIF0_CLK_SEL_MASK (0x3)
+
+/* Define the bits in register CSCDR1 */
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_OFFSET (22)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_MASK (0x7 << 22)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_MASK (0x7 << 19)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR1_PGC_CLK_PODF_OFFSET (14)
+#define MXC_CCM_CSCDR1_PGC_CLK_PODF_MASK (0x3 << 14)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_OFFSET (11)
+#define MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_MASK (0x7 << 11)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET (8)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK (0x7 << 8)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET (6)
+#define MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK (0x3 << 6)
+#define MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET (3)
+#define MXC_CCM_CSCDR1_UART_CLK_PRED_MASK (0x7 << 3)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CSCDR1_UART_CLK_PODF_MASK (0x7)
+
+/* Define the bits in register CS1CDR and CS2CDR */
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_OFFSET (22)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PRED_MASK (0x7 << 22)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_OFFSET (16)
+#define MXC_CCM_CS1CDR_SSI_EXT1_CLK_PODF_MASK (0x3F << 16)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CS1CDR_SSI1_CLK_PODF_MASK (0x3F)
+
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_OFFSET (22)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PRED_MASK (0x7 << 22)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_OFFSET (16)
+#define MXC_CCM_CS2CDR_SSI_EXT2_CLK_PODF_MASK (0x3F << 16)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CS2CDR_SSI2_CLK_PODF_MASK (0x3F)
+
+/* Define the bits in register CDCDR */
+#define MXC_CCM_CDCDR_TVE_CLK_PRED_OFFSET (28)
+#define MXC_CCM_CDCDR_TVE_CLK_PRED_MASK (0x7 << 28)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_OFFSET (25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PRED_MASK (0x7 << 25)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CDCDR_SPDIF0_CLK_PODF_MASK (0x3F << 19)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_OFFSET (9)
+#define MXC_CCM_CDCDR_SPDIF1_CLK_PODF_MASK (0x3F << 9)
+#define MXC_CCM_CDCDR_DI_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CDCDR_DI_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CDCDR_USB_PHY_PRED_OFFSET (3)
+#define MXC_CCM_CDCDR_USB_PHY_PRED_MASK (0x7 << 3)
+#define MXC_CCM_CDCDR_USB_PHY_PODF_OFFSET (0)
+#define MXC_CCM_CDCDR_USB_PHY_PODF_MASK (0x7)
+
+/* Define the bits in register CHSCCDR */
+#define MXC_CCM_CHSCCDR_ESC_CLK_PRED_OFFSET (12)
+#define MXC_CCM_CHSCCDR_ESC_CLK_PRED_MASK (0x7 << 12)
+#define MXC_CCM_CHSCCDR_ESC_CLK_PODF_OFFSET (6)
+#define MXC_CCM_CHSCCDR_ESC_CLK_PODF_MASK (0x3F << 6)
+#define MXC_CCM_CHSCCDR_HSC2_CLK_PODF_OFFSET (3)
+#define MXC_CCM_CHSCCDR_HSC2_CLK_PODF_MASK (0x7 << 3)
+#define MXC_CCM_CHSCCDR_HSC1_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CHSCCDR_HSC1_CLK_PODF_MASK (0x7)
+
+/* Define the bits in register CSCDR2 */
+#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET (25)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK (0x7 << 25)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET (19)
+#define MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK (0x3F << 19)
+#define MXC_CCM_CSCDR2_SIM_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CSCDR2_SIM_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR2_SIM_CLK_PODF_OFFSET (9)
+#define MXC_CCM_CSCDR2_SIM_CLK_PODF_MASK (0x3F << 9)
+#define MXC_CCM_CSCDR2_SLIMBUS_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CSCDR2_SLIMBUS_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CSCDR2_SLIMBUS_PODF_OFFSET (0)
+#define MXC_CCM_CSCDR2_SLIMBUS_PODF_MASK (0x3F)
+
+/* Define the bits in register CSCDR3 */
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PODF_OFFSET (9)
+#define MXC_CCM_CSCDR3_HSI2C_CLK_PODF_MASK (0x3F << 9)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CSCDR3_FIRI_CLK_PODF_MASK (0x3F)
+
+/* Define the bits in register CSCDR4 */
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_OFFSET (16)
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PRED_MASK (0x7 << 16)
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_OFFSET (9)
+#define MXC_CCM_CSCDR4_CSI_MCLK2_CLK_PODF_MASK (0x3F << 9)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_OFFSET (6)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PRED_MASK (0x7 << 6)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_OFFSET (0)
+#define MXC_CCM_CSCDR4_CSI_MCLK1_CLK_PODF_MASK (0x3F)
+
+/* Define the bits in register CDHIPR */
+#define MXC_CCM_CDHIPR_ARM_PODF_BUSY (1 << 16)
+#define MXC_CCM_CDHIPR_EMI_CLK_SEL_BUSY (1 << 6)
+#define MXC_CCM_CDHIPR_PERIPH_CLK_SEL_BUSY (1 << 5)
+#define MXC_CCM_CDHIPR_NFC_IPG_INT_MEM_PODF_BUSY (1 << 4)
+#define MXC_CCM_CDHIPR_AHB_PODF_BUSY (1 << 3)
+#define MXC_CCM_CDHIPR_EMI_PODF_BUSY (1 << 2)
+#define MXC_CCM_CDHIPR_AXI_B_PODF_BUSY (1 << 1)
+#define MXC_CCM_CDHIPR_AXI_A_PODF_BUSY (1 << 0)
+
+/* Define the bits in register CDCR */
+#define MXC_CCM_CDCR_ARM_FREQ_SHIFT_DIVIDER (0x1 << 2)
+#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_OFFSET (0)
+#define MXC_CCM_CDCR_PERIPH_CLK_DVFS_PODF_MASK (0x3)
+
+/* Define the bits in register CLPCR */
+#define MXC_CCM_CLPCR_BYPASS_HSC_LPM_HS (0x1 << 23)
+#define MXC_CCM_CLPCR_BYPASS_SCC_LPM_HS (0x1 << 22)
+#define MXC_CCM_CLPCR_BYPASS_MAX_LPM_HS (0x1 << 21)
+#define MXC_CCM_CLPCR_BYPASS_SDMA_LPM_HS (0x1 << 20)
+#define MXC_CCM_CLPCR_BYPASS_EMI_LPM_HS (0x1 << 19)
+#define MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS (0x1 << 18)
+#define MXC_CCM_CLPCR_BYPASS_RTIC_LPM_HS (0x1 << 17)
+#define MXC_CCM_CLPCR_BYPASS_RNGC_LPM_HS (0x1 << 16)
+#define MXC_CCM_CLPCR_COSC_PWRDOWN (0x1 << 11)
+#define MXC_CCM_CLPCR_STBY_COUNT_OFFSET (9)
+#define MXC_CCM_CLPCR_STBY_COUNT_MASK (0x3 << 9)
+#define MXC_CCM_CLPCR_VSTBY (0x1 << 8)
+#define MXC_CCM_CLPCR_DIS_REF_OSC (0x1 << 7)
+#define MXC_CCM_CLPCR_SBYOS (0x1 << 6)
+#define MXC_CCM_CLPCR_ARM_CLK_DIS_ON_LPM (0x1 << 5)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_OFFSET (3)
+#define MXC_CCM_CLPCR_LPSR_CLK_SEL_MASK (0x3 << 3)
+#define MXC_CCM_CLPCR_LPM_OFFSET (0)
+#define MXC_CCM_CLPCR_LPM_MASK (0x3)
+
+/* Define the bits in register CISR */
+#define MXC_CCM_CISR_ARM_PODF_LOADED (0x1 << 25)
+#define MXC_CCM_CISR_NFC_IPG_INT_MEM_PODF_LOADED (0x1 << 21)
+#define MXC_CCM_CISR_AHB_PODF_LOADED (0x1 << 20)
+#define MXC_CCM_CISR_EMI_PODF_LOADED (0x1 << 19)
+#define MXC_CCM_CISR_AXI_B_PODF_LOADED (0x1 << 18)
+#define MXC_CCM_CISR_AXI_A_PODF_LOADED (0x1 << 17)
+#define MXC_CCM_CISR_DIVIDER_LOADED (0x1 << 16)
+#define MXC_CCM_CISR_COSC_READY (0x1 << 6)
+#define MXC_CCM_CISR_CKIH2_READY (0x1 << 5)
+#define MXC_CCM_CISR_CKIH_READY (0x1 << 4)
+#define MXC_CCM_CISR_FPM_READY (0x1 << 3)
+#define MXC_CCM_CISR_LRF_PLL3 (0x1 << 2)
+#define MXC_CCM_CISR_LRF_PLL2 (0x1 << 1)
+#define MXC_CCM_CISR_LRF_PLL1 (0x1)
+
+/* Define the bits in register CIMR */
+#define MXC_CCM_CIMR_MASK_ARM_PODF_LOADED (0x1 << 25)
+#define MXC_CCM_CIMR_MASK_NFC_IPG_INT_MEM_PODF_LOADED (0x1 << 21)
+#define MXC_CCM_CIMR_MASK_EMI_PODF_LOADED (0x1 << 20)
+#define MXC_CCM_CIMR_MASK_AXI_C_PODF_LOADED (0x1 << 19)
+#define MXC_CCM_CIMR_MASK_AXI_B_PODF_LOADED (0x1 << 18)
+#define MXC_CCM_CIMR_MASK_AXI_A_PODF_LOADED (0x1 << 17)
+#define MXC_CCM_CIMR_MASK_DIVIDER_LOADED (0x1 << 16)
+#define MXC_CCM_CIMR_MASK_COSC_READY (0x1 << 5)
+#define MXC_CCM_CIMR_MASK_CKIH_READY (0x1 << 4)
+#define MXC_CCM_CIMR_MASK_FPM_READY (0x1 << 3)
+#define MXC_CCM_CIMR_MASK_LRF_PLL3 (0x1 << 2)
+#define MXC_CCM_CIMR_MASK_LRF_PLL2 (0x1 << 1)
+#define MXC_CCM_CIMR_MASK_LRF_PLL1 (0x1)
+
+/* Define the bits in register CCOSR */
+#define MXC_CCM_CCOSR_CKO2_EN_OFFSET (0x1 << 24)
+#define MXC_CCM_CCOSR_CKO2_DIV_OFFSET (21)
+#define MXC_CCM_CCOSR_CKO2_DIV_MASK (0x7 << 21)
+#define MXC_CCM_CCOSR_CKO2_SEL_OFFSET (16)
+#define MXC_CCM_CCOSR_CKO2_SEL_MASK (0x1F << 16)
+#define MXC_CCM_CCOSR_CKOL_EN (0x1 << 7)
+#define MXC_CCM_CCOSR_CKOL_DIV_OFFSET (4)
+#define MXC_CCM_CCOSR_CKOL_DIV_MASK (0x7 << 4)
+#define MXC_CCM_CCOSR_CKOL_SEL_OFFSET (0)
+#define MXC_CCM_CCOSR_CKOL_SEL_MASK (0xF)
+
+/* Define the bits in registers CGPR */
+#define MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE (0x1 << 4)
+#define MXC_CCM_CGPR_FPM_SEL (0x1 << 3)
+#define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_OFFSET (0)
+#define MXC_CCM_CGPR_VL_L2BIST_CLKDIV_MASK (0x7)
+
+/* Define the bits in registers CCGRx */
+#define MXC_CCM_CCGR_CG_MASK 0x3
+
+#define MXC_CCM_CCGR0_CG15_OFFSET 30
+#define MXC_CCM_CCGR0_CG15_MASK (0x3 << 30)
+#define MXC_CCM_CCGR0_CG14_OFFSET 28
+#define MXC_CCM_CCGR0_CG14_MASK (0x3 << 28)
+#define MXC_CCM_CCGR0_CG13_OFFSET 26
+#define MXC_CCM_CCGR0_CG13_MASK (0x3 << 26)
+#define MXC_CCM_CCGR0_CG12_OFFSET 24
+#define MXC_CCM_CCGR0_CG12_MASK (0x3 << 24)
+#define MXC_CCM_CCGR0_CG11_OFFSET 22
+#define MXC_CCM_CCGR0_CG11_MASK (0x3 << 22)
+#define MXC_CCM_CCGR0_CG10_OFFSET 20
+#define MXC_CCM_CCGR0_CG10_MASK (0x3 << 20)
+#define MXC_CCM_CCGR0_CG9_OFFSET 18
+#define MXC_CCM_CCGR0_CG9_MASK (0x3 << 18)
+#define MXC_CCM_CCGR0_CG8_OFFSET 16
+#define MXC_CCM_CCGR0_CG8_MASK (0x3 << 16)
+#define MXC_CCM_CCGR0_CG7_OFFSET 14
+#define MXC_CCM_CCGR0_CG6_OFFSET 12
+#define MXC_CCM_CCGR0_CG5_OFFSET 10
+#define MXC_CCM_CCGR0_CG5_MASK (0x3 << 10)
+#define MXC_CCM_CCGR0_CG4_OFFSET 8
+#define MXC_CCM_CCGR0_CG4_MASK (0x3 << 8)
+#define MXC_CCM_CCGR0_CG3_OFFSET 6
+#define MXC_CCM_CCGR0_CG3_MASK (0x3 << 6)
+#define MXC_CCM_CCGR0_CG2_OFFSET 4
+#define MXC_CCM_CCGR0_CG2_MASK (0x3 << 4)
+#define MXC_CCM_CCGR0_CG1_OFFSET 2
+#define MXC_CCM_CCGR0_CG1_MASK (0x3 << 2)
+#define MXC_CCM_CCGR0_CG0_OFFSET 0
+#define MXC_CCM_CCGR0_CG0_MASK 0x3
+
+#define MXC_CCM_CCGR1_CG15_OFFSET 30
+#define MXC_CCM_CCGR1_CG14_OFFSET 28
+#define MXC_CCM_CCGR1_CG13_OFFSET 26
+#define MXC_CCM_CCGR1_CG12_OFFSET 24
+#define MXC_CCM_CCGR1_CG11_OFFSET 22
+#define MXC_CCM_CCGR1_CG10_OFFSET 20
+#define MXC_CCM_CCGR1_CG9_OFFSET 18
+#define MXC_CCM_CCGR1_CG8_OFFSET 16
+#define MXC_CCM_CCGR1_CG7_OFFSET 14
+#define MXC_CCM_CCGR1_CG6_OFFSET 12
+#define MXC_CCM_CCGR1_CG5_OFFSET 10
+#define MXC_CCM_CCGR1_CG4_OFFSET 8
+#define MXC_CCM_CCGR1_CG3_OFFSET 6
+#define MXC_CCM_CCGR1_CG2_OFFSET 4
+#define MXC_CCM_CCGR1_CG1_OFFSET 2
+#define MXC_CCM_CCGR1_CG0_OFFSET 0
+
+#define MXC_CCM_CCGR2_CG15_OFFSET 30
+#define MXC_CCM_CCGR2_CG14_OFFSET 28
+#define MXC_CCM_CCGR2_CG13_OFFSET 26
+#define MXC_CCM_CCGR2_CG12_OFFSET 24
+#define MXC_CCM_CCGR2_CG11_OFFSET 22
+#define MXC_CCM_CCGR2_CG10_OFFSET 20
+#define MXC_CCM_CCGR2_CG9_OFFSET 18
+#define MXC_CCM_CCGR2_CG8_OFFSET 16
+#define MXC_CCM_CCGR2_CG7_OFFSET 14
+#define MXC_CCM_CCGR2_CG6_OFFSET 12
+#define MXC_CCM_CCGR2_CG5_OFFSET 10
+#define MXC_CCM_CCGR2_CG4_OFFSET 8
+#define MXC_CCM_CCGR2_CG3_OFFSET 6
+#define MXC_CCM_CCGR2_CG2_OFFSET 4
+#define MXC_CCM_CCGR2_CG1_OFFSET 2
+#define MXC_CCM_CCGR2_CG0_OFFSET 0
+
+#define MXC_CCM_CCGR3_CG15_OFFSET 30
+#define MXC_CCM_CCGR3_CG14_OFFSET 28
+#define MXC_CCM_CCGR3_CG13_OFFSET 26
+#define MXC_CCM_CCGR3_CG12_OFFSET 24
+#define MXC_CCM_CCGR3_CG11_OFFSET 22
+#define MXC_CCM_CCGR3_CG10_OFFSET 20
+#define MXC_CCM_CCGR3_CG9_OFFSET 18
+#define MXC_CCM_CCGR3_CG8_OFFSET 16
+#define MXC_CCM_CCGR3_CG7_OFFSET 14
+#define MXC_CCM_CCGR3_CG6_OFFSET 12
+#define MXC_CCM_CCGR3_CG5_OFFSET 10
+#define MXC_CCM_CCGR3_CG4_OFFSET 8
+#define MXC_CCM_CCGR3_CG3_OFFSET 6
+#define MXC_CCM_CCGR3_CG2_OFFSET 4
+#define MXC_CCM_CCGR3_CG1_OFFSET 2
+#define MXC_CCM_CCGR3_CG0_OFFSET 0
+
+#define MXC_CCM_CCGR4_CG15_OFFSET 30
+#define MXC_CCM_CCGR4_CG14_OFFSET 28
+#define MXC_CCM_CCGR4_CG13_OFFSET 26
+#define MXC_CCM_CCGR4_CG12_OFFSET 24
+#define MXC_CCM_CCGR4_CG11_OFFSET 22
+#define MXC_CCM_CCGR4_CG10_OFFSET 20
+#define MXC_CCM_CCGR4_CG9_OFFSET 18
+#define MXC_CCM_CCGR4_CG8_OFFSET 16
+#define MXC_CCM_CCGR4_CG7_OFFSET 14
+#define MXC_CCM_CCGR4_CG6_OFFSET 12
+#define MXC_CCM_CCGR4_CG5_OFFSET 10
+#define MXC_CCM_CCGR4_CG4_OFFSET 8
+#define MXC_CCM_CCGR4_CG3_OFFSET 6
+#define MXC_CCM_CCGR4_CG2_OFFSET 4
+#define MXC_CCM_CCGR4_CG1_OFFSET 2
+#define MXC_CCM_CCGR4_CG0_OFFSET 0
+
+#define MXC_CCM_CCGR5_CG15_OFFSET 30
+#define MXC_CCM_CCGR5_CG14_OFFSET 28
+#define MXC_CCM_CCGR5_CG14_MASK (0x3 << 28)
+#define MXC_CCM_CCGR5_CG13_OFFSET 26
+#define MXC_CCM_CCGR5_CG13_MASK (0x3 << 26)
+#define MXC_CCM_CCGR5_CG12_OFFSET 24
+#define MXC_CCM_CCGR5_CG12_MASK (0x3 << 24)
+#define MXC_CCM_CCGR5_CG11_OFFSET 22
+#define MXC_CCM_CCGR5_CG11_MASK (0x3 << 22)
+#define MXC_CCM_CCGR5_CG10_OFFSET 20
+#define MXC_CCM_CCGR5_CG10_MASK (0x3 << 20)
+#define MXC_CCM_CCGR5_CG9_OFFSET 18
+#define MXC_CCM_CCGR5_CG9_MASK (0x3 << 18)
+#define MXC_CCM_CCGR5_CG8_OFFSET 16
+#define MXC_CCM_CCGR5_CG8_MASK (0x3 << 16)
+#define MXC_CCM_CCGR5_CG7_OFFSET 14
+#define MXC_CCM_CCGR5_CG7_MASK (0x3 << 14)
+#define MXC_CCM_CCGR5_CG6_OFFSET 12
+#define MXC_CCM_CCGR5_CG5_OFFSET 10
+#define MXC_CCM_CCGR5_CG4_OFFSET 8
+#define MXC_CCM_CCGR5_CG3_OFFSET 6
+#define MXC_CCM_CCGR5_CG2_OFFSET 4
+#define MXC_CCM_CCGR5_CG2_MASK (0x3 << 4)
+#define MXC_CCM_CCGR5_CG1_OFFSET 2
+#define MXC_CCM_CCGR5_CG0_OFFSET 0
+
+#define MXC_CCM_CCGR6_CG4_OFFSET 8
+#define MXC_CCM_CCGR6_CG4_MASK (0x3 << 8)
+#define MXC_CCM_CCGR6_CG3_OFFSET 6
+#define MXC_CCM_CCGR6_CG2_OFFSET 4
+#define MXC_CCM_CCGR6_CG1_OFFSET 2
+#define MXC_CCM_CCGR6_CG0_OFFSET 0
+
+#define MXC_CORTEXA8_BASE IO_ADDRESS(ARM_BASE_ADDR)
+#define MXC_GPC_BASE IO_ADDRESS(GPC_BASE_ADDR)
+#define MXC_DPTC_LP_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x80)
+#define MXC_DPTC_GP_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x100)
+#define MXC_DVFS_CORE_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x180)
+#define MXC_DPTC_PER_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x1C0)
+#define MXC_PGC_IPU_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x220)
+#define MXC_PGC_VPU_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x240)
+#define MXC_PGC_GPU_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x260)
+#define MXC_SRPG_NEON_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x280)
+#define MXC_SRPG_ARM_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x2A0)
+#define MXC_SRPG_EMPGC0_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x2C0)
+#define MXC_SRPG_EMPGC1_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x2D0)
+#define MXC_SRPG_MEGAMIX_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x2E0)
+#define MXC_SRPG_EMI_BASE IO_ADDRESS(GPC_BASE_ADDR + 0x300)
+
+/* CORTEXA8 platform */
+#define MXC_CORTEXA8_PLAT_PVID (MXC_CORTEXA8_BASE + 0x0)
+#define MXC_CORTEXA8_PLAT_GPC (MXC_CORTEXA8_BASE + 0x4)
+#define MXC_CORTEXA8_PLAT_PIC (MXC_CORTEXA8_BASE + 0x8)
+#define MXC_CORTEXA8_PLAT_LPC (MXC_CORTEXA8_BASE + 0xC)
+#define MXC_CORTEXA8_PLAT_NEON_LPC (MXC_CORTEXA8_BASE + 0x10)
+#define MXC_CORTEXA8_PLAT_ICGC (MXC_CORTEXA8_BASE + 0x14)
+#define MXC_CORTEXA8_PLAT_AMC (MXC_CORTEXA8_BASE + 0x18)
+#define MXC_CORTEXA8_PLAT_NMC (MXC_CORTEXA8_BASE + 0x20)
+#define MXC_CORTEXA8_PLAT_NMS (MXC_CORTEXA8_BASE + 0x24)
+
+/* DVFS CORE */
+#define MXC_DVFSTHRS (MXC_DVFS_CORE_BASE + 0x00)
+#define MXC_DVFSCOUN (MXC_DVFS_CORE_BASE + 0x04)
+#define MXC_DVFSSIG1 (MXC_DVFS_CORE_BASE + 0x08)
+#define MXC_DVFSSIG0 (MXC_DVFS_CORE_BASE + 0x0C)
+#define MXC_DVFSGPC0 (MXC_DVFS_CORE_BASE + 0x10)
+#define MXC_DVFSGPC1 (MXC_DVFS_CORE_BASE + 0x14)
+#define MXC_DVFSGPBT (MXC_DVFS_CORE_BASE + 0x18)
+#define MXC_DVFSEMAC (MXC_DVFS_CORE_BASE + 0x1C)
+#define MXC_DVFSCNTR (MXC_DVFS_CORE_BASE + 0x20)
+#define MXC_DVFSLTR0_0 (MXC_DVFS_CORE_BASE + 0x24)
+#define MXC_DVFSLTR0_1 (MXC_DVFS_CORE_BASE + 0x28)
+#define MXC_DVFSLTR1_0 (MXC_DVFS_CORE_BASE + 0x2C)
+#define MXC_DVFSLTR1_1 (MXC_DVFS_CORE_BASE + 0x30)
+#define MXC_DVFSPT0 (MXC_DVFS_CORE_BASE + 0x34)
+#define MXC_DVFSPT1 (MXC_DVFS_CORE_BASE + 0x38)
+#define MXC_DVFSPT2 (MXC_DVFS_CORE_BASE + 0x3C)
+#define MXC_DVFSPT3 (MXC_DVFS_CORE_BASE + 0x40)
+
+/* GPC */
+#define MXC_GPC_CNTR (MXC_GPC_BASE + 0x0)
+#define MXC_GPC_PGR (MXC_GPC_BASE + 0x4)
+#define MXC_GPC_VCR (MXC_GPC_BASE + 0x8)
+#define MXC_GPC_ALL_PU (MXC_GPC_BASE + 0xC)
+#define MXC_GPC_NEON (MXC_GPC_BASE + 0x10)
+#define MXC_GPC_PGR_ARMPG_OFFSET 8
+#define MXC_GPC_PGR_ARMPG_MASK (3 << 8)
+
+/* PGC */
+#define MXC_PGC_IPU_PGCR (MXC_PGC_IPU_BASE + 0x0)
+#define MXC_PGC_IPU_PGSR (MXC_PGC_IPU_BASE + 0xC)
+#define MXC_PGC_VPU_PGCR (MXC_PGC_VPU_BASE + 0x0)
+#define MXC_PGC_VPU_PGSR (MXC_PGC_VPU_BASE + 0xC)
+#define MXC_PGC_GPU_PGCR (MXC_PGC_GPU_BASE + 0x0)
+#define MXC_PGC_GPU_PGSR (MXC_PGC_GPU_BASE + 0xC)
+
+#define MXC_PGCR_PCR 1
+#define MXC_SRPGCR_PCR 1
+#define MXC_EMPGCR_PCR 1
+#define MXC_PGSR_PSR 1
+
+
+#define MXC_CORTEXA8_PLAT_LPC_DSM (1 << 0)
+#define MXC_CORTEXA8_PLAT_LPC_DBG_DSM (1 << 1)
+
+/* SRPG */
+#define MXC_SRPG_NEON_SRPGCR (MXC_SRPG_NEON_BASE + 0x0)
+#define MXC_SRPG_NEON_PUPSCR (MXC_SRPG_NEON_BASE + 0x4)
+#define MXC_SRPG_NEON_PDNSCR (MXC_SRPG_NEON_BASE + 0x8)
+
+#define MXC_SRPG_ARM_SRPGCR (MXC_SRPG_ARM_BASE + 0x0)
+#define MXC_SRPG_ARM_PUPSCR (MXC_SRPG_ARM_BASE + 0x4)
+#define MXC_SRPG_ARM_PDNSCR (MXC_SRPG_ARM_BASE + 0x8)
+
+#define MXC_SRPG_EMPGC0_SRPGCR (MXC_SRPG_EMPGC0_BASE + 0x0)
+#define MXC_SRPG_EMPGC0_PUPSCR (MXC_SRPG_EMPGC0_BASE + 0x4)
+#define MXC_SRPG_EMPGC0_PDNSCR (MXC_SRPG_EMPGC0_BASE + 0x8)
+
+#define MXC_SRPG_EMPGC1_SRPGCR (MXC_SRPG_EMPGC1_BASE + 0x0)
+#define MXC_SRPG_EMPGC1_PUPSCR (MXC_SRPG_EMPGC1_BASE + 0x4)
+#define MXC_SRPG_EMPGC1_PDNSCR (MXC_SRPG_EMPGC1_BASE + 0x8)
+
+#define MXC_SRPG_MEGAMIX_SRPGCR (MXC_SRPG_MEGAMIX_BASE + 0x0)
+#define MXC_SRPG_MEGAMIX_PUPSCR (MXC_SRPG_MEGAMIX_BASE + 0x4)
+#define MXC_SRPG_MEGAMIX_PDNSCR (MXC_SRPG_MEGAMIX_BASE + 0x8)
+
+#define MXC_SRPGC_EMI_SRPGCR (MXC_SRPGC_EMI_BASE + 0x0)
+#define MXC_SRPGC_EMI_PUPSCR (MXC_SRPGC_EMI_BASE + 0x4)
+#define MXC_SRPGC_EMI_PDNSCR (MXC_SRPGC_EMI_BASE + 0x8)
+
+#endif /* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */
diff --git a/arch/arm/mach-mx51/devices.c b/arch/arm/mach-mx51/devices.c
new file mode 100644
index 000000000000..7333263ff980
--- /dev/null
+++ b/arch/arm/mach-mx51/devices.c
@@ -0,0 +1,913 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/spi/spi.h>
+#include <mach/hardware.h>
+#include <mach/spba.h>
+#include "iomux.h"
+#include "crm_regs.h"
+#include <mach/sdma.h>
+#include "sdma_script_code.h"
+#include <mach/mxc_scc2_driver.h>
+
+/* Flag used to indicate when IRAM has been initialized */
+int iram_ready;
+
+void mxc_sdma_get_script_info(sdma_script_start_addrs * sdma_script_addr)
+{
+ /* AP<->BP */
+ sdma_script_addr->mxc_sdma_ap_2_ap_addr = ap_2_ap_ADDR;
+ sdma_script_addr->mxc_sdma_ap_2_bp_addr = -1;
+ sdma_script_addr->mxc_sdma_bp_2_ap_addr = -1;
+ sdma_script_addr->mxc_sdma_ap_2_ap_fixed_addr = -1;
+
+ /*misc */
+ sdma_script_addr->mxc_sdma_loopback_on_dsp_side_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_interrupt_only_addr = -1;
+
+ /* firi */
+ sdma_script_addr->mxc_sdma_firi_2_per_addr = -1;
+ sdma_script_addr->mxc_sdma_firi_2_mcu_addr = -1;
+ sdma_script_addr->mxc_sdma_per_2_firi_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_2_firi_addr = -1;
+
+ /* uart */
+ sdma_script_addr->mxc_sdma_uart_2_per_addr = uart_2_per_ADDR;
+ sdma_script_addr->mxc_sdma_uart_2_mcu_addr = uart_2_mcu_ADDR;
+
+ /* UART SH */
+ sdma_script_addr->mxc_sdma_uartsh_2_per_addr = uartsh_2_per_ADDR;
+ sdma_script_addr->mxc_sdma_uartsh_2_mcu_addr = uartsh_2_mcu_ADDR;
+
+ /* SHP */
+ sdma_script_addr->mxc_sdma_per_2_shp_addr = per_2_shp_ADDR;
+ sdma_script_addr->mxc_sdma_shp_2_per_addr = shp_2_per_ADDR;
+ sdma_script_addr->mxc_sdma_mcu_2_shp_addr = mcu_2_shp_ADDR;
+ sdma_script_addr->mxc_sdma_shp_2_mcu_addr = shp_2_mcu_ADDR;
+
+ /* ATA */
+ sdma_script_addr->mxc_sdma_mcu_2_ata_addr = mcu_2_ata_ADDR;
+ sdma_script_addr->mxc_sdma_ata_2_mcu_addr = ata_2_mcu_ADDR;
+
+ /* app */
+ sdma_script_addr->mxc_sdma_app_2_per_addr = app_2_per_ADDR;
+ sdma_script_addr->mxc_sdma_app_2_mcu_addr = app_2_mcu_ADDR;
+ sdma_script_addr->mxc_sdma_per_2_app_addr = per_2_app_ADDR;
+ sdma_script_addr->mxc_sdma_mcu_2_app_addr = mcu_2_app_ADDR;
+
+ /* MSHC */
+ sdma_script_addr->mxc_sdma_mshc_2_mcu_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_2_mshc_addr = -1;
+
+ /* spdif */
+ sdma_script_addr->mxc_sdma_spdif_2_mcu_addr = -1;
+ sdma_script_addr->mxc_sdma_mcu_2_spdif_addr = mcu_2_spdif_ADDR;
+
+ /* IPU */
+ sdma_script_addr->mxc_sdma_ext_mem_2_ipu_addr = ext_mem__ipu_ram_ADDR;
+
+ /* DVFS */
+ sdma_script_addr->mxc_sdma_dptc_dvfs_addr = -1;
+
+ /* core */
+ sdma_script_addr->mxc_sdma_start_addr = (unsigned short *)sdma_code;
+ sdma_script_addr->mxc_sdma_ram_code_start_addr = RAM_CODE_START_ADDR;
+ sdma_script_addr->mxc_sdma_ram_code_size = RAM_CODE_SIZE;
+}
+
+static void mxc_nop_release(struct device *dev)
+{
+ /* Nothing */
+}
+
+#if defined(CONFIG_W1_MASTER_MXC) || defined(CONFIG_W1_MASTER_MXC_MODULE)
+static struct resource w1_resources[] = {
+ {
+ .start = MXC_INT_OWIRE,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct mxc_w1_config mxc_w1_data = {
+ .search_rom_accelerator = 1,
+};
+
+static struct platform_device mxc_w1_devices = {
+ .name = "mxc_w1",
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_w1_data,
+ },
+ .num_resources = ARRAY_SIZE(w1_resources),
+ .resource = w1_resources,
+ .id = 0
+};
+
+static void mxc_init_owire(void)
+{
+ (void)platform_device_register(&mxc_w1_devices);
+}
+#else
+static inline void mxc_init_owire(void)
+{
+}
+#endif
+
+#if defined(CONFIG_RTC_DRV_MXC_V2) || defined(CONFIG_RTC_DRV_MXC_V2_MODULE)
+static struct mxc_srtc_platform_data srtc_data = {
+ .srtc_sec_mode_addr = 0x83F98840,
+};
+
+static struct resource rtc_resources[] = {
+ {
+ .start = SRTC_BASE_ADDR,
+ .end = SRTC_BASE_ADDR + 0x40,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_INT_SRTC_NTZ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+static struct platform_device mxc_rtc_device = {
+ .name = "mxc_rtc",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &srtc_data,
+ },
+ .num_resources = ARRAY_SIZE(rtc_resources),
+ .resource = rtc_resources,
+};
+static void mxc_init_rtc(void)
+{
+ (void)platform_device_register(&mxc_rtc_device);
+}
+#else
+static inline void mxc_init_rtc(void)
+{
+}
+#endif
+
+#if defined(CONFIG_MXC_WATCHDOG) || defined(CONFIG_MXC_WATCHDOG_MODULE)
+
+static struct resource wdt_resources[] = {
+ {
+ .start = WDOG1_BASE_ADDR,
+ .end = WDOG1_BASE_ADDR + 0x30,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device mxc_wdt_device = {
+ .name = "mxc_wdt",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(wdt_resources),
+ .resource = wdt_resources,
+};
+
+static void mxc_init_wdt(void)
+{
+ (void)platform_device_register(&mxc_wdt_device);
+}
+#else
+static inline void mxc_init_wdt(void)
+{
+}
+#endif
+
+#if defined(CONFIG_MXC_IPU_V3) || defined(CONFIG_MXC_IPU_V3_MODULE)
+static struct mxc_ipu_config mxc_ipu_data = {
+ .rev = 1,
+};
+
+static struct resource ipu_resources[] = {
+ {
+ .start = IPU_CTRL_BASE_ADDR,
+ .end = IPU_CTRL_BASE_ADDR + SZ_512M,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_INT_IPU_SYN,
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ .start = MXC_INT_IPU_ERR,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mxc_ipu_device = {
+ .name = "mxc_ipu",
+ .id = -1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_ipu_data,
+ },
+ .num_resources = ARRAY_SIZE(ipu_resources),
+ .resource = ipu_resources,
+};
+
+static void mxc_init_ipu(void)
+{
+ u32 reg_hsc_mcd = IO_ADDRESS(MIPI_HSC_BASE_ADDR);
+ u32 reg_hsc_mxt_conf = IO_ADDRESS(MIPI_HSC_BASE_ADDR + 0x800);
+ struct clk *clk;
+ uint32_t temp;
+
+ /* Select IPUv3 h/w version */
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) > 0)
+ mxc_ipu_data.rev = 2;
+
+ mxc_ipu_data.di_clk[1] = clk_get(NULL, "ipu_di_clk");
+ clk = clk_get(NULL, "tve_clk");
+ clk_set_parent(mxc_ipu_data.di_clk[1], clk);
+ clk_put(clk);
+
+ /* Temporarily setup MIPI module to legacy mode */
+ clk = clk_get(NULL, "mipi_hsp_clk");
+ if (!IS_ERR(clk)) {
+ clk_enable(clk);
+
+ /* Temporarily setup MIPI module to legacy mode */
+ __raw_writel(0xF00, reg_hsc_mcd);
+
+ /* CSI mode reserved*/
+ temp = __raw_readl(reg_hsc_mxt_conf);
+ __raw_writel(temp | 0x0FF, reg_hsc_mxt_conf);
+
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) > 0) {
+ temp = __raw_readl(reg_hsc_mxt_conf);
+ __raw_writel(temp | 0x10000, reg_hsc_mxt_conf);
+ }
+
+ clk_disable(clk);
+ clk_put(clk);
+ }
+ platform_device_register(&mxc_ipu_device);
+}
+#else
+static inline void mxc_init_ipu(void)
+{
+}
+#endif
+
+#if defined(CONFIG_MXC_VPU) || defined(CONFIG_MXC_VPU_MODULE)
+static struct resource vpu_resources[] = {
+ {
+ .start = VPU_IRAM_BASE_ADDR,
+ .end = VPU_IRAM_BASE_ADDR + VPU_IRAM_SIZE,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+/*! Platform Data for MXC VPU */
+static struct platform_device mxcvpu_device = {
+ .name = "mxc_vpu",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(vpu_resources),
+ .resource = vpu_resources,
+};
+
+static inline void mxc_init_vpu(void)
+{
+ if (platform_device_register(&mxcvpu_device) < 0)
+ printk(KERN_ERR "Error: Registering the VPU.\n");
+}
+#else
+static inline void mxc_init_vpu(void)
+{
+}
+#endif
+
+/*!
+ * This is platform device structure for adding SCC
+ */
+#if defined(CONFIG_MXC_SECURITY_SCC) || defined(CONFIG_MXC_SECURITY_SCC_MODULE)
+static struct platform_device mxc_scc_device = {
+ .name = "mxc_scc",
+ .id = 0,
+};
+
+static void mxc_init_scc(void)
+{
+ platform_device_register(&mxc_scc_device);
+}
+#else
+static inline void mxc_init_scc(void)
+{
+ uint32_t reg_value;
+ uint32_t reg_mask = 0;
+ uint8_t *UMID_base;
+ uint32_t *MAP_base;
+ uint8_t i;
+ uint32_t partition_no;
+ uint32_t scc_partno;
+ void *scm_ram_base;
+ void *scc_base;
+ uint8_t iram_partitions = 16;
+
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0)
+ iram_partitions = 12;
+
+ scc_base = ioremap((uint32_t) SCC_BASE_ADDR, 0x140);
+ if (scc_base == NULL) {
+ printk(KERN_ERR "FAILED TO MAP IRAM REGS\n");
+ return;
+ }
+ scm_ram_base = ioremap((uint32_t) IRAM_BASE_ADDR, IRAM_SIZE);
+ if (scm_ram_base == NULL) {
+ printk(KERN_ERR "FAILED TO MAP IRAM\n");
+ return;
+ }
+
+ for (partition_no = 0; partition_no < iram_partitions; partition_no++) {
+ reg_value = ((partition_no << SCM_ZCMD_PART_SHIFT) &
+ SCM_ZCMD_PART_MASK) | ((0x03 <<
+ SCM_ZCMD_CCMD_SHIFT)
+ & SCM_ZCMD_CCMD_MASK);
+ __raw_writel(reg_value, scc_base + SCM_ZCMD_REG);
+
+ while ((__raw_readl(scc_base + SCM_STATUS_REG) &
+ SCM_STATUS_SRS_READY) != SCM_STATUS_SRS_READY) ;
+
+ __raw_writel(0, scc_base + (SCM_SMID0_REG + 8 * partition_no));
+
+ reg_mask |= (3 << (2 * (partition_no)));
+ }
+
+ msleep(1);
+ reg_value = __raw_readl(scc_base + SCM_PART_OWNERS_REG);
+
+ if ((reg_value & reg_mask) != reg_mask) {
+ printk(KERN_ERR "FAILED TO ACQUIRE IRAM PARTITION\n");
+ iounmap(scm_ram_base);
+ iounmap(scc_base);
+ return;
+ }
+
+ for (partition_no = 0; partition_no < iram_partitions; partition_no++) {
+ MAP_base = scm_ram_base + (partition_no * 0x2000);
+ UMID_base = (uint8_t *) MAP_base + 0x10;
+
+ for (i = 0; i < 16; i++)
+ UMID_base[i] = 0;
+
+ MAP_base[0] = SCM_PERM_NO_ZEROIZE | SCM_PERM_HD_SUP_DISABLE |
+ SCM_PERM_HD_READ | SCM_PERM_HD_WRITE |
+ SCM_PERM_TH_READ | SCM_PERM_TH_WRITE;
+
+ }
+
+ /* Freeing 2 partitions for SCC2 */
+ scc_partno = iram_partitions - (SCC_IRAM_SIZE / SZ_8K);
+ for (partition_no = scc_partno; partition_no < iram_partitions;
+ partition_no++) {
+ reg_value = ((partition_no << SCM_ZCMD_PART_SHIFT) &
+ SCM_ZCMD_PART_MASK) | ((0x03 <<
+ SCM_ZCMD_CCMD_SHIFT)
+ & SCM_ZCMD_CCMD_MASK);
+ __raw_writel(reg_value, scc_base + SCM_ZCMD_REG);
+
+ while ((__raw_readl(scc_base + SCM_STATUS_REG) &
+ SCM_STATUS_SRS_READY) != SCM_STATUS_SRS_READY) ;
+ }
+ iounmap(scm_ram_base);
+ iounmap(scc_base);
+ printk(KERN_INFO "IRAM READY\n");
+ iram_ready = 1;
+}
+#endif
+
+/* SPI controller and device data */
+#if defined(CONFIG_SPI_MXC) || defined(CONFIG_SPI_MXC_MODULE)
+
+#ifdef CONFIG_SPI_MXC_SELECT1
+/*!
+ * Resource definition for the CSPI1
+ */
+static struct resource mxcspi1_resources[] = {
+ [0] = {
+ .start = CSPI1_BASE_ADDR,
+ .end = CSPI1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_CSPI1,
+ .end = MXC_INT_CSPI1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC CSPI1 */
+static struct mxc_spi_master mxcspi1_data = {
+ .maxchipselect = 4,
+ .spi_version = 23,
+};
+
+/*! Device Definition for MXC CSPI1 */
+static struct platform_device mxcspi1_device = {
+ .name = "mxc_spi",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxcspi1_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcspi1_resources),
+ .resource = mxcspi1_resources,
+};
+
+#endif /* CONFIG_SPI_MXC_SELECT1 */
+
+#ifdef CONFIG_SPI_MXC_SELECT2
+/*!
+ * Resource definition for the CSPI2
+ */
+static struct resource mxcspi2_resources[] = {
+ [0] = {
+ .start = CSPI2_BASE_ADDR,
+ .end = CSPI2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_CSPI2,
+ .end = MXC_INT_CSPI2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC CSPI2 */
+static struct mxc_spi_master mxcspi2_data = {
+ .maxchipselect = 4,
+ .spi_version = 23,
+};
+
+/*! Device Definition for MXC CSPI2 */
+static struct platform_device mxcspi2_device = {
+ .name = "mxc_spi",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxcspi2_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcspi2_resources),
+ .resource = mxcspi2_resources,
+};
+#endif /* CONFIG_SPI_MXC_SELECT2 */
+
+#ifdef CONFIG_SPI_MXC_SELECT3
+/*!
+ * Resource definition for the CSPI3
+ */
+static struct resource mxcspi3_resources[] = {
+ [0] = {
+ .start = CSPI3_BASE_ADDR,
+ .end = CSPI3_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_CSPI,
+ .end = MXC_INT_CSPI,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC CSPI3 */
+static struct mxc_spi_master mxcspi3_data = {
+ .maxchipselect = 4,
+ .spi_version = 7,
+};
+
+/*! Device Definition for MXC CSPI3 */
+static struct platform_device mxcspi3_device = {
+ .name = "mxc_spi",
+ .id = 2,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxcspi3_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcspi3_resources),
+ .resource = mxcspi3_resources,
+};
+#endif /* CONFIG_SPI_MXC_SELECT3 */
+
+void __init mxc_init_spi(void)
+{
+ /* SPBA configuration for CSPI2 - MCU is set */
+ spba_take_ownership(SPBA_CSPI1, SPBA_MASTER_A);
+#ifdef CONFIG_SPI_MXC_SELECT1
+ if (platform_device_register(&mxcspi1_device) < 0)
+ printk(KERN_ERR "Error: Registering the SPI Controller_1\n");
+#endif /* CONFIG_SPI_MXC_SELECT1 */
+#ifdef CONFIG_SPI_MXC_SELECT2
+ if (platform_device_register(&mxcspi2_device) < 0)
+ printk(KERN_ERR "Error: Registering the SPI Controller_2\n");
+#endif /* CONFIG_SPI_MXC_SELECT2 */
+#ifdef CONFIG_SPI_MXC_SELECT3
+ if (platform_device_register(&mxcspi3_device) < 0)
+ printk(KERN_ERR "Error: Registering the SPI Controller_3\n");
+#endif /* CONFIG_SPI_MXC_SELECT3 */
+}
+#else
+void __init mxc_init_spi(void)
+{
+}
+#endif
+
+/* I2C controller and device data */
+#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE)
+
+#ifdef CONFIG_I2C_MXC_SELECT1
+/*!
+ * Resource definition for the I2C1
+ */
+static struct resource mxci2c1_resources[] = {
+ [0] = {
+ .start = I2C1_BASE_ADDR,
+ .end = I2C1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_I2C1,
+ .end = MXC_INT_I2C1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC I2C */
+static struct mxc_i2c_platform_data mxci2c1_data = {
+ .i2c_clk = 100000,
+};
+#endif
+
+#ifdef CONFIG_I2C_MXC_SELECT2
+/*!
+ * Resource definition for the I2C2
+ */
+static struct resource mxci2c2_resources[] = {
+ [0] = {
+ .start = I2C2_BASE_ADDR,
+ .end = I2C2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_I2C2,
+ .end = MXC_INT_I2C2,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC I2C */
+static struct mxc_i2c_platform_data mxci2c2_data = {
+ .i2c_clk = 100000,
+};
+#endif
+
+#ifdef CONFIG_I2C_MXC_SELECT3
+/*!
+ * Resource definition for the I2C3
+ */
+static struct resource mxci2c3_resources[] = {
+ [0] = {
+ .start = I2C3_BASE_ADDR,
+ .end = I2C3_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_I2C3,
+ .end = MXC_INT_I2C3,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC I2C */
+static struct mxc_i2c_platform_data mxci2c3_data = {
+ .i2c_clk = 100000,
+};
+#endif
+
+/*! Device Definition for MXC I2C1 */
+static struct platform_device mxci2c_devices[] = {
+#ifdef CONFIG_I2C_MXC_SELECT1
+ {
+ .name = "mxc_i2c",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxci2c1_data,
+ },
+ .num_resources = ARRAY_SIZE(mxci2c1_resources),
+ .resource = mxci2c1_resources,},
+#endif
+#ifdef CONFIG_I2C_MXC_SELECT2
+ {
+ .name = "mxc_i2c",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxci2c2_data,
+ },
+ .num_resources = ARRAY_SIZE(mxci2c2_resources),
+ .resource = mxci2c2_resources,},
+#endif
+#ifdef CONFIG_I2C_MXC_SELECT3
+ {
+ .name = "mxc_i2c",
+ .id = 2,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxci2c3_data,
+ },
+ .num_resources = ARRAY_SIZE(mxci2c3_resources),
+ .resource = mxci2c3_resources,},
+#endif
+};
+
+static inline void mxc_init_i2c(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(mxci2c_devices); i++) {
+ if (platform_device_register(&mxci2c_devices[i]) < 0)
+ dev_err(&mxci2c_devices[i].dev,
+ "Unable to register I2C device\n");
+ }
+}
+#else
+static inline void mxc_init_i2c(void)
+{
+}
+#endif
+
+#if defined(CONFIG_I2C_MXC_HS) || defined(CONFIG_I2C_MXC_HS_MODULE)
+static struct resource mxci2c_hs_resources[] = {
+ [0] = {
+ .start = HSI2C_DMA_BASE_ADDR,
+ .end = HSI2C_DMA_BASE_ADDR + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_HS_I2C,
+ .end = MXC_INT_HS_I2C,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for MXC I2C */
+static struct mxc_i2c_platform_data mxci2c_hs_data = {
+ .i2c_clk = 400000,
+};
+
+static struct platform_device mxci2c_hs_device = {
+ .name = "mxc_i2c_hs",
+ .id = 3,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxci2c_hs_data,
+ },
+ .num_resources = ARRAY_SIZE(mxci2c_hs_resources),
+ .resource = mxci2c_hs_resources
+};
+
+static inline void mxc_init_i2c_hs(void)
+{
+ if (platform_device_register(&mxci2c_hs_device) < 0)
+ dev_err(&mxci2c_hs_device.dev,
+ "Unable to register High Speed I2C device\n");
+}
+#else
+static inline void mxc_init_i2c_hs(void)
+{
+}
+#endif
+
+#if defined(CONFIG_FB_MXC_TVOUT_TVE) || defined(CONFIG_FB_MXC_TVOUT_TVE_MODULE)
+static struct resource tve_resources[] = {
+ {
+ .start = TVE_BASE_ADDR,
+ .end = TVE_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = MXC_INT_TVE,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+static struct tve_platform_data tve_data = {
+ .dac_reg = "VVIDEO",
+ .dig_reg = "VDIG",
+};
+
+static struct platform_device mxc_tve_device = {
+ .name = "tve",
+ .dev = {
+ .platform_data = &tve_data,
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(tve_resources),
+ .resource = tve_resources,
+};
+
+void __init mxc_init_tve(void)
+{
+ platform_device_register(&mxc_tve_device);
+}
+#else
+static inline void mxc_init_tve(void)
+{
+}
+#endif
+
+/*!
+ * Resource definition for the DVFS CORE
+ */
+static struct resource dvfs_core_resources[] = {
+ [0] = {
+ .start = MXC_DVFS_CORE_BASE,
+ .end = MXC_DVFS_CORE_BASE + 4 * SZ_16 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_GPC1,
+ .end = MXC_INT_GPC1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Platform Data for DVFS CORE */
+struct mxc_dvfs_platform_data dvfs_core_data = {
+ .reg_id = "SW1",
+ .clk1_id = "cpu_clk",
+ .clk2_id = "gpc_dvfs_clk",
+ .gpc_cntr_reg_addr = MXC_GPC_CNTR,
+ .gpc_vcr_reg_addr = MXC_GPC_VCR,
+ .dvfs_thrs_reg_addr = MXC_DVFSTHRS,
+ .dvfs_coun_reg_addr = MXC_DVFSCOUN,
+ .dvfs_emac_reg_addr = MXC_DVFSEMAC,
+ .dvfs_cntr_reg_addr = MXC_DVFSCNTR,
+ .div3ck_mask = 0xE0000000,
+ .div3ck_offset = 29,
+ .div3ck_val = 2,
+ .emac_val = 0x10,
+ .upthr_val = 25,
+ .dnthr_val = 9,
+ .pncthr_val = 33,
+ .upcnt_val = 3,
+ .dncnt_val = 3,
+ .delay_time = 30,
+ .num_wp = 2,
+};
+
+/*! Device Definition for MXC DVFS core */
+static struct platform_device mxc_dvfs_core_device = {
+ .name = "mxc_dvfs_core",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &dvfs_core_data,
+ },
+ .num_resources = ARRAY_SIZE(dvfs_core_resources),
+ .resource = dvfs_core_resources,
+};
+
+static inline void mxc_init_dvfs(void)
+{
+ if (platform_device_register(&mxc_dvfs_core_device) < 0)
+ dev_err(&mxc_dvfs_core_device.dev,
+ "Unable to register DVFS core device\n");
+}
+
+struct mxc_gpio_port mxc_gpio_ports[GPIO_PORT_NUM] = {
+ {
+ .num = 0,
+ .base = IO_ADDRESS(GPIO1_BASE_ADDR),
+ .irq_0_15 = MXC_INT_GPIO1_LOW,
+ .irq_16_31 = MXC_INT_GPIO1_HIGH,
+ .virtual_irq_start = MXC_GPIO_INT_BASE,
+ },
+ {
+ .num = 1,
+ .base = IO_ADDRESS(GPIO2_BASE_ADDR),
+ .irq_0_15 = MXC_INT_GPIO2_LOW,
+ .irq_16_31 = MXC_INT_GPIO2_HIGH,
+ .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 1,
+ },
+ {
+ .num = 2,
+ .base = IO_ADDRESS(GPIO3_BASE_ADDR),
+ .irq_0_15 = MXC_INT_GPIO3_LOW,
+ .irq_16_31 = MXC_INT_GPIO3_HIGH,
+ .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 2,
+ },
+ {
+ .num = 3,
+ .base = IO_ADDRESS(GPIO4_BASE_ADDR),
+ .irq_0_15 = MXC_INT_GPIO4_LOW,
+ .irq_16_31 = MXC_INT_GPIO4_HIGH,
+ .virtual_irq_start = MXC_GPIO_INT_BASE + GPIO_NUM_PIN * 3,
+ },
+};
+
+static struct platform_device mxc_dma_device = {
+ .name = "mxc_dma",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+};
+
+static inline void mxc_init_dma(void)
+{
+ (void)platform_device_register(&mxc_dma_device);
+}
+
+static struct resource spdif_resources[] = {
+ {
+ .start = SPDIF_BASE_ADDR,
+ .end = SPDIF_BASE_ADDR + 0x50,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct mxc_spdif_platform_data mxc_spdif_data = {
+ .spdif_tx = 1,
+ .spdif_rx = 0,
+ .spdif_clk_44100 = 0, /* spdif_ext_clk source for 44.1KHz */
+ .spdif_clk_48000 = 7, /* audio osc source */
+ .spdif_clkid = 0,
+ .spdif_clk = NULL, /* spdif bus clk */
+};
+
+static struct platform_device mxc_alsa_spdif_device = {
+ .name = "mxc_alsa_spdif",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_spdif_data,
+ },
+ .num_resources = ARRAY_SIZE(spdif_resources),
+ .resource = spdif_resources,
+};
+
+static inline void mxc_init_spdif(void)
+{
+ mxc_spdif_data.spdif_core_clk = clk_get(NULL, "spdif_xtal_clk");
+ clk_put(mxc_spdif_data.spdif_core_clk);
+ platform_device_register(&mxc_alsa_spdif_device);
+}
+
+static struct platform_device mx51_lpmode_device = {
+ .name = "mx51_lpmode",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+};
+
+static inline void mx51_init_lpmode(void)
+{
+ (void)platform_device_register(&mx51_lpmode_device);
+}
+
+int __init mxc_init_devices(void)
+{
+ mxc_init_wdt();
+ mxc_init_spi();
+ mxc_init_i2c();
+ mxc_init_i2c_hs();
+ mxc_init_rtc();
+ mxc_init_scc();
+ mxc_init_dma();
+ mxc_init_owire();
+ mxc_init_ipu();
+ mxc_init_vpu();
+ mxc_init_spdif();
+ mxc_init_tve();
+ mx51_init_lpmode();
+ mxc_init_dvfs();
+ return 0;
+}
diff --git a/arch/arm/mach-mx51/dma.c b/arch/arm/mach-mx51/dma.c
new file mode 100644
index 000000000000..a27d7e2a2349
--- /dev/null
+++ b/arch/arm/mach-mx51/dma.c
@@ -0,0 +1,666 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/init.h>
+#include <linux/device.h>
+#include <asm/dma.h>
+#include <mach/hardware.h>
+
+#include "serial.h"
+
+#define MXC_MMC_BUFFER_ACCESS 0x20
+#define MXC_SDHC_MMC_WML 64
+#define MXC_SDHC_SD_WML 256
+#define MXC_SSI_TX0_REG 0x0
+#define MXC_SSI_TX1_REG 0x4
+#define MXC_SSI_RX0_REG 0x8
+#define MXC_SSI_RX1_REG 0xC
+#define MXC_SSI_TXFIFO_WML 0x4
+#define MXC_SSI_RXFIFO_WML 0x6
+#define MXC_SPDIF_TXFIFO_WML 0x8
+#define MXC_SPDIF_TX_REG 0x2C
+
+typedef struct mxc_sdma_info_entry_s {
+ mxc_dma_device_t device;
+ mxc_sdma_channel_params_t *chnl_info;
+} mxc_sdma_info_entry_t;
+
+static mxc_sdma_channel_params_t mxc_sdma_uart1_rx_params = {
+ .chnl_params = {
+ .watermark_level = UART1_UFCR_RXTL,
+ .per_address = UART1_BASE_ADDR,
+ .peripheral_type = UART,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_UART1_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART1_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart1_tx_params = {
+ .chnl_params = {
+ .watermark_level = UART1_UFCR_TXTL,
+ .per_address = UART1_BASE_ADDR + MXC_UARTUTXD,
+ .peripheral_type = UART,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_UART1_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART1_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart2_rx_params = {
+ .chnl_params = {
+ .watermark_level = UART2_UFCR_RXTL,
+ .per_address = UART2_BASE_ADDR,
+ .peripheral_type = UART,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_UART2_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART2_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart2_tx_params = {
+ .chnl_params = {
+ .watermark_level = UART2_UFCR_TXTL,
+ .per_address = UART2_BASE_ADDR + MXC_UARTUTXD,
+ .peripheral_type = UART,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_UART2_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART2_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart3_rx_params = {
+ .chnl_params = {
+ .watermark_level = UART3_UFCR_RXTL,
+ .per_address = UART3_BASE_ADDR,
+ .peripheral_type = UART_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_UART3_RX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART3_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_uart3_tx_params = {
+ .chnl_params = {
+ .watermark_level = UART3_UFCR_TXTL,
+ .per_address = UART3_BASE_ADDR + MXC_UARTUTXD,
+ .peripheral_type = UART_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_UART3_TX,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_UART3_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_mmc1_width1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SDHC_MMC_WML,
+ .per_address =
+ MMC_SDHC1_BASE_ADDR + MXC_MMC_BUFFER_ACCESS,
+ .peripheral_type = MMC,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SDHC1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_MMC1,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_mmc1_width4_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SDHC_SD_WML,
+ .per_address =
+ MMC_SDHC1_BASE_ADDR + MXC_MMC_BUFFER_ACCESS,
+ .peripheral_type = MMC,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SDHC1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_MMC1,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_mmc2_width1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SDHC_MMC_WML,
+ .per_address =
+ MMC_SDHC2_BASE_ADDR + MXC_MMC_BUFFER_ACCESS,
+ .peripheral_type = MMC,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SDHC2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_MMC2,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_mmc2_width4_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SDHC_SD_WML,
+ .per_address =
+ MMC_SDHC2_BASE_ADDR + MXC_MMC_BUFFER_ACCESS,
+ .peripheral_type = MMC,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SDHC2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_MMC2,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_8bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_16bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI1_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi1_24bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI1_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI1_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI1_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_rx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_tx0_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX0_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX1,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_8bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_8BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_16bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_rx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_RXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_RX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_SSI2_RX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_RX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ssi2_24bit_tx1_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SSI_TXFIFO_WML,
+ .per_address = SSI2_BASE_ADDR + MXC_SSI_TX1_REG,
+ .peripheral_type = SSI_SP,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SSI2_TX2,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SSI2_TX,
+ .chnl_priority = 2,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_memory_params = {
+ .chnl_params = {
+ .peripheral_type = MEMORY,
+ .transfer_type = emi_2_emi,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_MEMORY,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ata_rx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_IDE_DMA_WATERMARK,
+ .per_address = ATA_DMA_BASE_ADDR,
+ .peripheral_type = ATA,
+ .transfer_type = per_2_emi,
+ .event_id = DMA_REQ_ATA_TX_END,
+ .event_id2 = DMA_REQ_ATA_RX,
+ .bd_number = MXC_IDE_DMA_BD_NR,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_ATA_RX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_ata_tx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_IDE_DMA_WATERMARK,
+ .per_address = ATA_DMA_BASE_ADDR + 0x18,
+ .peripheral_type = ATA,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_ATA_TX_END,
+ .event_id2 = DMA_REQ_ATA_TX,
+ .bd_number = MXC_IDE_DMA_BD_NR,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_ATA_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_spdif_16bit_tx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SPDIF_TXFIFO_WML,
+ .per_address = SPDIF_BASE_ADDR + MXC_SPDIF_TX_REG,
+ .peripheral_type = SPDIF,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SPDIF,
+ .bd_number = 32,
+ .word_size = TRANSFER_16BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SPDIF_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_channel_params_t mxc_sdma_spdif_32bit_tx_params = {
+ .chnl_params = {
+ .watermark_level = MXC_SPDIF_TXFIFO_WML,
+ .per_address = SPDIF_BASE_ADDR + MXC_SPDIF_TX_REG,
+ .peripheral_type = SPDIF,
+ .transfer_type = emi_2_per,
+ .event_id = DMA_REQ_SPDIF,
+ .bd_number = 32,
+ .word_size = TRANSFER_32BIT,
+ },
+ .channel_num = MXC_DMA_CHANNEL_SPDIF_TX,
+ .chnl_priority = MXC_SDMA_DEFAULT_PRIORITY,
+};
+
+static mxc_sdma_info_entry_t mxc_sdma_active_dma_info[] = {
+ {MXC_DMA_UART1_RX, &mxc_sdma_uart1_rx_params},
+ {MXC_DMA_UART1_TX, &mxc_sdma_uart1_tx_params},
+ {MXC_DMA_UART2_RX, &mxc_sdma_uart2_rx_params},
+ {MXC_DMA_UART2_TX, &mxc_sdma_uart2_tx_params},
+ {MXC_DMA_UART3_RX, &mxc_sdma_uart3_rx_params},
+ {MXC_DMA_UART3_TX, &mxc_sdma_uart3_tx_params},
+ {MXC_DMA_MMC1_WIDTH_1, &mxc_sdma_mmc1_width1_params},
+ {MXC_DMA_MMC1_WIDTH_4, &mxc_sdma_mmc1_width4_params},
+ {MXC_DMA_MMC2_WIDTH_1, &mxc_sdma_mmc2_width1_params},
+ {MXC_DMA_MMC2_WIDTH_4, &mxc_sdma_mmc2_width4_params},
+ {MXC_DMA_SSI1_8BIT_RX0, &mxc_sdma_ssi1_8bit_rx0_params},
+ {MXC_DMA_SSI1_8BIT_TX0, &mxc_sdma_ssi1_8bit_tx0_params},
+ {MXC_DMA_SSI1_16BIT_RX0, &mxc_sdma_ssi1_16bit_rx0_params},
+ {MXC_DMA_SSI1_16BIT_TX0, &mxc_sdma_ssi1_16bit_tx0_params},
+ {MXC_DMA_SSI1_24BIT_RX0, &mxc_sdma_ssi1_24bit_rx0_params},
+ {MXC_DMA_SSI1_24BIT_TX0, &mxc_sdma_ssi1_24bit_tx0_params},
+ {MXC_DMA_SSI1_8BIT_RX1, &mxc_sdma_ssi1_8bit_rx1_params},
+ {MXC_DMA_SSI1_8BIT_TX1, &mxc_sdma_ssi1_8bit_tx1_params},
+ {MXC_DMA_SSI1_16BIT_RX1, &mxc_sdma_ssi1_16bit_rx1_params},
+ {MXC_DMA_SSI1_16BIT_TX1, &mxc_sdma_ssi1_16bit_tx1_params},
+ {MXC_DMA_SSI1_24BIT_RX1, &mxc_sdma_ssi1_24bit_rx1_params},
+ {MXC_DMA_SSI1_24BIT_TX1, &mxc_sdma_ssi1_24bit_tx1_params},
+ {MXC_DMA_SSI2_8BIT_RX0, &mxc_sdma_ssi2_8bit_rx0_params},
+ {MXC_DMA_SSI2_8BIT_TX0, &mxc_sdma_ssi2_8bit_tx0_params},
+ {MXC_DMA_SSI2_16BIT_RX0, &mxc_sdma_ssi2_16bit_rx0_params},
+ {MXC_DMA_SSI2_16BIT_TX0, &mxc_sdma_ssi2_16bit_tx0_params},
+ {MXC_DMA_SSI2_24BIT_RX0, &mxc_sdma_ssi2_24bit_rx0_params},
+ {MXC_DMA_SSI2_24BIT_TX0, &mxc_sdma_ssi2_24bit_tx0_params},
+ {MXC_DMA_SSI2_8BIT_RX1, &mxc_sdma_ssi2_8bit_rx1_params},
+ {MXC_DMA_SSI2_8BIT_TX1, &mxc_sdma_ssi2_8bit_tx1_params},
+ {MXC_DMA_SSI2_16BIT_RX1, &mxc_sdma_ssi2_16bit_rx1_params},
+ {MXC_DMA_SSI2_16BIT_TX1, &mxc_sdma_ssi2_16bit_tx1_params},
+ {MXC_DMA_SSI2_24BIT_RX1, &mxc_sdma_ssi2_24bit_rx1_params},
+ {MXC_DMA_SSI2_24BIT_TX1, &mxc_sdma_ssi2_24bit_tx1_params},
+ {MXC_DMA_MEMORY, &mxc_sdma_memory_params},
+ {MXC_DMA_ATA_RX, &mxc_sdma_ata_rx_params},
+ {MXC_DMA_ATA_TX, &mxc_sdma_ata_tx_params},
+ {MXC_DMA_SPDIF_16BIT_TX, &mxc_sdma_spdif_16bit_tx_params},
+ {MXC_DMA_SPDIF_32BIT_TX, &mxc_sdma_spdif_32bit_tx_params},
+};
+
+static int mxc_sdma_info_entrys =
+ sizeof(mxc_sdma_active_dma_info) / sizeof(mxc_sdma_active_dma_info[0]);
+
+/*!
+ * This functions Returns the SDMA paramaters associated for a module
+ *
+ * @param channel_id the ID of the module requesting DMA
+ * @return returns the sdma parameters structure for the device
+ */
+mxc_sdma_channel_params_t *mxc_sdma_get_channel_params(mxc_dma_device_t
+ channel_id)
+{
+ mxc_sdma_info_entry_t *p = mxc_sdma_active_dma_info;
+ int i;
+
+ for (i = 0; i < mxc_sdma_info_entrys; i++, p++) {
+ if (p->device == channel_id)
+ return p->chnl_info;
+
+ }
+ return NULL;
+}
+
+/*!
+ * This functions marks the SDMA channels that are statically allocated
+ *
+ * @param chnl the channel array used to store channel information
+ */
+void mxc_get_static_channels(mxc_dma_channel_t *chnl)
+{
+#ifdef CONFIG_SDMA_IRAM
+ int i;
+ for (i = MXC_DMA_CHANNEL_IRAM; i < MAX_DMA_CHANNELS; i++)
+ chnl[i].dynamic = 0;
+#endif
+}
+
+EXPORT_SYMBOL(mxc_sdma_get_channel_params);
+EXPORT_SYMBOL(mxc_get_static_channels);
diff --git a/arch/arm/mach-mx51/iomux.c b/arch/arm/mach-mx51/iomux.c
new file mode 100644
index 000000000000..57e7cb1f5205
--- /dev/null
+++ b/arch/arm/mach-mx51/iomux.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup GPIO_MX51 Board GPIO and Muxing Setup
+ * @ingroup MSL_MX51
+ */
+/*!
+ * @file mach-mx51/iomux.c
+ *
+ * @brief I/O Muxing control functions
+ *
+ * @ingroup GPIO_MX51
+ */
+
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <mach/hardware.h>
+#include <mach/gpio.h>
+#include "iomux.h"
+
+/*!
+ * IOMUX register (base) addresses
+ */
+enum iomux_reg_addr {
+ IOMUXGPR0 = IO_ADDRESS(IOMUXC_BASE_ADDR),
+ IOMUXGPR1 = IO_ADDRESS(IOMUXC_BASE_ADDR) + 0x004,
+ IOMUXSW_MUX_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR),
+ IOMUXSW_MUX_END = IO_ADDRESS(IOMUXC_BASE_ADDR) + MUX_I_END,
+ IOMUXSW_PAD_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR) + PAD_I_START,
+ IOMUXSW_INPUT_CTL = IO_ADDRESS(IOMUXC_BASE_ADDR),
+};
+
+#define MUX_PIN_NUM_MAX (((MUX_I_END - MUX_I_START) >> 2) + 1)
+
+static u8 iomux_pin_res_table[MUX_PIN_NUM_MAX];
+static DEFINE_SPINLOCK(gpio_mux_lock);
+
+static inline u32 _get_mux_reg(iomux_pin_name_t pin)
+{
+ u32 mux_reg = PIN_TO_IOMUX_MUX(pin);
+
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) {
+ if ((pin == MX51_PIN_NANDF_RB5) ||
+ (pin == MX51_PIN_NANDF_RB6) ||
+ (pin == MX51_PIN_NANDF_RB7))
+ ; /* Do nothing */
+ else if (mux_reg >= 0x2FC)
+ mux_reg += 8;
+ else if (mux_reg >= 0x130)
+ mux_reg += 0xC;
+ }
+ mux_reg += IOMUXSW_MUX_CTL;
+ return mux_reg;
+}
+
+static inline u32 _get_pad_reg(iomux_pin_name_t pin)
+{
+ u32 pad_reg = PIN_TO_IOMUX_PAD(pin);
+
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) {
+ if ((pin == MX51_PIN_NANDF_RB5) ||
+ (pin == MX51_PIN_NANDF_RB6) ||
+ (pin == MX51_PIN_NANDF_RB7))
+ ; /* Do nothing */
+ else if (pad_reg == 0x4D0 - PAD_I_START)
+ pad_reg += 0x4C;
+ else if (pad_reg == 0x860 - PAD_I_START)
+ pad_reg += 0x9C;
+ else if (pad_reg >= 0x804 - PAD_I_START)
+ pad_reg += 0xB0;
+ else if (pad_reg >= 0x7FC - PAD_I_START)
+ pad_reg += 0xB4;
+ else if (pad_reg >= 0x4E4 - PAD_I_START)
+ pad_reg += 0xCC;
+ else
+ pad_reg += 8;
+ }
+ pad_reg += IOMUXSW_PAD_CTL;
+ return pad_reg;
+}
+
+static inline u32 _get_mux_end(void)
+{
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0)
+ return(IO_ADDRESS(IOMUXC_BASE_ADDR) + (0x3F8 - 4));
+ else
+ return(IO_ADDRESS(IOMUXC_BASE_ADDR) + (0x3F0 - 4));
+}
+
+/*!
+ * This function is used to configure a pin through the IOMUX module.
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param config a configuration as defined in \b #iomux_pin_cfg_t
+ *
+ * @return 0 if successful; Non-zero otherwise
+ */
+static int iomux_config_mux(iomux_pin_name_t pin, iomux_pin_cfg_t config)
+{
+ u32 ret = 0;
+ u32 pin_index = PIN_TO_IOMUX_INDEX(pin);
+ u32 mux_reg = _get_mux_reg(pin);
+ u32 mux_data = 0;
+ u8 *rp;
+
+ BUG_ON((mux_reg > _get_mux_end()) || (mux_reg < IOMUXSW_MUX_CTL));
+ spin_lock(&gpio_mux_lock);
+
+ if (config == IOMUX_CONFIG_GPIO)
+ mux_data = PIN_TO_ALT_GPIO(pin);
+ else
+ mux_data = config;
+
+ __raw_writel(mux_data, mux_reg);
+
+ /*
+ * Log a warning if a pin changes ownership
+ */
+ rp = iomux_pin_res_table + pin_index;
+ if ((mux_data & *rp) && (*rp != mux_data)) {
+ /*
+ * Don't call printk if we're tweaking the console uart or
+ * we'll deadlock.
+ */
+ printk(KERN_ERR "iomux_config_mux: Warning: iomux pin"
+ " config changed, pin=%d, "
+ " prev=0x%x new=0x%x\n", mux_reg, *rp, mux_data);
+ ret = -EINVAL;
+ }
+ *rp = mux_data;
+ spin_unlock(&gpio_mux_lock);
+ return ret;
+}
+
+/*!
+ * Request ownership for an IO pin. This function has to be the first one
+ * being called before that pin is used. The caller has to check the
+ * return value to make sure it returns 0.
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param config a configuration as defined in \b #iomux_pin_cfg_t
+ *
+ * @return 0 if successful; Non-zero otherwise
+ */
+int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t config)
+{
+ int ret = iomux_config_mux(pin, config);
+ int gpio_port = GPIO_TO_PORT(IOMUX_TO_GPIO(pin));
+
+ if (!ret && (gpio_port != NON_GPIO_PORT)
+ && ((config == IOMUX_CONFIG_GPIO)
+ || (config == PIN_TO_ALT_GPIO(pin))))
+ ret |= mxc_request_gpio(pin);
+
+ return ret;
+}
+EXPORT_SYMBOL(mxc_request_iomux);
+
+/*!
+ * Release ownership for an IO pin
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param config config as defined in \b #iomux_pin_ocfg_t
+ */
+void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t config)
+{
+ u32 pin_index = PIN_TO_IOMUX_INDEX(pin);
+ u8 *rp = iomux_pin_res_table + pin_index;
+ int gpio_port = GPIO_TO_PORT(IOMUX_TO_GPIO(pin));
+
+ *rp = 0;
+ if ((gpio_port != NON_GPIO_PORT)
+ && ((config == IOMUX_CONFIG_GPIO)
+ || (config == PIN_TO_ALT_GPIO(pin))))
+ mxc_free_gpio(pin);
+
+}
+EXPORT_SYMBOL(mxc_free_iomux);
+
+/*!
+ * This function configures the pad value for a IOMUX pin.
+ *
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param config the ORed value of elements defined in \b #iomux_pad_config_t
+ */
+void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config)
+{
+ u32 pad_reg = _get_pad_reg(pin);
+
+ BUG_ON(pad_reg < IOMUXSW_PAD_CTL);
+ __raw_writel(config, pad_reg);
+}
+EXPORT_SYMBOL(mxc_iomux_set_pad);
+
+unsigned int mxc_iomux_get_pad(iomux_pin_name_t pin)
+{
+ u32 pad_reg = _get_pad_reg(pin);
+
+ return __raw_readl(pad_reg);
+}
+EXPORT_SYMBOL(mxc_iomux_get_pad);
+
+/*!
+ * This function configures input path.
+ *
+ * @param input index of input select register as defined in \b #iomux_input_select_t
+ * @param config the binary value of elements defined in \b #iomux_input_config_t
+ * */
+void mxc_iomux_set_input(iomux_input_select_t input, u32 config)
+{
+ u32 reg = IOMUXSW_INPUT_CTL + (input << 2);
+
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) {
+ if (input == MUX_IN_IPU_IPP_DI_0_IND_DISPB_SD_D_SELECT_INPUT)
+ input -= 4;
+ else if (input == MUX_IN_IPU_IPP_DI_1_IND_DISPB_SD_D_SELECT_INPUT)
+ input -= 3;
+ else if (input >= MUX_IN_KPP_IPP_IND_COL_6_SELECT_INPUT)
+ input -= 2;
+ else if (input >= MUX_IN_HSC_MIPI_MIX_PAR_SISG_TRIG_SELECT_INPUT)
+ input -= 5;
+ else if (input >= MUX_IN_HSC_MIPI_MIX_IPP_IND_SENS1_DATA_EN_SELECT_INPUT)
+ input -= 3;
+ else if (input >= MUX_IN_ECSPI2_IPP_IND_SS_B_3_SELECT_INPUT)
+ input -= 2;
+ else if (input >= MUX_IN_CCM_PLL1_BYPASS_CLK_SELECT_INPUT)
+ input -= 1;
+
+ reg += INPUT_CTL_START_TO1;
+ } else {
+ reg += INPUT_CTL_START;
+ }
+
+
+ BUG_ON(input >= MUX_INPUT_NUM_MUX);
+ __raw_writel(config, reg);
+}
+EXPORT_SYMBOL(mxc_iomux_set_input);
diff --git a/arch/arm/mach-mx51/iomux.h b/arch/arm/mach-mx51/iomux.h
new file mode 100644
index 000000000000..5f673d106984
--- /dev/null
+++ b/arch/arm/mach-mx51/iomux.h
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __MACH_MX51_IOMUX_H__
+#define __MACH_MX51_IOMUX_H__
+
+#include <linux/types.h>
+#include <mach/gpio.h>
+#include "mx51_pins.h"
+
+/*!
+ * @file mach-mx51/iomux.h
+ *
+ * @brief I/O Muxing control definitions and functions
+ *
+ * @ingroup GPIO_MX51
+ */
+
+/*!
+ * various IOMUX output functions
+ */
+typedef enum iomux_config {
+ IOMUX_CONFIG_ALT0, /*!< used as alternate function 0 */
+ IOMUX_CONFIG_ALT1, /*!< used as alternate function 1 */
+ IOMUX_CONFIG_ALT2, /*!< used as alternate function 2 */
+ IOMUX_CONFIG_ALT3, /*!< used as alternate function 3 */
+ IOMUX_CONFIG_ALT4, /*!< used as alternate function 4 */
+ IOMUX_CONFIG_ALT5, /*!< used as alternate function 5 */
+ IOMUX_CONFIG_ALT6, /*!< used as alternate function 6 */
+ IOMUX_CONFIG_ALT7, /*!< used as alternate function 7 */
+ IOMUX_CONFIG_GPIO, /*!< added to help user use GPIO mode */
+ IOMUX_CONFIG_SION = 0x1 << 4, /*!< used as LOOPBACK:MUX SION bit */
+} iomux_pin_cfg_t;
+
+/*!
+ * various IOMUX pad functions
+ */
+typedef enum iomux_pad_config {
+ PAD_CTL_SRE_SLOW = 0x0 << 0,
+ PAD_CTL_SRE_FAST = 0x1 << 0,
+ PAD_CTL_DRV_LOW = 0x0 << 1,
+ PAD_CTL_DRV_MEDIUM = 0x1 << 1,
+ PAD_CTL_DRV_HIGH = 0x2 << 1,
+ PAD_CTL_DRV_MAX = 0x3 << 1,
+ PAD_CTL_ODE_OPENDRAIN_NONE = 0x0 << 3,
+ PAD_CTL_ODE_OPENDRAIN_ENABLE = 0x1 << 3,
+ PAD_CTL_100K_PD = 0x0 << 4,
+ PAD_CTL_47K_PU = 0x1 << 4,
+ PAD_CTL_100K_PU = 0x2 << 4,
+ PAD_CTL_22K_PU = 0x3 << 4,
+ PAD_CTL_PUE_KEEPER = 0x0 << 6,
+ PAD_CTL_PUE_PULL = 0x1 << 6,
+ PAD_CTL_PKE_NONE = 0x0 << 7,
+ PAD_CTL_PKE_ENABLE = 0x1 << 7,
+ PAD_CTL_HYS_NONE = 0x0 << 8,
+ PAD_CTL_HYS_ENABLE = 0x1 << 8,
+ PAD_CTL_DDR_INPUT_CMOS = 0x0 << 9,
+ PAD_CTL_DDR_INPUT_DDR = 0x1 << 9,
+ PAD_CTL_DRV_VOT_LOW = 0x0 << 13,
+ PAD_CTL_DRV_VOT_HIGH = 0x1 << 13,
+} iomux_pad_config_t;
+
+/*!
+ * various IOMUX input select register index
+ */
+typedef enum iomux_input_select {
+ MUX_IN_AUDMUX_P4_INPUT_DA_AMX_SELECT_I = 0,
+ MUX_IN_AUDMUX_P4_INPUT_DB_AMX_SELECT_I,
+ MUX_IN_AUDMUX_P4_INPUT_TXCLK_AMX_SELECT_INPUT,
+ MUX_IN_AUDMUX_P4_INPUT_TXFS_AMX_SELECT_INPUT,
+ MUX_IN_AUDMUX_P5_INPUT_DA_AMX_SELECT_INPUT,
+ MUX_IN_AUDMUX_P5_INPUT_DB_AMX_SELECT_INPUT,
+ MUX_IN_AUDMUX_P5_INPUT_RXCLK_AMX_SELECT_INPUT,
+ MUX_IN_AUDMUX_P5_INPUT_RXFS_AMX_SELECT,
+ MUX_IN_AUDMUX_P5_INPUT_TXCLK_AMX_SELECT_INPUT,
+ MUX_IN_AUDMUX_P5_INPUT_TXFS_AMX_SELECT_INPUT,
+ MUX_IN_AUDMUX_P6_INPUT_DA_AMX_SELECT_INPUT,
+ MUX_IN_AUDMUX_P6_INPUT_DB_AMX_SELECT_INPUT,
+ MUX_IN_AUDMUX_P6_INPUT_RXCLK_AMX_SELECT_INPUT,
+ MUX_IN_AUDMUX_P6_INPUT_RXFS_AMX_SELECT_INPUT,
+ MUX_IN_AUDMUX_P6_INPUT_TXCLK_AMX_SELECT_INPUT,
+ MUX_IN_AUDMUX_P6_INPUT_TXFS_AMX_SELECT_INPUT,
+ MUX_IN_CCM_IPP_DI_CLK_SELECT_INPUT,
+ /* TO2 */
+ MUX_IN_CCM_IPP_DI1_CLK_SELECT_INPUT,
+ MUX_IN_CCM_PLL1_BYPASS_CLK_SELECT_INPUT,
+ MUX_IN_CCM_PLL2_BYPASS_CLK_SELECT_INPUT,
+ MUX_IN_CSPI_IPP_CSPI_CLK_IN_SELECT_INPUT,
+ MUX_IN_CSPI_IPP_IND_MISO_SELECT_INPUT,
+ MUX_IN_CSPI_IPP_IND_MOSI_SELECT_INPUT,
+ MUX_IN_CSPI_IPP_IND_SS_B_1_SELECT_INPUT,
+ MUX_IN_CSPI_IPP_IND_SS_B_2_SELECT_INPUT,
+ MUX_IN_CSPI_IPP_IND_SS_B_3_SELECT_INPUT,
+ MUX_IN_DPLLIP1_L1T_TOG_EN_SELECT_INPUT,
+ /* TO2 */
+ MUX_IN_ECSPI2_IPP_IND_SS_B_1_SELECT_INPUT,
+ MUX_IN_ECSPI2_IPP_IND_SS_B_3_SELECT_INPUT,
+ MUX_IN_EMI_IPP_IND_RDY_INT_SELECT_INPUT,
+ MUX_IN_ESDHC3_IPP_DAT0_IN_SELECT_INPUT,
+ MUX_IN_ESDHC3_IPP_DAT1_IN_SELECT_INPUT,
+ MUX_IN_ESDHC3_IPP_DAT2_IN_SELECT_INPUT,
+ MUX_IN_ESDHC3_IPP_DAT3_IN_SELECT_INPUT,
+ MUX_IN_FEC_FEC_COL_SELECT_INPUT,
+ MUX_IN_FEC_FEC_CRS_SELECT_INPUT,
+ MUX_IN_FEC_FEC_MDI_SELECT_INPUT,
+ MUX_IN_FEC_FEC_RDATA_0_SELECT_INPUT,
+ MUX_IN_FEC_FEC_RDATA_1_SELECT_INPUT,
+ MUX_IN_FEC_FEC_RDATA_2_SELECT_INPUT,
+ MUX_IN_FEC_FEC_RDATA_3_SELECT_INPUT,
+ MUX_IN_FEC_FEC_RX_CLK_SELECT_INPUT,
+ MUX_IN_FEC_FEC_RX_DV_SELECT_INPUT,
+ MUX_IN_FEC_FEC_RX_ER_SELECT_INPUT,
+ MUX_IN_FEC_FEC_TX_CLK_SELECT_INPUT,
+ MUX_IN_GPIO3_IPP_IND_G_IN_1_SELECT_INPUT,
+ MUX_IN_GPIO3_IPP_IND_G_IN_2_SELECT_INPUT,
+ MUX_IN_GPIO3_IPP_IND_G_IN_3_SELECT_INPUT,
+ MUX_IN_GPIO3_IPP_IND_G_IN_4_SELECT_INPUT,
+ MUX_IN_GPIO3_IPP_IND_G_IN_5_SELECT_INPUT,
+ MUX_IN_GPIO3_IPP_IND_G_IN_6_SELECT_INPUT,
+ MUX_IN_GPIO3_IPP_IND_G_IN_7_SELECT_INPUT,
+ MUX_IN_GPIO3_IPP_IND_G_IN_8_SELECT_INPUT,
+ /* TO2 */
+ MUX_IN_GPIO3_IPP_IND_G_IN_12_SELECT_INPUT,
+ MUX_IN_HSC_MIPI_MIX_IPP_IND_SENS1_DATA_EN_SELECT_INPUT,
+ MUX_IN_HSC_MIPI_MIX_IPP_IND_SENS2_DATA_EN_SELECT_INPUT,
+ /* TO2 */
+ MUX_IN_HSC_MIPI_MIX_PAR_VSYNC_SELECT_INPUT,
+ /* TO2 */
+ MUX_IN_HSC_MIPI_MIX_PAR_DI_WAIT_SELECT_INPUT,
+ MUX_IN_HSC_MIPI_MIX_PAR_SISG_TRIG_SELECT_INPUT,
+ MUX_IN_I2C1_IPP_SCL_IN_SELECT_INPUT,
+ MUX_IN_I2C1_IPP_SDA_IN_SELECT_INPUT,
+ MUX_IN_I2C2_IPP_SCL_IN_SELECT_INPUT,
+ MUX_IN_I2C2_IPP_SDA_IN_SELECT_INPUT,
+
+ MUX_IN_IPU_IPP_DI_0_IND_DISPB_SD_D_SELECT_INPUT,
+
+ MUX_IN_IPU_IPP_DI_1_IND_DISPB_SD_D_SELECT_INPUT,
+
+ MUX_IN_KPP_IPP_IND_COL_6_SELECT_INPUT,
+ MUX_IN_KPP_IPP_IND_COL_7_SELECT_INPUT,
+ MUX_IN_KPP_IPP_IND_ROW_4_SELECT_INPUT,
+ MUX_IN_KPP_IPP_IND_ROW_5_SELECT_INPUT,
+ MUX_IN_KPP_IPP_IND_ROW_6_SELECT_INPUT,
+ MUX_IN_KPP_IPP_IND_ROW_7_SELECT_INPUT,
+ MUX_IN_UART1_IPP_UART_RTS_B_SELECT_INPUT,
+ MUX_IN_UART1_IPP_UART_RXD_MUX_SELECT_INPUT,
+ MUX_IN_UART2_IPP_UART_RTS_B_SELECT_INPUT,
+ MUX_IN_UART2_IPP_UART_RXD_MUX_SELECT_INPUT,
+ MUX_IN_UART3_IPP_UART_RTS_B_SELECT_INPUT,
+ MUX_IN_UART3_IPP_UART_RXD_MUX_SELECT_INPUT,
+ MUX_IN_USBOH3_IPP_IND_UH3_CLK_SELECT_INPUT,
+ MUX_IN_USBOH3_IPP_IND_UH3_DATA_0_SELECT_INPUT,
+ MUX_IN_USBOH3_IPP_IND_UH3_DATA_1_SELECT_INPUT,
+ MUX_IN_USBOH3_IPP_IND_UH3_DATA_2_SELECT_INPUT,
+ MUX_IN_USBOH3_IPP_IND_UH3_DATA_3_SELECT_INPUT,
+ MUX_IN_USBOH3_IPP_IND_UH3_DATA_4_SELECT_INPUT,
+ MUX_IN_USBOH3_IPP_IND_UH3_DATA_5_SELECT_INPUT,
+ MUX_IN_USBOH3_IPP_IND_UH3_DATA_6_SELECT_INPUT,
+ MUX_IN_USBOH3_IPP_IND_UH3_DATA_7_SELECT_INPUT,
+ MUX_IN_USBOH3_IPP_IND_UH3_DIR_SELECT_INPUT,
+ MUX_IN_USBOH3_IPP_IND_UH3_NXT_SELECT_INPUT,
+ MUX_IN_USBOH3_IPP_IND_UH3_STP_SELECT_INPUT,
+ MUX_INPUT_NUM_MUX,
+} iomux_input_select_t;
+
+/*!
+ * various IOMUX input functions
+ */
+typedef enum iomux_input_config {
+ INPUT_CTL_PATH0 = 0x0,
+ INPUT_CTL_PATH1,
+ INPUT_CTL_PATH2,
+ INPUT_CTL_PATH3,
+ INPUT_CTL_PATH4,
+ INPUT_CTL_PATH5,
+ INPUT_CTL_PATH6,
+ INPUT_CTL_PATH7,
+} iomux_input_config_t;
+
+/*!
+ * Request ownership for an IO pin. This function has to be the first one
+ * being called before that pin is used. The caller has to check the
+ * return value to make sure it returns 0.
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param config config as defined in \b #iomux_pin_ocfg_t
+ *
+ * @return 0 if successful; Non-zero otherwise
+ */
+int mxc_request_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t config);
+
+/*!
+ * Release ownership for an IO pin
+ *
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param config config as defined in \b #iomux_pin_ocfg_t
+ */
+void mxc_free_iomux(iomux_pin_name_t pin, iomux_pin_cfg_t config);
+
+/*!
+ * This function configures the pad value for a IOMUX pin.
+ *
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @param config the ORed value of elements defined in
+ * \b #iomux_pad_config_t
+ */
+void mxc_iomux_set_pad(iomux_pin_name_t pin, u32 config);
+
+/*!
+ * This function gets the current pad value for a IOMUX pin.
+ *
+ * @param pin a pin number as defined in \b #iomux_pin_name_t
+ * @return current pad value
+ */
+unsigned int mxc_iomux_get_pad(iomux_pin_name_t pin);
+
+/*!
+ * This function configures input path.
+ *
+ * @param input index of input select register as defined in
+ * \b #iomux_input_select_t
+ * @param config the binary value of elements defined in \b #iomux_input_config_t
+ */
+void mxc_iomux_set_input(iomux_input_select_t input, u32 config);
+
+#endif /* __MACH_MX51_IOMUX_H__ */
diff --git a/arch/arm/mach-mx51/lpmodes.c b/arch/arm/mach-mx51/lpmodes.c
new file mode 100644
index 000000000000..7cba15df76e0
--- /dev/null
+++ b/arch/arm/mach-mx51/lpmodes.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file mx51_lpmodes.c
+ *
+ * @brief Driver for the Freescale Semiconductor MXC low power modes setup.
+ *
+ * MX51 is designed to play and video with minimal power consumption.
+ * This driver enables the platform to enter and exit audio and video low
+ * power modes.
+ *
+ * @ingroup PM
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <mach/clock.h>
+#include <mach/hardware.h>
+#include <linux/regulator/regulator-platform.h>
+#include "crm_regs.h"
+
+#define ARM_LP_CLK 200000000
+#define GP_LPM_VOLTAGE 775000
+#define GP_NORMAL_VOLTAGE 1050000
+
+static int org_cpu_rate;
+int lp_video_mode;
+int lp_audio_mode;
+static struct device *lpmode_dev;
+struct regulator *gp_core;
+
+void enter_lp_video_mode(void)
+{
+}
+
+void exit_lp_video_mode(void)
+{
+}
+
+void enter_lp_audio_mode(void)
+{
+ struct clk *tclk;
+ int ret;
+
+ tclk = clk_get(NULL, "cpu_clk");
+ org_cpu_rate = clk_get_rate(tclk);
+
+ ret = clk_set_rate(tclk, ARM_LP_CLK);
+ if (ret != 0)
+ printk(KERN_DEBUG "cannot set CPU clock rate\n");
+ clk_put(tclk);
+
+ /* Set the voltage to 0.775v for the GP domain. */
+ ret = regulator_set_voltage(gp_core, GP_LPM_VOLTAGE);
+ if (ret < 0)
+ printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!\n");
+
+ lp_audio_mode = 1;
+}
+
+void exit_lp_audio_mode(void)
+{
+ struct clk *tclk;
+ int ret;
+
+ /* Set the voltage to 1.05v for the GP domain. */
+ ret = regulator_set_voltage(gp_core, GP_NORMAL_VOLTAGE);
+ if (ret < 0)
+ printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!\n");
+
+ tclk = clk_get(NULL, "cpu_clk");
+ ret = clk_set_rate(tclk, org_cpu_rate);
+ if (ret != 0)
+ printk(KERN_DEBUG "cannot set CPU clock rate\n");
+ clk_put(tclk);
+
+ lp_audio_mode = 0;
+
+}
+
+static ssize_t lp_curr_mode(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (lp_video_mode)
+ return sprintf(buf, "in lp_video_mode\n");
+ else if (lp_audio_mode)
+ return sprintf(buf, "in lp_audio_mode\n");
+ else
+ return sprintf(buf, "in normal mode\n");
+}
+
+static ssize_t set_lp_mode(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ printk(KERN_DEBUG "In set_lp_mode() \n");
+
+ if (strstr(buf, "enable_lp_video") != NULL) {
+ if (!lp_video_mode)
+ enter_lp_video_mode();
+ } else if (strstr(buf, "disable_lp_video") != NULL) {
+ if (lp_video_mode)
+ exit_lp_video_mode();
+ } else if (strstr(buf, "enable_lp_audio") != NULL) {
+ if (!lp_audio_mode)
+ enter_lp_audio_mode();
+ } else if (strstr(buf, "disable_lp_audio") != NULL) {
+ if (lp_audio_mode)
+ exit_lp_audio_mode();
+ }
+ return size;
+}
+
+static DEVICE_ATTR(lp_modes, 0644, lp_curr_mode, set_lp_mode);
+
+/*!
+ * This is the probe routine for the lp_mode driver.
+ *
+ * @param pdev The platform device structure
+ *
+ * @return The function returns 0 on success
+ *
+ */
+static int __devinit mx51_lpmode_probe(struct platform_device *pdev)
+{
+ u32 res = 0;
+ lpmode_dev = &pdev->dev;
+
+ res = sysfs_create_file(&lpmode_dev->kobj, &dev_attr_lp_modes.attr);
+ if (res) {
+ printk(KERN_ERR
+ "lpmode_dev: Unable to register sysdev entry for lpmode_dev");
+ return res;
+ }
+
+ if (res != 0) {
+ printk(KERN_ERR "lpmode_dev: Unable to start");
+ return res;
+ }
+ gp_core = regulator_get(NULL, "SW1");
+ lp_video_mode = 0;
+ lp_audio_mode = 0;
+
+ return 0;
+}
+
+static struct platform_driver mx51_lpmode_driver = {
+ .driver = {
+ .name = "mx51_lpmode",
+ },
+ .probe = mx51_lpmode_probe,
+};
+
+/*!
+ * Initialise the mx51_lpmode_driver.
+ *
+ * @return The function always returns 0.
+ */
+
+static int __init lpmode_init(void)
+{
+ if (platform_driver_register(&mx51_lpmode_driver) != 0) {
+ printk(KERN_ERR "mx37_lpmode_driver register failed\n");
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "LPMode driver module loaded\n");
+ return 0;
+}
+
+static void __exit lpmode_cleanup(void)
+{
+ sysfs_remove_file(&lpmode_dev->kobj, &dev_attr_lp_modes.attr);
+
+ /* Unregister the device structure */
+ platform_driver_unregister(&mx51_lpmode_driver);
+}
+
+module_init(lpmode_init);
+module_exit(lpmode_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("LPMode driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/mach-mx51/mm.c b/arch/arm/mach-mx51/mm.c
new file mode 100644
index 000000000000..7834d02b386a
--- /dev/null
+++ b/arch/arm/mach-mx51/mm.c
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/mm.h>
+#include <linux/init.h>
+#include <mach/hardware.h>
+#include <asm/pgtable.h>
+#include <asm/mach/map.h>
+
+/*!
+ * @file mach-mx51/mm.c
+ *
+ * @brief This file creates static mapping between physical to virtual memory.
+ *
+ * @ingroup Memory_MX51
+ */
+
+/*!
+ * This structure defines the MX51 memory map.
+ */
+static struct map_desc mxc_io_desc[] __initdata = {
+ {
+ .virtual = IRAM_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(IRAM_BASE_ADDR),
+ .length = IRAM_SIZE,
+ .type = MT_DEVICE},
+ {
+ .virtual = DEBUG_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(DEBUG_BASE_ADDR),
+ .length = DEBUG_SIZE,
+ .type = MT_DEVICE},
+ {
+ .virtual = TZIC_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(TZIC_BASE_ADDR),
+ .length = TZIC_SIZE,
+ .type = MT_DEVICE},
+ {
+ .virtual = AIPS1_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AIPS1_BASE_ADDR),
+ .length = AIPS1_SIZE,
+ .type = MT_DEVICE},
+ {
+ .virtual = SPBA0_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(SPBA0_BASE_ADDR),
+ .length = SPBA0_SIZE,
+ .type = MT_DEVICE},
+ {
+ .virtual = AIPS2_BASE_ADDR_VIRT,
+ .pfn = __phys_to_pfn(AIPS2_BASE_ADDR),
+ .length = AIPS2_SIZE,
+ .type = MT_DEVICE},
+ {
+ .virtual = NFC_BASE_ADDR_AXI_VIRT,
+ .pfn = __phys_to_pfn(NFC_BASE_ADDR_AXI),
+ .length = NFC_AXI_SIZE,
+ .type = MT_DEVICE},
+};
+
+/*!
+ * This function initializes the memory map. It is called during the
+ * system startup to create static physical to virtual memory map for
+ * the IO modules.
+ */
+void __init mxc_map_io(void)
+{
+ u32 tzic_addr;
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0)
+ tzic_addr = 0x8FFFC000;
+ else
+ tzic_addr = 0xE0003000;
+
+ mxc_io_desc[2].pfn = __phys_to_pfn(tzic_addr);
+ iotable_init(mxc_io_desc, ARRAY_SIZE(mxc_io_desc));
+}
diff --git a/arch/arm/mach-mx51/mx51_3stack.c b/arch/arm/mach-mx51/mx51_3stack.c
new file mode 100644
index 000000000000..fa2a8615011b
--- /dev/null
+++ b/arch/arm/mach-mx51/mx51_3stack.c
@@ -0,0 +1,1054 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/mach/keypad.h>
+#include <linux/init.h>
+#include <linux/input.h>
+#include <linux/nodemask.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/spi/spi.h>
+#include <linux/i2c.h>
+#include <linux/ata.h>
+#if defined(CONFIG_MTD) || defined(CONFIG_MTD_MODULE)
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/mach/flash.h>
+#endif
+
+#include <linux/regulator/regulator.h>
+#include <mach/hardware.h>
+#include <mach/spba.h>
+#include <asm/irq.h>
+#include <asm/setup.h>
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+#include <mach/memory.h>
+#include <mach/gpio.h>
+#include <mach/mmc.h>
+#include <mach/pmic_external.h>
+#include <mach/ipu.h>
+
+#include "board-mx51_3stack.h"
+#include "iomux.h"
+#include "crm_regs.h"
+
+/*!
+ * @file mach-mx51/mx51_3stack.c
+ *
+ * @brief This file contains the board specific initialization routines.
+ *
+ * @ingroup MSL_MX51
+ */
+
+/* working point(wp): 0 - 800MHz; 1 - 200MHz; */
+static struct cpu_wp cpu_wp_auto[] = {
+ {
+ .pll_rate = 800000000,
+ .cpu_rate = 800000000,
+ .pdf = 0,
+ .mfi = 8,
+ .mfd = 2,
+ .mfn = 1,
+ .cpu_podf = 0,
+ .cpu_voltage = 1050000,},
+ {
+ .pll_rate = 800000000,
+ .cpu_rate = 200000000,
+ .pdf = 3,
+ .mfi = 8,
+ .mfd = 2,
+ .mfn = 1,
+ .cpu_podf = 3,
+ .cpu_voltage = 775000,},
+};
+
+struct cpu_wp *get_cpu_wp(int *wp)
+{
+ *wp = 2;
+ return cpu_wp_auto;
+}
+
+static void mc13892_reg_int(void)
+{
+ int i = 0;
+ struct regulator *regulator;
+ struct regulator *gp;
+ struct regulator *lp;
+ char *reg_name[] = {
+ "SW1",
+ "SW2",
+ "SW3",
+ "SW4",
+ "SW1_STBY",
+ "SW2_STBY",
+ "SW3_STBY",
+ "SW4_STBY",
+ "SW1_DVS",
+ "SW2_DVS",
+ "SWBST",
+ "VIOHI",
+ "VPLL",
+ "VDIG",
+ "VSD",
+ "VUSB2",
+ "VVIDEO",
+ "VAUDIO",
+ "VCAM",
+ "VGEN1",
+ "VGEN2",
+ "VGEN3",
+ "USB",
+ "GPO1",
+ "GPO2",
+ "GPO3",
+ "GPO4",
+ };
+
+ for (i = 0; i < ARRAY_SIZE(reg_name); i++) {
+ regulator = regulator_get(NULL, reg_name[i]);
+ if (regulator != ERR_PTR(-ENOENT)) {
+ regulator_enable(regulator);
+ regulator_put(regulator, NULL);
+ }
+ }
+ for (i = 0; i < ARRAY_SIZE(reg_name); i++) {
+ if ((strcmp(reg_name[i], "VIOHI") == 0) ||
+ (strcmp(reg_name[i], "VPLL") == 0) ||
+ (strcmp(reg_name[i], "VDIG") == 0) ||
+ (strcmp(reg_name[i], "VGEN2") == 0))
+ continue;
+ regulator = regulator_get(NULL, reg_name[i]);
+ if (regulator != ERR_PTR(-ENOENT)) {
+ regulator_disable(regulator);
+ regulator_put(regulator, NULL);
+ }
+ }
+
+ gp = regulator_get(NULL, "SW1_STBY");
+ lp = regulator_get(NULL, "SW2_STBY");
+ regulator_enable(gp);
+ regulator_enable(lp);
+
+ if (regulator_set_voltage(gp, 700000, 700000))
+ printk(KERN_INFO "cannot set GP STBY voltage\n");
+
+ if ((mxc_cpu_is_rev(CHIP_REV_2_0)) < 0) {
+ if (regulator_set_voltage(lp, 1100000, 1100000))
+ printk(KERN_INFO "cannot set LP STBY voltage\n");
+ } else {
+ /* Cannot drop voltage for TO2.0 */
+ if (regulator_set_voltage(lp, 900000, 900000))
+ printk(KERN_INFO "cannot set LP STBY voltage\n");
+ }
+
+ regulator_disable(gp);
+ regulator_disable(lp);
+
+ regulator_put(gp);
+ regulator_put(lp);
+}
+
+late_initcall(mc13892_reg_int);
+
+static void mxc_nop_release(struct device *dev)
+{
+ /* Nothing */
+}
+
+#if defined(CONFIG_KEYBOARD_MXC) || defined(CONFIG_KEYBOARD_MXC_MODULE)
+static u16 keymapping[24] = {
+ KEY_1, KEY_2, KEY_3, KEY_F1, KEY_UP, KEY_F2,
+ KEY_4, KEY_5, KEY_6, KEY_LEFT, KEY_SELECT, KEY_RIGHT,
+ KEY_7, KEY_8, KEY_9, KEY_F3, KEY_DOWN, KEY_F4,
+ KEY_0, KEY_OK, KEY_ESC, KEY_ENTER, KEY_MENU, KEY_BACK,
+};
+
+static struct resource mxc_kpp_resources[] = {
+ [0] = {
+ .start = MXC_INT_KPP,
+ .end = MXC_INT_KPP,
+ .flags = IORESOURCE_IRQ,
+ }
+};
+
+static struct keypad_data keypad_plat_data = {
+ .rowmax = 4,
+ .colmax = 6,
+ .irq = MXC_INT_KPP,
+ .learning = 0,
+ .delay = 2,
+ .matrix = keymapping,
+};
+
+/* mxc keypad driver */
+static struct platform_device mxc_keypad_device = {
+ .name = "mxc_keypad",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(mxc_kpp_resources),
+ .resource = mxc_kpp_resources,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &keypad_plat_data,
+ },
+};
+
+static void mxc_init_keypad(void)
+{
+ (void)platform_device_register(&mxc_keypad_device);
+}
+#else
+static inline void mxc_init_keypad(void)
+{
+}
+#endif
+
+/* MTD NAND flash */
+#if defined(CONFIG_MTD_NAND_MXC) \
+ || defined(CONFIG_MTD_NAND_MXC_MODULE) \
+ || defined(CONFIG_MTD_NAND_MXC_V2) \
+ || defined(CONFIG_MTD_NAND_MXC_V2_MODULE) \
+ || defined(CONFIG_MTD_NAND_MXC_V3) \
+ || defined(CONFIG_MTD_NAND_MXC_V3_MODULE)
+
+static struct mtd_partition mxc_nand_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 3 * 1024 * 1024},
+ {
+ .name = "nand.kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 5 * 1024 * 1024},
+ {
+ .name = "nand.rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 128 * 1024 * 1024},
+ {
+ .name = "nand.userfs1",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 256 * 1024 * 1024},
+ {
+ .name = "nand.userfs2",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL},
+};
+
+extern void gpio_nand_active(void);
+extern void gpio_nand_inactive(void);
+
+static int nand_init(void)
+{
+ /* Configure the pins */
+ gpio_nand_active();
+ return 0;
+}
+
+static void nand_exit(void)
+{
+ /* Free the pins */
+ gpio_nand_inactive();
+}
+
+static struct flash_platform_data mxc_nand_data = {
+ .parts = mxc_nand_partitions,
+ .nr_parts = ARRAY_SIZE(mxc_nand_partitions),
+ .width = 1,
+ .init = nand_init,
+ .exit = nand_exit,
+};
+
+static struct platform_device mxc_nandv2_mtd_device = {
+ .name = "mxc_nandv2_flash",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_nand_data,
+ },
+};
+
+static void mxc_init_nand_mtd(void)
+{
+ (void)platform_device_register(&mxc_nandv2_mtd_device);
+}
+#else
+static inline void mxc_init_nand_mtd(void)
+{
+}
+#endif
+
+#if defined(CONFIG_FB_MXC_SYNC_PANEL) || \
+ defined(CONFIG_FB_MXC_SYNC_PANEL_MODULE)
+static struct platform_device mxc_fb_device[] = {
+ {
+ .name = "mxc_sdc_fb",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+ },
+ {
+ .name = "mxc_sdc_fb",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+ },
+ {
+ .name = "mxc_sdc_fb",
+ .id = 2,
+ .dev = {
+ .release = mxc_nop_release,
+ .coherent_dma_mask = 0xFFFFFFFF,
+ },
+ },
+};
+
+static void lcd_reset_to2(void)
+{
+ ipu_reset_disp_panel();
+
+ return;
+}
+
+static void lcd_reset(void)
+{
+ static int first;
+
+ /* ensure that LCDIO(1.8V) has been turn on */
+ /* active reset line GPIO */
+ if (!first) {
+ mxc_request_iomux(MX51_PIN_DISPB2_SER_RS, IOMUX_CONFIG_GPIO);
+ first = 1;
+ }
+ mxc_set_gpio_dataout(MX51_PIN_DISPB2_SER_RS, 0);
+ mxc_set_gpio_direction(MX51_PIN_DISPB2_SER_RS, 0);
+ /* do reset */
+ msleep(10); /* tRES >= 100us */
+ mxc_set_gpio_dataout(MX51_PIN_DISPB2_SER_RS, 1);
+ msleep(60);
+}
+
+static struct mxc_lcd_platform_data lcd_data = {
+ .core_reg = "VIOHI",
+ .io_reg = "SW4",
+ .reset = lcd_reset,
+};
+
+static struct platform_device mxc_lcd_device = {
+ .name = "lcd_spi",
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &lcd_data,
+ },
+};
+
+extern void gpio_lcd_active(void);
+
+static void mxc_init_fb(void)
+{
+ gpio_lcd_active();
+
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) > 0)
+ lcd_data.reset = lcd_reset_to2;
+
+ (void)platform_device_register(&mxc_lcd_device);
+
+ (void)platform_device_register(&mxc_fb_device[0]);
+ (void)platform_device_register(&mxc_fb_device[1]);
+ (void)platform_device_register(&mxc_fb_device[2]);
+}
+#else
+static inline void mxc_init_fb(void)
+{
+}
+#endif
+
+static struct platform_device mxcbl_device = {
+ .name = "mxc_mc13892_bl",
+};
+
+static inline void mxc_init_bl(void)
+{
+ platform_device_register(&mxcbl_device);
+}
+
+#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE)
+
+#ifdef CONFIG_I2C_MXC_SELECT1
+static struct i2c_board_info mxc_i2c0_board_info[] __initdata = {
+};
+#endif
+#ifdef CONFIG_I2C_MXC_SELECT2
+static struct i2c_board_info mxc_i2c1_board_info[] __initdata = {
+ {
+ .type = "mc13892",
+ .addr = 0x08,
+ .platform_data = (void *)MX51_PIN_GPIO1_5,
+ },
+ {
+ .type = "wm8903-i2c",
+ .addr = 0x1a,
+ },
+ {
+ .type = "sgtl5000-i2c",
+ .addr = 0x0a,
+ },
+ {
+ .type = "tsc2007",
+ .addr = 0x48,
+ .irq = IOMUX_TO_IRQ(MX51_PIN_GPIO1_5),
+ },
+};
+#endif
+#if defined(CONFIG_I2C_MXC_HS) || defined(CONFIG_I2C_MXC_HS_MODULE)
+static struct mxc_camera_platform_data camera_data = {
+ .io_regulator = "SW4",
+ .analog_regulator = "VIOHI",
+ .mclk = 24000000,
+ .csi = 0,
+};
+static struct mxc_lightsensor_platform_data ls_data = {
+ .vdd_reg = NULL,
+ .rext = 100,
+};
+
+static struct i2c_board_info mxc_i2c_hs_board_info[] __initdata = {
+ {
+ .type = "ov3640",
+ .addr = 0x3C,
+ .platform_data = (void *)&camera_data,
+ },
+ {
+ .type = "isl29003",
+ .addr = 0x44,
+ .platform_data = &ls_data,
+ },
+};
+#endif
+
+#endif
+
+static u32 cpld_base_addr;
+
+/*lan9217 device*/
+#if defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)
+static struct resource smsc911x_resources[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = LAN9217_IRQ,
+ .end = LAN9217_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+static struct platform_device smsc_lan9217_device = {
+ .name = "smsc911x",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ },
+ .num_resources = ARRAY_SIZE(smsc911x_resources),
+ .resource = smsc911x_resources,
+};
+static void mxc_init_enet(void)
+{
+ smsc_lan9217_device.resource[0].start =
+ LAN9217_BASE_ADDR(cpld_base_addr);
+ smsc_lan9217_device.resource[0].end = LAN9217_BASE_ADDR(cpld_base_addr)
+ + 0x100;
+ (void)platform_device_register(&smsc_lan9217_device);
+}
+#else
+static inline void mxc_init_enet(void)
+{
+}
+#endif
+
+#if defined(CONFIG_FEC) || defined(CONFIG_FEC_MODULE)
+unsigned int expio_intr_fec;
+
+EXPORT_SYMBOL(expio_intr_fec);
+#endif
+
+#if defined(CONFIG_MMC_IMX_ESDHCI) || defined(CONFIG_MMC_IMX_ESDHCI_MODULE)
+static struct mxc_mmc_platform_data mmc_data = {
+ .ocr_mask = MMC_VDD_32_33,
+ .caps = MMC_CAP_4_BIT_DATA,
+ .min_clk = 400000,
+ .max_clk = 52000000,
+ .card_inserted_state = 0,
+ .status = sdhc_get_card_det_status,
+ .wp_status = sdhc_write_protect,
+ .clock_mmc = "esdhc_clk",
+ .power_mmc = NULL,
+};
+
+/*!
+ * Resource definition for the SDHC1
+ */
+static struct resource mxcsdhc1_resources[] = {
+ [0] = {
+ .start = MMC_SDHC1_BASE_ADDR,
+ .end = MMC_SDHC1_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_MMC_SDHC1,
+ .end = MXC_INT_MMC_SDHC1,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*!
+ * Resource definition for the SDHC2
+ */
+static struct resource mxcsdhc2_resources[] = {
+ [0] = {
+ .start = MMC_SDHC2_BASE_ADDR,
+ .end = MMC_SDHC2_BASE_ADDR + SZ_4K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_MMC_SDHC2,
+ .end = MXC_INT_MMC_SDHC2,
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/*! Device Definition for MXC SDHC1 */
+static struct platform_device mxcsdhc1_device = {
+ .name = "mxsdhci",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mmc_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcsdhc1_resources),
+ .resource = mxcsdhc1_resources,
+};
+
+/*! Device Definition for MXC SDHC2 */
+static struct platform_device mxcsdhc2_device = {
+ .name = "mxsdhci",
+ .id = 1,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mmc_data,
+ },
+ .num_resources = ARRAY_SIZE(mxcsdhc2_resources),
+ .resource = mxcsdhc2_resources,
+};
+
+static inline void mxc_init_mmc(void)
+{
+ int cd_irq;
+
+ cd_irq = sdhc_init_card_det(0);
+ if (cd_irq) {
+ mxcsdhc1_device.resource[2].start = cd_irq;
+ mxcsdhc1_device.resource[2].end = cd_irq;
+ }
+
+ cd_irq = sdhc_init_card_det(1);
+ if (cd_irq) {
+ mxcsdhc2_device.resource[2].start = cd_irq;
+ mxcsdhc2_device.resource[2].end = cd_irq;
+ }
+
+ (void)platform_device_register(&mxcsdhc1_device);
+ (void)platform_device_register(&mxcsdhc2_device);
+}
+#else
+static inline void mxc_init_mmc(void)
+{
+}
+#endif
+
+static u32 brd_io;
+static void expio_ack_irq(u32 irq);
+
+static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 imr_val;
+ u32 int_valid;
+ u32 expio_irq;
+
+ desc->chip->mask(irq); /* irq = gpio irq number */
+
+ imr_val = __raw_readw(brd_io + INTR_MASK_REG);
+ int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val;
+
+ if (unlikely(!int_valid))
+ goto out;
+
+ expio_irq = MXC_EXP_IO_BASE;
+ for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
+ struct irq_desc *d;
+ if ((int_valid & 1) == 0)
+ continue;
+ d = irq_desc + expio_irq;
+ if (unlikely(!(d->handle_irq))) {
+ printk(KERN_ERR "\nEXPIO irq: %d unhandled\n",
+ expio_irq);
+ BUG(); /* oops */
+ }
+ d->handle_irq(expio_irq, d);
+ }
+
+ out:
+ desc->chip->ack(irq);
+ desc->chip->unmask(irq);
+}
+
+/*
+ * Disable an expio pin's interrupt by setting the bit in the imr.
+ * @param irq an expio virtual irq number
+ */
+static void expio_mask_irq(u32 irq)
+{
+ u16 reg;
+ u32 expio = MXC_IRQ_TO_EXPIO(irq);
+ /* mask the interrupt */
+ reg = __raw_readw(brd_io + INTR_MASK_REG);
+ reg |= (1 << expio);
+ __raw_writew(reg, brd_io + INTR_MASK_REG);
+}
+
+/*
+ * Acknowledge an expanded io pin's interrupt by clearing the bit in the isr.
+ * @param irq an expanded io virtual irq number
+ */
+static void expio_ack_irq(u32 irq)
+{
+ u32 expio = MXC_IRQ_TO_EXPIO(irq);
+ /* clear the interrupt status */
+ __raw_writew(1 << expio, brd_io + INTR_RESET_REG);
+ __raw_writew(0, brd_io + INTR_RESET_REG);
+ /* mask the interrupt */
+ expio_mask_irq(irq);
+}
+
+/*
+ * Enable a expio pin's interrupt by clearing the bit in the imr.
+ * @param irq a expio virtual irq number
+ */
+static void expio_unmask_irq(u32 irq)
+{
+ u16 reg;
+ u32 expio = MXC_IRQ_TO_EXPIO(irq);
+ /* unmask the interrupt */
+ reg = __raw_readw(brd_io + INTR_MASK_REG);
+ reg &= ~(1 << expio);
+ __raw_writew(reg, brd_io + INTR_MASK_REG);
+}
+
+static struct irq_chip expio_irq_chip = {
+ .ack = expio_ack_irq,
+ .mask = expio_mask_irq,
+ .unmask = expio_unmask_irq,
+};
+
+static int __init mxc_expio_init(void)
+{
+ int i;
+
+ brd_io = (u32) ioremap(BOARD_IO_ADDR(CS5_BASE_ADDR), SZ_4K);
+ if (brd_io == 0)
+ return -ENOMEM;
+
+ if ((__raw_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) ||
+ (__raw_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) ||
+ (__raw_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) {
+ iounmap((void *)brd_io);
+ brd_io = (u32) ioremap(BOARD_IO_ADDR(CS1_BASE_ADDR), SZ_4K);
+ if (brd_io == 0)
+ return -ENOMEM;
+
+ if ((__raw_readw(brd_io + MAGIC_NUMBER1_REG) != 0xAAAA) ||
+ (__raw_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) ||
+ (__raw_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) {
+ iounmap((void *)brd_io);
+ brd_io = 0;
+ return -ENODEV;
+ }
+ cpld_base_addr = CS1_BASE_ADDR;
+ } else {
+ cpld_base_addr = CS5_BASE_ADDR;
+ }
+
+ pr_info("3-Stack Debug board detected, rev = 0x%04X\n",
+ readw(brd_io + CPLD_CODE_VER_REG));
+
+ /*
+ * Configure INT line as GPIO input
+ */
+ mxc_request_iomux(MX51_PIN_GPIO1_6, IOMUX_CONFIG_GPIO);
+ mxc_set_gpio_direction(MX51_PIN_GPIO1_6, 1);
+
+ /* disable the interrupt and clear the status */
+ __raw_writew(0, brd_io + INTR_MASK_REG);
+ __raw_writew(0xFFFF, brd_io + INTR_RESET_REG);
+ __raw_writew(0, brd_io + INTR_RESET_REG);
+ __raw_writew(0x1F, brd_io + INTR_MASK_REG);
+ for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
+ i++) {
+ set_irq_chip(i, &expio_irq_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+ set_irq_type(EXPIO_PARENT_INT, IRQF_TRIGGER_LOW);
+ set_irq_chained_handler(EXPIO_PARENT_INT, mxc_expio_irq_handler);
+
+ return 0;
+}
+
+#if defined(CONFIG_PATA_FSL) || defined(CONFIG_PATA_FSL_MODULE)
+extern void gpio_ata_active(void);
+extern void gpio_ata_inactive(void);
+
+static int ata_init(struct platform_device *pdev)
+{
+ /* Configure the pins */
+ gpio_ata_active();
+ return 0;
+}
+
+static void ata_exit(void)
+{
+ /* Free the pins */
+ gpio_ata_inactive();
+}
+
+static struct fsl_ata_platform_data ata_data = {
+ .udma_mask = ATA_UDMA3,
+ .mwdma_mask = ATA_MWDMA2,
+ .pio_mask = ATA_PIO4,
+ .fifo_alarm = MXC_IDE_DMA_WATERMARK / 2,
+ .max_sg = MXC_IDE_DMA_BD_NR,
+ .init = ata_init,
+ .exit = ata_exit,
+ .core_reg = NULL,
+ .io_reg = NULL,
+};
+
+static struct resource pata_fsl_resources[] = {
+ [0] = {
+ .start = ATA_BASE_ADDR,
+ .end = ATA_BASE_ADDR + 0x000000C8,
+ .flags = IORESOURCE_MEM,},
+ [2] = {
+ .start = MXC_INT_ATA,
+ .end = MXC_INT_ATA,
+ .flags = IORESOURCE_IRQ,},
+};
+
+static struct platform_device pata_fsl_device = {
+ .name = "pata_fsl",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pata_fsl_resources),
+ .resource = pata_fsl_resources,
+ .dev = {
+ .platform_data = &ata_data,
+ .coherent_dma_mask = ~0,},
+};
+
+static void __init mxc_init_pata(void)
+{
+ (void)platform_device_register(&pata_fsl_device);
+}
+#else /* CONFIG_PATA_FSL */
+static void __init mxc_init_pata(void)
+{
+}
+#endif /* CONFIG_PATA_FSL */
+
+#if defined(CONFIG_TOUCHSCREEN_TSC2007) \
+ || defined(CONFIG_TOUCHSCREEN_TSC2007_MODULE)
+
+static int __init mxc_init_touchscreen(void)
+{
+ int pad_val;
+
+ mxc_request_iomux(MX51_PIN_GPIO1_5, IOMUX_CONFIG_GPIO);
+ pad_val = PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU;
+ mxc_iomux_set_pad(MX51_PIN_GPIO1_5, pad_val);
+ mxc_set_gpio_direction(MX51_PIN_GPIO1_5, 1);
+
+ return 0;
+}
+#else
+static int __init mxc_init_touchscreen(void)
+{
+ return 0;
+}
+#endif
+
+static int __init mxc_init_srpgconfig(void)
+{
+ struct clk *gpcclk = clk_get(NULL, "gpc_dvfs_clk");
+ clk_enable(gpcclk);
+
+ /* Setup the number of clock cycles to wait for SRPG
+ * power up and power down requests.
+ */
+ __raw_writel(0x010F0201, MXC_SRPG_ARM_PUPSCR);
+ __raw_writel(0x010F0201, MXC_SRPG_NEON_PUPSCR);
+ __raw_writel(0x00000008, MXC_SRPG_EMPGC0_PUPSCR);
+ __raw_writel(0x00000008, MXC_SRPG_EMPGC1_PUPSCR);
+
+ __raw_writel(0x01010101, MXC_SRPG_ARM_PDNSCR);
+ __raw_writel(0x01010101, MXC_SRPG_NEON_PDNSCR);
+ __raw_writel(0x00000018, MXC_SRPG_EMPGC0_PDNSCR);
+ __raw_writel(0x00000018, MXC_SRPG_EMPGC1_PDNSCR);
+
+ clk_disable(gpcclk);
+ clk_put(gpcclk);
+
+ return 0;
+}
+
+#if defined(CONFIG_SND_SOC_IMX_3STACK_WM8903) \
+ || defined(CONFIG_SND_SOC_IMX_3STACK_WM8903_MODULE)
+static struct mxc_audio_platform_data mxc_audio_data;
+
+static struct platform_device mxc_alsa_device = {
+ .name = "imx-3stack-wm8903",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_audio_data,
+ },
+};
+
+static void __init mxc_init_audio(void)
+{
+ mxc_audio_data.ssi_clk[0] = clk_get(NULL, "ssi_clk.0");
+ clk_put(mxc_audio_data.ssi_clk[0]);
+
+ mxc_audio_data.ssi_clk[1] = clk_get(NULL, "ssi_clk.1");
+ clk_put(mxc_audio_data.ssi_clk[1]);
+
+ mxc_audio_data.ssi_num = 1;
+ mxc_audio_data.src_port = 2;
+ mxc_audio_data.ext_port = 3;
+
+ (void)platform_device_register(&mxc_alsa_device);
+}
+#else
+static void __init mxc_init_audio(void)
+{
+}
+#endif
+
+#if defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000) \
+ || defined(CONFIG_SND_SOC_IMX_3STACK_SGTL5000_MODULE)
+
+static struct mxc_sgtl5000_platform_data sgtl5000_data = {
+ .ssi_num = 1,
+ .src_port = 2,
+ .ext_port = 3,
+ .hp_irq = IOMUX_TO_IRQ(MX51_PIN_EIM_A26),
+ .hp_status = headphone_det_status,
+ .amp_gpo = "GPO2",
+ .vddio = 1800000,
+ .vdda = 1800000,
+ .vddd = 12000000,
+ .sysclk = 12000000,
+};
+
+static struct platform_device sgtl5000_device = {
+ .name = "sgtl5000-imx",
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &sgtl5000_data,
+ },
+};
+
+static void mxc_sgtl5000_init(void)
+{
+ int err, pin;
+
+ pin = MX51_PIN_EIM_A26;
+ err = mxc_request_iomux(pin, IOMUX_CONFIG_GPIO);
+ if (err) {
+ sgtl5000_data.hp_irq = -1;
+ printk(KERN_ERR "Error: sgtl5000_init request gpio failed!\n");
+ return;
+ }
+ mxc_iomux_set_pad(pin, PAD_CTL_PKE_ENABLE | PAD_CTL_100K_PU);
+ mxc_set_gpio_direction(pin, 1);
+
+ platform_device_register(&sgtl5000_device);
+}
+#else
+static inline void mxc_sgtl5000_init(void)
+{
+}
+#endif
+
+static void bt_reset(void)
+{
+ int err;
+
+ err = mxc_request_iomux(MX51_PIN_EIM_D19, IOMUX_CONFIG_GPIO);
+ if (err) {
+ printk(KERN_ERR "Error: bt reset request gpio failed!\n");
+ return;
+ }
+ mxc_set_gpio_dataout(MX51_PIN_EIM_D19, 1);
+ mxc_set_gpio_direction(MX51_PIN_EIM_D19, 0);
+ mxc_free_iomux(MX51_PIN_EIM_D19, IOMUX_CONFIG_GPIO);
+}
+
+static struct mxc_bt_platform_data mxc_bt_data = {
+ .bt_vdd = NULL,
+ .bt_vdd_parent = NULL,
+ .bt_vusb = "SW4",
+ .bt_vusb_parent = NULL,
+ .bt_reset = bt_reset,
+};
+
+static struct platform_device mxc_bt_device = {
+ .name = "mxc_bt",
+ .id = 0,
+ .dev = {
+ .release = mxc_nop_release,
+ .platform_data = &mxc_bt_data,
+ },
+};
+
+static void mxc_init_bluetooth(void)
+{
+ (void)platform_device_register(&mxc_bt_device);
+}
+
+/*!
+ * Board specific fixup function. It is called by \b setup_arch() in
+ * setup.c file very early on during kernel starts. It allows the user to
+ * statically fill in the proper values for the passed-in parameters. None of
+ * the parameters is used currently.
+ *
+ * @param desc pointer to \b struct \b machine_desc
+ * @param tags pointer to \b struct \b tag
+ * @param cmdline pointer to the command line
+ * @param mi pointer to \b struct \b meminfo
+ */
+static void __init fixup_mxc_board(struct machine_desc *desc, struct tag *tags,
+ char **cmdline, struct meminfo *mi)
+{
+ mxc_cpu_init();
+
+#ifdef CONFIG_DISCONTIGMEM
+ do {
+ int nid;
+ mi->nr_banks = MXC_NUMNODES;
+ for (nid = 0; nid < mi->nr_banks; nid++)
+ SET_NODE(mi, nid);
+
+ } while (0);
+#endif
+}
+
+/*!
+ * Board specific initialization.
+ */
+static void __init mxc_board_init(void)
+{
+ mxc_cpu_common_init();
+ mxc_gpio_init();
+ early_console_setup(saved_command_line);
+ mxc_init_devices();
+
+ mxc_expio_init();
+ mxc_init_enet();
+ mxc_init_pata();
+ mxc_init_fb();
+ mxc_init_bl();
+ mxc_init_keypad();
+ mxc_init_nand_mtd();
+ mxc_init_mmc();
+ mxc_init_srpgconfig();
+
+#if defined(CONFIG_I2C_MXC) || defined(CONFIG_I2C_MXC_MODULE)
+
+#ifdef CONFIG_I2C_MXC_SELECT1
+ i2c_register_board_info(0, mxc_i2c0_board_info,
+ ARRAY_SIZE(mxc_i2c0_board_info));
+#endif
+#ifdef CONFIG_I2C_MXC_SELECT2
+ i2c_register_board_info(1, mxc_i2c1_board_info,
+ ARRAY_SIZE(mxc_i2c1_board_info));
+#endif
+#if defined(CONFIG_I2C_MXC_HS) || defined(CONFIG_I2C_MXC_HS_MODULE)
+ i2c_register_board_info(3, mxc_i2c_hs_board_info,
+ ARRAY_SIZE(mxc_i2c_hs_board_info));
+#endif
+
+#endif
+ mxc_init_touchscreen();
+ mxc_init_audio();
+
+ mxc_sgtl5000_init();
+ mxc_init_bluetooth();
+}
+
+static void __init mx51_3stack_timer_init(void)
+{
+ mxc_clocks_init(32768, 24000000, 22579200, 24576000);
+ mxc_timer_init("gpt_clk.0");
+}
+
+static struct sys_timer mxc_timer = {
+ .init = mx51_3stack_timer_init,
+};
+
+/*
+ * The following uses standard kernel macros define in arch.h in order to
+ * initialize __mach_desc_MX51_3STACK data structure.
+ */
+/* *INDENT-OFF* */
+MACHINE_START(MX51_3DS, "Freescale MX51 3-Stack Board")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .phys_io = AIPS1_BASE_ADDR,
+ .io_pg_offst = ((AIPS1_BASE_ADDR_VIRT) >> 18) & 0xfffc,
+ .boot_params = PHYS_OFFSET + 0x100,
+ .fixup = fixup_mxc_board,
+ .map_io = mxc_map_io,
+ .init_irq = mxc_init_irq,
+ .init_machine = mxc_board_init,
+ .timer = &mxc_timer,
+MACHINE_END
diff --git a/arch/arm/mach-mx51/mx51_3stack_gpio.c b/arch/arm/mach-mx51/mx51_3stack_gpio.c
new file mode 100644
index 000000000000..d2beb2f0a7e9
--- /dev/null
+++ b/arch/arm/mach-mx51/mx51_3stack_gpio.c
@@ -0,0 +1,1706 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <asm/io.h>
+#include <mach/hardware.h>
+#include <mach/clock.h>
+#include <mach/gpio.h>
+
+#include "iomux.h"
+
+/*!
+ * @file mach-mx51/mx51_3stack_gpio.c
+ *
+ * @brief This file contains all the GPIO setup functions for the board.
+ *
+ * @ingroup GPIO
+ */
+
+void gpio_activate_audio_ports(void);
+
+/*!
+ * Setup GPIO for a UART port to be active
+ *
+ * @param port a UART port
+ * @param no_irda indicates if the port is used for SIR
+ */
+void gpio_uart_active(int port, int no_irda)
+{
+ /*
+ * Configure the IOMUX control registers for the UART signals
+ * and enable the UART transceivers
+ */
+ switch (port) {
+ /* UART 1 IOMUX Configs */
+ case 0:
+ mxc_request_iomux(MX51_PIN_UART1_RXD, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_UART1_RXD, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_input(MUX_IN_UART1_IPP_UART_RXD_MUX_SELECT_INPUT,
+ INPUT_CTL_PATH0);
+ mxc_request_iomux(MX51_PIN_UART1_TXD, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_UART1_TXD, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ mxc_request_iomux(MX51_PIN_UART1_RTS, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_UART1_RTS, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH);
+ mxc_iomux_set_input(MUX_IN_UART1_IPP_UART_RTS_B_SELECT_INPUT,
+ INPUT_CTL_PATH0);
+ mxc_request_iomux(MX51_PIN_UART1_CTS, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_UART1_CTS, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH);
+ break;
+ /* UART 2 IOMUX Configs */
+ case 1:
+ mxc_request_iomux(MX51_PIN_UART2_RXD, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_UART2_RXD, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_input(MUX_IN_UART2_IPP_UART_RXD_MUX_SELECT_INPUT,
+ INPUT_CTL_PATH2);
+ mxc_request_iomux(MX51_PIN_UART2_TXD, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_UART2_TXD, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ /* UART2_RTS */
+ mxc_request_iomux(MX51_PIN_EIM_D26, IOMUX_CONFIG_ALT4);
+ mxc_iomux_set_pad(MX51_PIN_EIM_D26, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_input(MUX_IN_UART2_IPP_UART_RTS_B_SELECT_INPUT,
+ INPUT_CTL_PATH3);
+ /* UART2_CTS */
+ mxc_request_iomux(MX51_PIN_EIM_D25, IOMUX_CONFIG_ALT4);
+ mxc_iomux_set_pad(MX51_PIN_EIM_D25, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ break;
+ case 2:
+ /* UART 3 IOMUX Configs */
+ mxc_request_iomux(MX51_PIN_UART3_RXD, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_UART3_RXD, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_input(MUX_IN_UART3_IPP_UART_RXD_MUX_SELECT_INPUT,
+ INPUT_CTL_PATH0);
+ mxc_request_iomux(MX51_PIN_UART3_TXD, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_UART3_TXD, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ /* UART3_RTS */
+ mxc_request_iomux(MX51_PIN_EIM_D27, IOMUX_CONFIG_ALT3);
+ mxc_iomux_set_pad(MX51_PIN_EIM_D27, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_input(MUX_IN_UART3_IPP_UART_RTS_B_SELECT_INPUT,
+ INPUT_CTL_PATH2);
+ /* UART3_CTS */
+ mxc_request_iomux(MX51_PIN_EIM_D24, IOMUX_CONFIG_ALT3);
+ mxc_iomux_set_pad(MX51_PIN_EIM_D24, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_uart_active);
+
+/*!
+ * Setup GPIO for a UART port to be inactive
+ *
+ * @param port a UART port
+ * @param no_irda indicates if the port is used for SIR
+ */
+void gpio_uart_inactive(int port, int no_irda)
+{
+ switch (port) {
+ /* UART 1 */
+ case 0:
+ mxc_request_gpio(MX51_PIN_UART1_RXD);
+ mxc_request_gpio(MX51_PIN_UART1_TXD);
+ mxc_request_gpio(MX51_PIN_UART1_RTS);
+ mxc_request_gpio(MX51_PIN_UART1_CTS);
+
+ mxc_free_iomux(MX51_PIN_UART1_RXD, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_UART1_TXD, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_UART1_RTS, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_UART1_CTS, IOMUX_CONFIG_GPIO);
+ break;
+ /* UART 2 */
+ case 1:
+ mxc_request_gpio(MX51_PIN_UART2_RXD);
+ mxc_request_gpio(MX51_PIN_UART2_TXD);
+
+ mxc_free_iomux(MX51_PIN_UART2_RXD, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_UART2_TXD, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_EIM_D26, IOMUX_CONFIG_ALT4);
+ mxc_free_iomux(MX51_PIN_EIM_D25, IOMUX_CONFIG_ALT4);
+ break;
+ case 2:
+ /* UART 3 */
+ mxc_request_gpio(MX51_PIN_UART3_RXD);
+ mxc_request_gpio(MX51_PIN_UART3_TXD);
+ mxc_request_gpio(MX51_PIN_EIM_D27);
+ mxc_request_gpio(MX51_PIN_EIM_D24);
+
+ mxc_free_iomux(MX51_PIN_UART3_RXD, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_UART3_TXD, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_EIM_D27, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_EIM_D24, IOMUX_CONFIG_GPIO);
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_uart_inactive);
+
+/*!
+ * Configure the IOMUX GPR register to receive shared SDMA UART events
+ *
+ * @param port a UART port
+ */
+void config_uartdma_event(int port)
+{
+
+}
+
+EXPORT_SYMBOL(config_uartdma_event);
+
+/*!
+ * Setup GPIO for a CSPI device to be active
+ *
+ * @param cspi_mod an CSPI device
+ */
+void gpio_spi_active(int cspi_mod)
+{
+ switch (cspi_mod) {
+ case 0:
+ /* SPI1 */
+ mxc_request_iomux(MX51_PIN_CSPI1_MISO, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_CSPI1_MISO, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH |
+ PAD_CTL_SRE_FAST);
+
+ mxc_request_iomux(MX51_PIN_CSPI1_MOSI, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_CSPI1_MOSI, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH |
+ PAD_CTL_SRE_FAST);
+
+ mxc_request_iomux(MX51_PIN_CSPI1_RDY, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_CSPI1_RDY, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH |
+ PAD_CTL_SRE_FAST);
+
+ mxc_request_iomux(MX51_PIN_CSPI1_SCLK, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_CSPI1_SCLK, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH |
+ PAD_CTL_SRE_FAST);
+
+ mxc_request_iomux(MX51_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_CSPI1_SS0, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH |
+ PAD_CTL_SRE_FAST);
+
+ mxc_request_iomux(MX51_PIN_CSPI1_SS1, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_CSPI1_SS1, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_HIGH |
+ PAD_CTL_SRE_FAST);
+ break;
+ case 1:
+ /* SPI2 */
+ mxc_request_iomux(MX51_PIN_NANDF_RB2, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_RB2, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_PKE_ENABLE);
+
+ mxc_request_iomux(MX51_PIN_NANDF_RB3, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_RB3, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_PKE_ENABLE);
+
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) {
+ mxc_request_iomux(MX51_PIN_NANDF_RB4, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_RB4, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_PKE_ENABLE);
+
+ mxc_request_iomux(MX51_PIN_NANDF_RB7, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_RB7, PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_ENABLE | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_KEEPER | PAD_CTL_100K_PU |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_DRV_HIGH);
+ } else {
+ mxc_request_iomux(MX51_PIN_NANDF_RDY_INT, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_RDY_INT, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_PKE_ENABLE);
+
+ mxc_request_iomux(MX51_PIN_NANDF_D15, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D15, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_HIGH | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_KEEPER);
+
+ mxc_request_iomux(MX51_PIN_NANDF_D12, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D12, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_HIGH | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_PKE_ENABLE);
+ }
+ break;
+ case 2:
+ /* SPI3 */
+ mxc_request_iomux(MX51_PIN_USBH1_NXT, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_NXT, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+
+ mxc_request_iomux(MX51_PIN_USBH1_DIR, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DIR, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+
+ mxc_request_iomux(MX51_PIN_USBH1_CLK, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_CLK, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+
+ mxc_request_iomux(MX51_PIN_USBH1_DATA5, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA5, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_spi_active);
+
+/*!
+ * Setup GPIO for a CSPI device to be inactive
+ *
+ * @param cspi_mod a CSPI device
+ */
+void gpio_spi_inactive(int cspi_mod)
+{
+ switch (cspi_mod) {
+ case 0:
+ /* SPI1 */
+ mxc_free_iomux(MX51_PIN_CSPI1_MISO, IOMUX_CONFIG_ALT0);
+ mxc_free_iomux(MX51_PIN_CSPI1_MOSI, IOMUX_CONFIG_ALT0);
+ mxc_free_iomux(MX51_PIN_CSPI1_RDY, IOMUX_CONFIG_ALT0);
+ mxc_free_iomux(MX51_PIN_CSPI1_SCLK, IOMUX_CONFIG_ALT0);
+ mxc_free_iomux(MX51_PIN_CSPI1_SS0, IOMUX_CONFIG_ALT0);
+ mxc_free_iomux(MX51_PIN_CSPI1_SS1, IOMUX_CONFIG_ALT0);
+ break;
+ case 1:
+ /* SPI2 */
+ mxc_free_iomux(MX51_PIN_NANDF_RB2, IOMUX_CONFIG_ALT2);
+ mxc_free_iomux(MX51_PIN_NANDF_RB3, IOMUX_CONFIG_ALT2);
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) < 0) {
+ mxc_free_iomux(MX51_PIN_NANDF_RB4, IOMUX_CONFIG_ALT2);
+ mxc_free_iomux(MX51_PIN_NANDF_RB7, IOMUX_CONFIG_ALT2);
+ } else {
+ mxc_free_iomux(MX51_PIN_NANDF_RDY_INT, IOMUX_CONFIG_ALT2);
+ mxc_free_iomux(MX51_PIN_NANDF_D15, IOMUX_CONFIG_ALT2);
+ mxc_free_iomux(MX51_PIN_NANDF_D12, IOMUX_CONFIG_ALT2);
+ }
+ break;
+ case 2:
+ /* SPI3 */
+ mxc_free_iomux(MX51_PIN_USBH1_NXT, IOMUX_CONFIG_ALT1);
+ mxc_free_iomux(MX51_PIN_USBH1_DIR, IOMUX_CONFIG_ALT1);
+ mxc_free_iomux(MX51_PIN_USBH1_CLK, IOMUX_CONFIG_ALT1);
+ mxc_free_iomux(MX51_PIN_USBH1_DATA5, IOMUX_CONFIG_ALT1);
+ break;
+ default:
+ break;
+ }
+
+}
+
+EXPORT_SYMBOL(gpio_spi_inactive);
+
+/*!
+ * Setup 1-Wire to be active
+ */
+void gpio_owire_active(void)
+{
+ mxc_request_iomux(MX51_PIN_OWIRE_LINE, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_OWIRE_LINE, PAD_CTL_HYS_ENABLE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_ODE_OPENDRAIN_ENABLE |
+ PAD_CTL_DRV_HIGH | PAD_CTL_SRE_FAST);
+}
+
+EXPORT_SYMBOL(gpio_owire_active);
+
+/*!
+ * Setup 1-Wire to be active
+ */
+void gpio_owire_inactive(void)
+{
+ mxc_free_iomux(MX51_PIN_OWIRE_LINE, IOMUX_CONFIG_ALT0);
+}
+
+EXPORT_SYMBOL(gpio_owire_inactive);
+
+/*!
+ * Setup GPIO for an I2C device to be active
+ *
+ * @param i2c_num an I2C device
+ */
+void gpio_i2c_active(int i2c_num)
+{
+ switch (i2c_num) {
+ case 0:
+ /*i2c1 sda */
+ mxc_request_iomux(MX51_PIN_CSPI1_MOSI,
+ IOMUX_CONFIG_ALT1 | IOMUX_CONFIG_SION);
+ mxc_iomux_set_input(MUX_IN_I2C1_IPP_SDA_IN_SELECT_INPUT,
+ INPUT_CTL_PATH1);
+ mxc_iomux_set_pad(MX51_PIN_CSPI1_MOSI,
+ PAD_CTL_SRE_FAST |
+ PAD_CTL_ODE_OPENDRAIN_ENABLE |
+ PAD_CTL_DRV_HIGH |
+ PAD_CTL_100K_PU |
+ PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_VOT_LOW | PAD_CTL_DDR_INPUT_CMOS);
+
+ /*i2c1 scl */
+ mxc_request_iomux(MX51_PIN_CSPI1_SCLK,
+ IOMUX_CONFIG_ALT1 | IOMUX_CONFIG_SION);
+ mxc_iomux_set_input(MUX_IN_I2C1_IPP_SCL_IN_SELECT_INPUT,
+ INPUT_CTL_PATH1);
+ mxc_iomux_set_pad(MX51_PIN_CSPI1_SCLK,
+ PAD_CTL_SRE_FAST |
+ PAD_CTL_ODE_OPENDRAIN_ENABLE |
+ PAD_CTL_DRV_HIGH |
+ PAD_CTL_100K_PU |
+ PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_VOT_LOW | PAD_CTL_DDR_INPUT_CMOS);
+ break;
+
+ case 1:
+ mxc_request_iomux(MX51_PIN_GPIO1_2,
+ IOMUX_CONFIG_ALT2 | IOMUX_CONFIG_SION);
+ mxc_request_iomux(MX51_PIN_GPIO1_3,
+ IOMUX_CONFIG_ALT2 | IOMUX_CONFIG_SION);
+
+ mxc_iomux_set_input(MUX_IN_I2C2_IPP_SDA_IN_SELECT_INPUT,
+ INPUT_CTL_PATH3);
+ mxc_iomux_set_input(MUX_IN_I2C2_IPP_SCL_IN_SELECT_INPUT,
+ INPUT_CTL_PATH3);
+
+ mxc_iomux_set_pad(MX51_PIN_GPIO1_2,
+ PAD_CTL_SRE_FAST |
+ PAD_CTL_ODE_OPENDRAIN_ENABLE |
+ PAD_CTL_DRV_HIGH |
+ PAD_CTL_100K_PU |
+ PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_VOT_LOW | PAD_CTL_DDR_INPUT_CMOS);
+ mxc_iomux_set_pad(MX51_PIN_GPIO1_3,
+ PAD_CTL_SRE_FAST |
+ PAD_CTL_ODE_OPENDRAIN_ENABLE |
+ PAD_CTL_DRV_HIGH |
+ PAD_CTL_100K_PU |
+ PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_VOT_LOW | PAD_CTL_DDR_INPUT_CMOS);
+ break;
+ case 2:
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_i2c_active);
+
+/*!
+ * Setup GPIO for an I2C device to be inactive
+ *
+ * @param i2c_num an I2C device
+ */
+void gpio_i2c_inactive(int i2c_num)
+{
+ switch (i2c_num) {
+ case 0:
+ /*i2c1 sda */
+ mxc_free_iomux(MX51_PIN_CSPI1_MOSI,
+ IOMUX_CONFIG_ALT1 | IOMUX_CONFIG_SION);
+ /*i2c1 scl */
+ mxc_free_iomux(MX51_PIN_CSPI1_SCLK,
+ IOMUX_CONFIG_ALT1 | IOMUX_CONFIG_SION);
+ break;
+ case 1:
+ mxc_free_iomux(MX51_PIN_GPIO1_2,
+ IOMUX_CONFIG_ALT2 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX51_PIN_GPIO1_3,
+ IOMUX_CONFIG_ALT2 | IOMUX_CONFIG_SION);
+ break;
+ case 2:
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_i2c_inactive);
+
+void gpio_i2c_hs_active(void)
+{
+ mxc_request_iomux(MX51_PIN_I2C1_CLK,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_iomux_set_pad(MX51_PIN_I2C1_CLK, 0x1E4);
+
+ mxc_request_iomux(MX51_PIN_I2C1_DAT,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_iomux_set_pad(MX51_PIN_I2C1_DAT, 0x1E4);
+}
+
+EXPORT_SYMBOL(gpio_i2c_hs_active);
+
+void gpio_i2c_hs_inactive(void)
+{
+ mxc_free_iomux(MX51_PIN_I2C1_CLK,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX51_PIN_I2C1_DAT,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+}
+
+EXPORT_SYMBOL(gpio_i2c_hs_inactive);
+
+void gpio_pmic_active(void)
+{
+ mxc_request_iomux(MX51_PIN_GPIO1_5, IOMUX_CONFIG_GPIO
+ | IOMUX_CONFIG_SION);
+ mxc_iomux_set_pad(MX51_PIN_GPIO1_5, PAD_CTL_SRE_SLOW |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_DRV_MEDIUM |
+ PAD_CTL_100K_PU |
+ PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_VOT_HIGH | PAD_CTL_DDR_INPUT_CMOS);
+ mxc_set_gpio_direction(MX51_PIN_GPIO1_5, 1);
+}
+
+EXPORT_SYMBOL(gpio_pmic_active);
+
+/*!
+ * This function activates DAM port 3 to enable audio I/O.
+ */
+void gpio_activate_audio_ports(void)
+{
+ unsigned int pad_val;
+
+ pad_val = PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH |
+ PAD_CTL_ODE_OPENDRAIN_NONE | PAD_CTL_100K_PU |
+ PAD_CTL_HYS_NONE | PAD_CTL_DDR_INPUT_CMOS | PAD_CTL_DRV_VOT_LOW;
+
+ /* AUD3_TXD */
+ mxc_request_iomux(MX51_PIN_AUD3_BB_TXD, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_AUD3_BB_TXD, pad_val);
+
+ /* AUD3_RXD */
+ mxc_request_iomux(MX51_PIN_AUD3_BB_RXD, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_AUD3_BB_RXD, pad_val);
+
+ /* AUD3_CLK */
+ mxc_request_iomux(MX51_PIN_AUD3_BB_CK, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_AUD3_BB_CK, pad_val);
+
+ /* AUD3_FS */
+ mxc_request_iomux(MX51_PIN_AUD3_BB_FS, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_AUD3_BB_FS, pad_val);
+
+ /* EIM_D16 */
+ /* osc_en is shared by SPDIF */
+ mxc_request_iomux(MX51_PIN_EIM_D16, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_EIM_D16,
+ PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_set_gpio_direction(MX51_PIN_EIM_D16, 0);
+ mxc_set_gpio_dataout(MX51_PIN_EIM_D16, 1);
+
+}
+
+EXPORT_SYMBOL(gpio_activate_audio_ports);
+
+/*!
+ * Setup GPIO for SDHC to be active
+ *
+ * @param module SDHC module number
+ */
+void gpio_sdhc_active(int module)
+{
+ switch (module) {
+ case 0:
+ mxc_request_iomux(MX51_PIN_SD1_CMD,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_request_iomux(MX51_PIN_SD1_CLK,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+
+ mxc_request_iomux(MX51_PIN_SD1_DATA0,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_request_iomux(MX51_PIN_SD1_DATA1,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_request_iomux(MX51_PIN_SD1_DATA2,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_request_iomux(MX51_PIN_SD1_DATA3,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_iomux_set_pad(MX51_PIN_SD1_CMD,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_ENABLE | PAD_CTL_47K_PU |
+ PAD_CTL_PUE_PULL |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX51_PIN_SD1_CLK,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_NONE | PAD_CTL_47K_PU |
+ PAD_CTL_PUE_PULL |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX51_PIN_SD1_DATA0,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_ENABLE | PAD_CTL_47K_PU |
+ PAD_CTL_PUE_PULL |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX51_PIN_SD1_DATA1,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_ENABLE | PAD_CTL_47K_PU |
+ PAD_CTL_PUE_PULL |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX51_PIN_SD1_DATA2,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_ENABLE | PAD_CTL_47K_PU |
+ PAD_CTL_PUE_PULL |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_iomux_set_pad(MX51_PIN_SD1_DATA3,
+ PAD_CTL_DRV_MAX | PAD_CTL_DRV_VOT_HIGH |
+ PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PD |
+ PAD_CTL_PUE_PULL |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ /* Write Protected Pin */
+ mxc_request_iomux(MX51_PIN_GPIO1_1, IOMUX_CONFIG_ALT0 |
+ IOMUX_CONFIG_SION);
+ mxc_iomux_set_pad(MX51_PIN_GPIO1_1, PAD_CTL_DRV_HIGH |
+ PAD_CTL_HYS_ENABLE | PAD_CTL_100K_PU |
+ PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_SRE_FAST);
+ mxc_set_gpio_direction(MX51_PIN_GPIO1_1, 1);
+ break;
+ case 1:
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_sdhc_active);
+
+/*!
+ * Setup GPIO for SDHC1 to be inactive
+ *
+ * @param module SDHC module number
+ */
+void gpio_sdhc_inactive(int module)
+{
+ switch (module) {
+ case 0:
+ mxc_free_iomux(MX51_PIN_SD1_CMD,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX51_PIN_SD1_CLK,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX51_PIN_SD1_DATA0,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX51_PIN_SD1_DATA1,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX51_PIN_SD1_DATA2,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+ mxc_free_iomux(MX51_PIN_SD1_DATA3,
+ IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
+
+ mxc_iomux_set_pad(MX51_PIN_SD1_CLK,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX51_PIN_SD1_CMD,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX51_PIN_SD1_DATA0,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX51_PIN_SD1_DATA1,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX51_PIN_SD1_DATA2,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ mxc_iomux_set_pad(MX51_PIN_SD1_DATA3,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+
+ /* Free Write Protected Pin */
+ mxc_free_iomux(MX51_PIN_GPIO1_1, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_GPIO1_1,
+ (PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW));
+ break;
+ case 1:
+ /* TODO:what are the pins for SDHC2? */
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_sdhc_inactive);
+
+/*
+ * Probe for the card. If present the GPIO data would be set.
+ */
+int sdhc_get_card_det_status(struct device *dev)
+{
+ int ret;
+
+ if (to_platform_device(dev)->id == 0) {
+ ret = mxc_get_gpio_datain(MX51_PIN_GPIO1_0);
+ return ret;
+ } else { /* config the det pin for SDHC2 */
+ return 0;
+ }
+}
+
+EXPORT_SYMBOL(sdhc_get_card_det_status);
+
+/*
+ * Return the card detect pin.
+ */
+int sdhc_init_card_det(int id)
+{
+ if (id == 0) {
+ mxc_request_iomux(MX51_PIN_GPIO1_0, IOMUX_CONFIG_ALT0 |
+ IOMUX_CONFIG_SION);
+ mxc_iomux_set_pad(MX51_PIN_GPIO1_0, PAD_CTL_DRV_HIGH |
+ PAD_CTL_HYS_ENABLE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_set_gpio_direction(MX51_PIN_GPIO1_0, 1);
+ return IOMUX_TO_IRQ(MX51_PIN_GPIO1_0);
+ } else { /* config the det pin for SDHC2 */
+ return 0;
+
+ }
+}
+
+EXPORT_SYMBOL(sdhc_init_card_det);
+
+/*!
+ * Get WP pin value to detect write protection
+ */
+int sdhc_write_protect(struct device *dev)
+{
+ unsigned short rc = 0;
+
+ if (to_platform_device(dev)->id == 0)
+ rc = mxc_get_gpio_datain(MX51_PIN_GPIO1_1);
+ else
+ rc = 0;
+ if (rc > 0)
+ return 1;
+ else
+ return 0;
+}
+
+EXPORT_SYMBOL(sdhc_write_protect);
+
+/*!
+ * Setup GPIO for LCD to be active
+ *
+ */
+void gpio_lcd_active(void)
+{
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) > 0) {
+ mxc_request_iomux(MX51_PIN_DI1_D1_CS, IOMUX_CONFIG_ALT4);
+ mxc_set_gpio_direction(MX51_PIN_DI1_D1_CS, 0);
+ mxc_request_iomux(MX51_PIN_DI1_D0_CS, IOMUX_CONFIG_ALT1);
+ mxc_request_iomux(MX51_PIN_DI1_PIN11, IOMUX_CONFIG_ALT1);
+ mxc_request_iomux(MX51_PIN_DI1_PIN12, IOMUX_CONFIG_ALT1);
+ mxc_request_iomux(MX51_PIN_DI1_PIN13, IOMUX_CONFIG_ALT1);
+ } else {
+ mxc_request_iomux(MX51_PIN_DISP2_DAT15, IOMUX_CONFIG_ALT5);
+ mxc_request_iomux(MX51_PIN_DI_GP2, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_DI_GP3, IOMUX_CONFIG_ALT0);
+ }
+}
+
+/*!
+ * Setup GPIO for LCD to be inactive
+ *
+ */
+void gpio_lcd_inactive(void)
+{
+}
+
+/*!
+ * Setup pins for SLCD to be active
+ *
+ */
+void slcd_gpio_config(void)
+{
+}
+
+/*!
+ * Switch to the specified sensor
+ *
+ */
+void gpio_sensor_select(int sensor)
+{
+}
+
+/*!
+ * Setup GPIO for sensor to be active
+ *
+ * @param csi csi 0 or csi 1
+ *
+ */
+void gpio_sensor_active(unsigned int csi)
+{
+ switch (csi) {
+ case 0:
+ mxc_iomux_set_pad(MX51_PIN_CSI1_D10, PAD_CTL_HYS_NONE);
+ mxc_iomux_set_pad(MX51_PIN_CSI1_D11, PAD_CTL_HYS_NONE);
+ mxc_iomux_set_pad(MX51_PIN_CSI1_D12, PAD_CTL_HYS_NONE);
+ mxc_iomux_set_pad(MX51_PIN_CSI1_D13, PAD_CTL_HYS_NONE);
+ mxc_iomux_set_pad(MX51_PIN_CSI1_D14, PAD_CTL_HYS_NONE);
+ mxc_iomux_set_pad(MX51_PIN_CSI1_D15, PAD_CTL_HYS_NONE);
+ mxc_iomux_set_pad(MX51_PIN_CSI1_D16, PAD_CTL_HYS_NONE);
+ mxc_iomux_set_pad(MX51_PIN_CSI1_D17, PAD_CTL_HYS_NONE);
+ mxc_iomux_set_pad(MX51_PIN_CSI1_D18, PAD_CTL_HYS_NONE);
+ mxc_iomux_set_pad(MX51_PIN_CSI1_D19, PAD_CTL_HYS_NONE);
+ mxc_iomux_set_pad(MX51_PIN_CSI1_PKE0, PAD_CTL_PKE_ENABLE);
+
+ mxc_request_iomux(MX51_PIN_CSI1_VSYNC, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_CSI1_VSYNC, PAD_CTL_HYS_NONE |
+ PAD_CTL_SRE_SLOW);
+
+ mxc_request_iomux(MX51_PIN_CSI1_HSYNC, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_CSI1_HSYNC, PAD_CTL_HYS_NONE |
+ PAD_CTL_SRE_SLOW);
+
+ mxc_iomux_set_pad(MX51_PIN_CSI1_PIXCLK, PAD_CTL_HYS_NONE);
+
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) > 0) {
+ /* Camera low power */
+ mxc_request_iomux(MX51_PIN_CSI1_D8, IOMUX_CONFIG_ALT3);
+ mxc_iomux_set_pad(MX51_PIN_CSI1_D8, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_LOW |
+ PAD_CTL_SRE_SLOW);
+ mxc_iomux_set_input
+ (MUX_IN_GPIO3_IPP_IND_G_IN_12_SELECT_INPUT,
+ INPUT_CTL_PATH1);
+ mxc_set_gpio_direction(MX51_PIN_CSI1_D8, 0);
+ mxc_set_gpio_dataout(MX51_PIN_CSI1_D8, 0);
+
+ /* Camera reset */
+ mxc_request_iomux(MX51_PIN_CSI1_D9, IOMUX_CONFIG_ALT3);
+ mxc_iomux_set_pad(MX51_PIN_CSI1_D9, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_LOW |
+ PAD_CTL_SRE_SLOW);
+ mxc_set_gpio_direction(MX51_PIN_CSI1_D9, 0);
+ mxc_set_gpio_dataout(MX51_PIN_CSI1_D9, 1);
+ } else {
+ mxc_request_iomux(MX51_PIN_EIM_EB2, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_EIM_EB2, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_PULL |
+ PAD_CTL_100K_PD | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_DRV_LOW | PAD_CTL_SRE_SLOW);
+ mxc_set_gpio_direction(MX51_PIN_EIM_EB2, 0);
+ mxc_set_gpio_dataout(MX51_PIN_EIM_EB2, 0);
+ }
+
+ mxc_request_iomux(MX51_PIN_EIM_A26, IOMUX_CONFIG_ALT5);
+ mxc_iomux_set_input
+ (MUX_IN_HSC_MIPI_MIX_IPP_IND_SENS2_DATA_EN_SELECT_INPUT,
+ INPUT_CTL_PATH0);
+ mxc_iomux_set_pad(MX51_PIN_EIM_A26,
+ PAD_CTL_HYS_NONE | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_PUE_PULL);
+ break;
+ case 1:
+ mxc_iomux_set_pad(MX51_PIN_CSI2_PKE0, PAD_CTL_PKE_ENABLE);
+
+ mxc_request_iomux(MX51_PIN_CSI2_D12, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_CSI2_D12, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_LOW |
+ PAD_CTL_SRE_SLOW);
+
+ mxc_request_iomux(MX51_PIN_CSI2_D13, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_CSI2_D13, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_LOW |
+ PAD_CTL_SRE_SLOW);
+
+ mxc_request_iomux(MX51_PIN_CSI2_D18, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_CSI2_D18, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_LOW |
+ PAD_CTL_SRE_SLOW);
+
+ mxc_request_iomux(MX51_PIN_CSI2_D19, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_CSI2_D19, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_LOW |
+ PAD_CTL_SRE_SLOW);
+
+ mxc_request_iomux(MX51_PIN_CSI2_VSYNC, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_CSI2_VSYNC, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_LOW |
+ PAD_CTL_SRE_SLOW);
+
+ mxc_request_iomux(MX51_PIN_CSI2_HSYNC, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_CSI2_HSYNC, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_LOW |
+ PAD_CTL_SRE_SLOW);
+
+ mxc_request_iomux(MX51_PIN_CSI2_PIXCLK, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_CSI2_PIXCLK, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_LOW |
+ PAD_CTL_SRE_SLOW);
+
+ mxc_request_iomux(MX51_PIN_GPIO1_5, IOMUX_CONFIG_ALT6);
+ mxc_iomux_set_pad(MX51_PIN_GPIO1_5, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_DRV_LOW | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_SRE_SLOW);
+
+ mxc_request_iomux(MX51_PIN_DI2_PIN4, IOMUX_CONFIG_ALT3);
+ mxc_iomux_set_pad(MX51_PIN_DI2_PIN4, PAD_CTL_HYS_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_DRV_LOW |
+ PAD_CTL_SRE_SLOW);
+ mxc_iomux_set_input(MUX_IN_FEC_FEC_COL_SELECT_INPUT,
+ INPUT_CTL_PATH1);
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_sensor_active);
+
+/*!
+ * Setup GPIO for sensor to be inactive
+ *
+ * @param csi csi 0 or csi 1
+ *
+ */
+void gpio_sensor_inactive(unsigned int csi)
+{
+ switch (csi) {
+ case 0:
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) > 0) {
+ mxc_free_iomux(MX51_PIN_CSI1_D8, IOMUX_CONFIG_GPIO);
+ mxc_request_iomux(MX51_PIN_CSI1_D8, IOMUX_CONFIG_ALT0);
+
+ mxc_free_iomux(MX51_PIN_CSI1_D9, IOMUX_CONFIG_GPIO);
+ mxc_request_iomux(MX51_PIN_CSI1_D9, IOMUX_CONFIG_ALT0);
+ } else {
+ mxc_free_iomux(MX51_PIN_EIM_EB2, IOMUX_CONFIG_GPIO);
+ mxc_request_iomux(MX51_PIN_EIM_EB2, IOMUX_CONFIG_ALT0);
+ }
+ mxc_request_iomux(MX51_PIN_EIM_A26, IOMUX_CONFIG_ALT0);
+ break;
+ case 1:
+ mxc_request_iomux(MX51_PIN_GPIO1_5, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_DI2_PIN4, IOMUX_CONFIG_ALT0);
+ break;
+ default:
+ break;
+ }
+}
+
+EXPORT_SYMBOL(gpio_sensor_inactive);
+
+/*!
+ * Setup GPIO for ATA interface
+ *
+ */
+void gpio_ata_active(void)
+{
+#define ATA_PAD_CONFIG PAD_CTL_DRV_HIGH | PAD_CTL_DRV_VOT_HIGH
+
+ /*BUFFER_EN */
+ mxc_request_iomux(MX51_PIN_NANDF_ALE, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_ALE, ATA_PAD_CONFIG);
+
+ /*PATA_CS_0 */
+ mxc_request_iomux(MX51_PIN_NANDF_CS2, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_CS2, ATA_PAD_CONFIG);
+
+ /*PATA_CS_1 */
+ mxc_request_iomux(MX51_PIN_NANDF_CS3, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_CS3, ATA_PAD_CONFIG);
+
+ /*PATA_DA0 */
+ mxc_request_iomux(MX51_PIN_NANDF_CS4, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_CS4, ATA_PAD_CONFIG);
+
+ /*PATA_DA1 */
+ mxc_request_iomux(MX51_PIN_NANDF_CS5, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_CS5, ATA_PAD_CONFIG);
+
+ /*PATA_DA2 */
+ mxc_request_iomux(MX51_PIN_NANDF_CS6, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_CS6, ATA_PAD_CONFIG);
+
+ /*PATA_DIOR */
+ mxc_request_iomux(MX51_PIN_NANDF_RE_B, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_RE_B, ATA_PAD_CONFIG);
+
+ /*PATA_DIOW */
+ mxc_request_iomux(MX51_PIN_NANDF_WE_B, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_WE_B, ATA_PAD_CONFIG);
+
+ /*PATA_RESET */
+ mxc_request_iomux(MX51_PIN_NANDF_CLE, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_CLE, ATA_PAD_CONFIG);
+
+ /*PATA_DMARQ */
+ mxc_request_iomux(MX51_PIN_NANDF_RB0, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_RB0, ATA_PAD_CONFIG);
+
+ /*PATA_DMACK */
+ mxc_request_iomux(MX51_PIN_NANDF_WP_B, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_WP_B, ATA_PAD_CONFIG);
+
+ /*PATA_INTRQ */
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) > 0) {
+ mxc_request_iomux(MX51_PIN_GPIO_NAND, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_GPIO_NAND, ATA_PAD_CONFIG);
+ } else {
+ mxc_request_iomux(MX51_PIN_NANDF_RB5, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_RB5, ATA_PAD_CONFIG);
+ }
+
+ /*PATA_IORDY */
+ mxc_request_iomux(MX51_PIN_NANDF_RB1, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_RB1, ATA_PAD_CONFIG);
+
+ /*PATA_D0 */
+ mxc_request_iomux(MX51_PIN_NANDF_D0, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D0, ATA_PAD_CONFIG);
+
+ /*PATA_D1 */
+ mxc_request_iomux(MX51_PIN_NANDF_D1, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D1, ATA_PAD_CONFIG);
+
+ /*PATA_D2 */
+ mxc_request_iomux(MX51_PIN_NANDF_D2, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D2, ATA_PAD_CONFIG);
+
+ /*PATA_D3 */
+ mxc_request_iomux(MX51_PIN_NANDF_D3, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D3, ATA_PAD_CONFIG);
+
+ /*PATA_D4 */
+ mxc_request_iomux(MX51_PIN_NANDF_D4, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D4, ATA_PAD_CONFIG);
+
+ /*PATA_D5 */
+ mxc_request_iomux(MX51_PIN_NANDF_D5, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D5, ATA_PAD_CONFIG);
+
+ /*PATA_D6 */
+ mxc_request_iomux(MX51_PIN_NANDF_D6, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D6, ATA_PAD_CONFIG);
+
+ /*PATA_D7 */
+ mxc_request_iomux(MX51_PIN_NANDF_D7, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D7, ATA_PAD_CONFIG);
+
+ /*PATA_D8 */
+ mxc_request_iomux(MX51_PIN_NANDF_D8, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D8, ATA_PAD_CONFIG);
+
+ /*PATA_D9 */
+ mxc_request_iomux(MX51_PIN_NANDF_D9, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D9, ATA_PAD_CONFIG);
+
+ /*PATA_D10 */
+ mxc_request_iomux(MX51_PIN_NANDF_D10, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D10, ATA_PAD_CONFIG);
+
+ /*PATA_D11 */
+ mxc_request_iomux(MX51_PIN_NANDF_D11, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D11, ATA_PAD_CONFIG);
+
+ /*PATA_D12 */
+ mxc_request_iomux(MX51_PIN_NANDF_D12, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D12, ATA_PAD_CONFIG);
+
+ /*PATA_D13 */
+ mxc_request_iomux(MX51_PIN_NANDF_D13, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D13, ATA_PAD_CONFIG);
+
+ /*PATA_D14 */
+ mxc_request_iomux(MX51_PIN_NANDF_D14, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D14, ATA_PAD_CONFIG);
+
+ /*PATA_D15 */
+ mxc_request_iomux(MX51_PIN_NANDF_D15, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_NANDF_D15, ATA_PAD_CONFIG);
+
+}
+
+EXPORT_SYMBOL(gpio_ata_active);
+
+/*!
+ * Restore ATA interface pins to reset values
+ *
+ */
+void gpio_ata_inactive(void)
+{
+ /*BUFFER_EN */
+ mxc_request_iomux(MX51_PIN_NANDF_ALE, IOMUX_CONFIG_ALT0);
+
+ /*PATA_CS_0 */
+ mxc_request_iomux(MX51_PIN_NANDF_CS2, IOMUX_CONFIG_ALT0);
+
+ /*PATA_CS_1 */
+ mxc_request_iomux(MX51_PIN_NANDF_CS3, IOMUX_CONFIG_ALT0);
+
+ /*PATA_DA0 */
+ mxc_request_iomux(MX51_PIN_NANDF_CS4, IOMUX_CONFIG_ALT0);
+
+ /*PATA_DA1 */
+ mxc_request_iomux(MX51_PIN_NANDF_CS5, IOMUX_CONFIG_ALT0);
+
+ /*PATA_DA2 */
+ mxc_request_iomux(MX51_PIN_NANDF_CS6, IOMUX_CONFIG_ALT0);
+
+ /*PATA_DIOR */
+ mxc_request_iomux(MX51_PIN_NANDF_RE_B, IOMUX_CONFIG_ALT0);
+
+ /*PATA_DIOW */
+ mxc_request_iomux(MX51_PIN_NANDF_WE_B, IOMUX_CONFIG_ALT0);
+
+ /*PATA_DMARQ */
+ mxc_request_iomux(MX51_PIN_NANDF_RB0, IOMUX_CONFIG_ALT0);
+
+ /*PATA_DMACK */
+ mxc_request_iomux(MX51_PIN_NANDF_WP_B, IOMUX_CONFIG_ALT0);
+
+ /*PATA_INTRQ */
+ if (cpu_is_mx51_rev(CHIP_REV_2_0) > 0) {
+ mxc_request_iomux(MX51_PIN_GPIO_NAND, IOMUX_CONFIG_ALT0);
+ } else {
+ mxc_request_iomux(MX51_PIN_NANDF_RB5, IOMUX_CONFIG_ALT0);
+ }
+
+ /*PATA_IORDY */
+ mxc_request_iomux(MX51_PIN_NANDF_RB1, IOMUX_CONFIG_ALT0);
+
+ /*PATA_D0 */
+ mxc_request_iomux(MX51_PIN_NANDF_D0, IOMUX_CONFIG_ALT0);
+
+ /*PATA_D1 */
+ mxc_request_iomux(MX51_PIN_NANDF_D1, IOMUX_CONFIG_ALT0);
+
+ /*PATA_D2 */
+ mxc_request_iomux(MX51_PIN_NANDF_D2, IOMUX_CONFIG_ALT0);
+
+ /*PATA_D3 */
+ mxc_request_iomux(MX51_PIN_NANDF_D3, IOMUX_CONFIG_ALT0);
+
+ /*PATA_D4 */
+ mxc_request_iomux(MX51_PIN_NANDF_D4, IOMUX_CONFIG_ALT0);
+
+ /*PATA_D5 */
+ mxc_request_iomux(MX51_PIN_NANDF_D5, IOMUX_CONFIG_ALT0);
+
+ /*PATA_D6 */
+ mxc_request_iomux(MX51_PIN_NANDF_D6, IOMUX_CONFIG_ALT0);
+
+ /*PATA_D7 */
+ mxc_request_iomux(MX51_PIN_NANDF_D7, IOMUX_CONFIG_ALT0);
+
+ /*PATA_D8 */
+ mxc_request_iomux(MX51_PIN_NANDF_D8, IOMUX_CONFIG_ALT0);
+
+ /*PATA_D9 */
+ mxc_request_iomux(MX51_PIN_NANDF_D9, IOMUX_CONFIG_ALT0);
+
+ /*PATA_D10 */
+ mxc_request_iomux(MX51_PIN_NANDF_D10, IOMUX_CONFIG_ALT0);
+
+ /*PATA_D11 */
+ mxc_request_iomux(MX51_PIN_NANDF_D11, IOMUX_CONFIG_ALT0);
+
+ /*PATA_D12 */
+ mxc_request_iomux(MX51_PIN_NANDF_D12, IOMUX_CONFIG_ALT0);
+
+ /*PATA_D13 */
+ mxc_request_iomux(MX51_PIN_NANDF_D13, IOMUX_CONFIG_ALT0);
+
+ /*PATA_D14 */
+ mxc_request_iomux(MX51_PIN_NANDF_D14, IOMUX_CONFIG_ALT0);
+
+ /*PATA_D15 */
+ mxc_request_iomux(MX51_PIN_NANDF_D15, IOMUX_CONFIG_ALT0);
+
+ /*PATA_RESET */
+ mxc_request_iomux(MX51_PIN_NANDF_CLE, IOMUX_CONFIG_ALT0);
+
+}
+
+EXPORT_SYMBOL(gpio_ata_inactive);
+
+void gpio_nand_active(void)
+{
+ mxc_request_iomux(MX51_PIN_NANDF_CS0, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_NANDF_CS1, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_NANDF_CS2, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_NANDF_CS3, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_NANDF_CS4, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_NANDF_CS5, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_NANDF_CS6, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_NANDF_CS7, IOMUX_CONFIG_ALT0);
+}
+
+EXPORT_SYMBOL(gpio_nand_active);
+
+void gpio_nand_inactive(void)
+{
+ mxc_free_iomux(MX51_PIN_NANDF_CS0, IOMUX_CONFIG_ALT0);
+ mxc_free_iomux(MX51_PIN_NANDF_CS1, IOMUX_CONFIG_ALT0);
+ mxc_free_iomux(MX51_PIN_NANDF_CS2, IOMUX_CONFIG_ALT0);
+ mxc_free_iomux(MX51_PIN_NANDF_CS3, IOMUX_CONFIG_ALT0);
+ mxc_free_iomux(MX51_PIN_NANDF_CS4, IOMUX_CONFIG_ALT0);
+ mxc_free_iomux(MX51_PIN_NANDF_CS5, IOMUX_CONFIG_ALT0);
+ mxc_free_iomux(MX51_PIN_NANDF_CS6, IOMUX_CONFIG_ALT0);
+ mxc_free_iomux(MX51_PIN_NANDF_CS7, IOMUX_CONFIG_ALT0);
+}
+
+EXPORT_SYMBOL(gpio_nand_inactive);
+/*!
+ * Setup GPIO for Keypad to be active
+ *
+ */
+void gpio_keypad_active(void)
+{
+ /*
+ * Configure the IOMUX control register for keypad signals.
+ */
+ mxc_request_iomux(MX51_PIN_KEY_COL0, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_KEY_COL1, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_KEY_COL2, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_KEY_COL3, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_KEY_COL4, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_KEY_COL5, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_KEY_ROW0, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_KEY_ROW1, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_KEY_ROW2, IOMUX_CONFIG_ALT0);
+ mxc_request_iomux(MX51_PIN_KEY_ROW3, IOMUX_CONFIG_ALT0);
+}
+
+EXPORT_SYMBOL(gpio_keypad_active);
+
+/*!
+ * Setup GPIO for Keypad to be inactive
+ *
+ */
+void gpio_keypad_inactive(void)
+{
+ mxc_request_gpio(MX51_PIN_KEY_COL0);
+ mxc_request_gpio(MX51_PIN_KEY_COL1);
+ mxc_request_gpio(MX51_PIN_KEY_COL2);
+ mxc_request_gpio(MX51_PIN_KEY_COL3);
+ mxc_request_gpio(MX51_PIN_KEY_COL4);
+ mxc_request_gpio(MX51_PIN_KEY_COL5);
+ mxc_request_gpio(MX51_PIN_KEY_ROW0);
+ mxc_request_gpio(MX51_PIN_KEY_ROW1);
+ mxc_request_gpio(MX51_PIN_KEY_ROW2);
+ mxc_request_gpio(MX51_PIN_KEY_ROW3);
+
+ mxc_free_iomux(MX51_PIN_KEY_COL0, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_KEY_COL1, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_KEY_COL2, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_KEY_COL3, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_KEY_COL4, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_KEY_COL5, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_KEY_ROW0, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_KEY_ROW1, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_KEY_ROW2, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_KEY_ROW3, IOMUX_CONFIG_GPIO);
+}
+
+EXPORT_SYMBOL(gpio_keypad_inactive);
+
+/*
+ * USB OTG HS port
+ */
+int gpio_usbotg_hs_active(void)
+{
+ /* USB_PWR */
+ mxc_request_iomux(MX51_PIN_GPIO1_8, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_GPIO1_8, PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_NONE | PAD_CTL_HYS_ENABLE);
+
+ /* USB_OC */
+ mxc_request_iomux(MX51_PIN_GPIO1_9, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_GPIO1_9, PAD_CTL_SRE_SLOW |
+ PAD_CTL_DRV_LOW | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_HYS_ENABLE);
+ return 0;
+}
+
+EXPORT_SYMBOL(gpio_usbotg_hs_active);
+
+void gpio_usbotg_hs_inactive(void)
+{
+ mxc_request_gpio(MX51_PIN_GPIO1_8);
+ mxc_request_gpio(MX51_PIN_GPIO1_9);
+
+ mxc_free_iomux(MX51_PIN_GPIO1_8, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_GPIO1_9, IOMUX_CONFIG_GPIO);
+}
+
+EXPORT_SYMBOL(gpio_usbotg_hs_inactive);
+
+/*
+ * USB Host1 HS port
+ */
+int gpio_usbh1_active(void)
+{
+ /* Set USBH1_STP to GPIO and toggle it */
+ mxc_request_iomux(MX51_PIN_USBH1_STP, IOMUX_CONFIG_GPIO |
+ IOMUX_CONFIG_SION);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_STP, PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS |
+ PAD_CTL_DRV_VOT_LOW);
+ mxc_set_gpio_direction(MX51_PIN_USBH1_STP, 0);
+ mxc_set_gpio_dataout(MX51_PIN_USBH1_STP, 1);
+
+ msleep(100);
+
+ /* USBH1_CLK */
+ mxc_request_iomux(MX51_PIN_USBH1_CLK, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_CLK, PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_NONE |
+ PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS |
+ PAD_CTL_DRV_VOT_LOW);
+
+ /* USBH1_DIR */
+ mxc_request_iomux(MX51_PIN_USBH1_DIR, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DIR, PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS |
+ PAD_CTL_DRV_VOT_LOW);
+
+ /* USBH1_NXT */
+ mxc_request_iomux(MX51_PIN_USBH1_NXT, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_NXT, PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS |
+ PAD_CTL_DRV_VOT_LOW);
+
+ /* USBH1_DATA0 */
+ mxc_request_iomux(MX51_PIN_USBH1_DATA0, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA0, PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_100K_PU | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE);
+
+ /* USBH1_DATA1 */
+ mxc_request_iomux(MX51_PIN_USBH1_DATA1, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA1, PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_100K_PU | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE);
+
+ /* USBH1_DATA2 */
+ mxc_request_iomux(MX51_PIN_USBH1_DATA2, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA2, PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_100K_PU | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE);
+
+ /* USBH1_DATA3 */
+ mxc_request_iomux(MX51_PIN_USBH1_DATA3, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA3, PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_100K_PU | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE);
+
+ /* USBH1_DATA4 */
+ mxc_request_iomux(MX51_PIN_USBH1_DATA4, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA4, PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_100K_PU | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE);
+
+ /* USBH1_DATA5 */
+ mxc_request_iomux(MX51_PIN_USBH1_DATA5, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA5, PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_100K_PU | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE);
+
+ /* USBH1_DATA6 */
+ mxc_request_iomux(MX51_PIN_USBH1_DATA6, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA6, PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_100K_PU | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE);
+
+ /* USBH1_DATA7 */
+ mxc_request_iomux(MX51_PIN_USBH1_DATA7, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_DATA7, PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_100K_PU | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_HYS_ENABLE);
+
+ /* USB_PWR */
+ mxc_request_iomux(MX51_PIN_GPIO1_8, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_GPIO1_8, PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_NONE | PAD_CTL_HYS_ENABLE);
+
+ /* USB_OC */
+ mxc_request_iomux(MX51_PIN_GPIO1_9, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_GPIO1_9, PAD_CTL_SRE_SLOW |
+ PAD_CTL_DRV_LOW | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_HYS_ENABLE);
+
+ /* FPGA_USBOTG_RST_B */
+ mxc_request_iomux(MX51_PIN_EIM_D17, IOMUX_CONFIG_ALT1);
+ mxc_iomux_set_pad(MX51_PIN_EIM_D17, PAD_CTL_DRV_HIGH |
+ PAD_CTL_HYS_NONE | PAD_CTL_PUE_KEEPER |
+ PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PKE_ENABLE | PAD_CTL_SRE_FAST);
+ mxc_set_gpio_direction(MX51_PIN_EIM_D17, 0);
+ mxc_set_gpio_dataout(MX51_PIN_EIM_D17, 1);
+
+ msleep(100);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(gpio_usbh1_active);
+
+void gpio_usbh1_setback_stp(void)
+{
+ /* setback USBH1_STP to be function */
+ mxc_request_iomux(MX51_PIN_USBH1_STP, IOMUX_CONFIG_ALT0);
+ mxc_iomux_set_pad(MX51_PIN_USBH1_STP, PAD_CTL_SRE_FAST |
+ PAD_CTL_DRV_HIGH | PAD_CTL_ODE_OPENDRAIN_NONE |
+ PAD_CTL_PUE_KEEPER | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_HYS_ENABLE | PAD_CTL_DDR_INPUT_CMOS |
+ PAD_CTL_DRV_VOT_LOW);
+}
+
+EXPORT_SYMBOL(gpio_usbh1_setback_stp);
+
+void gpio_usbh1_inactive(void)
+{
+ mxc_request_gpio(MX51_PIN_USBH1_CLK);
+ mxc_request_gpio(MX51_PIN_USBH1_DIR);
+ mxc_request_gpio(MX51_PIN_USBH1_NXT);
+ mxc_request_gpio(MX51_PIN_USBH1_STP);
+ mxc_request_gpio(MX51_PIN_USBH1_DATA0);
+ mxc_request_gpio(MX51_PIN_USBH1_DATA1);
+ mxc_request_gpio(MX51_PIN_USBH1_DATA2);
+ mxc_request_gpio(MX51_PIN_USBH1_DATA3);
+ mxc_request_gpio(MX51_PIN_USBH1_DATA4);
+ mxc_request_gpio(MX51_PIN_USBH1_DATA5);
+ mxc_request_gpio(MX51_PIN_USBH1_DATA6);
+ mxc_request_gpio(MX51_PIN_USBH1_DATA7);
+ mxc_request_gpio(MX51_PIN_GPIO1_8);
+ mxc_request_gpio(MX51_PIN_GPIO1_9);
+
+ mxc_free_iomux(MX51_PIN_USBH1_CLK, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_USBH1_DIR, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_USBH1_NXT, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_USBH1_STP, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_USBH1_DATA0, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_USBH1_DATA1, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_USBH1_DATA2, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_USBH1_DATA3, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_USBH1_DATA4, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_USBH1_DATA5, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_USBH1_DATA6, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_USBH1_DATA7, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_GPIO1_8, IOMUX_CONFIG_GPIO);
+ mxc_free_iomux(MX51_PIN_GPIO1_9, IOMUX_CONFIG_GPIO);
+
+ mxc_free_iomux(MX51_PIN_EIM_D17, IOMUX_CONFIG_GPIO);
+}
+
+EXPORT_SYMBOL(gpio_usbh1_inactive);
+
+/*!
+ * Setup GPIO for PCMCIA interface
+ *
+ */
+void gpio_pcmcia_active(void)
+{
+}
+
+EXPORT_SYMBOL(gpio_pcmcia_active);
+
+/*!
+ * Setup GPIO for pcmcia to be inactive
+ */
+void gpio_pcmcia_inactive(void)
+{
+}
+
+EXPORT_SYMBOL(gpio_pcmcia_inactive);
+
+/*!
+ * Setup GPIO for fec to be active
+ */
+void gpio_fec_active(void)
+{
+ /*TX_ER */
+ mxc_request_iomux(MX51_PIN_DI_GP3, IOMUX_CONFIG_ALT2);
+ /*CRS */
+ mxc_request_iomux(MX51_PIN_DI2_PIN4, IOMUX_CONFIG_ALT2);
+ /*MDC */
+ mxc_request_iomux(MX51_PIN_DI2_PIN2, IOMUX_CONFIG_ALT2);
+ /*MDIO */
+ mxc_request_iomux(MX51_PIN_DI2_PIN3, IOMUX_CONFIG_ALT2);
+ /*RDATA[1] */
+ mxc_request_iomux(MX51_PIN_DI2_DISP_CLK, IOMUX_CONFIG_ALT2);
+ /*RDATA[2] */
+ mxc_request_iomux(MX51_PIN_DI_GP4, IOMUX_CONFIG_ALT2);
+ /*RDATA[3] */
+ mxc_request_iomux(MX51_PIN_DISP2_DAT0, IOMUX_CONFIG_ALT2);
+ /*RX_ER */
+ mxc_request_iomux(MX51_PIN_DISP2_DAT1, IOMUX_CONFIG_ALT2);
+ /*TDATA[1] */
+ mxc_request_iomux(MX51_PIN_DISP2_DAT6, IOMUX_CONFIG_ALT2);
+ /*TDATA[2] */
+ mxc_request_iomux(MX51_PIN_DISP2_DAT7, IOMUX_CONFIG_ALT2);
+ /*TDATA[3] */
+ mxc_request_iomux(MX51_PIN_DISP2_DAT8, IOMUX_CONFIG_ALT2);
+ /*TX_EN */
+ mxc_request_iomux(MX51_PIN_DISP2_DAT9, IOMUX_CONFIG_ALT2);
+ /*COL */
+ mxc_request_iomux(MX51_PIN_DISP2_DAT10, IOMUX_CONFIG_ALT2);
+ /*RX_CLK */
+ mxc_request_iomux(MX51_PIN_DISP2_DAT11, IOMUX_CONFIG_ALT2);
+ /*RX_DV */
+ mxc_request_iomux(MX51_PIN_DISP2_DAT12, IOMUX_CONFIG_ALT2);
+ /*TX_CLK */
+ mxc_request_iomux(MX51_PIN_DISP2_DAT13, IOMUX_CONFIG_ALT2);
+ /*RDATA[0] */
+ mxc_request_iomux(MX51_PIN_DISP2_DAT14, IOMUX_CONFIG_ALT2);
+ /*TDATA[0] */
+ mxc_request_iomux(MX51_PIN_DISP2_DAT15, IOMUX_CONFIG_ALT2);
+
+ /*TX_ER */
+ mxc_iomux_set_pad(MX51_PIN_DI_GP3,
+ PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH |
+ PAD_CTL_DRV_VOT_HIGH);
+ /*CRS */
+ mxc_iomux_set_pad(MX51_PIN_DI2_PIN4,
+ PAD_CTL_100K_PU | PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_VOT_HIGH);
+ /*MDC */
+ mxc_iomux_set_pad(MX51_PIN_DI2_PIN2,
+ PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH |
+ PAD_CTL_DRV_VOT_HIGH);
+ /*MDIO */
+ mxc_iomux_set_pad(MX51_PIN_DI2_PIN3,
+ PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH |
+ PAD_CTL_ODE_OPENDRAIN_ENABLE | PAD_CTL_22K_PU |
+ PAD_CTL_HYS_ENABLE | PAD_CTL_DRV_VOT_HIGH);
+ /*RDATA[1] */
+ mxc_iomux_set_pad(MX51_PIN_DI2_DISP_CLK,
+ PAD_CTL_100K_PU | PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_VOT_HIGH);
+ /*RDATA[2] */
+ mxc_iomux_set_pad(MX51_PIN_DI_GP4,
+ PAD_CTL_100K_PU | PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_VOT_HIGH);
+ /*RDATA[3] */
+ mxc_iomux_set_pad(MX51_PIN_DISP2_DAT0,
+ PAD_CTL_100K_PU | PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_VOT_HIGH);
+ /*RX_ER */
+ mxc_iomux_set_pad(MX51_PIN_DISP2_DAT1,
+ PAD_CTL_100K_PU | PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_VOT_HIGH);
+ /*TDATA[1] */
+ mxc_iomux_set_pad(MX51_PIN_DISP2_DAT6,
+ PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH |
+ PAD_CTL_DRV_VOT_HIGH);
+ /*TDATA[2] */
+ mxc_iomux_set_pad(MX51_PIN_DISP2_DAT7,
+ PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH |
+ PAD_CTL_DRV_VOT_HIGH);
+ /*TDATA[3] */
+ mxc_iomux_set_pad(MX51_PIN_DISP2_DAT8,
+ PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH |
+ PAD_CTL_DRV_VOT_HIGH);
+ /*TX_EN */
+ mxc_iomux_set_pad(MX51_PIN_DISP2_DAT9,
+ PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH |
+ PAD_CTL_DRV_VOT_HIGH);
+ /*COL */
+ mxc_iomux_set_pad(MX51_PIN_DISP2_DAT10,
+ PAD_CTL_100K_PU | PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_VOT_HIGH);
+ /*RX_CLK */
+ mxc_iomux_set_pad(MX51_PIN_DISP2_DAT11,
+ PAD_CTL_100K_PU | PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_VOT_HIGH);
+ /*RX_DV */
+ mxc_iomux_set_pad(MX51_PIN_DISP2_DAT12,
+ PAD_CTL_100K_PU | PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_VOT_HIGH);
+ /*TX_CLK */
+ mxc_iomux_set_pad(MX51_PIN_DISP2_DAT13,
+ PAD_CTL_100K_PU | PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_VOT_HIGH);
+ /*RDATA[0] */
+ mxc_iomux_set_pad(MX51_PIN_DISP2_DAT14,
+ PAD_CTL_100K_PU | PAD_CTL_HYS_ENABLE |
+ PAD_CTL_DRV_VOT_HIGH);
+ /*TDATA[0] */
+ mxc_iomux_set_pad(MX51_PIN_DISP2_DAT15,
+ PAD_CTL_100K_PU | PAD_CTL_DRV_HIGH |
+ PAD_CTL_DRV_VOT_HIGH);
+
+ /*COL */
+ mxc_iomux_set_input(MUX_IN_FEC_FEC_COL_SELECT_INPUT, INPUT_CTL_PATH1);
+ /*CRS */
+ mxc_iomux_set_input(MUX_IN_FEC_FEC_CRS_SELECT_INPUT, INPUT_CTL_PATH1);
+ /*MDIO */
+ mxc_iomux_set_input(MUX_IN_FEC_FEC_MDI_SELECT_INPUT, INPUT_CTL_PATH1);
+ /*RDATA[0] */
+ mxc_iomux_set_input(MUX_IN_FEC_FEC_RDATA_0_SELECT_INPUT,
+ INPUT_CTL_PATH1);
+ /*RDATA[1] */
+ mxc_iomux_set_input(MUX_IN_FEC_FEC_RDATA_1_SELECT_INPUT,
+ INPUT_CTL_PATH1);
+ /*RDATA[2] */
+ mxc_iomux_set_input(MUX_IN_FEC_FEC_RDATA_2_SELECT_INPUT,
+ INPUT_CTL_PATH1);
+ /*RDATA[3] */
+ mxc_iomux_set_input(MUX_IN_FEC_FEC_RDATA_3_SELECT_INPUT,
+ INPUT_CTL_PATH1);
+ /*RX_CLK */
+ mxc_iomux_set_input(MUX_IN_FEC_FEC_RX_CLK_SELECT_INPUT,
+ INPUT_CTL_PATH1);
+ /*RX_DV */
+ mxc_iomux_set_input(MUX_IN_FEC_FEC_RX_DV_SELECT_INPUT, INPUT_CTL_PATH1);
+ /*RX_ER */
+ mxc_iomux_set_input(MUX_IN_FEC_FEC_RX_ER_SELECT_INPUT, INPUT_CTL_PATH1);
+ /*TX_CLK */
+ mxc_iomux_set_input(MUX_IN_FEC_FEC_TX_CLK_SELECT_INPUT,
+ INPUT_CTL_PATH1);
+
+ /*reset */
+ mxc_request_iomux(MX51_PIN_DISPB2_SER_DIO, IOMUX_CONFIG_GPIO);
+ mxc_iomux_set_pad(MX51_PIN_DISPB2_SER_DIO,
+ PAD_CTL_SRE_FAST | PAD_CTL_DRV_HIGH | PAD_CTL_100K_PU
+ | PAD_CTL_PUE_PULL | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_DRV_VOT_HIGH);
+ mxc_set_gpio_direction(MX51_PIN_DISPB2_SER_DIO, 0);
+ mxc_set_gpio_dataout(MX51_PIN_DISPB2_SER_DIO, 0);
+ msleep(10);
+ mxc_set_gpio_dataout(MX51_PIN_DISPB2_SER_DIO, 1);
+ msleep(100);
+}
+
+EXPORT_SYMBOL(gpio_fec_active);
+
+/*!
+ * Setup GPIO for fec to be inactive
+ */
+void gpio_fec_inactive(void)
+{
+ /*TX_ER */
+ mxc_free_iomux(MX51_PIN_DI_GP3, IOMUX_CONFIG_ALT2);
+ /*CRS */
+ mxc_free_iomux(MX51_PIN_DI2_PIN4, IOMUX_CONFIG_ALT2);
+ /*MDC */
+ mxc_free_iomux(MX51_PIN_DI2_PIN2, IOMUX_CONFIG_ALT2);
+ /*MDIO */
+ mxc_free_iomux(MX51_PIN_DI2_PIN3, IOMUX_CONFIG_ALT2);
+ /*RDATA[1] */
+ mxc_free_iomux(MX51_PIN_DI2_DISP_CLK, IOMUX_CONFIG_ALT2);
+ /*RDATA[2] */
+ mxc_free_iomux(MX51_PIN_DI_GP4, IOMUX_CONFIG_ALT2);
+ /*RDATA[3] */
+ mxc_free_iomux(MX51_PIN_DISP2_DAT0, IOMUX_CONFIG_ALT2);
+ /*RX_ER */
+ mxc_free_iomux(MX51_PIN_DISP2_DAT1, IOMUX_CONFIG_ALT2);
+ /*TDATA[1] */
+ mxc_free_iomux(MX51_PIN_DISP2_DAT6, IOMUX_CONFIG_ALT2);
+ /*TDATA[2] */
+ mxc_free_iomux(MX51_PIN_DISP2_DAT7, IOMUX_CONFIG_ALT2);
+ /*TDATA[3] */
+ mxc_free_iomux(MX51_PIN_DISP2_DAT8, IOMUX_CONFIG_ALT2);
+ /*TX_EN */
+ mxc_free_iomux(MX51_PIN_DISP2_DAT9, IOMUX_CONFIG_ALT2);
+ /*COL */
+ mxc_free_iomux(MX51_PIN_DISP2_DAT10, IOMUX_CONFIG_ALT2);
+ /*RX_CLK */
+ mxc_free_iomux(MX51_PIN_DISP2_DAT11, IOMUX_CONFIG_ALT2);
+ /*RX_DV */
+ mxc_free_iomux(MX51_PIN_DISP2_DAT12, IOMUX_CONFIG_ALT2);
+ /*TX_CLK */
+ mxc_free_iomux(MX51_PIN_DISP2_DAT13, IOMUX_CONFIG_ALT2);
+ /*RDATA[0] */
+ mxc_free_iomux(MX51_PIN_DISP2_DAT14, IOMUX_CONFIG_ALT2);
+ /*TDATA[0] */
+ mxc_free_iomux(MX51_PIN_DISP2_DAT15, IOMUX_CONFIG_ALT2);
+ /*reset */
+ mxc_free_iomux(MX51_PIN_DISPB2_SER_DIO, IOMUX_CONFIG_GPIO);
+
+}
+
+EXPORT_SYMBOL(gpio_fec_inactive);
+
+void gpio_spdif_active(void)
+{
+ mxc_request_iomux(MX51_PIN_GPIO1_7, IOMUX_CONFIG_ALT2);
+ mxc_iomux_set_pad(MX51_PIN_GPIO1_7,
+ PAD_CTL_DRV_HIGH | PAD_CTL_PUE_PULL |
+ PAD_CTL_100K_PU | PAD_CTL_PKE_ENABLE |
+ PAD_CTL_SRE_FAST);
+}
+
+EXPORT_SYMBOL(gpio_spdif_active);
+
+void gpio_spdif_inactive(void)
+{
+ mxc_free_iomux(MX51_PIN_GPIO1_7, IOMUX_CONFIG_ALT2);
+
+}
+
+EXPORT_SYMBOL(gpio_spdif_inactive);
+
+int headphone_det_status(void)
+{
+ return mxc_get_gpio_datain(MX51_PIN_EIM_A26);
+}
+
+EXPORT_SYMBOL(headphone_det_status);
diff --git a/arch/arm/mach-mx51/mx51_pins.h b/arch/arm/mach-mx51/mx51_pins.h
new file mode 100644
index 000000000000..5b08a5f29460
--- /dev/null
+++ b/arch/arm/mach-mx51/mx51_pins.h
@@ -0,0 +1,361 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_MXC_MX51_PINS_H__
+#define __ASM_ARCH_MXC_MX51_PINS_H__
+
+/*!
+ * @file arch-mxc/mx51_pins.h
+ *
+ * @brief MX51 I/O Pin List
+ *
+ * @ingroup GPIO_MX51
+ */
+
+#ifndef __ASSEMBLY__
+
+/*!
+ * @name IOMUX/PAD Bit field definitions
+ */
+
+/*! @{ */
+
+/*!
+ * In order to identify pins more effectively, each mux-controlled pin's
+ * enumerated value is constructed in the following way:
+ *
+ * -------------------------------------------------------------------
+ * 31-29 | 28 - 24 | 23 - 21 | 20 - 10| 9 - 0
+ * -------------------------------------------------------------------
+ * IO_P | IO_I | GPIO_I | PAD_I | MUX_I
+ * -------------------------------------------------------------------
+ *
+ * Bit 0 to 9 contains MUX_I used to identify the register
+ * offset (0-based. base is IOMUX_module_base) defined in the Section
+ * "sw_pad_ctl & sw_mux_ctl details" of the IC Spec. The
+ * similar field definitions are used for the pad control register.
+ * For example, the MX51_PIN_ETM_D0 is defined in the enumeration:
+ * ( (0x28 - MUX_I_START) << MUX_I)|( (0x250 - PAD_I_START) << PAD_I)
+ * It means the mux control register is at register offset 0x28. The pad control
+ * register offset is: 0x250 and also occupy the least significant bits
+ * within the register.
+ */
+
+/*!
+ * Starting bit position within each entry of \b iomux_pins to represent the
+ * MUX control register offset
+ */
+#define MUX_I 0
+/*!
+ * Starting bit position within each entry of \b iomux_pins to represent the
+ * PAD control register offset
+ */
+#define PAD_I 10
+/*!
+ * Starting bit position within each entry of \b iomux_pins to represent which
+ * mux mode is for GPIO (0-based)
+ */
+#define GPIO_I 21
+
+#define NON_GPIO_PORT 0x7
+#define PIN_TO_MUX_MASK ((1 << (PAD_I - MUX_I)) - 1)
+#define PIN_TO_PAD_MASK ((1 << (GPIO_I - PAD_I)) - 1)
+#define PIN_TO_ALT_GPIO_MASK ((1 << (MUX_IO_I - GPIO_I)) - 1)
+
+#define NON_MUX_I PIN_TO_MUX_MASK
+#define MUX_I_START 0x001C
+#define PAD_I_START 0x3F0
+#define INPUT_CTL_START 0x8C4
+#define INPUT_CTL_START_TO1 0x928
+#define MUX_I_END (PAD_I_START - 4)
+
+#define _MXC_BUILD_PIN(gp, gi, ga, mi, pi) \
+ (((gp) << MUX_IO_P) | ((gi) << MUX_IO_I) | \
+ ((mi) << MUX_I) | \
+ ((pi - PAD_I_START) << PAD_I) | \
+ ((ga) << GPIO_I))
+
+#define _MXC_BUILD_GPIO_PIN(gp, gi, ga, mi, pi) \
+ _MXC_BUILD_PIN(gp, gi, ga, mi, pi)
+
+#define _MXC_BUILD_NON_GPIO_PIN(mi, pi) \
+ _MXC_BUILD_PIN(NON_GPIO_PORT, 0, 0, mi, pi)
+
+#define PIN_TO_IOMUX_MUX(pin) ((pin >> MUX_I) & PIN_TO_MUX_MASK)
+#define PIN_TO_IOMUX_PAD(pin) ((pin >> PAD_I) & PIN_TO_PAD_MASK)
+#define PIN_TO_ALT_GPIO(pin) ((pin >> GPIO_I) & PIN_TO_ALT_GPIO_MASK)
+#define PIN_TO_IOMUX_INDEX(pin) (PIN_TO_IOMUX_MUX(pin) >> 2)
+
+/*! @} End IOMUX/PAD Bit field definitions */
+
+/*!
+ * This enumeration is constructed based on the Section
+ * "sw_pad_ctl & sw_mux_ctl details" of the MX51 IC Spec. Each enumerated
+ * value is constructed based on the rules described above.
+ */
+enum iomux_pins {
+ MX51_PIN_EIM_DA0 = _MXC_BUILD_NON_GPIO_PIN(0x1C, 0x7A8),
+ MX51_PIN_EIM_DA1 = _MXC_BUILD_NON_GPIO_PIN(0x20, 0x7A8),
+ MX51_PIN_EIM_DA2 = _MXC_BUILD_NON_GPIO_PIN(0x24, 0x7A8),
+ MX51_PIN_EIM_DA3 = _MXC_BUILD_NON_GPIO_PIN(0x28, 0x7A8),
+ MX51_PIN_EIM_DA4 = _MXC_BUILD_NON_GPIO_PIN(0x2C, 0x7AC),
+ MX51_PIN_EIM_DA5 = _MXC_BUILD_NON_GPIO_PIN(0x30, 0x7AC),
+ MX51_PIN_EIM_DA6 = _MXC_BUILD_NON_GPIO_PIN(0x34, 0x7AC),
+ MX51_PIN_EIM_DA7 = _MXC_BUILD_NON_GPIO_PIN(0x38, 0x7AC),
+ MX51_PIN_EIM_DA8 = _MXC_BUILD_NON_GPIO_PIN(0x3C, 0x7B0),
+ MX51_PIN_EIM_DA9 = _MXC_BUILD_NON_GPIO_PIN(0x40, 0x7B0),
+ MX51_PIN_EIM_DA10 = _MXC_BUILD_NON_GPIO_PIN(0x44, 0x7B0),
+ MX51_PIN_EIM_DA11 = _MXC_BUILD_NON_GPIO_PIN(0x48, 0x7B0),
+ MX51_PIN_EIM_DA12 = _MXC_BUILD_NON_GPIO_PIN(0x4C, 0x7BC),
+ MX51_PIN_EIM_DA13 = _MXC_BUILD_NON_GPIO_PIN(0x50, 0x7BC),
+ MX51_PIN_EIM_DA14 = _MXC_BUILD_NON_GPIO_PIN(0x54, 0x7BC),
+ MX51_PIN_EIM_DA15 = _MXC_BUILD_NON_GPIO_PIN(0x58, 0x7BC),
+ MX51_PIN_EIM_D16 = _MXC_BUILD_GPIO_PIN(1, 0, 1, 0x5C, 0x3F0),
+ MX51_PIN_EIM_D17 = _MXC_BUILD_GPIO_PIN(1, 1, 1, 0x60, 0x3F4),
+ MX51_PIN_EIM_D18 = _MXC_BUILD_GPIO_PIN(1, 2, 1, 0x64, 0x3F8),
+ MX51_PIN_EIM_D19 = _MXC_BUILD_GPIO_PIN(1, 3, 1, 0x68, 0x3FC),
+ MX51_PIN_EIM_D20 = _MXC_BUILD_GPIO_PIN(1, 4, 1, 0x6C, 0x400),
+ MX51_PIN_EIM_D21 = _MXC_BUILD_GPIO_PIN(1, 5, 1, 0x70, 0x404),
+ MX51_PIN_EIM_D22 = _MXC_BUILD_GPIO_PIN(1, 6, 1, 0x74, 0x408),
+ MX51_PIN_EIM_D23 = _MXC_BUILD_GPIO_PIN(1, 7, 1, 0x78, 0x40C),
+ MX51_PIN_EIM_D24 = _MXC_BUILD_GPIO_PIN(1, 8, 1, 0x7C, 0x410),
+ MX51_PIN_EIM_D25 = _MXC_BUILD_NON_GPIO_PIN(0x80, 0x414),
+ MX51_PIN_EIM_D26 = _MXC_BUILD_NON_GPIO_PIN(0x84, 0x418),
+ MX51_PIN_EIM_D27 = _MXC_BUILD_GPIO_PIN(1, 9, 1, 0x88, 0x41C),
+ MX51_PIN_EIM_D28 = _MXC_BUILD_NON_GPIO_PIN(0x8C, 0x420),
+ MX51_PIN_EIM_D29 = _MXC_BUILD_NON_GPIO_PIN(0x90, 0x424),
+ MX51_PIN_EIM_D30 = _MXC_BUILD_NON_GPIO_PIN(0x94, 0x428),
+ MX51_PIN_EIM_D31 = _MXC_BUILD_NON_GPIO_PIN(0x98, 0x42C),
+ MX51_PIN_EIM_A16 = _MXC_BUILD_GPIO_PIN(1, 10, 1, 0x9C, 0x430),
+ MX51_PIN_EIM_A17 = _MXC_BUILD_GPIO_PIN(1, 11, 1, 0xA0, 0x434),
+ MX51_PIN_EIM_A18 = _MXC_BUILD_GPIO_PIN(1, 12, 1, 0xA4, 0x438),
+ MX51_PIN_EIM_A19 = _MXC_BUILD_GPIO_PIN(1, 13, 1, 0xA8, 0x43C),
+ MX51_PIN_EIM_A20 = _MXC_BUILD_GPIO_PIN(1, 14, 1, 0xAC, 0x440),
+ MX51_PIN_EIM_A21 = _MXC_BUILD_GPIO_PIN(1, 15, 1, 0xB0, 0x444),
+ MX51_PIN_EIM_A22 = _MXC_BUILD_GPIO_PIN(1, 16, 1, 0xB4, 0x448),
+ MX51_PIN_EIM_A23 = _MXC_BUILD_GPIO_PIN(1, 17, 1, 0xB8, 0x44C),
+ MX51_PIN_EIM_A24 = _MXC_BUILD_GPIO_PIN(1, 18, 1, 0xBC, 0x450),
+ MX51_PIN_EIM_A25 = _MXC_BUILD_GPIO_PIN(1, 19, 1, 0xC0, 0x454),
+ MX51_PIN_EIM_A26 = _MXC_BUILD_GPIO_PIN(1, 20, 1, 0xC4, 0x458),
+ MX51_PIN_EIM_A27 = _MXC_BUILD_GPIO_PIN(1, 21, 1, 0xC8, 0x45C),
+ MX51_PIN_EIM_EB0 = _MXC_BUILD_NON_GPIO_PIN(0xCC, 0x460),
+ MX51_PIN_EIM_EB1 = _MXC_BUILD_NON_GPIO_PIN(0xD0, 0x464),
+ MX51_PIN_EIM_EB2 = _MXC_BUILD_GPIO_PIN(1, 22, 1, 0xD4, 0x468),
+ MX51_PIN_EIM_EB3 = _MXC_BUILD_GPIO_PIN(1, 23, 1, 0xD8, 0x46C),
+ MX51_PIN_EIM_OE = _MXC_BUILD_GPIO_PIN(1, 24, 1, 0xDC, 0x470),
+ MX51_PIN_EIM_CS0 = _MXC_BUILD_GPIO_PIN(1, 25, 1, 0xE0, 0x474),
+ MX51_PIN_EIM_CS1 = _MXC_BUILD_GPIO_PIN(1, 26, 1, 0xE4, 0x478),
+ MX51_PIN_EIM_CS2 = _MXC_BUILD_GPIO_PIN(1, 27, 1, 0xE8, 0x47C),
+ MX51_PIN_EIM_CS3 = _MXC_BUILD_GPIO_PIN(1, 28, 1, 0xEC, 0x480),
+ MX51_PIN_EIM_CS4 = _MXC_BUILD_GPIO_PIN(1, 29, 1, 0xF0, 0x484),
+ MX51_PIN_EIM_CS5 = _MXC_BUILD_GPIO_PIN(1, 30, 1, 0xF4, 0x488),
+ MX51_PIN_EIM_DTACK = _MXC_BUILD_GPIO_PIN(1, 31, 1, 0xF8, 0x48C),
+ MX51_PIN_EIM_LBA = _MXC_BUILD_GPIO_PIN(2, 1, 1, 0xFC, 0x494),
+ MX51_PIN_EIM_CRE = _MXC_BUILD_GPIO_PIN(2, 2, 1, 0x100, 0x4A0),
+ MX51_PIN_DRAM_CS1 = _MXC_BUILD_NON_GPIO_PIN(0x104, 0x4D0),
+ MX51_PIN_NANDF_WE_B = _MXC_BUILD_GPIO_PIN(2, 3, 3, 0x108, 0x4E4),
+ MX51_PIN_NANDF_RE_B = _MXC_BUILD_GPIO_PIN(2, 4, 3, 0x10C, 0x4E8),
+ MX51_PIN_NANDF_ALE = _MXC_BUILD_GPIO_PIN(2, 5, 3, 0x110, 0x4EC),
+ MX51_PIN_NANDF_CLE = _MXC_BUILD_GPIO_PIN(2, 6, 3, 0x114, 0x4F0),
+ MX51_PIN_NANDF_WP_B = _MXC_BUILD_GPIO_PIN(2, 7, 3, 0x118, 0x4F4),
+ MX51_PIN_NANDF_RB0 = _MXC_BUILD_GPIO_PIN(2, 8, 3, 0x11C, 0x4F8),
+ MX51_PIN_NANDF_RB1 = _MXC_BUILD_GPIO_PIN(2, 9, 3, 0x120, 0x4FC),
+ MX51_PIN_NANDF_RB2 = _MXC_BUILD_GPIO_PIN(2, 10, 3, 0x124, 0x500),
+ MX51_PIN_NANDF_RB3 = _MXC_BUILD_GPIO_PIN(2, 11, 3, 0x128, 0x504),
+ MX51_PIN_GPIO_NAND = _MXC_BUILD_GPIO_PIN(2, 12, 3, 0x12C, 0x514),
+ MX51_PIN_NANDF_RB4 = MX51_PIN_GPIO_NAND,
+ MX51_PIN_NANDF_RB5 = _MXC_BUILD_GPIO_PIN(2, 13, 3, 0x130, 0x5D8),
+ MX51_PIN_NANDF_RB6 = _MXC_BUILD_GPIO_PIN(2, 14, 3, 0x134, 0x5DC),
+ MX51_PIN_NANDF_RB7 = _MXC_BUILD_GPIO_PIN(2, 15, 3, 0x138, 0x5E0),
+ MX51_PIN_NANDF_CS0 = _MXC_BUILD_GPIO_PIN(2, 16, 3, 0x130, 0x518),
+ MX51_PIN_NANDF_CS1 = _MXC_BUILD_GPIO_PIN(2, 17, 3, 0x134, 0x51C),
+ MX51_PIN_NANDF_CS2 = _MXC_BUILD_GPIO_PIN(2, 18, 3, 0x138, 0x520),
+ MX51_PIN_NANDF_CS3 = _MXC_BUILD_GPIO_PIN(2, 19, 3, 0x13C, 0x524),
+ MX51_PIN_NANDF_CS4 = _MXC_BUILD_GPIO_PIN(2, 20, 3, 0x140, 0x528),
+ MX51_PIN_NANDF_CS5 = _MXC_BUILD_GPIO_PIN(2, 21, 3, 0x144, 0x52C),
+ MX51_PIN_NANDF_CS6 = _MXC_BUILD_GPIO_PIN(2, 22, 3, 0x148, 0x530),
+ MX51_PIN_NANDF_CS7 = _MXC_BUILD_GPIO_PIN(2, 23, 3, 0x14C, 0x534),
+ MX51_PIN_NANDF_RDY_INT = _MXC_BUILD_GPIO_PIN(2, 24, 3, 0x150, 0x538),
+ MX51_PIN_NANDF_D15 = _MXC_BUILD_GPIO_PIN(2, 25, 3, 0x154, 0x53C),
+ MX51_PIN_NANDF_D14 = _MXC_BUILD_GPIO_PIN(2, 26, 3, 0x158, 0x540),
+ MX51_PIN_NANDF_D13 = _MXC_BUILD_GPIO_PIN(2, 27, 3, 0x15C, 0x544),
+ MX51_PIN_NANDF_D12 = _MXC_BUILD_GPIO_PIN(2, 28, 3, 0x160, 0x548),
+ MX51_PIN_NANDF_D11 = _MXC_BUILD_GPIO_PIN(2, 29, 3, 0x164, 0x54C),
+ MX51_PIN_NANDF_D10 = _MXC_BUILD_GPIO_PIN(2, 30, 3, 0x168, 0x550),
+ MX51_PIN_NANDF_D9 = _MXC_BUILD_GPIO_PIN(2, 31, 3, 0x16C, 0x554),
+ MX51_PIN_NANDF_D8 = _MXC_BUILD_GPIO_PIN(3, 0, 3, 0x170, 0x558),
+ MX51_PIN_NANDF_D7 = _MXC_BUILD_GPIO_PIN(3, 1, 3, 0x174, 0x55C),
+ MX51_PIN_NANDF_D6 = _MXC_BUILD_GPIO_PIN(3, 2, 3, 0x178, 0x560),
+ MX51_PIN_NANDF_D5 = _MXC_BUILD_GPIO_PIN(3, 3, 3, 0x17C, 0x564),
+ MX51_PIN_NANDF_D4 = _MXC_BUILD_GPIO_PIN(3, 4, 3, 0x180, 0x568),
+ MX51_PIN_NANDF_D3 = _MXC_BUILD_GPIO_PIN(3, 5, 3, 0x184, 0x56C),
+ MX51_PIN_NANDF_D2 = _MXC_BUILD_GPIO_PIN(3, 6, 3, 0x188, 0x570),
+ MX51_PIN_NANDF_D1 = _MXC_BUILD_GPIO_PIN(3, 7, 3, 0x18C, 0x574),
+ MX51_PIN_NANDF_D0 = _MXC_BUILD_GPIO_PIN(3, 8, 3, 0x190, 0x578),
+ MX51_PIN_CSI1_D8 = _MXC_BUILD_GPIO_PIN(2, 12, 3, 0x194, 0x57C),
+ MX51_PIN_CSI1_D9 = _MXC_BUILD_GPIO_PIN(2, 13, 3, 0x198, 0x580),
+ MX51_PIN_CSI1_D10 = _MXC_BUILD_NON_GPIO_PIN(0x19C, 0x584),
+ MX51_PIN_CSI1_D11 = _MXC_BUILD_NON_GPIO_PIN(0x1A0, 0x588),
+ MX51_PIN_CSI1_D12 = _MXC_BUILD_NON_GPIO_PIN(0x1A4, 0x58C),
+ MX51_PIN_CSI1_D13 = _MXC_BUILD_NON_GPIO_PIN(0x1A8, 0x590),
+ MX51_PIN_CSI1_D14 = _MXC_BUILD_NON_GPIO_PIN(0x1AC, 0x594),
+ MX51_PIN_CSI1_D15 = _MXC_BUILD_NON_GPIO_PIN(0x1B0, 0x598),
+ MX51_PIN_CSI1_D16 = _MXC_BUILD_NON_GPIO_PIN(0x1B4, 0x59C),
+ MX51_PIN_CSI1_D17 = _MXC_BUILD_NON_GPIO_PIN(0x1B8, 0x5A0),
+ MX51_PIN_CSI1_D18 = _MXC_BUILD_NON_GPIO_PIN(0x1BC, 0x5A4),
+ MX51_PIN_CSI1_D19 = _MXC_BUILD_NON_GPIO_PIN(0x1C0, 0x5A8),
+ MX51_PIN_CSI1_VSYNC = _MXC_BUILD_NON_GPIO_PIN(0x1C4, 0x5AC),
+ MX51_PIN_CSI1_HSYNC = _MXC_BUILD_NON_GPIO_PIN(0x1C8, 0x5B0),
+ MX51_PIN_CSI1_PIXCLK = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x5B4),
+ MX51_PIN_CSI1_MCLK = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x5B8),
+ MX51_PIN_CSI1_PKE0 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x860),
+ MX51_PIN_CSI2_D12 = _MXC_BUILD_GPIO_PIN(3, 9, 3, 0x1CC, 0x5BC),
+ MX51_PIN_CSI2_D13 = _MXC_BUILD_GPIO_PIN(3, 10, 3, 0x1D0, 0x5C0),
+ MX51_PIN_CSI2_D14 = _MXC_BUILD_GPIO_PIN(3, 11, 3, 0x1D4, 0x5C4),
+ MX51_PIN_CSI2_D15 = _MXC_BUILD_GPIO_PIN(3, 12, 3, 0x1D8, 0x5C8),
+ MX51_PIN_CSI2_D16 = _MXC_BUILD_GPIO_PIN(3, 11, 3, 0x1DC, 0x5CC),
+ MX51_PIN_CSI2_D17 = _MXC_BUILD_GPIO_PIN(3, 12, 3, 0x1E0, 0x5D0),
+ MX51_PIN_CSI2_D18 = _MXC_BUILD_GPIO_PIN(3, 11, 3, 0x1E4, 0x5D4),
+ MX51_PIN_CSI2_D19 = _MXC_BUILD_GPIO_PIN(3, 12, 3, 0x1E8, 0x5D8),
+ MX51_PIN_CSI2_VSYNC = _MXC_BUILD_GPIO_PIN(3, 13, 3, 0x1EC, 0x5DC),
+ MX51_PIN_CSI2_HSYNC = _MXC_BUILD_GPIO_PIN(3, 14, 3, 0x1F0, 0x5E0),
+ MX51_PIN_CSI2_PIXCLK = _MXC_BUILD_GPIO_PIN(3, 15, 3, 0x1F4, 0x5E4),
+ MX51_PIN_CSI2_PKE0 = _MXC_BUILD_NON_GPIO_PIN(NON_MUX_I, 0x81C),
+ MX51_PIN_I2C1_CLK = _MXC_BUILD_GPIO_PIN(3, 16, 3, 0x1F8, 0x5E8),
+ MX51_PIN_I2C1_DAT = _MXC_BUILD_GPIO_PIN(3, 17, 3, 0x1FC, 0x5EC),
+ MX51_PIN_AUD3_BB_TXD = _MXC_BUILD_GPIO_PIN(3, 18, 3, 0x200, 0x5F0),
+ MX51_PIN_AUD3_BB_RXD = _MXC_BUILD_GPIO_PIN(3, 19, 3, 0x204, 0x5F4),
+ MX51_PIN_AUD3_BB_CK = _MXC_BUILD_GPIO_PIN(3, 20, 3, 0x208, 0x5F8),
+ MX51_PIN_AUD3_BB_FS = _MXC_BUILD_GPIO_PIN(3, 21, 3, 0x20C, 0x5FC),
+ MX51_PIN_CSPI1_MOSI = _MXC_BUILD_GPIO_PIN(3, 22, 3, 0x210, 0x600),
+ MX51_PIN_CSPI1_MISO = _MXC_BUILD_GPIO_PIN(3, 23, 3, 0x214, 0x604),
+ MX51_PIN_CSPI1_SS0 = _MXC_BUILD_GPIO_PIN(3, 24, 3, 0x218, 0x608),
+ MX51_PIN_CSPI1_SS1 = _MXC_BUILD_GPIO_PIN(3, 25, 3, 0x21C, 0x60C),
+ MX51_PIN_CSPI1_RDY = _MXC_BUILD_GPIO_PIN(3, 26, 3, 0x220, 0x610),
+ MX51_PIN_CSPI1_SCLK = _MXC_BUILD_GPIO_PIN(3, 27, 3, 0x224, 0x614),
+ MX51_PIN_UART1_RXD = _MXC_BUILD_GPIO_PIN(3, 28, 3, 0x228, 0x618),
+ MX51_PIN_UART1_TXD = _MXC_BUILD_GPIO_PIN(3, 29, 3, 0x22C, 0x61C),
+ MX51_PIN_UART1_RTS = _MXC_BUILD_GPIO_PIN(3, 30, 3, 0x230, 0x620),
+ MX51_PIN_UART1_CTS = _MXC_BUILD_GPIO_PIN(3, 31, 3, 0x234, 0x624),
+ MX51_PIN_UART2_RXD = _MXC_BUILD_GPIO_PIN(0, 20, 3, 0x238, 0x628),
+ MX51_PIN_UART2_TXD = _MXC_BUILD_GPIO_PIN(0, 21, 3, 0x23C, 0x62C),
+ MX51_PIN_UART3_RXD = _MXC_BUILD_GPIO_PIN(0, 22, 3, 0x240, 0x630),
+ MX51_PIN_UART3_TXD = _MXC_BUILD_GPIO_PIN(0, 23, 3, 0x244, 0x634),
+ MX51_PIN_OWIRE_LINE = _MXC_BUILD_GPIO_PIN(0, 24, 3, 0x248, 0x638),
+ MX51_PIN_KEY_ROW0 = _MXC_BUILD_NON_GPIO_PIN(0x24C, 0x63C),
+ MX51_PIN_KEY_ROW1 = _MXC_BUILD_NON_GPIO_PIN(0x250, 0x640),
+ MX51_PIN_KEY_ROW2 = _MXC_BUILD_NON_GPIO_PIN(0x254, 0x644),
+ MX51_PIN_KEY_ROW3 = _MXC_BUILD_NON_GPIO_PIN(0x258, 0x648),
+ MX51_PIN_KEY_COL0 = _MXC_BUILD_NON_GPIO_PIN(0x25C, 0x64C),
+ MX51_PIN_KEY_COL1 = _MXC_BUILD_NON_GPIO_PIN(0x260, 0x650),
+ MX51_PIN_KEY_COL2 = _MXC_BUILD_NON_GPIO_PIN(0x264, 0x654),
+ MX51_PIN_KEY_COL3 = _MXC_BUILD_NON_GPIO_PIN(0x268, 0x658),
+ MX51_PIN_KEY_COL4 = _MXC_BUILD_NON_GPIO_PIN(0x26C, 0x65C),
+ MX51_PIN_KEY_COL5 = _MXC_BUILD_NON_GPIO_PIN(0x270, 0x660),
+ MX51_PIN_USBH1_CLK = _MXC_BUILD_GPIO_PIN(0, 25, 2, 0x278, 0x678),
+ MX51_PIN_USBH1_DIR = _MXC_BUILD_GPIO_PIN(0, 26, 2, 0x27C, 0x67C),
+ MX51_PIN_USBH1_STP = _MXC_BUILD_GPIO_PIN(0, 27, 2, 0x280, 0x680),
+ MX51_PIN_USBH1_NXT = _MXC_BUILD_GPIO_PIN(0, 28, 2, 0x284, 0x684),
+ MX51_PIN_USBH1_DATA0 = _MXC_BUILD_GPIO_PIN(0, 11, 2, 0x288, 0x688),
+ MX51_PIN_USBH1_DATA1 = _MXC_BUILD_GPIO_PIN(0, 12, 2, 0x28C, 0x68C),
+ MX51_PIN_USBH1_DATA2 = _MXC_BUILD_GPIO_PIN(0, 13, 2, 0x290, 0x690),
+ MX51_PIN_USBH1_DATA3 = _MXC_BUILD_GPIO_PIN(0, 14, 2, 0x294, 0x694),
+ MX51_PIN_USBH1_DATA4 = _MXC_BUILD_GPIO_PIN(0, 15, 2, 0x298, 0x698),
+ MX51_PIN_USBH1_DATA5 = _MXC_BUILD_GPIO_PIN(0, 16, 2, 0x29C, 0x69C),
+ MX51_PIN_USBH1_DATA6 = _MXC_BUILD_GPIO_PIN(0, 17, 2, 0x2A0, 0x6A0),
+ MX51_PIN_USBH1_DATA7 = _MXC_BUILD_GPIO_PIN(0, 18, 2, 0x2A4, 0x6A4),
+ MX51_PIN_DI1_PIN11 = _MXC_BUILD_GPIO_PIN(2, 0, 4, 0x2A8, 0x6A8),
+ MX51_PIN_DI1_PIN12 = _MXC_BUILD_GPIO_PIN(2, 1, 4, 0x2AC, 0x6AC),
+ MX51_PIN_DI1_PIN13 = _MXC_BUILD_GPIO_PIN(2, 2, 4, 0x2B0, 0x6B0),
+ MX51_PIN_DI1_D0_CS = _MXC_BUILD_GPIO_PIN(2, 3, 4, 0x2B4, 0x6B4),
+ MX51_PIN_DI1_D1_CS = _MXC_BUILD_GPIO_PIN(2, 4, 4, 0x2B8, 0x6B8),
+ MX51_PIN_DISPB2_SER_DIN = _MXC_BUILD_GPIO_PIN(2, 5, 4, 0x2BC, 0x6BC),
+ MX51_PIN_DISPB2_SER_DIO = _MXC_BUILD_GPIO_PIN(2, 6, 4, 0x2C0, 0x6C0),
+ MX51_PIN_DISPB2_SER_CLK = _MXC_BUILD_GPIO_PIN(2, 7, 4, 0x2C4, 0x6C4),
+ MX51_PIN_DISPB2_SER_RS = _MXC_BUILD_GPIO_PIN(2, 8, 4, 0x2C8, 0x6C8),
+ MX51_PIN_DISP1_DAT0 = _MXC_BUILD_NON_GPIO_PIN(0x2CC, 0x6CC),
+ MX51_PIN_DISP1_DAT1 = _MXC_BUILD_NON_GPIO_PIN(0x2D0, 0x6D0),
+ MX51_PIN_DISP1_DAT2 = _MXC_BUILD_NON_GPIO_PIN(0x2D4, 0x6D4),
+ MX51_PIN_DISP1_DAT3 = _MXC_BUILD_NON_GPIO_PIN(0x2D8, 0x6D8),
+ MX51_PIN_DISP1_DAT4 = _MXC_BUILD_NON_GPIO_PIN(0x2DC, 0x6DC),
+ MX51_PIN_DISP1_DAT5 = _MXC_BUILD_NON_GPIO_PIN(0x2E0, 0x6E0),
+ MX51_PIN_DISP1_DAT6 = _MXC_BUILD_NON_GPIO_PIN(0x2E4, 0x6E4),
+ MX51_PIN_DISP1_DAT7 = _MXC_BUILD_NON_GPIO_PIN(0x2E8, 0x6E8),
+ MX51_PIN_DISP1_DAT8 = _MXC_BUILD_NON_GPIO_PIN(0x2EC, 0x6EC),
+ MX51_PIN_DISP1_DAT9 = _MXC_BUILD_NON_GPIO_PIN(0x2F0, 0x6F0),
+ MX51_PIN_DISP1_DAT10 = _MXC_BUILD_NON_GPIO_PIN(0x2F4, 0x6F4),
+ MX51_PIN_DISP1_DAT11 = _MXC_BUILD_NON_GPIO_PIN(0x2F8, 0x6F8),
+ MX51_PIN_DISP1_DAT12 = _MXC_BUILD_NON_GPIO_PIN(0x2FC, 0x6FC),
+ MX51_PIN_DISP1_DAT13 = _MXC_BUILD_NON_GPIO_PIN(0x300, 0x700),
+ MX51_PIN_DISP1_DAT14 = _MXC_BUILD_NON_GPIO_PIN(0x304, 0x704),
+ MX51_PIN_DISP1_DAT15 = _MXC_BUILD_NON_GPIO_PIN(0x308, 0x708),
+ MX51_PIN_DISP1_DAT16 = _MXC_BUILD_NON_GPIO_PIN(0x30C, 0x70C),
+ MX51_PIN_DISP1_DAT17 = _MXC_BUILD_NON_GPIO_PIN(0x310, 0x710),
+ MX51_PIN_DISP1_DAT18 = _MXC_BUILD_NON_GPIO_PIN(0x314, 0x714),
+ MX51_PIN_DISP1_DAT19 = _MXC_BUILD_NON_GPIO_PIN(0x318, 0x718),
+ MX51_PIN_DISP1_DAT20 = _MXC_BUILD_NON_GPIO_PIN(0x31C, 0x71C),
+ MX51_PIN_DISP1_DAT21 = _MXC_BUILD_NON_GPIO_PIN(0x320, 0x720),
+ MX51_PIN_DISP1_DAT22 = _MXC_BUILD_NON_GPIO_PIN(0x324, 0x724),
+ MX51_PIN_DISP1_DAT23 = _MXC_BUILD_NON_GPIO_PIN(0x328, 0x728),
+ MX51_PIN_DI1_PIN3 = _MXC_BUILD_NON_GPIO_PIN(0x32C, 0x72C),
+ MX51_PIN_DI1_PIN2 = _MXC_BUILD_NON_GPIO_PIN(0x330, 0x734),
+ MX51_PIN_DI_GP1 = _MXC_BUILD_NON_GPIO_PIN(0x334, 0x73C),
+ MX51_PIN_DI_GP2 = _MXC_BUILD_NON_GPIO_PIN(0x338, 0x740),
+ MX51_PIN_DI_GP3 = _MXC_BUILD_NON_GPIO_PIN(0x33C, 0x744),
+ MX51_PIN_DI2_PIN4 = _MXC_BUILD_NON_GPIO_PIN(0x340, 0x748),
+ MX51_PIN_DI2_PIN2 = _MXC_BUILD_NON_GPIO_PIN(0x344, 0x74C),
+ MX51_PIN_DI2_PIN3 = _MXC_BUILD_NON_GPIO_PIN(0x348, 0x750),
+ MX51_PIN_DI2_DISP_CLK = _MXC_BUILD_NON_GPIO_PIN(0x34C, 0x754),
+ MX51_PIN_DI_GP4 = _MXC_BUILD_NON_GPIO_PIN(0x350, 0x758),
+ MX51_PIN_DISP2_DAT0 = _MXC_BUILD_NON_GPIO_PIN(0x354, 0x75C),
+ MX51_PIN_DISP2_DAT1 = _MXC_BUILD_NON_GPIO_PIN(0x358, 0x760),
+ MX51_PIN_DISP2_DAT2 = _MXC_BUILD_NON_GPIO_PIN(0x35C, 0x764),
+ MX51_PIN_DISP2_DAT3 = _MXC_BUILD_NON_GPIO_PIN(0x360, 0x768),
+ MX51_PIN_DISP2_DAT4 = _MXC_BUILD_NON_GPIO_PIN(0x364, 0x76C),
+ MX51_PIN_DISP2_DAT5 = _MXC_BUILD_NON_GPIO_PIN(0x368, 0x770),
+ MX51_PIN_DISP2_DAT6 = _MXC_BUILD_GPIO_PIN(0, 19, 5, 0x36C, 0x774),
+ MX51_PIN_DISP2_DAT7 = _MXC_BUILD_GPIO_PIN(0, 29, 5, 0x370, 0x778),
+ MX51_PIN_DISP2_DAT8 = _MXC_BUILD_GPIO_PIN(0, 30, 5, 0x374, 0x77C),
+ MX51_PIN_DISP2_DAT9 = _MXC_BUILD_GPIO_PIN(0, 31, 5, 0x378, 0x780),
+ MX51_PIN_DISP2_DAT10 = _MXC_BUILD_NON_GPIO_PIN(0x37C, 0x784),
+ MX51_PIN_DISP2_DAT11 = _MXC_BUILD_NON_GPIO_PIN(0x380, 0x788),
+ MX51_PIN_DISP2_DAT12 = _MXC_BUILD_NON_GPIO_PIN(0x384, 0x78C),
+ MX51_PIN_DISP2_DAT13 = _MXC_BUILD_NON_GPIO_PIN(0x388, 0x790),
+ MX51_PIN_DISP2_DAT14 = _MXC_BUILD_NON_GPIO_PIN(0x38C, 0x794),
+ MX51_PIN_DISP2_DAT15 = _MXC_BUILD_NON_GPIO_PIN(0x390, 0x798),
+ MX51_PIN_SD1_CMD = _MXC_BUILD_NON_GPIO_PIN(0x394, 0x79C),
+ MX51_PIN_SD1_CLK = _MXC_BUILD_NON_GPIO_PIN(0x398, 0x7A0),
+ MX51_PIN_SD1_DATA0 = _MXC_BUILD_NON_GPIO_PIN(0x39C, 0x7A4),
+ MX51_PIN_SD1_DATA1 = _MXC_BUILD_NON_GPIO_PIN(0x3A0, 0x7A8),
+ MX51_PIN_SD1_DATA2 = _MXC_BUILD_NON_GPIO_PIN(0x3A4, 0x7AC),
+ MX51_PIN_SD1_DATA3 = _MXC_BUILD_NON_GPIO_PIN(0x3A8, 0x7B0),
+ MX51_PIN_GPIO1_0 = _MXC_BUILD_GPIO_PIN(0, 0, 1, 0x3AC, 0x7B4),
+ MX51_PIN_GPIO1_1 = _MXC_BUILD_GPIO_PIN(0, 1, 1, 0x3B0, 0x7B8),
+ MX51_PIN_SD2_CMD = _MXC_BUILD_NON_GPIO_PIN(0x3B4, 0x7BC),
+ MX51_PIN_SD2_CLK = _MXC_BUILD_NON_GPIO_PIN(0x3B8, 0x7C0),
+ MX51_PIN_SD2_DATA0 = _MXC_BUILD_NON_GPIO_PIN(0x3BC, 0x7C4),
+ MX51_PIN_SD2_DATA1 = _MXC_BUILD_NON_GPIO_PIN(0x3C0, 0x7C8),
+ MX51_PIN_SD2_DATA2 = _MXC_BUILD_NON_GPIO_PIN(0x3C4, 0x7CC),
+ MX51_PIN_SD2_DATA3 = _MXC_BUILD_NON_GPIO_PIN(0x3C8, 0x7D0),
+ MX51_PIN_GPIO1_2 = _MXC_BUILD_GPIO_PIN(0, 2, 0, 0x3CC, 0x7D4),
+ MX51_PIN_GPIO1_3 = _MXC_BUILD_GPIO_PIN(0, 3, 0, 0x3D0, 0x7D8),
+ MX51_PIN_PMIC_INT_REQ = _MXC_BUILD_NON_GPIO_PIN(0x3D4, 0x7FC),
+ MX51_PIN_GPIO1_4 = _MXC_BUILD_GPIO_PIN(0, 4, 0, 0x3D8, 0x804),
+ MX51_PIN_GPIO1_5 = _MXC_BUILD_GPIO_PIN(0, 5, 0, 0x3DC, 0x808),
+ MX51_PIN_GPIO1_6 = _MXC_BUILD_GPIO_PIN(0, 6, 0, 0x3E0, 0x80C),
+ MX51_PIN_GPIO1_7 = _MXC_BUILD_GPIO_PIN(0, 7, 0, 0x3E4, 0x810),
+ MX51_PIN_GPIO1_8 = _MXC_BUILD_GPIO_PIN(0, 8, 0, 0x3E8, 0x814),
+ MX51_PIN_GPIO1_9 = _MXC_BUILD_GPIO_PIN(0, 9, 0, 0x3EC, 0x818),
+};
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_ARCH_MXC_MX51_PINS_H__ */
diff --git a/arch/arm/mach-mx51/pm.c b/arch/arm/mach-mx51/pm.c
new file mode 100644
index 000000000000..5d5f4ddd2f07
--- /dev/null
+++ b/arch/arm/mach-mx51/pm.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/regulator.h>
+#include <linux/suspend.h>
+#include "crm_regs.h"
+
+static struct device *pm_dev;
+struct clk *gpc_dvfs_clk;
+extern void cpu_do_suspend_workaround(void);
+extern void cpu_cortexa8_do_idle(u32);
+
+extern int iram_ready;
+
+static int mx51_suspend_enter(suspend_state_t state)
+{
+ if (tzic_enable_wake(0) != 0)
+ return -EAGAIN;
+
+ if (gpc_dvfs_clk == NULL)
+ gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs_clk");
+ /* gpc clock is needed for SRPG */
+ clk_enable(gpc_dvfs_clk);
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ mxc_cpu_lp_set(STOP_POWER_OFF);
+ break;
+ case PM_SUSPEND_STANDBY:
+ mxc_cpu_lp_set(WAIT_UNCLOCKED_POWER_OFF);
+ break;
+ default:
+ return -EINVAL;
+ }
+ if (state == PM_SUSPEND_MEM) {
+ cpu_do_suspend_workaround();
+ /*clear the EMPGC0/1 bits */
+ __raw_writel(0, MXC_SRPG_EMPGC0_SRPGCR);
+ __raw_writel(0, MXC_SRPG_EMPGC1_SRPGCR);
+ } else {
+ if ((mxc_cpu_is_rev(CHIP_REV_2_0)) < 0) {
+ /* do cpu_idle_workaround */
+ u32 l2_iram_addr = IDLE_IRAM_BASE_ADDR;
+ if (!iram_ready)
+ return 0;
+ if (l2_iram_addr > 0x1FFE8000)
+ cpu_cortexa8_do_idle(IO_ADDRESS(l2_iram_addr));
+ } else {
+ cpu_do_idle();
+ }
+ }
+ clk_disable(gpc_dvfs_clk);
+
+ return 0;
+}
+
+/*
+ * Called after processes are frozen, but before we shut down devices.
+ */
+static int mx51_suspend_prepare(void)
+{
+ return 0;
+}
+
+/*
+ * Called before devices are re-setup.
+ */
+static void mx51_suspend_finish(void)
+{
+}
+
+/*
+ * Called after devices are re-setup, but before processes are thawed.
+ */
+static void mx51_suspend_end(void)
+{
+}
+
+static int mx51_pm_valid(suspend_state_t state)
+{
+ return (state > PM_SUSPEND_ON && state <= PM_SUSPEND_MAX);
+}
+
+struct platform_suspend_ops mx51_suspend_ops = {
+ .valid = mx51_pm_valid,
+ .prepare = mx51_suspend_prepare,
+ .enter = mx51_suspend_enter,
+ .finish = mx51_suspend_finish,
+ .end = mx51_suspend_end,
+};
+
+
+static int __devinit mx51_pm_probe(struct platform_device *pdev)
+{
+ pm_dev = &pdev->dev;
+ return 0;
+}
+
+static struct platform_driver mx51_pm_driver = {
+ .driver = {
+ .name = "mx51_pm",
+ },
+ .probe = mx51_pm_probe,
+};
+
+static int __init pm_init(void)
+{
+ pr_info("Static Power Management for Freescale i.MX51\n");
+ if (platform_driver_register(&mx51_pm_driver) != 0) {
+ printk(KERN_ERR "mx51_pm_driver register failed\n");
+ return -ENODEV;
+ }
+ suspend_set_ops(&mx51_suspend_ops);
+
+ printk(KERN_INFO "PM driver module loaded\n");
+
+ return 0;
+}
+
+
+static void __exit pm_cleanup(void)
+{
+ /* Unregister the device structure */
+ platform_driver_unregister(&mx51_pm_driver);
+}
+
+module_init(pm_init);
+module_exit(pm_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("PM driver");
+MODULE_LICENSE("GPL");
+
diff --git a/arch/arm/mach-mx51/sdma_script_code.h b/arch/arm/mach-mx51/sdma_script_code.h
new file mode 100644
index 000000000000..9b8de26ab74a
--- /dev/null
+++ b/arch/arm/mach-mx51/sdma_script_code.h
@@ -0,0 +1,170 @@
+/*
+ * Copyright 2008 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 */
+
+/*!
+ * @file sdma_script_code.h
+ * @brief This file contains functions of SDMA scripts code initialization
+ *
+ * The file was generated automatically. Based on sdma scripts library.
+ *
+ * @ingroup SDMA
+ */
+/*******************************************************************************
+
+ SDMA RELEASE LABEL: "SS15_ELVIS"
+
+*******************************************************************************/
+
+#ifndef __SDMA_SCRIPT_CODE_H__
+#define __SDMA_SCRIPT_CODE_H__
+
+/*!
+* SDMA ROM scripts start addresses and sizes
+*/
+
+#define start_ADDR 0
+#define start_SIZE 24
+
+#define core_ADDR 80
+#define core_SIZE 232
+
+#define common_ADDR 312
+#define common_SIZE 330
+
+#define ap_2_ap_ADDR 642
+#define ap_2_ap_SIZE 41
+
+#define app_2_mcu_ADDR 683
+#define app_2_mcu_SIZE 64
+
+#define mcu_2_app_ADDR 747
+#define mcu_2_app_SIZE 70
+
+#define uart_2_mcu_ADDR 817
+#define uart_2_mcu_SIZE 75
+
+#define shp_2_mcu_ADDR 892
+#define shp_2_mcu_SIZE 69
+
+#define mcu_2_shp_ADDR 961
+#define mcu_2_shp_SIZE 72
+
+#define app_2_per_ADDR 1033
+#define app_2_per_SIZE 66
+
+#define per_2_app_ADDR 1099
+#define per_2_app_SIZE 74
+
+#define per_2_shp_ADDR 1173
+#define per_2_shp_SIZE 78
+
+#define shp_2_per_ADDR 1251
+#define shp_2_per_SIZE 72
+
+#define uartsh_2_mcu_ADDR 1323
+#define uartsh_2_mcu_SIZE 69
+
+#define mcu_2_ata_ADDR 1392
+#define mcu_2_ata_SIZE 81
+
+#define ata_2_mcu_ADDR 1473
+#define ata_2_mcu_SIZE 96
+
+#define loop_DMAs_routines_ADDR 1569
+#define loop_DMAs_routines_SIZE 227
+
+#define test_ADDR 1796
+#define test_SIZE 63
+
+#define signature_ADDR 1023
+#define signature_SIZE 1
+
+/*!
+* SDMA RAM scripts start addresses and sizes
+*/
+
+#define ext_mem__ipu_ram_ADDR 6144
+#define ext_mem__ipu_ram_SIZE 123
+
+#define mcu_2_spdif_ADDR 6267
+#define mcu_2_spdif_SIZE 59
+
+#define uart_2_per_ADDR 6326
+#define uart_2_per_SIZE 73
+
+#define uartsh_2_per_ADDR 6399
+#define uartsh_2_per_SIZE 67
+
+/*!
+* SDMA RAM image start address and size
+*/
+
+#define RAM_CODE_START_ADDR 6144
+#define RAM_CODE_SIZE 322
+
+/*!
+* Buffer that holds the SDMA RAM image
+*/
+__attribute__ ((__aligned__(4)))
+#ifndef CONFIG_XIP_KERNEL
+const
+#endif
+static const short sdma_code[] = {
+ 0x0e70, 0x0611, 0x5616, 0xc13c, 0x7d2a, 0x5ade, 0x008e, 0xc14e,
+ 0x7c26, 0x5be0, 0x5ef0, 0x5ce8, 0x0688, 0x08ff, 0x0011, 0x28ff,
+ 0x00bc, 0x53f6, 0x05df, 0x7d0b, 0x6dc5, 0x03df, 0x7d03, 0x6bd5,
+ 0xd84f, 0x982b, 0x6b05, 0xc681, 0x7e27, 0x7f29, 0x982b, 0x6d01,
+ 0x03df, 0x7d05, 0x6bd5, 0xc6ab, 0x7e18, 0x7f1a, 0x982b, 0x6b05,
+ 0xc621, 0x7e07, 0x7f06, 0x52de, 0x53e6, 0xc159, 0x7dd7, 0x0200,
+ 0x9803, 0x0007, 0x6004, 0x680c, 0x53f6, 0x028e, 0x00a3, 0xc256,
+ 0x048b, 0x0498, 0x0454, 0x068a, 0x982b, 0x0207, 0x680c, 0x6ddf,
+ 0x0107, 0x68ff, 0x60d0, 0x9834, 0x0207, 0x68ff, 0x6d28, 0x0107,
+ 0x6004, 0x680c, 0x9834, 0x0007, 0x68ff, 0x60d0, 0x9834, 0x0288,
+ 0x03a5, 0x3b03, 0x3d03, 0x4d00, 0x7d0a, 0x0804, 0x00a5, 0x00da,
+ 0x7d1a, 0x02a0, 0x7b01, 0x65d8, 0x7eee, 0x65ff, 0x7eec, 0x0804,
+ 0x02d0, 0x7d11, 0x4b00, 0x7c0f, 0x008a, 0x3003, 0x6dcf, 0x6bdf,
+ 0x0015, 0x0015, 0x7b02, 0x65d8, 0x0000, 0x7edd, 0x63ff, 0x7edb,
+ 0x3a03, 0x6dcd, 0x6bdd, 0x008a, 0x7b02, 0x65d8, 0x0000, 0x7ed3,
+ 0x65ff, 0x7ed1, 0x0006, 0xc1d9, 0xc1e3, 0x57db, 0x52f3, 0x6a01,
+ 0x008f, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5deb, 0x56fb, 0x0478,
+ 0x7d28, 0x0479, 0x7c16, 0x0015, 0x0015, 0x0388, 0x620a, 0x0808,
+ 0x7801, 0x0217, 0x5a06, 0x7f1d, 0x620a, 0x0808, 0x7801, 0x0217,
+ 0x5a26, 0x7f17, 0x2301, 0x4b00, 0x7cf1, 0x0b70, 0x0311, 0x5313,
+ 0x98aa, 0x0015, 0x0015, 0x0015, 0x7804, 0x620b, 0x5a06, 0x620b,
+ 0x5a26, 0x7c07, 0x0000, 0x55eb, 0x4d00, 0x7d06, 0xc1fa, 0x57db,
+ 0x9880, 0x0007, 0x680c, 0xc213, 0xc20a, 0x987d, 0xc1e3, 0x57db,
+ 0x52f3, 0x6ad5, 0x56fb, 0x028e, 0x1a94, 0x6ac3, 0x62c8, 0x0269,
+ 0x7d1e, 0x1e94, 0x6ee3, 0x62d0, 0x5aeb, 0x62c8, 0x0248, 0x6ed3,
+ 0x6ac8, 0x2694, 0x52eb, 0x6ad5, 0x6ee3, 0x62c8, 0x026e, 0x7d27,
+ 0x6ac8, 0x7f23, 0x2501, 0x4d00, 0x7d26, 0x028e, 0x1a98, 0x6ac3,
+ 0x62c8, 0x6ec3, 0x0260, 0x7df1, 0x62d0, 0xc27a, 0x98fb, 0x6ee3,
+ 0x008f, 0x2001, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x62c8, 0x026e,
+ 0x7d0e, 0x6ac8, 0x7f0a, 0x2001, 0x7cf9, 0x6add, 0x7f06, 0x0000,
+ 0x4d00, 0x7d09, 0xc1fa, 0x57db, 0x98ba, 0x0007, 0x6aff, 0x62d0,
+ 0xc27a, 0x0458, 0x0454, 0x6add, 0x7ff8, 0xc20a, 0x98b7, 0xc1d9,
+ 0xc1e3, 0x57db, 0x52f3, 0x6ad5, 0x56fb, 0x028e, 0x1a94, 0x5202,
+ 0x0269, 0x7d17, 0x1e94, 0x5206, 0x0248, 0x5a06, 0x2694, 0x5206,
+ 0x026e, 0x7d26, 0x6ac8, 0x7f22, 0x2501, 0x4d00, 0x7d27, 0x028e,
+ 0x1a98, 0x5202, 0x0260, 0x7df3, 0x6add, 0x7f18, 0x62d0, 0xc27a,
+ 0x993e, 0x008f, 0x2001, 0x00d5, 0x7d01, 0x008d, 0x05a0, 0x5206,
+ 0x026e, 0x7d0e, 0x6ac8, 0x7f0a, 0x2001, 0x7cf9, 0x6add, 0x7f06,
+ 0x0000, 0x4d00, 0x7d0b, 0xc1fa, 0x57db, 0x9904, 0x0007, 0x6aff,
+ 0x6add, 0x7ffc, 0x62d0, 0xc27a, 0x0458, 0x0454, 0x6add, 0x7ff6,
+ 0xc20a, 0x9901
+};
+#endif
diff --git a/arch/arm/mach-mx51/serial.c b/arch/arm/mach-mx51/serial.c
new file mode 100644
index 000000000000..89cb943b396f
--- /dev/null
+++ b/arch/arm/mach-mx51/serial.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+/*!
+ * @file mach-mx51/serial.c
+ *
+ * @brief This file contains the UART initiliazation.
+ *
+ * @ingroup MSL_MX51
+ */
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <mach/hardware.h>
+#include <mach/mxc_uart.h>
+#include <mach/spba.h>
+#include "serial.h"
+#include "board-mx51_3stack.h"
+
+#if defined(CONFIG_SERIAL_MXC) || defined(CONFIG_SERIAL_MXC_MODULE)
+
+/*!
+ * This is an array where each element holds information about a UART port,
+ * like base address of the UART, interrupt numbers etc. This structure is
+ * passed to the serial_core.c file. Based on which UART is used, the core file
+ * passes back the appropriate port structure as an argument to the control
+ * functions.
+ */
+static uart_mxc_port mxc_ports[] = {
+ [0] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART1_BASE_ADDR),
+ .mapbase = UART1_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART1_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 0,
+ },
+ .ints_muxed = UART1_MUX_INTS,
+ .irqs = {UART1_INT2, UART1_INT3},
+ .mode = UART1_MODE,
+ .ir_mode = UART1_IR,
+ .enabled = UART1_ENABLED,
+ .hardware_flow = UART1_HW_FLOW,
+ .cts_threshold = UART1_UCR4_CTSTL,
+ .dma_enabled = UART1_DMA_ENABLE,
+ .dma_rxbuf_size = UART1_DMA_RXBUFSIZE,
+ .rx_threshold = UART1_UFCR_RXTL,
+ .tx_threshold = UART1_UFCR_TXTL,
+ .shared = UART1_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART1_TX,
+ .dma_rx_id = MXC_DMA_UART1_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ },
+ [1] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART2_BASE_ADDR),
+ .mapbase = UART2_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART2_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 1,
+ },
+ .ints_muxed = UART2_MUX_INTS,
+ .irqs = {UART2_INT2, UART2_INT3},
+ .mode = UART2_MODE,
+ .ir_mode = UART2_IR,
+ .enabled = UART2_ENABLED,
+ .hardware_flow = UART2_HW_FLOW,
+ .cts_threshold = UART2_UCR4_CTSTL,
+ .dma_enabled = UART2_DMA_ENABLE,
+ .dma_rxbuf_size = UART2_DMA_RXBUFSIZE,
+ .rx_threshold = UART2_UFCR_RXTL,
+ .tx_threshold = UART2_UFCR_TXTL,
+ .shared = UART2_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART2_TX,
+ .dma_rx_id = MXC_DMA_UART2_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ },
+ [2] = {
+ .port = {
+ .membase = (void *)IO_ADDRESS(UART3_BASE_ADDR),
+ .mapbase = UART3_BASE_ADDR,
+ .iotype = SERIAL_IO_MEM,
+ .irq = UART3_INT1,
+ .fifosize = 32,
+ .flags = ASYNC_BOOT_AUTOCONF,
+ .line = 2,
+ },
+ .ints_muxed = UART3_MUX_INTS,
+ .irqs = {UART3_INT2, UART3_INT3},
+ .mode = UART3_MODE,
+ .ir_mode = UART3_IR,
+ .enabled = UART3_ENABLED,
+ .hardware_flow = UART3_HW_FLOW,
+ .cts_threshold = UART3_UCR4_CTSTL,
+ .dma_enabled = UART3_DMA_ENABLE,
+ .dma_rxbuf_size = UART3_DMA_RXBUFSIZE,
+ .rx_threshold = UART3_UFCR_RXTL,
+ .tx_threshold = UART3_UFCR_TXTL,
+ .shared = UART3_SHARED_PERI,
+ .dma_tx_id = MXC_DMA_UART3_TX,
+ .dma_rx_id = MXC_DMA_UART3_RX,
+ .rxd_mux = MXC_UART_RXDMUX,
+ },
+};
+
+static struct platform_device mxc_uart_device1 = {
+ .name = "mxcintuart",
+ .id = 0,
+ .dev = {
+ .platform_data = &mxc_ports[0],
+ },
+};
+
+static struct platform_device mxc_uart_device2 = {
+ .name = "mxcintuart",
+ .id = 1,
+ .dev = {
+ .platform_data = &mxc_ports[1],
+ },
+};
+
+static struct platform_device mxc_uart_device3 = {
+ .name = "mxcintuart",
+ .id = 2,
+ .dev = {
+ .platform_data = &mxc_ports[2],
+ },
+};
+
+static int __init mxc_init_uart(void)
+{
+ /* Register all the MXC UART platform device structures */
+ platform_device_register(&mxc_uart_device1);
+ platform_device_register(&mxc_uart_device2);
+
+ /* Grab ownership of shared UARTs 3 and 4, only when enabled */
+#if UART3_ENABLED == 1
+#if UART3_DMA_ENABLE == 1
+ spba_take_ownership(UART3_SHARED_PERI, (SPBA_MASTER_A | SPBA_MASTER_C));
+#else
+ spba_take_ownership(UART3_SHARED_PERI, SPBA_MASTER_A);
+#endif /* UART3_DMA_ENABLE */
+ platform_device_register(&mxc_uart_device3);
+#endif /* UART3_ENABLED */
+
+ return 0;
+}
+
+#else
+static int __init mxc_init_uart(void)
+{
+ return 0;
+}
+#endif
+
+arch_initcall(mxc_init_uart);
diff --git a/arch/arm/mach-mx51/serial.h b/arch/arm/mach-mx51/serial.h
new file mode 100644
index 000000000000..ff4928c3b002
--- /dev/null
+++ b/arch/arm/mach-mx51/serial.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ARCH_ARM_MACH_MX51_SERIAL_H__
+#define __ARCH_ARM_MACH_MX51_SERIAL_H__
+
+#include <mach/mxc_uart.h>
+
+/* UART 1 configuration */
+/*!
+ * This option allows to choose either an interrupt-driven software controlled
+ * hardware flow control (set this option to 0) or hardware-driven hardware
+ * flow control (set this option to 1).
+ */
+/* UART used as wakeup source */
+#define UART1_HW_FLOW 0
+/*!
+ * This specifies the threshold at which the CTS pin is deasserted by the
+ * RXFIFO. Set this value in Decimal to anything from 0 to 32 for
+ * hardware-driven hardware flow control. Read the HW spec while specifying
+ * this value. When using interrupt-driven software controlled hardware
+ * flow control set this option to -1.
+ */
+#define UART1_UCR4_CTSTL 16
+/*!
+ * This is option to enable (set this option to 1) or disable DMA data transfer
+ */
+#define UART1_DMA_ENABLE 0
+/*!
+ * Specify the size of the DMA receive buffer. The minimum buffer size is 512
+ * bytes. The buffer size should be a multiple of 256.
+ */
+#define UART1_DMA_RXBUFSIZE 1024
+/*!
+ * Specify the MXC UART's Receive Trigger Level. This controls the threshold at
+ * which a maskable interrupt is generated by the RxFIFO. Set this value in
+ * Decimal to anything from 0 to 32. Read the HW spec while specifying this
+ * value.
+ */
+#define UART1_UFCR_RXTL 16
+/*!
+ * Specify the MXC UART's Transmit Trigger Level. This controls the threshold at
+ * which a maskable interrupt is generated by the TxFIFO. Set this value in
+ * Decimal to anything from 0 to 32. Read the HW spec while specifying this
+ * value.
+ */
+#define UART1_UFCR_TXTL 16
+/* UART 2 configuration */
+#define UART2_HW_FLOW 0
+#define UART2_UCR4_CTSTL -1
+#define UART2_DMA_ENABLE 0
+#define UART2_DMA_RXBUFSIZE 512
+#define UART2_UFCR_RXTL 16
+#define UART2_UFCR_TXTL 16
+/* UART 3 configuration */
+#define UART3_HW_FLOW 1
+#define UART3_UCR4_CTSTL 16
+#define UART3_DMA_ENABLE 1
+#define UART3_DMA_RXBUFSIZE 1024
+#define UART3_UFCR_RXTL 16
+#define UART3_UFCR_TXTL 16
+/*
+ * UART Chip level Configuration that a user may not have to edit. These
+ * configuration vary depending on how the UART module is integrated with
+ * the ARM core
+ */
+/*
+ * Is the MUXED interrupt output sent to the ARM core
+ */
+#define INTS_NOTMUXED 0
+#define INTS_MUXED 1
+/* UART 1 configuration */
+/*!
+ * This define specifies whether the muxed ANDed interrupt line or the
+ * individual interrupts from the UART port is integrated with the ARM core.
+ * There exists a define like this for each UART port. Valid values that can
+ * be used are \b INTS_NOTMUXED or \b INTS_MUXED.
+ */
+#define UART1_MUX_INTS INTS_MUXED
+/*!
+ * This define specifies the transmitter interrupt number or the interrupt
+ * number of the ANDed interrupt in case the interrupts are muxed. There exists
+ * a define like this for each UART port.
+ */
+#define UART1_INT1 MXC_INT_UART1
+/*!
+ * This define specifies the receiver interrupt number. If the interrupts of
+ * the UART are muxed, then we specify here a dummy value -1. There exists a
+ * define like this for each UART port.
+ */
+#define UART1_INT2 -1
+/*!
+ * This specifies the master interrupt number. If the interrupts of the UART
+ * are muxed, then we specify here a dummy value of -1. There exists a define
+ * like this for each UART port.
+ */
+#define UART1_INT3 -1
+/*!
+ * This specifies if the UART is a shared peripheral. It holds the shared
+ * peripheral number if it is shared or -1 if it is not shared. There exists
+ * a define like this for each UART port.
+ */
+#define UART1_SHARED_PERI -1
+/* UART 2 configuration */
+#define UART2_MUX_INTS INTS_MUXED
+#define UART2_INT1 MXC_INT_UART2
+#define UART2_INT2 -1
+#define UART2_INT3 -1
+#define UART2_SHARED_PERI -1
+/* UART 3 configuration */
+#define UART3_MUX_INTS INTS_MUXED
+#define UART3_INT1 MXC_INT_UART3
+#define UART3_INT2 -1
+#define UART3_INT3 -1
+#define UART3_SHARED_PERI SPBA_UART3
+
+#endif /* __ARCH_ARM_MACH_MX51_SERIAL_H__ */
diff --git a/arch/arm/mach-mx51/suspend.S b/arch/arm/mach-mx51/suspend.S
new file mode 100644
index 000000000000..9533b467cb87
--- /dev/null
+++ b/arch/arm/mach-mx51/suspend.S
@@ -0,0 +1,145 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/linkage.h>
+
+#define ARM_CTRL_DCACHE 1 << 2
+#define ARM_CTRL_ICACHE 1 << 12
+#define ARM_AUXCR_L2EN 1 << 1
+
+
+/*
+ * cpu_do_suspend_workaround()
+ *
+ * Suspend the processor (eg, wait for interrupt).
+ *
+ * IRQs are already disabled.
+ */
+ENTRY(cpu_do_suspend_workaround)
+ stmfd sp!, {r4,r5,r7,r9,r10,r11} @ Save registers
+
+ /* Disable L1 caches */
+ mrc p15, 0, r0, c1, c0, 0 @ R0 = system control reg
+ bic r0, r0, #ARM_CTRL_ICACHE @ Disable ICache
+ bic r0, r0, #ARM_CTRL_DCACHE @ Disable DCache
+ mcr p15, 0, r0, c1, c0, 0 @ Update system control reg
+
+ mrc p15, 1, r0, c0, c0, 1 @ Read CLIDR
+ ands r3, r0, #0x7000000 @ Isolate level of coherency
+ mov r3, r3, lsr #23 @ Cache level value (naturally aligned)
+ beq FinishedClean
+ mov r10, #0
+Loop1Clean:
+ add r2, r10, r10, lsr #1 @ Work out cache level
+ mov r1, r0, lsr r2 @ R0 bottom 3 bits = Cache Type for this level
+ and r1, r1, #7 @ Get those 3 bits alone
+ cmp r1, #2
+ blt SkipClean @ No cache or only instruction cache at this level
+ mcr p15, 2, r10, c0, c0, 0 @ Write the Cache Size selection register
+ mov r1, #0
+ .long 0xF57FF06F @ ISB
+ mrc p15, 1, r1, c0, c0, 0 @ Reads current Cache Size ID register
+ and r2, r1, #7 @ Extract the line length field
+ add r2, r2, #4 @ Add 4 for the line length offset (log2 16 bytes)
+ ldr r4, =0x3FF
+ ands r4, r4, r1, lsr #3 @ R4 is the max number on the way size (right aligned)
+ clz r5, r4 @ R5 is the bit position of the way size increment
+ ldr r7, =0x00007FFF
+ ands r7, r7, r1, lsr #13 @ R7 is the max number of the index size (right aligned)
+Loop2Clean:
+ mov r9, r4 @ R9 working copy of the max way size (right aligned)
+Loop3Clean:
+ orr r11, r10, r9, lsl r5 @ Factor in the way number and cache number into R11
+ orr r11, r11, r7, lsl r2 @ Factor in the index number
+ mcr p15, 0, r11, c7, c14, 2 @ Clean and invalidate by set/way
+ subs r9, r9, #1 @ Decrement the way number
+ bge Loop3Clean
+ subs r7, r7, #1 @ Decrement the index
+ bge Loop2Clean
+SkipClean:
+ add r10, r10, #2 @ Increment the cache number
+ cmp r3, r10
+ bgt Loop1Clean
+
+FinishedClean:
+
+ /* Disable L2 cache */
+ mrc p15, 0, r0, c1, c0, 1 @ R0 = auxiliary control reg
+ bic r0, r0, #ARM_AUXCR_L2EN @ Disable L2 cache
+ mcr p15, 0, r0, c1, c0, 1 @ Update aux control reg
+
+ .long 0xe320f003 @ Opcode for WFI
+
+ mov r0, #0
+ mcr p15, 0, r0, c7, c5, 0 @ Invalidate inst cache
+
+ /* Invalidate data caches */
+ mrc p15, 1, r0, c0, c0, 1 @ Read CLIDR
+ ands r3, r0, #0x7000000 @ Isolate level of coherency
+ mov r3, r3, lsr #23 @ Cache level value (naturally aligned)
+ beq FinishedInvalidate
+ mov r10, #0
+Loop1Invalidate:
+ add r2, r10, r10, lsr #1 @ Work out cache level
+ mov r1, r0, lsr r2 @ R0 bottom 3 bits = Cache Type for this level
+ and r1, r1, #7 @ Get those 3 bits alone
+ cmp r1, #2
+ blt SkipInvalidate @ No cache or only instruction cache at this level
+ mcr p15, 2, r10, c0, c0, 0 @ Write the Cache Size selection register
+ mov r1, #0
+ .long 0xF57FF06F @ ISB
+ mrc p15, 1, r1, c0, c0, 0 @ Reads current Cache Size ID register
+ and r2, r1, #7 @ Extract the line length field
+ add r2, r2, #4 @ Add 4 for the line length offset (log2 16 bytes)
+ ldr r4, =0x3FF
+ ands r4, r4, r1, lsr #3 @ R4 is the max number on the way size (right aligned)
+ clz r5, r4 @ R5 is the bit position of the way size increment
+ ldr r7, =0x00007FFF
+ ands r7, r7, r1, lsr #13 @ R7 is the max number of the index size (right aligned)
+Loop2Invalidate:
+ mov r9, r4 @ R9 working copy of the max way size (right aligned)
+Loop3Invalidate:
+ orr r11, r10, r9, lsl r5 @ Factor in the way number and cache number into R11
+ orr r11, r11, r7, lsl r2 @ Factor in the index number
+ mcr p15, 0, r11, c7, c6, 2 @ Invalidate by set/way
+ subs r9, r9, #1 @ Decrement the way number
+ bge Loop3Invalidate
+ subs r7, r7, #1 @ Decrement the index
+ bge Loop2Invalidate
+SkipInvalidate:
+ add r10, r10, #2 @ Increment the cache number
+ cmp r3, r10
+ bgt Loop1Invalidate
+
+FinishedInvalidate:
+
+ /* Enable L2 cache */
+ mrc p15, 0, r0, c1, c0, 1 @ R0 = auxiliary control reg
+ orr r0, r0, #ARM_AUXCR_L2EN @ Enable L2 cache
+ mcr p15, 0, r0, c1, c0, 1 @ Update aux control reg
+
+ /* Enable L1 caches */
+ mrc p15, 0, r0, c1, c0, 0 @ R0 = system control reg
+ orr r0, r0, #ARM_CTRL_ICACHE @ Enable ICache
+ orr r0, r0, #ARM_CTRL_DCACHE @ Enable DCache
+ mcr p15, 0, r0, c1, c0, 0 @ Update system control reg
+
+ /* Restore registers */
+ ldmfd sp!, {r4,r5,r7,r9,r10,r11}
+ mov pc, lr
+
+ .type cpu_do_suspend, #object
+ENTRY(cpu_do_suspend)
+ .word cpu_do_suspend_workaround
+ .size cpu_do_suspend_workaround, . - cpu_do_suspend_workaround
+
+
diff --git a/arch/arm/mach-mx51/system.c b/arch/arm/mach-mx51/system.c
new file mode 100644
index 000000000000..3aa444f84080
--- /dev/null
+++ b/arch/arm/mach-mx51/system.c
@@ -0,0 +1,186 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <asm/io.h>
+#include <mach/hardware.h>
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+#include "crm_regs.h"
+
+/*!
+ * @defgroup MSL_MX51 i.MX51 Machine Specific Layer (MSL)
+ */
+
+/*!
+ * @file mach-mx51/system.c
+ * @brief This file contains idle and reset functions.
+ *
+ * @ingroup MSL_MX51
+ */
+
+extern int mxc_jtag_enabled;
+extern int iram_ready;
+static struct clk *gpc_dvfs_clk;
+
+extern void cpu_cortexa8_do_idle(u32 addr);
+
+
+/* set cpu low power mode before WFI instruction */
+void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode)
+{
+ u32 plat_lpc, gpc_pgr, arm_srpgcr, ccm_clpcr;
+ u32 empgc0, empgc1;
+ int stop_mode = 0;
+
+ /* always allow platform to issue a deep sleep mode request */
+ plat_lpc = __raw_readl(MXC_CORTEXA8_PLAT_LPC) &
+ ~(MXC_CORTEXA8_PLAT_LPC_DSM);
+ ccm_clpcr = __raw_readl(MXC_CCM_CLPCR) & ~(MXC_CCM_CLPCR_LPM_MASK);
+ arm_srpgcr = __raw_readl(MXC_SRPG_ARM_SRPGCR) & ~(MXC_SRPGCR_PCR);
+ empgc0 = __raw_readl(MXC_SRPG_EMPGC0_SRPGCR) & ~(MXC_SRPGCR_PCR);
+ empgc1 = __raw_readl(MXC_SRPG_EMPGC1_SRPGCR) & ~(MXC_SRPGCR_PCR);
+
+ gpc_pgr = __raw_readl(MXC_GPC_PGR) & ~(MXC_GPC_PGR_ARMPG_MASK);
+
+ switch (mode) {
+ case WAIT_CLOCKED:
+ break;
+ case WAIT_UNCLOCKED:
+ ccm_clpcr |= (0x1 << MXC_CCM_CLPCR_LPM_OFFSET);
+ break;
+ case WAIT_UNCLOCKED_POWER_OFF:
+ case STOP_POWER_OFF:
+ plat_lpc |= MXC_CORTEXA8_PLAT_LPC_DSM
+ | MXC_CORTEXA8_PLAT_LPC_DBG_DSM;
+ if (mode == WAIT_UNCLOCKED_POWER_OFF) {
+ ccm_clpcr |= (0x1 << MXC_CCM_CLPCR_LPM_OFFSET);
+ ccm_clpcr &= ~MXC_CCM_CLPCR_VSTBY;
+ stop_mode = 0;
+ } else {
+ ccm_clpcr |= (0x2 << MXC_CCM_CLPCR_LPM_OFFSET);
+ ccm_clpcr |= (0x3 << MXC_CCM_CLPCR_STBY_COUNT_OFFSET);
+ ccm_clpcr |= MXC_CCM_CLPCR_VSTBY;
+ ccm_clpcr |= MXC_CCM_CLPCR_SBYOS;
+ stop_mode = 1;
+ }
+
+ arm_srpgcr |= MXC_SRPGCR_PCR;
+ gpc_pgr |= (0x1 << MXC_GPC_PGR_ARMPG_OFFSET);
+ if (stop_mode) {
+ empgc0 |= MXC_SRPGCR_PCR;
+ empgc1 |= MXC_SRPGCR_PCR;
+ }
+
+ if (tzic_enable_wake(1) != 0)
+ return;
+ break;
+ case STOP_POWER_ON:
+ ccm_clpcr |= (0x2 << MXC_CCM_CLPCR_LPM_OFFSET);
+ break;
+ default:
+ printk(KERN_WARNING "UNKNOWN cpu power mode: %d\n", mode);
+ return;
+ }
+
+ __raw_writel(plat_lpc, MXC_CORTEXA8_PLAT_LPC);
+ __raw_writel(ccm_clpcr, MXC_CCM_CLPCR);
+ __raw_writel(gpc_pgr, MXC_GPC_PGR);
+ __raw_writel(arm_srpgcr, MXC_SRPG_ARM_SRPGCR);
+ __raw_writel(arm_srpgcr, MXC_SRPG_NEON_SRPGCR);
+ if (stop_mode) {
+ __raw_writel(empgc0, MXC_SRPG_EMPGC0_SRPGCR);
+ __raw_writel(empgc1, MXC_SRPG_EMPGC1_SRPGCR);
+ }
+}
+
+void mxc_pg_enable(struct platform_device *pdev)
+{
+ if (pdev == NULL)
+ return;
+
+ if (strcmp(pdev->name, "mxc_ipu") == 0) {
+ __raw_writel(MXC_PGCR_PCR, MXC_PGC_IPU_PGCR);
+ __raw_writel(MXC_PGSR_PSR, MXC_PGC_IPU_PGSR);
+ } else if (strcmp(pdev->name, "mxc_vpu") == 0) {
+ __raw_writel(MXC_PGCR_PCR, MXC_PGC_VPU_PGCR);
+ __raw_writel(MXC_PGSR_PSR, MXC_PGC_VPU_PGSR);
+ }
+}
+
+EXPORT_SYMBOL(mxc_pg_enable);
+
+void mxc_pg_disable(struct platform_device *pdev)
+{
+ if (pdev == NULL)
+ return;
+
+ if (strcmp(pdev->name, "mxc_ipu") == 0) {
+ __raw_writel(0x0, MXC_PGC_IPU_PGCR);
+ if (__raw_readl(MXC_PGC_IPU_PGSR) & MXC_PGSR_PSR)
+ dev_dbg(&pdev->dev, "power gating successful\n");
+ __raw_writel(MXC_PGSR_PSR, MXC_PGC_IPU_PGSR);
+ } else if (strcmp(pdev->name, "mxc_vpu") == 0) {
+ __raw_writel(0x0, MXC_PGC_VPU_PGCR);
+ if (__raw_readl(MXC_PGC_VPU_PGSR) & MXC_PGSR_PSR)
+ dev_dbg(&pdev->dev, "power gating successful\n");
+ __raw_writel(MXC_PGSR_PSR, MXC_PGC_VPU_PGSR);
+ }
+}
+
+EXPORT_SYMBOL(mxc_pg_disable);
+
+/* To change the idle power mode, need to set arch_idle_mode to a different
+ * power mode as in enum mxc_cpu_pwr_mode.
+ * May allow dynamically changing the idle mode.
+ */
+static int arch_idle_mode = WAIT_UNCLOCKED_POWER_OFF;
+/*!
+ * This function puts the CPU into idle mode. It is called by default_idle()
+ * in process.c file.
+ */
+void arch_idle(void)
+{
+ if (likely(!mxc_jtag_enabled)) {
+ if (gpc_dvfs_clk == NULL)
+ gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs_clk");
+ /* gpc clock is needed for SRPG */
+ clk_enable(gpc_dvfs_clk);
+ mxc_cpu_lp_set(arch_idle_mode);
+ if ((mxc_cpu_is_rev(CHIP_REV_2_0)) < 0) {
+ u32 l2_iram_addr = IDLE_IRAM_BASE_ADDR;
+
+ if (!iram_ready)
+ return;
+
+ if (l2_iram_addr > 0x1FFE8000)
+ cpu_cortexa8_do_idle(IO_ADDRESS(l2_iram_addr));
+ } else {
+ cpu_do_idle();
+ }
+ clk_disable(gpc_dvfs_clk);
+ }
+}
+
+/*
+ * This function resets the system. It is called by machine_restart().
+ *
+ * @param mode indicates different kinds of resets
+ */
+void arch_reset(char mode)
+{
+ /* Assert SRS signal */
+ mxc_wd_reset();
+}
diff --git a/arch/arm/mach-mx51/usb.h b/arch/arm/mach-mx51/usb.h
new file mode 100644
index 000000000000..fc073e39c950
--- /dev/null
+++ b/arch/arm/mach-mx51/usb.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright 2005-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+
+extern int usbotg_init(struct platform_device *pdev);
+extern void usbotg_uninit(struct fsl_usb2_platform_data *pdata);
+extern int gpio_usbotg_hs_active(void);
+extern void gpio_usbotg_hs_inactive(void);
+extern struct platform_device *host_pdev_register(struct resource *res,
+ int n_res, struct fsl_usb2_platform_data *config);
+
+extern int fsl_usb_host_init(struct platform_device *pdev);
+extern void fsl_usb_host_uninit(struct fsl_usb2_platform_data *pdata);
+extern int gpio_usbh1_active(void);
+extern void gpio_usbh1_inactive(void);
+extern int gpio_usbotg_utmi_active(void);
+extern void gpio_usbotg_utmi_inactive(void);
+
+/*
+ * Determine which platform_data struct to use for the DR controller,
+ * based on which transceiver is configured.
+ * PDATA is a pointer to it.
+ */
+#if defined(CONFIG_ISP1301_MXC)
+static struct fsl_usb2_platform_data __maybe_unused dr_1301_config;
+#define PDATA (&dr_1301_config)
+#elif defined(CONFIG_MC13783_MXC)
+static struct fsl_usb2_platform_data __maybe_unused dr_13783_config;
+#define PDATA (&dr_13783_config)
+#elif defined(CONFIG_UTMI_MXC)
+static struct fsl_usb2_platform_data __maybe_unused dr_utmi_config;
+#define PDATA (&dr_utmi_config)
+#endif
+
+
+/*
+ * Used to set pdata->operating_mode before registering the platform_device.
+ * If OTG is configured, the controller operates in OTG mode,
+ * otherwise it's either host or device.
+ */
+#ifdef CONFIG_USB_OTG
+#define DR_UDC_MODE FSL_USB2_DR_OTG
+#define DR_HOST_MODE FSL_USB2_DR_OTG
+#else
+#define DR_UDC_MODE FSL_USB2_DR_DEVICE
+#define DR_HOST_MODE FSL_USB2_DR_HOST
+#endif
+
+
+#ifdef CONFIG_USB_EHCI_ARC_OTG
+static inline void dr_register_host(struct resource *r, int rs)
+{
+ PDATA->operating_mode = DR_HOST_MODE;
+ host_pdev_register(r, rs, PDATA);
+}
+#else
+static inline void dr_register_host(struct resource *r, int rs)
+{
+}
+#endif
+
+#ifdef CONFIG_USB_GADGET_ARC
+static struct platform_device dr_udc_device;
+
+static inline void dr_register_udc(void)
+{
+ PDATA->operating_mode = DR_UDC_MODE;
+ dr_udc_device.dev.platform_data = PDATA;
+
+ if (platform_device_register(&dr_udc_device))
+ printk(KERN_ERR "usb: can't register DR gadget\n");
+ else
+ printk(KERN_INFO "usb: DR gadget (%s) registered\n",
+ PDATA->transceiver);
+}
+#else
+static inline void dr_register_udc(void)
+{
+}
+#endif
+
+#ifdef CONFIG_USB_OTG
+static struct platform_device dr_otg_device;
+
+/*
+ * set the proper operating_mode and
+ * platform_data pointer, then register the
+ * device.
+ */
+static inline void dr_register_otg(void)
+{
+ PDATA->operating_mode = FSL_USB2_DR_OTG;
+ dr_otg_device.dev.platform_data = PDATA;
+
+ if (platform_device_register(&dr_otg_device))
+ printk(KERN_ERR "usb: can't register otg device\n");
+ else
+ printk(KERN_INFO "usb: DR OTG registered\n");
+}
+#else
+static inline void dr_register_otg(void)
+{
+}
+#endif
diff --git a/arch/arm/mach-mx51/usb_dr.c b/arch/arm/mach-mx51/usb_dr.c
new file mode 100644
index 000000000000..d1d3bdf08e61
--- /dev/null
+++ b/arch/arm/mach-mx51/usb_dr.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <mach/arc_otg.h>
+#include "usb.h"
+
+static int usbotg_init_ext(struct platform_device *pdev);
+static void usbotg_uninit_ext(struct fsl_usb2_platform_data *pdata);
+
+/*
+ * platform data structs
+ * - Which one to use is determined by CONFIG options in usb.h
+ * - operating_mode plugged at run time
+ */
+static struct fsl_usb2_platform_data __maybe_unused dr_utmi_config = {
+ .name = "DR",
+ .platform_init = usbotg_init_ext,
+ .platform_uninit = usbotg_uninit_ext,
+ .phy_mode = FSL_USB2_PHY_UTMI_WIDE,
+ .power_budget = 500, /* 500 mA max power */
+ .gpio_usb_active = gpio_usbotg_hs_active,
+ .gpio_usb_inactive = gpio_usbotg_hs_inactive,
+ .transceiver = "utmi",
+};
+
+
+/*
+ * resources
+ */
+static struct resource otg_resources[] = {
+ [0] = {
+ .start = (u32)(USB_OTGREGS_BASE),
+ .end = (u32)(USB_OTGREGS_BASE + 0x1ff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_USB_OTG,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+
+static u64 dr_udc_dmamask = ~(u32) 0;
+static void dr_udc_release(struct device *dev)
+{
+}
+
+static u64 dr_otg_dmamask = ~(u32) 0;
+static void dr_otg_release(struct device *dev)
+{
+}
+
+/*
+ * platform device structs
+ * dev.platform_data field plugged at run time
+ */
+static struct platform_device dr_udc_device = {
+ .name = "fsl-usb2-udc",
+ .id = -1,
+ .dev = {
+ .release = dr_udc_release,
+ .dma_mask = &dr_udc_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .resource = otg_resources,
+ .num_resources = ARRAY_SIZE(otg_resources),
+};
+
+static struct platform_device __maybe_unused dr_otg_device = {
+ .name = "fsl-usb2-otg",
+ .id = -1,
+ .dev = {
+ .release = dr_otg_release,
+ .dma_mask = &dr_otg_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .resource = otg_resources,
+ .num_resources = ARRAY_SIZE(otg_resources),
+};
+
+/* Notes: configure USB clock*/
+static int usbotg_init_ext(struct platform_device *pdev)
+{
+ struct clk *usb_clk;
+
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_enable(usb_clk);
+ clk_put(usb_clk);
+
+ usb_clk = clk_get(NULL, "usb_phy_clk");
+ clk_enable(usb_clk);
+ clk_put(usb_clk);
+
+ /*derive clock from oscillator */
+ usb_clk = clk_get(NULL, "usb_utmi_clk");
+ clk_disable(usb_clk);
+ clk_put(usb_clk);
+
+ return usbotg_init(pdev);
+}
+
+static void usbotg_uninit_ext(struct fsl_usb2_platform_data *pdata)
+{
+ struct clk *usb_clk;
+
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_disable(usb_clk);
+ clk_put(usb_clk);
+
+ usb_clk = clk_get(NULL, "usb_phy_clk");
+ clk_disable(usb_clk);
+ clk_put(usb_clk);
+
+ usbotg_uninit(pdata);
+}
+
+static int __init usb_dr_init(void)
+{
+ pr_debug("%s: \n", __func__);
+
+ dr_register_otg();
+ dr_register_host(otg_resources, ARRAY_SIZE(otg_resources));
+ dr_register_udc();
+
+ return 0;
+}
+
+module_init(usb_dr_init);
diff --git a/arch/arm/mach-mx51/usb_h1.c b/arch/arm/mach-mx51/usb_h1.c
new file mode 100644
index 000000000000..e3ca4a9c3847
--- /dev/null
+++ b/arch/arm/mach-mx51/usb_h1.c
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <mach/arc_otg.h>
+#include "usb.h"
+
+static struct fsl_usb2_platform_data usbh1_config = {
+ .name = "Host 1",
+ .platform_init = fsl_usb_host_init,
+ .platform_uninit = fsl_usb_host_uninit,
+ .operating_mode = FSL_USB2_MPH_HOST,
+ .phy_mode = FSL_USB2_PHY_ULPI,
+ .power_budget = 500, /* 500 mA max power */
+ .gpio_usb_active = gpio_usbh1_active,
+ .gpio_usb_inactive = gpio_usbh1_inactive,
+ .transceiver = "isp1504",
+};
+
+static struct resource usbh1_resources[] = {
+ [0] = {
+ .start = (u32) (USB_H1REGS_BASE),
+ .end = (u32) (USB_H1REGS_BASE + 0x1ff),
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = MXC_INT_USB_H1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static int __init usbh1_init(void)
+{
+ pr_debug("%s: \n", __func__);
+
+ host_pdev_register(usbh1_resources, ARRAY_SIZE(usbh1_resources),
+ &usbh1_config);
+ return 0;
+}
+
+module_init(usbh1_init);
diff --git a/arch/arm/mach-mx51/wfi.S b/arch/arm/mach-mx51/wfi.S
new file mode 100644
index 000000000000..559669611b6a
--- /dev/null
+++ b/arch/arm/mach-mx51/wfi.S
@@ -0,0 +1,427 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/linkage.h>
+
+#define ARM_CTRL_DCACHE 1 << 2
+#define ARM_AUXCR_L2EN 1 << 1
+/*
+ * cpu_cortexa8_do_idle()
+ *
+ * Idle the processor (eg, wait for interrupt).
+ *
+ * IRQs are already disabled.
+ */
+ENTRY(cpu_cortexa8_do_idle)
+
+ mrc p15, 0, r1, c1, c0, 1 @ R1 = auxiliary control reg
+ ands r2, r1, #ARM_AUXCR_L2EN @ Check if L2 is disabled
+ beq SkipL2Access
+
+ mrc p15, 0, r2, c1, c0, 0 @ R2 = system control reg
+ bic r2, r2, #ARM_CTRL_DCACHE @ Disable DCache
+ mcr p15, 0, r2, c1, c0, 0 @ Update system control reg
+
+ bic r1, r1, #ARM_AUXCR_L2EN @ Disable L2 cache
+ mcr p15, 0, r1, c1, c0, 1 @ Update aux control reg
+
+ ldr r1, =(0x0 << 6) @ A[6] = 0
+ mcr p15, 0, r1, c15, c9, 2 @ Read L2 tag RAM into L2 data 0 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0x00] @ Save tag info
+
+ ldr r1, =(0x1 << 6) @ A[6] = 1
+ mcr p15, 0, r1, c15, c9, 2 @ Read L2 tag RAM into L2 data 0 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0x04] @ Save tag info
+
+ ldr r1, =(0x0 << 3) @ A[6:3] = b0000
+ mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0x08] @ Store data info
+ mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2
+ str r2, [r0, #0x0C] @ Store data info
+ mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2
+ str r2, [r0, #0x10] @ Store data info
+
+ ldr r1, =(0x1 << 3) @ A[6:3] = b0001
+ mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0x14] @ Store data info
+ mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2
+ str r2, [r0, #0x18] @ Store data info
+ mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2
+ str r2, [r0, #0x1C] @ Store data info
+
+ ldr r1, =(0x2 << 3) @ A[6:3] = b0010
+ mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0x20] @ Store data info
+ mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2
+ str r2, [r0, #0x24] @ Store data info
+ mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2
+ str r2, [r0, #0x28] @ Store data info
+
+ ldr r1, =(0x3 << 3) @ A[6:3] = b0011
+ mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0x2C] @ Store data info
+ mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2
+ str r2, [r0, #0x30] @ Store data info
+ mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2
+ str r2, [r0, #0x34] @ Store data info
+
+ ldr r1, =(0x4 << 3) @ A[6:3] = b0100
+ mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0x38] @ Store data info
+ mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2
+ str r2, [r0, #0x3C] @ Store data info
+ mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2
+ str r2, [r0, #0x40] @ Store data info
+
+ ldr r1, =(0x5 << 3) @ A[6:3] = b0101
+ mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0x44] @ Store data info
+ mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2
+ str r2, [r0, #0x48] @ Store data info
+ mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2
+ str r2, [r0, #0x4C] @ Store data info
+
+ ldr r1, =(0x6 << 3) @ A[6:3] = b0110
+ mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0x50] @ Store data info
+ mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2
+ str r2, [r0, #0x54] @ Store data info
+ mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2
+ str r2, [r0, #0x58] @ Store data info
+
+ ldr r1, =(0x7 << 3) @ A[6:3] = b0111
+ mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0x5C] @ Store data info
+ mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2
+ str r2, [r0, #0x60] @ Store data info
+ mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2
+ str r2, [r0, #0x64] @ Store data info
+
+ ldr r1, =(0x8 << 3) @ A[6:3] = b1000
+ mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0x68] @ Store data info
+ mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2
+ str r2, [r0, #0x6C] @ Store data info
+ mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2
+ str r2, [r0, #0x70] @ Store data info
+
+ ldr r1, =(0x9 << 3) @ A[6:3] = b1001
+ mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0x74] @ Store data info
+ mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2
+ str r2, [r0, #0x78] @ Store data info
+ mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2
+ str r2, [r0, #0x7C] @ Store data info
+
+ ldr r1, =(0xA << 3) @ A[6:3] = b1010
+ mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0x80] @ Store data info
+ mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2
+ str r2, [r0, #0x84] @ Store data info
+ mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2
+ str r2, [r0, #0x88] @ Store data info
+
+ ldr r1, =(0xB << 3) @ A[6:3] = b1011
+ mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0x8C] @ Store data info
+ mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2
+ str r2, [r0, #0x90] @ Store data info
+ mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2
+ str r2, [r0, #0x94] @ Store data info
+
+ ldr r1, =(0xC << 3) @ A[6:3] = b1100
+ mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0x98] @ Store data info
+ mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2
+ str r2, [r0, #0x9C] @ Store data info
+ mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2
+ str r2, [r0, #0xA0] @ Store data info
+
+ ldr r1, =(0xD << 3) @ A[6:3] = b1101
+ mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0xA4] @ Store data info
+ mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2
+ str r2, [r0, #0xA8] @ Store data info
+ mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2
+ str r2, [r0, #0xAC] @ Store data info
+
+ ldr r1, =(0xE << 3) @ A[6:3] = b1110
+ mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0xB0] @ Store data info
+ mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2
+ str r2, [r0, #0xB4] @ Store data info
+ mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2
+ str r2, [r0, #0xB8] @ Store data info
+
+ ldr r1, =(0xF << 3) @ A[6:3] = b1111
+ mcr p15, 0, r1, c15, c9, 3 @ Read L2 Data RAM into L2 data 0-2 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0xBC] @ Store data info
+ mrc p15, 0, r2, c15, c8, 1 @ Move L2 data 1 register to R2
+ str r2, [r0, #0xC0] @ Store data info
+ mrc p15, 0, r2, c15, c8, 5 @ Move L2 data 2 register to R2
+ str r2, [r0, #0xC4] @ Store data info
+
+ ldr r1, =(0x2 << 29) | (0x0 << 6) @ WAY = A[31:29] = 2, A[6] = 0
+ mcr p15, 0, r1, c15, c9, 2 @ Read L2 tag RAM into L2 data 0 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0xC8] @ Save tag info
+
+ ldr r1, =(0x2 << 29) | (0x1 << 6) @ WAY = A[31:29] = 2, A[6] = 1
+ mcr p15, 0, r1, c15, c9, 2 @ Read L2 tag RAM into L2 data 0 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0xCC] @ Save tag info
+
+ ldr r1, =(0x4 << 29) | (0x0 << 6) @ WAY = A[31:29] = 4, A[6] = 0
+ mcr p15, 0, r1, c15, c9, 2 @ Read L2 tag RAM into L2 data 0 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0xD0] @ Save tag info
+
+ ldr r1, =(0x4 << 29) | (0x1 << 6) @ WAY = A[31:29] = 4, A[6] = 1
+ mcr p15, 0, r1, c15, c9, 2 @ Read L2 tag RAM into L2 data 0 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0xD4] @ Save tag info
+
+ ldr r1, =(0x6 << 29) | (0x0 << 6) @ WAY = A[31:29] = 6, A[6] = 0
+ mcr p15, 0, r1, c15, c9, 2 @ Read L2 tag RAM into L2 data 0 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0xD8] @ Save tag info
+
+ ldr r1, =(0x6 << 29) | (0x1 << 6) @ WAY = A[31:29] = 6, A[6] = 1
+ mcr p15, 0, r1, c15, c9, 2 @ Read L2 tag RAM into L2 data 0 register
+ mrc p15, 0, r2, c15, c8, 0 @ Move L2 data 0 register to R2
+ str r2, [r0, #0xDC] @ Save tag info
+
+ .long 0xe320f003 @ Opcode for WFI
+
+ ldr r1, =(0x0 << 6) @ A[6] = 0
+ ldr r2, [r0, #0x00] @ Load tag info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ mcr p15, 0, r1, c15, c8, 2 @ Write L2 data 0 register to L2 tag RAM
+
+ ldr r1, =(0x1 << 6) @ A[6] = 1
+ ldr r2, [r0, #0x04] @ Load tag info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ mcr p15, 0, r1, c15, c8, 2 @ Write L2 data 0 register to L2 tag RAM
+
+ ldr r1, =(0x0 << 3) @ A[6:3] = b0000
+ ldr r2, [r0, #0x08] @ Load data info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ ldr r2, [r0, #0x0C] @ Load data info
+ mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register
+ ldr r2, [r0, #0x10] @ Load data info
+ mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register
+ mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM
+
+ ldr r1, =(0x1 << 3) @ A[6:3] = b0001
+ ldr r2, [r0, #0x14] @ Load data info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ ldr r2, [r0, #0x18] @ Load data info
+ mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register
+ ldr r2, [r0, #0x1C] @ Load data info
+ mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register
+ mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM
+
+ ldr r1, =(0x2 << 3) @ A[6:3] = b0010
+ ldr r2, [r0, #0x20] @ Load data info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ ldr r2, [r0, #0x24] @ Load data info
+ mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register
+ ldr r2, [r0, #0x28] @ Load data info
+ mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register
+ mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM
+
+ ldr r1, =(0x3 << 3) @ A[6:3] = b0011
+ ldr r2, [r0, #0x2C] @ Load data info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ ldr r2, [r0, #0x30] @ Load data info
+ mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register
+ ldr r2, [r0, #0x34] @ Load data info
+ mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register
+ mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM
+
+ ldr r1, =(0x4 << 3) @ A[6:3] = b0100
+ ldr r2, [r0, #0x38] @ Load data info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ ldr r2, [r0, #0x3C] @ Load data info
+ mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register
+ ldr r2, [r0, #0x40] @ Load data info
+ mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register
+ mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM
+
+ ldr r1, =(0x5 << 3) @ A[6:3] = b0101
+ ldr r2, [r0, #0x44] @ Load data info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ ldr r2, [r0, #0x48] @ Load data info
+ mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register
+ ldr r2, [r0, #0x4C] @ Load data info
+ mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register
+ mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM
+
+ ldr r1, =(0x6 << 3) @ A[6:3] = b0110
+ ldr r2, [r0, #0x50] @ Load data info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ ldr r2, [r0, #0x54] @ Load data info
+ mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register
+ ldr r2, [r0, #0x58] @ Load data info
+ mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register
+ mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM
+
+ ldr r1, =(0x7 << 3) @ A[6:3] = b0111
+ ldr r2, [r0, #0x5C] @ Load data info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ ldr r2, [r0, #0x60] @ Load data info
+ mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register
+ ldr r2, [r0, #0x64] @ Load data info
+ mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register
+ mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM
+
+ ldr r1, =(0x8 << 3) @ A[6:3] = b1000
+ ldr r2, [r0, #0x68] @ Load data info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ ldr r2, [r0, #0x6C] @ Load data info
+ mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register
+ ldr r2, [r0, #0x70] @ Load data info
+ mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register
+ mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM
+
+ ldr r1, =(0x9 << 3) @ A[6:3] = b1001
+ ldr r2, [r0, #0x74] @ Load data info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ ldr r2, [r0, #0x78] @ Load data info
+ mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register
+ ldr r2, [r0, #0x7C] @ Load data info
+ mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register
+ mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM
+
+ ldr r1, =(0xA << 3) @ A[6:3] = b1010
+ ldr r2, [r0, #0x80] @ Load data info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ ldr r2, [r0, #0x84] @ Load data info
+ mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register
+ ldr r2, [r0, #0x88] @ Load data info
+ mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register
+ mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM
+
+ ldr r1, =(0xB << 3) @ A[6:3] = b1011
+ ldr r2, [r0, #0x8C] @ Load data info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ ldr r2, [r0, #0x90] @ Load data info
+ mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register
+ ldr r2, [r0, #0x94] @ Load data info
+ mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register
+ mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM
+
+ ldr r1, =(0xC << 3) @ A[6:3] = b1100
+ ldr r2, [r0, #0x98] @ Load data info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ ldr r2, [r0, #0x9C] @ Load data info
+ mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register
+ ldr r2, [r0, #0xA0] @ Load data info
+ mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register
+ mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM
+
+ ldr r1, =(0xD << 3) @ A[6:3] = b1101
+ ldr r2, [r0, #0xA4] @ Load data info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ ldr r2, [r0, #0xA8] @ Load data info
+ mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register
+ ldr r2, [r0, #0xAC] @ Load data info
+ mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register
+ mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM
+
+ ldr r1, =(0xE << 3) @ A[6:3] = b1110
+ ldr r2, [r0, #0xB0] @ Load data info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ ldr r2, [r0, #0xB4] @ Load data info
+ mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register
+ ldr r2, [r0, #0xB8] @ Load data info
+ mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register
+ mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM
+
+ ldr r1, =(0xF << 3) @ A[6:3] = b1111
+ ldr r2, [r0, #0xBC] @ Load data info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ ldr r2, [r0, #0xC0] @ Load data info
+ mcr p15, 0, r2, c15, c8, 1 @ Move R2 to L2 data 1 register
+ ldr r2, [r0, #0xC4] @ Load data info
+ mcr p15, 0, r2, c15, c8, 5 @ Move R2 to L2 data 2 register
+ mcr p15, 0, r1, c15, c8, 3 @ Write L2 data 0-2 registers to L2 data RAM
+
+ ldr r1, =(0x2 << 29) | (0x0 << 6) @ WAY = A[31:29] = 2, A[6] = 0
+ ldr r2, [r0, #0xC8] @ Load tag info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ mcr p15, 0, r1, c15, c8, 2 @ Write L2 data 0 register to L2 tag RAM
+
+ ldr r1, =(0x2 << 29) | (0x1 << 6) @ WAY = A[31:29] = 2, A[6] = 1
+ ldr r2, [r0, #0xCC] @ Load tag info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ mcr p15, 0, r1, c15, c8, 2 @ Write L2 data 0 register to L2 tag RAM
+
+ ldr r1, =(0x4 << 29) | (0x0 << 6) @ WAY = A[31:29] = 4, A[6] = 0
+ ldr r2, [r0, #0xD0] @ Load tag info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ mcr p15, 0, r1, c15, c8, 2 @ Write L2 data 0 register to L2 tag RAM
+
+ ldr r1, =(0x4 << 29) | (0x1 << 6) @ WAY = A[31:29] = 4, A[6] = 1
+ ldr r2, [r0, #0xD4] @ Load tag info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ mcr p15, 0, r1, c15, c8, 2 @ Write L2 data 0 register to L2 tag RAM
+
+ ldr r1, =(0x6 << 29) | (0x0 << 6) @ WAY = A[31:29] = 6, A[6] = 0
+ ldr r2, [r0, #0xD8] @ Load tag info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ mcr p15, 0, r1, c15, c8, 2 @ Write L2 data 0 register to L2 tag RAM
+
+ ldr r1, =(0x6 << 29) | (0x1 << 6) @ WAY = A[31:29] = 6, A[6] = 1
+ ldr r2, [r0, #0xDC] @ Load tag info
+ mcr p15, 0, r2, c15, c8, 0 @ Move R2 to L2 data 0 register
+ mcr p15, 0, r1, c15, c8, 2 @ Write L2 data 0 register to L2 tag RAM
+
+ mrc p15, 0, r1, c1, c0, 1 @ R1 = auxiliary control reg
+ orr r1, r1, #ARM_AUXCR_L2EN @ Enable L2 cache
+ mcr p15, 0, r1, c1, c0, 1 @ Update aux control reg
+
+ mrc p15, 0, r2, c1, c0, 0 @ R2 = system control reg
+ orr r2, r2, #ARM_CTRL_DCACHE @ Enable DCache
+ mcr p15, 0, r2, c1, c0, 0 @ Update system control reg
+
+ b Done
+
+SkipL2Access:
+ .long 0xe320f003 @ Opcode for WFI
+
+Done:
+ mov pc, lr
+
+ .type cortexa8_idle_workaround, #object
+ENTRY(cortexa8_idle_workaround)
+ .word cpu_cortexa8_do_idle
+ .size cortexa8_idle_workaround, . - cortexa8_idle_workaround
+
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index ab5f7a21350b..fd2ab84ae017 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -187,7 +187,7 @@ config CPU_ARM926T
ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || \
ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || \
ARCH_AT91SAM9G20 || ARCH_AT91CAP9 || \
- ARCH_NS9XXX || ARCH_DAVINCI || ARCH_MX2
+ ARCH_NS9XXX || ARCH_DAVINCI || ARCH_MX2 || ARCH_MXC
default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || \
ARCH_OMAP730 || ARCH_OMAP16XX || \
ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || \
@@ -400,7 +400,7 @@ config CPU_FEROCEON_OLD_ID
# ARMv6
config CPU_V6
bool "Support ARM V6 processor"
- depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3 || ARCH_MSM || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176
+ depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MXC || ARCH_MSM || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176
default y if ARCH_MX3
default y if ARCH_MSM
select CPU_32v6
@@ -428,7 +428,7 @@ config CPU_32v6K
# ARMv7
config CPU_V7
bool "Support ARM V7 processor"
- depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP3
+ depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP3 || ARCH_MXC
select CPU_32v6K
select CPU_32v7
select CPU_ABRT_EV7
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index b480f1d3591f..45563b8ecf1a 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -24,8 +24,16 @@
#include <asm/hardware/cache-l2x0.h>
#define CACHE_LINE_SIZE 32
+#ifdef CONFIG_OPROFILE_ARM11_EVTMON
+#include <linux/module.h>
+#define L2_ENABLE_BIT 0x1
+#define L2_EVTBUS_BIT 0x100000
+#define L2_CTL_REG (l2x0_base + L2X0_CTRL)
+#define L2_AUX_REG (l2x0_base + L2X0_AUX_CTRL)
+#endif
static void __iomem *l2x0_base;
+static unsigned long l2x0_aux;
static DEFINE_SPINLOCK(l2x0_lock);
static inline void sync_writel(unsigned long val, unsigned long reg,
@@ -53,6 +61,13 @@ static inline void l2x0_inv_all(void)
cache_sync();
}
+static void l2x0_flush_all(void)
+{
+ /* clean and invalidate all ways */
+ sync_writel(0xff, L2X0_CLEAN_INV_WAY, 0xff);
+ cache_sync();
+}
+
static void l2x0_inv_range(unsigned long start, unsigned long end)
{
unsigned long addr;
@@ -93,6 +108,49 @@ static void l2x0_flush_range(unsigned long start, unsigned long end)
cache_sync();
}
+#ifdef CONFIG_OPROFILE_ARM11_EVTMON
+/*!
+ * Enable the EVTBUS to monitor L2 cache events
+ */
+void l2x0_evtbus_enable(void)
+{
+ unsigned int flags;
+
+ local_irq_save(flags);
+ /* If L2 cache is enabled then disable L2 cache, enable L2 evtbus,
+ re-enable L2 cache */
+ if ((readl(L2_CTL_REG) & L2_ENABLE_BIT) != 0) {
+ writel(0, L2_CTL_REG);
+ writel((readl(L2_AUX_REG)| L2_EVTBUS_BIT), L2_AUX_REG);
+ writel(L2_ENABLE_BIT, L2_CTL_REG);
+ } else {
+ writel((readl(L2_AUX_REG)| L2_EVTBUS_BIT), L2_AUX_REG);
+ }
+ local_irq_restore(flags);
+}
+
+/*!
+ * Disable the EVTBUS
+ */
+void l2x0_evtbus_disable(void)
+{
+ unsigned int flags;
+
+ local_irq_save(flags);
+ /* If L2 cache is enabled then disable L2 cache, disable L2 evtbus,
+ re-enable L2 cache */
+ if ((readl(L2_CTL_REG) & L2_ENABLE_BIT) != 0) {
+ writel(0, L2_CTL_REG);
+ writel((readl(L2_AUX_REG)& ~L2_EVTBUS_BIT), L2_AUX_REG);
+ writel(L2_ENABLE_BIT, L2_CTL_REG);
+ } else {
+ writel((readl(L2_AUX_REG)& ~L2_EVTBUS_BIT), L2_AUX_REG);
+ }
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL(l2x0_evtbus_enable);
+EXPORT_SYMBOL(l2x0_evtbus_disable);
+#endif
void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
{
__u32 aux;
@@ -105,6 +163,7 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
aux = readl(l2x0_base + L2X0_AUX_CTRL);
aux &= aux_mask;
aux |= aux_val;
+ l2x0_aux = aux;
writel(aux, l2x0_base + L2X0_AUX_CTRL);
l2x0_inv_all();
@@ -115,6 +174,29 @@ void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
outer_cache.inv_range = l2x0_inv_range;
outer_cache.clean_range = l2x0_clean_range;
outer_cache.flush_range = l2x0_flush_range;
+ outer_cache.flush_all = l2x0_flush_all;
printk(KERN_INFO "L2X0 cache controller enabled\n");
}
+EXPORT_SYMBOL(outer_cache);
+
+void l2x0_disable(void)
+{
+ if (readl(l2x0_base + L2X0_CTRL)
+ && !(readl(l2x0_base + L2X0_DEBUG_CTRL) & 0x2)) {
+ l2x0_flush_all();
+ writel(0, l2x0_base + L2X0_CTRL);
+ l2x0_flush_all();
+ }
+}
+
+void l2x0_enable(void)
+{
+ if (!readl(l2x0_base + L2X0_CTRL)) {
+ writel(l2x0_aux, l2x0_base + L2X0_AUX_CTRL);
+ l2x0_inv_all();
+ /* enable L2X0 */
+ writel(1, l2x0_base + L2X0_CTRL);
+ }
+}
+
diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile
index 88e31f549f50..18c80fa3ad21 100644
--- a/arch/arm/oprofile/Makefile
+++ b/arch/arm/oprofile/Makefile
@@ -9,6 +9,7 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
oprofile-$(CONFIG_CPU_XSCALE) += op_model_xscale.o
oprofile-$(CONFIG_OPROFILE_ARM11_CORE) += op_model_arm11_core.o
+oprofile-$(CONFIG_OPROFILE_ARM11_EVTMON) += op_model_arm11_evtmon.o
oprofile-$(CONFIG_OPROFILE_ARMV6) += op_model_v6.o
oprofile-$(CONFIG_OPROFILE_MPCORE) += op_model_mpcore.o
oprofile-$(CONFIG_OPROFILE_ARMV7) += op_model_v7.o
diff --git a/arch/arm/oprofile/evtmon_regs.h b/arch/arm/oprofile/evtmon_regs.h
new file mode 100644
index 000000000000..def582bd17df
--- /dev/null
+++ b/arch/arm/oprofile/evtmon_regs.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * @file evtmon_regs.h
+ *
+ * @brief EVTMON Register definitions
+ *
+ * @ingroup MXC_Oprofile
+ */
+#ifndef _EVTMON_REGS_INCLUDED_
+#define _EVTMON_REGS_INCLUDED_
+
+#define MXC_CRM_AP_BASE (IO_ADDRESS(CRM_AP_BASE_ADDR))
+#define ECT_CTI_BASE (IO_ADDRESS(ECT_CTIO_BASE_ADDR))
+#define CLKCTR_BASE_ADDR (IO_ADDRESS(CLKCTL_BASE_ADDR))
+#define L2CC_BASE_ADDRESS (IO_ADDRESS(L2CC_BASE_ADDR))
+#define L2EM_BASE_ADDRESS (IO_ADDRESS(EVTMON_BASE_ADDR))
+
+/* L2 INT settings */
+#define L2EM_ENABLE_OVERFLOWINT 0x1
+#define L2EM_ENABLE_CNTINCRINT 0x3
+#define L2EM_ENABLE_MASK 0x1
+#define L2EM_INT_EDGE 0x2
+#define L2EM_INT_HIGH 0x4
+#define L2EM_INT_CLK_CYCLES (0x0 << 3)
+
+/* Reg definitions for EVTMON */
+#define L2EM_CTRL (L2EM_BASE_ADDRESS + 0x0)
+#define L2EM_STAT (L2EM_BASE_ADDRESS + 0x4)
+#define L2EM_CC(nr) (L2EM_BASE_ADDRESS + 0x8 +(4*nr))
+#define L2EM_CNT(nr) (L2EM_BASE_ADDRESS + 0x20 +(4*nr))
+
+/* Reg definitions for CLK_CTL */
+#define CLKCTL_SET_CTRL (CLKCTR_BASE_ADDR + 0x04)
+
+/* Reg definitions for ECT */
+#define ECT_CTI_CONTROL (ECT_CTI_BASE + 0x0)
+#define ECT_CTI_LOCK (ECT_CTI_BASE + 0x8)
+#define ECT_CTI_INEN(nr) (ECT_CTI_BASE + 0x20 + (4*nr))
+#define ECT_CTI_OUTEN(nr) (ECT_CTI_BASE + 0xA0 + (4*nr))
+#define ECT_CTI_INTACK (ECT_CTI_BASE + 0x10)
+#define ECT_CTI_TRIGOUTSTATUS (ECT_CTI_BASE + 0x134)
+
+#define ENABLE_L2CACHE 0x1
+#define EVTMON_ENABLE 0x001 /* Enable EVTMON */
+#define EVT_UNUSED 0x100
+#define MAX_PMUCOUNTERS 3
+
+#ifdef CONFIG_OPROFILE_ARM11_EVTMON
+#define ECT_WORKAROUND
+#endif
+
+#ifdef ECT_WORKAROUND
+#define ENABLE_CTI_CLOCK 0x00000020
+#define UNLOCK_ECT_CODE 0x0ACCE550
+#define ECT_CTI_CHAN_2 0x4
+#define ECT_CTI_CHAN_3 0x8
+#define ECT_CTI_TRIGIN_1 1
+#define ECT_CTI_TRIGIN_7 7
+#define ECT_CTI_TRIGOUT_2 2
+#define ECT_CTI_TRIGOUT_6 6
+#define ENABLE_ECT 0x1
+#define ACK_TRIG_OUT_2 0x4
+#define EM_SET_INT L2EM_ENABLE_CNTINCRINT
+#define EVENT_OVERFLOW_INT MXC_INT_ECT
+#else
+#define EVENT_OVERFLOW_INT ARM11_PMU_IRQ
+#define EM_SET_INT L2EM_ENABLE_OVERFLOWINT
+#endif
+
+int l2em_configure_counter(int nr, int type);
+void write_l2counter(int nr, u32 val);
+#endif
diff --git a/arch/arm/oprofile/op_model_arm11.c b/arch/arm/oprofile/op_model_arm11.c
new file mode 100644
index 000000000000..573269e36a48
--- /dev/null
+++ b/arch/arm/oprofile/op_model_arm11.c
@@ -0,0 +1,477 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup MXC_Oprofile ARM11 Driver for Oprofile
+ */
+
+/*!
+ * @file op_model_arm11.c
+ *
+ *Based on the op_model_xscale.c driver by author Zwane Mwaikambo
+ *
+ * @ingroup MXC_Oprofile
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include "op_counter.h"
+#include "op_arm_model.h"
+#include "evtmon_regs.h"
+
+/*!
+ * defines used in ARM11 performance unit
+ */
+#define PMU_ENABLE 0x001 /* Enable counters */
+#define EVTMON_ENABLE 0x001 /* Enable EVTMON */
+#define PMN_RESET 0x002 /* Reset event counters */
+#define CCNT_RESET 0x004 /* Reset clock counter */
+#define PMU_RESET (CCNT_RESET | PMN_RESET)
+#define PMU_CNT64 0x008 /* Make CCNT count every 64th cycle */
+
+#define PMU_FLAG_CR0 0x080
+#define PMU_FLAG_CR1 0x100
+#define PMU_FLAG_CC 0x200
+
+/*!
+ * Different types of events that can be counted by the ARM11 PMU
+ * as used by Oprofile userspace.
+ */
+#define EVT_ICACHE_MISS 0x00
+#define EVT_STALL_INSTR 0x01
+#define EVT_DATA_STALL 0x02
+#define EVT_ITLB_MISS 0x03
+#define EVT_DTLB_MISS 0x04
+#define EVT_BRANCH 0x05
+#define EVT_BRANCH_MISS 0x06
+#define EVT_INSTRUCTION 0x07
+#define EVT_DCACHE_FULL_STALL_CONTIG 0x09
+#define EVT_DCACHE_ACCESS 0x0A
+#define EVT_DCACHE_MISS 0x0B
+#define EVT_DCACE_WRITE_BACK 0x0C
+#define EVT_PC_CHANGED 0x0D
+#define EVT_TLB_MISS 0x0F
+#define EVT_BCU_REQUEST 0x10
+#define EVT_BCU_FULL 0x11
+#define EVT_BCU_DRAIN 0x12
+#define EVT_ETMEXTOT0 0x20
+#define EVT_ETMEXTOT1 0x21
+/* EVT_CCNT is not hardware defined */
+#define EVT_CCNT 0xFE
+#define EVT_INCREMENT 0xFF
+#define EVT_UNUSED 0x100
+
+#define ECT_WORKAROUND
+
+#define COUNTER_MSB 0x80000000
+#define ENABLE_L2CACHE 0x1
+#define ENABLE_EVTBUS 0x100000
+#define PMU_OVERFLOWBIT_MASK 0x700
+#define VAR_NUM 0x0
+#define REV_NUM 0x2
+
+#ifdef ECT_WORKAROUND
+#define ENABLE_CTI_CLOCK 0x00000020
+#define UNLOCK_ECT_CODE 0x0ACCE550
+#define ECT_CTI_CHAN_2 0x4
+#define ECT_CTI_CHAN_3 0x8
+#define ECT_CTI_TRIGIN_1 1
+#define ECT_CTI_TRIGIN_7 7
+#define ECT_CTI_TRIGOUT_2 2
+#define ECT_CTI_TRIGOUT_6 6
+#define ENABLE_ECT 0x1
+#define ACK_TRIG_OUT_2 0x4
+#define EM_SET_INT L2EM_ENABLE_CNTINCRINT
+#define EVENT_OVERFLOW_INT INT_ECT
+#else
+#define EVENT_OVERFLOW_INT ARM11_PMU_IRQ
+#define EM_SET_INT L2EM_ENABLE_OVERFLOWINT
+#endif
+
+struct pmu_counter {
+ volatile unsigned long ovf;
+ unsigned long reset_counter;
+};
+
+static unsigned int r0p2_or_older_core;
+enum { CCNT, PMN0, PMN1, MAX_PMUCOUNTERS };
+enum { EMC0 = MAX_PMUCOUNTERS, EMC1, EMC2, EMC3, MAX_L2COUNTERS };
+
+static struct pmu_counter results[MAX_L2COUNTERS];
+
+struct pmu_type {
+ int id;
+ char *name;
+ int num_counters;
+ unsigned int int_enable;
+ unsigned int cnt_ovf[MAX_L2COUNTERS];
+ unsigned int int_mask[MAX_L2COUNTERS];
+};
+
+static struct pmu_type pmu_parms[] = {
+ {
+ .id = 0,
+ .name = "arm/arm11",
+ .num_counters = MAX_L2COUNTERS,
+ .int_mask = {[PMN0] = 0x10,[PMN1] = 0x20,
+ [CCNT] = 0x40,[EMC0] = 0x800,[EMC1] = 0x400,[EMC2] =
+ 0x200,[EMC3] = 0x100},
+ .cnt_ovf = {[CCNT] = 0x400,[PMN0] = 0x100,
+ [PMN1] = 0x200,[EMC0] = 0x1,[EMC1] = 0x2,[EMC2] =
+ 0x4,[EMC3] = 0x8},
+ },
+};
+
+static struct pmu_type *pmu;
+
+extern void l2_evtbus_enable(void);
+extern void l2_evtbus_disable(void);
+
+/*!
+ * function is used to write the EVTMON counter configuration register.
+ */
+static int l2em_configure_counter(int nr, int type)
+{
+ /* Configure the counter event source */
+ __raw_writel(((type << 2) & 0x7c), L2EM_CC(nr));
+ if (type)
+ __raw_writel((__raw_readl(L2EM_CC(nr)) | EM_SET_INT),
+ L2EM_CC(nr));
+
+ return 0;
+}
+
+/*!
+ * function is used to write the EVTMON counters
+ */
+static void write_l2counter(int nr, u32 val)
+{
+ __raw_writel(val, L2EM_CNT(nr));
+}
+
+/*!
+ * function is used to write the control register for the ARM11 performance counters
+ */
+static void write_pmnc(u32 val)
+{
+ pr_debug("PMC value written is %#08x\n", val);
+ __asm__ __volatile__("mcr p15, 0, %0, c15, c12, 0"::"r"(val));
+}
+
+/*!
+ * function is used to read the control register for the ARM11 performance counters
+ */
+static u32 read_pmnc(void)
+{
+ u32 val;
+ pr_debug("In function %s\n", __FUNCTION__);
+ __asm__ __volatile__("mrc p15, 0, %0, c15, c12, 0":"=r"(val));
+ pr_debug("PMC value read is %#08x\n", val);
+ return val;
+}
+
+/*!
+ * function is used to read the ARM11 performance counters
+ */
+static u32 read_counter(int counter)
+{
+ u32 val = 0;
+ pr_debug("In function %s\n", __FUNCTION__);
+
+ switch (counter) {
+ case CCNT:
+ __asm__ __volatile__("mrc p15, 0, %0, c15, c12, 1":"=r"(val));
+ break;
+ case PMN0:
+ __asm__ __volatile__("mrc p15, 0, %0, c15, c12, 2":"=r"(val));
+ break;
+ case PMN1:
+ __asm__ __volatile__("mrc p15, 0, %0, c15, c12, 3":"=r"(val));
+ break;
+ }
+
+ pr_debug("counter %d value read is %#08x\n", counter, val);
+ return val;
+}
+
+/*!
+ * function is used to write to the ARM11 performance counters
+ */
+static void write_counter(int counter, u32 val)
+{
+ pr_debug("counter %d value written is %#08x\n", counter, val);
+
+ switch (counter) {
+ case CCNT:
+ __asm__ __volatile__("mcr p15, 0, %0, c15, c12, 1": :"r"(val));
+ break;
+ case PMN0:
+ __asm__ __volatile__("mcr p15, 0, %0, c15, c12, 2": :"r"(val));
+ break;
+ case PMN1:
+ __asm__ __volatile__("mcr p15, 0, %0, c15, c12, 3": :"r"(val));
+ break;
+ }
+}
+
+/*!
+ * function is used to check the status of the ARM11 performance counters
+ */
+static int arm11_setup_ctrs(void)
+{
+ u32 pmnc = 0;
+ int i;
+
+ for (i = CCNT; i < MAX_L2COUNTERS; i++) {
+ if (counter_config[i].enabled)
+ continue;
+ counter_config[i].event = EVT_UNUSED;
+ }
+
+ if (counter_config[PMN0].enabled)
+ pmnc |= (counter_config[PMN0].event << 20);
+
+ if (counter_config[PMN1].enabled)
+ pmnc |= (counter_config[PMN1].event << 12);
+
+ pr_debug("arm11_setup_ctrs: pmnc: %#08x\n", pmnc);
+ write_pmnc(pmnc);
+
+ for (i = CCNT; i < MAX_L2COUNTERS; i++) {
+ if (counter_config[i].event == EVT_UNUSED) {
+ counter_config[i].event = 0;
+ pmu->int_enable &= ~pmu->int_mask[i];
+ pr_debug
+ ("arm11_setup_ctrs: The counter event is %d for counter%d\n",
+ counter_config[i].event, i);
+ continue;
+ }
+
+ results[i].reset_counter = counter_config[i].count;
+ if (i < MAX_PMUCOUNTERS)
+ write_counter(i, -(u32) counter_config[i].count);
+ else {
+ write_l2counter(i - EMC0,
+ -(u32) counter_config[i].count);
+ l2em_configure_counter(i - EMC0,
+ counter_config[i].event);
+ }
+ pmu->int_enable |= pmu->int_mask[i];
+ pr_debug
+ ("arm11_setup_ctrs: The values of int mask and enables are %x, %x\n",
+ pmu->int_mask[i], pmu->int_enable);
+
+ pr_debug("arm11_setup_ctrs: counter%d %#08x from %#08lx\n", i,
+ read_counter(i), counter_config[i].count);
+ }
+
+ return 0;
+}
+
+/*!
+ * function is the interrupt service handler for the ARM11 performance counters
+ */
+static irqreturn_t arm11_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
+{
+ int i;
+ u32 pmnc, emcs;
+
+ /* Disable L2_EVTMON */
+ emcs = __raw_readl(L2EM_STAT);
+ __raw_writel((__raw_readl(L2EM_CTRL) & ~EVTMON_ENABLE), L2EM_CTRL);
+
+ /* Disable ARM11 PMU while retaining interrupts and overflow bits */
+ pmnc = read_pmnc();
+ pmnc &= ~(PMU_ENABLE | PMU_OVERFLOWBIT_MASK);
+ write_pmnc(pmnc);
+
+ /* Read the overflow flag bits */
+ pmnc = read_pmnc();
+
+#ifdef ECT_WORKAROUND
+ for (i = CCNT; i < MAX_PMUCOUNTERS; i++) {
+#else
+ for (i = CCNT; i < MAX_L2COUNTERS; i++) {
+#endif
+ /* Process the counters only if respective overflow interrupt is enabled */
+ if (!(pmu->int_mask[i] & pmu->int_enable)) {
+ continue;
+ }
+
+ /* As per ARM11 errata ARM11 cores with revision less than or equal to R0P2
+ * have known bug i.e., missing overflow interrupt for two events(event
+ * no 0x7 and 0x22) due to double increament for cycle. In this case we will
+ * discard the sample as the pc value belongs to different interrupt.
+ */
+ if (r0p2_or_older_core && !(pmnc & pmu->cnt_ovf[i])
+ && !(read_counter(i) & COUNTER_MSB)) {
+ write_counter(i, -(u32) (results[i].reset_counter));
+ }
+
+ /* Check for the overflowed counter by checking set overflow flag bits */
+ if (!(pmnc & pmu->cnt_ovf[i]) && !(emcs & pmu->cnt_ovf[i])) {
+ continue;
+ }
+
+ /* Reload the overflowed counter with preset value and
+ * add the sample for respective event.
+ */
+ pr_debug("arm11_pmu_interrupt: writing to file\n");
+ if (i < MAX_PMUCOUNTERS)
+ write_counter(i, -(u32) results[i].reset_counter);
+ else
+ write_l2counter(i - EMC0,
+ -(u32) counter_config[i].count);
+
+ oprofile_add_sample(regs, i);
+ }
+
+ /* Clear overflow flags */
+ write_pmnc(pmnc);
+
+#ifdef ECT_WORKAROUND
+ /*
+ * If ECTTRIGOUT signal is interrupt it should be acknowledged
+ * until trigger is off.
+ */
+ while (__raw_readl(ECT_CTI_TRIGOUTSTATUS) & ECT_CTI_CHAN_2)
+ __raw_writel(ACK_TRIG_OUT_2, ECT_CTI_INTACK);
+#endif
+
+ /* Re-enable ARM11 PMU */
+ pmnc |= PMU_ENABLE;
+ write_pmnc(pmnc);
+
+ /* Re-enable L2_EVTMON */
+ __raw_writel((__raw_readl(L2EM_CTRL) | L2EM_ENABLE_MASK), L2EM_CTRL);
+
+ return IRQ_HANDLED;
+}
+
+/*!
+ * function used to start the ARM11 performance counters
+ */
+static void arm11_pmu_stop(void)
+{
+ u32 pmnc = read_pmnc();
+
+ pmnc &= ~PMU_ENABLE;
+ write_pmnc(pmnc);
+ /* Disable the EVTMON */
+ __raw_writel((__raw_readl(L2EM_CTRL) & ~EVTMON_ENABLE), L2EM_CTRL);
+
+ /* Disable the EVTBUS */
+ l2_evtbus_disable();
+
+ free_irq(EVENT_OVERFLOW_INT, results);
+}
+
+/*!
+ * function used to start the ARM11 performance counters
+ */
+static int arm11_pmu_start(void)
+{
+ int ret;
+ u32 pmnc = read_pmnc();
+
+ ret = request_irq(EVENT_OVERFLOW_INT, arm11_pmu_interrupt, SA_INTERRUPT,
+ "ARM11 PMU", (void *)results);
+ pr_debug("requested IRQ\n");
+
+ if (ret < 0) {
+ printk(KERN_ERR
+ "oprofile: unable to request IRQ%d for ARM11 PMU\n",
+ ARM11_PMU_IRQ);
+ return ret;
+ }
+
+ /* Enable the EVTBUS */
+ l2_evtbus_enable();
+
+#ifdef ECT_WORKAROUND
+ __raw_writel(ENABLE_CTI_CLOCK, CLKCTL_SET_CTRL);
+ /* Unlock the AHB Interface */
+ __raw_writel(UNLOCK_ECT_CODE, ECT_CTI_LOCK);
+ /* Trigger to Channel Mapping */
+ __raw_writel(ECT_CTI_CHAN_2, ECT_CTI_INEN(ECT_CTI_TRIGIN_1));
+ /* Channel to triggers mapping */
+ __raw_writel(ECT_CTI_CHAN_2, ECT_CTI_OUTEN(ECT_CTI_TRIGOUT_2));
+ /* Trigger to Channel Mapping */
+ __raw_writel(ECT_CTI_CHAN_3, ECT_CTI_INEN(ECT_CTI_TRIGIN_7));
+ /* Channel to triggers mapping */
+ __raw_writel(ECT_CTI_CHAN_3, ECT_CTI_OUTEN(ECT_CTI_TRIGOUT_6));
+ /* Enable CTI Logic */
+ __raw_writel(ENABLE_ECT, ECT_CTI_CONTROL);
+#endif
+ pmnc |= pmu->int_enable;
+ pmnc |= PMU_ENABLE;
+
+ write_pmnc(pmnc);
+ pr_debug("arm11_pmu_start: pmnc: %#08x mask: %08x\n", pmnc,
+ pmu->int_enable);
+
+ /* Enable EVTMON with Edge triggered interrupt of one Clock Cycle */
+ __raw_writel((__raw_readl(L2EM_CTRL) |
+ (L2EM_INT_EDGE | L2EM_INT_CLK_CYCLES)), L2EM_CTRL);
+ __raw_writel((__raw_readl(L2EM_CTRL) | L2EM_ENABLE_MASK), L2EM_CTRL);
+
+ return 0;
+}
+
+/*!
+ * function detect the ARM11 performance counters
+ */
+static int arm11_detect_pmu(void)
+{
+ int ret = 0;
+ u32 id, rev;
+
+ id = (read_cpuid(CPUID_ID) >> 0x10) & 0xF;
+
+ switch (id) {
+ case 7:
+ pmu = &pmu_parms[0];
+ rev = read_cpuid(CPUID_ID);
+ /* Check if the ARM11 core is less than or equal to R0P2 */
+ if ((((rev >> 0x14) & 0xF) == VAR_NUM)
+ && (((rev & 0xF) <= REV_NUM))) {
+ r0p2_or_older_core = 1;
+ }
+ break;
+ default:
+ ret = -ENODEV;
+ break;
+ }
+
+ if (!ret) {
+ op_arm_spec.name = pmu->name;
+ op_arm_spec.num_counters = pmu->num_counters;
+ pr_debug("arm11_detect_pmu: detected %s PMU\n", pmu->name);
+ }
+
+ return ret;
+}
+
+struct op_arm_model_spec op_arm_spec = {
+ .init = arm11_detect_pmu,
+ .setup_ctrs = arm11_setup_ctrs,
+ .start = arm11_pmu_start,
+ .stop = arm11_pmu_stop,
+};
diff --git a/arch/arm/oprofile/op_model_arm11_core.c b/arch/arm/oprofile/op_model_arm11_core.c
index ad80752cb9fb..86b7d86bb721 100644
--- a/arch/arm/oprofile/op_model_arm11_core.c
+++ b/arch/arm/oprofile/op_model_arm11_core.c
@@ -13,7 +13,12 @@
#include "op_counter.h"
#include "op_arm_model.h"
#include "op_model_arm11_core.h"
+#include "evtmon_regs.h"
+#define NEED_OPROFILE_CCNT_FIX
+#ifdef NEED_OPROFILE_CCNT_FIX /* Workaround to correctly map from user space counters to kernel space counters */
+struct op_counter_config tmp;
+#endif
/*
* ARM11 PMU support
*/
@@ -63,6 +68,12 @@ int arm11_setup_pmu(void)
arm11_write_pmnc(PMCR_OFL_PMN0 | PMCR_OFL_PMN1 | PMCR_OFL_CCNT |
PMCR_C | PMCR_P);
+#ifdef NEED_OPROFILE_CCNT_FIX /* Workaround to correctly map from user space counters to kernel space counters */
+ tmp = counter_config[PMN0];
+ counter_config[PMN0] = counter_config[PMN1];
+ counter_config[PMN1] = counter_config[CCNT];
+ counter_config[CCNT] = tmp;
+#endif
for (pmnc = 0, cnt = PMN0; cnt <= CCNT; cnt++) {
unsigned long event;
@@ -119,16 +130,49 @@ static irqreturn_t arm11_pmu_interrupt(int irq, void *arg)
unsigned int cnt;
u32 pmnc;
+#ifdef ECT_WORKAROUND
+ /* Disable L2_EVTMON */
+ __raw_writel((__raw_readl(L2EM_CTRL) & ~EVTMON_ENABLE), L2EM_CTRL);
+
+ /* Disable ARM11 PMU while retaining interrupts and overflow bits */
+ pmnc = arm11_read_pmnc();
+ pmnc &= ~(PMU_ENABLE | PMU_OVERFLOWBIT_MASK);
+ arm11_write_pmnc(pmnc);
+
+ while (__raw_readl(ECT_CTI_TRIGOUTSTATUS) & ECT_CTI_CHAN_2)
+ __raw_writel(ACK_TRIG_OUT_2, ECT_CTI_INTACK);
+
+ pmnc = arm11_read_pmnc();
+
+ /* Re-enable ARM11 PMU */
+ pmnc |= PMU_ENABLE;
+ arm11_write_pmnc(pmnc);
+
+ /* Re-enable L2_EVTMON */
+ __raw_writel((__raw_readl(L2EM_CTRL) | L2EM_ENABLE_MASK), L2EM_CTRL);
+#else
pmnc = arm11_read_pmnc();
+#endif
for (cnt = PMN0; cnt <= CCNT; cnt++) {
if ((pmnc & (PMCR_OFL_PMN0 << cnt)) && (pmnc & (PMCR_IEN_PMN0 << cnt))) {
arm11_reset_counter(cnt);
+#ifdef NEED_OPROFILE_CCNT_FIX /* Workaround to correctly map from user space counters to kernel space counters */
+ if (cnt == PMN0)
+ oprofile_add_sample(regs, CPU_COUNTER(smp_processor_id(), PMN1));
+ else if (cnt == PMN1)
+ oprofile_add_sample(regs, CPU_COUNTER(smp_processor_id(), CCNT));
+ else if (cnt == CCNT)
+ oprofile_add_sample(regs, CPU_COUNTER(smp_processor_id(), PMN0));
+#else
oprofile_add_sample(regs, CPU_COUNTER(smp_processor_id(), cnt));
+#endif
}
}
+#ifndef ECT_WORKAROUND
/* Clear counter flag(s) */
arm11_write_pmnc(pmnc);
+#endif
return IRQ_HANDLED;
}
diff --git a/arch/arm/oprofile/op_model_arm11_core.h b/arch/arm/oprofile/op_model_arm11_core.h
index 6f8538e5a960..b59d15107d8d 100644
--- a/arch/arm/oprofile/op_model_arm11_core.h
+++ b/arch/arm/oprofile/op_model_arm11_core.h
@@ -35,6 +35,8 @@
#define CCNT 2
#define CPU_COUNTER(cpu, counter) ((cpu) * 3 + (counter))
+#define PMU_ENABLE 0x001 /* Enable counters */
+#define PMU_OVERFLOWBIT_MASK 0x700
int arm11_setup_pmu(void);
int arm11_start_pmu(void);
@@ -42,4 +44,15 @@ int arm11_stop_pmu(void);
int arm11_request_interrupts(int *, int);
void arm11_release_interrupts(int *, int);
+#ifdef CONFIG_OPROFILE_ARM11_EVTMON
+extern int arm11_evtmon_setup_ctrs(void);
+extern void arm11_evtmon_stop(void);
+extern int arm11_evtmon_start(void);
+extern int arm11_evtmon_detect(void);
+#else
+#define arm11_evtmon_setup_ctrs() do {} while(0)
+#define arm11_evtmon_stop() do {} while(0)
+#define arm11_evtmon_start() do {} while(0)
+#define arm11_evtmon_detect() do {} while(0)
+#endif
#endif
diff --git a/arch/arm/oprofile/op_model_arm11_evtmon.c b/arch/arm/oprofile/op_model_arm11_evtmon.c
new file mode 100644
index 000000000000..5ac3fa1f074a
--- /dev/null
+++ b/arch/arm/oprofile/op_model_arm11_evtmon.c
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup MXC_Oprofile ARM11 EVTMON Driver for Oprofile
+ */
+
+/*!
+ * @file op_model_arm11_evtmon.c
+ *
+ *Based on the op_model_xscale.c driver by author Zwane Mwaikambo
+ *
+ * @ingroup MXC_Oprofile
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/oprofile.h>
+#include <linux/interrupt.h>
+#include <mach/hardware.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+
+#include "op_counter.h"
+#include "op_arm_model.h"
+#include "evtmon_regs.h"
+
+struct pmu_counter {
+ volatile unsigned long ovf;
+ unsigned long reset_counter;
+};
+
+enum { EMC0 = MAX_PMUCOUNTERS, EMC1, EMC2, EMC3, MAX_L2COUNTERS };
+
+static struct pmu_counter results[MAX_L2COUNTERS];
+
+struct pmu_type {
+ int id;
+ char *name;
+ int num_counters;
+ unsigned int int_enable;
+ unsigned int cnt_ovf[MAX_L2COUNTERS];
+ unsigned int int_mask[MAX_L2COUNTERS];
+};
+
+static struct pmu_type pmu_parms[] = {
+ {
+ .id = 0,
+ .int_mask = {[EMC0] = 0x800,[EMC1] = 0x400,[EMC2] =
+ 0x200,[EMC3] = 0x100},
+ .cnt_ovf = {[EMC0] = 0x1,[EMC1] = 0x2,[EMC2] = 0x4,[EMC3] = 0x8},
+ },
+};
+
+static struct pmu_type *pmu;
+
+extern void l2x0_evtbus_enable(void);
+extern void l2x0_evtbus_disable(void);
+
+/*!
+ * function is used to write the EVTMON counter configuration register.
+ */
+int l2em_configure_counter(int nr, int type)
+{
+ /* Configure the counter event source */
+ __raw_writel(((type << 2) & 0x7c), L2EM_CC(nr));
+ if (type)
+ __raw_writel((__raw_readl(L2EM_CC(nr)) | EM_SET_INT),
+ L2EM_CC(nr));
+
+ return 0;
+}
+
+/*!
+ * function is used to write the EVTMON counters
+ */
+void write_l2counter(int nr, u32 val)
+{
+ __raw_writel(val, L2EM_CNT(nr));
+}
+
+/*!
+ * function is used to check the status of the ARM11 evtmon counters
+ */
+int arm11_evtmon_setup_ctrs(void)
+{
+ int i;
+
+ for (i = EMC0; i < MAX_L2COUNTERS; i++) {
+ if (counter_config[i].enabled)
+ continue;
+ counter_config[i].event = EVT_UNUSED;
+ }
+
+ for (i = EMC0; i < MAX_L2COUNTERS; i++) {
+ if (counter_config[i].event == EVT_UNUSED) {
+ counter_config[i].event = 0;
+ pmu->int_enable &= ~pmu->int_mask[i];
+ pr_debug
+ ("arm11_setup_ctrs: The counter event is %lu for counter%d\n",
+ counter_config[i].event, i);
+ continue;
+ }
+
+ results[i].reset_counter = counter_config[i].count;
+ write_l2counter(i - EMC0, -(u32) counter_config[i].count);
+ l2em_configure_counter(i - EMC0, counter_config[i].event);
+
+ pmu->int_enable |= pmu->int_mask[i];
+ pr_debug
+ ("arm11_setup_ctrs: The values of int mask and enables are %x, %x\n",
+ pmu->int_mask[i], pmu->int_enable);
+
+ }
+
+ return 0;
+}
+
+/*!
+ * function used to start the ARM11 evtmon counters
+ */
+void arm11_evtmon_stop(void)
+{
+
+ /* Disable the EVTMON */
+ __raw_writel((__raw_readl(L2EM_CTRL) & ~EVTMON_ENABLE), L2EM_CTRL);
+
+ /* Disable the EVTBUS */
+ l2x0_evtbus_disable();
+
+}
+
+/*!
+ * function used to start the ARM11 evtmon counters
+ */
+int arm11_evtmon_start(void)
+{
+
+ /* Enable the EVTBUS */
+ l2x0_evtbus_enable();
+
+#ifdef ECT_WORKAROUND
+ __raw_writel(ENABLE_CTI_CLOCK, CLKCTL_SET_CTRL);
+ /* Unlock the AHB Interface */
+ __raw_writel(UNLOCK_ECT_CODE, ECT_CTI_LOCK);
+ /* Trigger to Channel Mapping */
+ __raw_writel(ECT_CTI_CHAN_2, ECT_CTI_INEN(ECT_CTI_TRIGIN_1));
+ /* Channel to triggers mapping */
+ __raw_writel(ECT_CTI_CHAN_2, ECT_CTI_OUTEN(ECT_CTI_TRIGOUT_2));
+ /* Trigger to Channel Mapping */
+ __raw_writel(ECT_CTI_CHAN_3, ECT_CTI_INEN(ECT_CTI_TRIGIN_7));
+ /* Channel to triggers mapping */
+ __raw_writel(ECT_CTI_CHAN_3, ECT_CTI_OUTEN(ECT_CTI_TRIGOUT_6));
+ /* Enable CTI Logic */
+ __raw_writel(ENABLE_ECT, ECT_CTI_CONTROL);
+#endif
+
+ /* Enable EVTMON with Edge triggered interrupt of one Clock Cycle */
+ __raw_writel((__raw_readl(L2EM_CTRL) |
+ (L2EM_INT_EDGE | L2EM_INT_CLK_CYCLES)), L2EM_CTRL);
+ __raw_writel((__raw_readl(L2EM_CTRL) | L2EM_ENABLE_MASK), L2EM_CTRL);
+
+ return 0;
+}
+
+/*!
+ * function detect the ARM11 evtmon counters
+ */
+int arm11_evtmon_detect(void)
+{
+ int ret = 0;
+
+ pmu = &pmu_parms[0];
+ op_armv6_spec.num_counters = MAX_L2COUNTERS;
+
+ return ret;
+}
diff --git a/arch/arm/oprofile/op_model_v6.c b/arch/arm/oprofile/op_model_v6.c
index fe581383d3e2..a8bf2ab6cd0d 100644
--- a/arch/arm/oprofile/op_model_v6.c
+++ b/arch/arm/oprofile/op_model_v6.c
@@ -28,16 +28,21 @@
#include "op_counter.h"
#include "op_arm_model.h"
#include "op_model_arm11_core.h"
+#include "evtmon_regs.h"
static int irqs[] = {
#ifdef CONFIG_ARCH_OMAP2
3,
#endif
+#ifdef CONFIG_ARCH_MXC
+ EVENT_OVERFLOW_INT,
+#endif
};
static void armv6_pmu_stop(void)
{
arm11_stop_pmu();
+ arm11_evtmon_stop();
arm11_release_interrupts(irqs, ARRAY_SIZE(irqs));
}
@@ -46,21 +51,31 @@ static int armv6_pmu_start(void)
int ret;
ret = arm11_request_interrupts(irqs, ARRAY_SIZE(irqs));
- if (ret >= 0)
+ if (ret >= 0){
ret = arm11_start_pmu();
+ arm11_evtmon_start();
+ }
return ret;
}
+static int armv6_setup_pmu(void)
+{
+ arm11_setup_pmu();
+ arm11_evtmon_setup_ctrs();
+ return 0;
+}
+
static int armv6_detect_pmu(void)
{
+ arm11_evtmon_detect();
return 0;
}
struct op_arm_model_spec op_armv6_spec = {
.init = armv6_detect_pmu,
.num_counters = 3,
- .setup_ctrs = arm11_setup_pmu,
+ .setup_ctrs = armv6_setup_pmu,
.start = armv6_pmu_start,
.stop = armv6_pmu_stop,
.name = "arm/armv6",
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index b2a7e3fad117..4a00d04dfd8c 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -6,32 +6,144 @@ choice
prompt "MXC/iMX Base Type"
default ARCH_MX3
-config ARCH_MX2
- bool "MX2-based"
- help
- This enables support for systems based on the Freescale i.MX2 family
+config ARCH_MX37
+ bool "MX37-based"
+ help
+ This enables support for systems based on Freescale i.MX37
+
+config ARCH_MX35
+ bool "MX35-based"
+ help
+ This enables support for systems based on Freescale i.MX35
+
+config ARCH_MX51
+ bool "MX51-based"
+ help
+ This enables support for systems based on Freescale i.MX51
config ARCH_MX3
bool "MX3-based"
help
- This enables support for systems based on the Freescale i.MX3 family
+ This enables support for systems based on the Freescale i.MX31 and i.MX32
+
+config ARCH_MX27
+ bool "MX27-based"
+ help
+ This enables support for systems based on the Freescale i.MX27
+
+config ARCH_MX25
+ bool "MX25-based"
+ select MX25_OPTIONSS
+ help
+ This enables support for systems based on the Freescale i.MX25
endchoice
-source "arch/arm/mach-mx2/Kconfig"
+source "arch/arm/mach-mx27/Kconfig"
+
+source "arch/arm/mach-mx25/Kconfig"
+
source "arch/arm/mach-mx3/Kconfig"
+source "arch/arm/mach-mx35/Kconfig"
+
+source "arch/arm/mach-mx37/Kconfig"
+
+source "arch/arm/mach-mx51/Kconfig"
+
endmenu
-config MXC_IRQ_PRIOR
- bool "Use IRQ priority"
+config MXC_TZIC
+ bool
+ depends on ARCH_MXC
+
+config MXC_DSP_BRINGUP
+ bool
+ depends on ARCH_MXC
+
+config ARCH_HAS_EVTMON
+ bool
depends on ARCH_MXC
+
+config MXC_EMMA
+ bool
+ depends on ARCH_MXC
+
+config MXC_FB_IRAM
+ bool
+ depends on ARCH_MXC
+
+config DMA_ZONE_SIZE
+ int "DMA memory zone size"
+ range 0 64
+ default 24
help
- Select this if you want to use prioritized IRQ handling.
- This feature prevents higher priority ISR to be interrupted
- by lower priority IRQ even IRQF_DISABLED flag is not set.
- This may be useful in embedded applications, where are strong
- requirements for timing.
- Say N here, unless you have a specialized requirement.
+ This is the size in MB for the DMA zone. The DMA zone is used for
+ dedicated memory for large contiguous video buffers
+
+# set iff we need the 1504 transceiver code
+config ISP1504_MXC
+ bool
+ select ISP1504_MXC_OTG if USB_GADGET && USB_EHCI_HCD && USB_OTG
+ default y if USB_EHCI_FSL_1504 || USB_GADGET_FSL_1504
+
+config ISP1504_MXC_OTG
+ tristate
+ help
+ Support for USB OTG pin detect using the ISP1504 transceiver on MXC platforms.
+
+# set iff we need the UTMI transceiver code
+config UTMI_MXC
+ bool
+ select UTMI_MXC_OTG if ARCH_MX25 && USB_GADGET && USB_EHCI_HCD && USB_OTG
+ default y if USB_EHCI_FSL_UTMI || USB_GADGET_FSL_UTMI
+ depends on ARCH_MX25 || ARCH_MX35 || ARCH_MX37 || ARCH_MX51
+
+config UTMI_MXC_OTG
+ tristate
+ help
+ Support for USB OTG pin detect using the UTMI transceiver on MXC platforms.
+
+# set iff we need the 1301 transceiver code
+config ISP1301_MXC
+ bool
+ default y if USB_EHCI_FSL_1301 || USB_GADGET_FSL_1301
+ select I2C_MXC
+
+# set iff we need the mx13783 transceiver code
+config MC13783_MXC
+ bool
+ default y if USB_EHCI_FSL_MC13783 || USB_GADGET_FSL_MC13783
+ select SPI_MXC
+
+choice
+ prompt "Select serial USB transceiver mode"
+ depends on ISP1301_MXC || MC13783_MXC
+ default MXC_USB_SU6
+
+config MXC_USB_SU6
+ bool "Single Ended Unidirectional Mode"
+ help
+ If you say yes to this option, the serial tranceiver operates in SU6 mode.
+ This option will work for either the Freescale MC13783 or Philips ISP1301
+ transceiver.
+
+config MXC_USB_SB3
+ bool "Single Ended Bidirectional Mode"
+ help
+ If you say yes to this option, the serial tranceiver operates in SB3 mode.
+ Not recommended for the Freescale MC13783.
+
+config MXC_USB_DU6
+ bool "Differential Unidirectional Mode"
+ help
+ If you say yes to this option, the serial tranceiver operates in DU6 mode.
+
+config MXC_USB_DB4
+ bool "Differential Bidirectional Mode"
+ help
+ If you say yes to this option, the serial tranceiver operates in DB4 mode.
+
+endchoice
endif
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 067556f7c91f..cc7812c87911 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -3,6 +3,56 @@
#
# Common support
-obj-y := irq.o clock.o gpio.o time.o devices.o
+obj-y := cpu_common.o gpio.o clock.o wdog.o snoop.o io.o time.o
obj-$(CONFIG_ARCH_MX2) += iomux-mx1-mx2.o dma-mx1-mx2.o
+
+ifneq ($(CONFIG_ARCH_MX27),y)
+obj-y += spba.o sdma/
+endif
+
+ifeq ($(CONFIG_MXC_TZIC),y)
+obj-y += tzic.o
+else
+obj-y += irq.o
+endif
+
+obj-$(CONFIG_ARCH_MX27) += dma_mx2.o usb_common.o
+obj-$(CONFIG_ARCH_MX3) += dptc.o usb_common.o entry-pm.o
+obj-$(CONFIG_ARCH_MX35) += usb_common.o serialxc.o
+obj-$(CONFIG_ARCH_MX37) += usb_common.o utmixc.o dptc.o dvfs_core.o
+obj-$(CONFIG_ARCH_MX51) += usb_common.o utmixc.o dvfs_core.o
+
+# LEDs support
+obj-$(CONFIG_LEDS) += leds.o
+
+# CPU FREQ support
+obj-$(CONFIG_CPU_FREQ_IMX) += cpufreq.o
+
+# USB support
+obj-$(CONFIG_ISP1504_MXC) += isp1504xc.o
+obj-$(CONFIG_ISP1301_MXC) += isp1301xc.o
+obj-$(CONFIG_MC13783_MXC) += mc13783_xc.o
+
+# obj-$(CONFIG_USB_EHCI_FSL_UTMI) += utmixc.o
+ifneq ($(strip $(CONFIG_USB_EHCI_FSL_UTMI) $(CONFIG_USB_GADGET_FSL_UTMI)),)
+obj-y += utmixc.o
+endif
+
+ifneq ($(CONFIG_USB_EHCI_ARC_H1),)
+ifneq ($(CONFIG_ARCH_MX51),y)
+obj-y += serialxc.o
+else
+obj-y += isp1504xc.o
+endif
+endif
+
+ifneq ($(CONFIG_ARCH_MX25)$(CONFIG_USB),)
+obj-y += usb_common.o
+endif
+
+ifeq ($(CONFIG_ARCH_MX25),y)
+ifneq ($(CONFIG_USB_EHCI_ARC_H2),)
+obj-y += serialxc.o
+endif
+endif
diff --git a/arch/arm/plat-mxc/clock.c b/arch/arm/plat-mxc/clock.c
index 0a38f0b396eb..b55a03f7b0f0 100644
--- a/arch/arm/plat-mxc/clock.c
+++ b/arch/arm/plat-mxc/clock.c
@@ -4,7 +4,7 @@
* Copyright (C) 2004 - 2005 Nokia corporation
* Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
* Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
- * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de
*
* This program is free software; you can redistribute it and/or
@@ -25,6 +25,7 @@
/* #define DEBUG */
#include <linux/clk.h>
+#include <linux/cpufreq.h>
#include <linux/err.h>
#include <linux/errno.h>
#include <linux/init.h>
@@ -42,6 +43,7 @@
static LIST_HEAD(clocks);
static DEFINE_MUTEX(clocks_mutex);
+static DEFINE_SPINLOCK(clockfw_lock);
/*-------------------------------------------------------------------------
* Standard clock functions defined in include/linux/clk.h
@@ -113,14 +115,16 @@ EXPORT_SYMBOL(clk_get);
static void __clk_disable(struct clk *clk)
{
- if (clk == NULL || IS_ERR(clk))
+ if (clk == NULL || IS_ERR(clk) || !clk->usecount)
return;
- __clk_disable(clk->parent);
- __clk_disable(clk->secondary);
+ if (!(--clk->usecount)) {
+ if (clk->disable)
+ clk->disable(clk);
- if (!(--clk->usecount) && clk->disable)
- clk->disable(clk);
+ __clk_disable(clk->parent);
+ __clk_disable(clk->secondary);
+ }
}
static int __clk_enable(struct clk *clk)
@@ -128,12 +132,13 @@ static int __clk_enable(struct clk *clk)
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
- __clk_enable(clk->parent);
- __clk_enable(clk->secondary);
-
- if (clk->usecount++ == 0 && clk->enable)
- clk->enable(clk);
+ if (clk->usecount++ == 0) {
+ __clk_enable(clk->parent);
+ __clk_enable(clk->secondary);
+ if (clk->enable)
+ clk->enable(clk);
+ }
return 0;
}
@@ -142,15 +147,23 @@ static int __clk_enable(struct clk *clk)
*/
int clk_enable(struct clk *clk)
{
+ unsigned long flags;
int ret = 0;
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
- mutex_lock(&clocks_mutex);
+ spin_lock_irqsave(&clockfw_lock, flags);
+
ret = __clk_enable(clk);
- mutex_unlock(&clocks_mutex);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+#if defined(CONFIG_CPU_FREQ)
+ if ((clk->flags & CPU_FREQ_TRIG_UPDATE)
+ && (clk_get_usecount(clk) == 1))
+ cpufreq_update_policy(0);
+#endif
return ret;
}
EXPORT_SYMBOL(clk_enable);
@@ -161,15 +174,44 @@ EXPORT_SYMBOL(clk_enable);
*/
void clk_disable(struct clk *clk)
{
+ unsigned long flags;
+
if (clk == NULL || IS_ERR(clk))
return;
- mutex_lock(&clocks_mutex);
+ spin_lock_irqsave(&clockfw_lock, flags);
+
__clk_disable(clk);
- mutex_unlock(&clocks_mutex);
+
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+#if defined(CONFIG_CPU_FREQ)
+ if ((clk->flags & CPU_FREQ_TRIG_UPDATE)
+ && (clk_get_usecount(clk) == 0))
+ cpufreq_update_policy(0);
+#endif
}
EXPORT_SYMBOL(clk_disable);
+/*!
+ * @brief Function to get the usage count for the requested clock.
+ *
+ * This function returns the reference count for the clock.
+ *
+ * @param clk Handle to clock to disable.
+ *
+ * @return Returns the usage count for the requested clock.
+ */
+int clk_get_usecount(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return 0;
+
+ return clk->usecount;
+}
+
+EXPORT_SYMBOL(clk_get_usecount);
+
/* Retrieve the *current* clock rate. If the clock itself
* does not provide a special calculation routine, ask
* its parent and so on, until one is able to return
@@ -180,10 +222,7 @@ unsigned long clk_get_rate(struct clk *clk)
if (clk == NULL || IS_ERR(clk))
return 0UL;
- if (clk->get_rate)
- return clk->get_rate(clk);
-
- return clk_get_rate(clk->parent);
+ return clk->rate;
}
EXPORT_SYMBOL(clk_get_rate);
@@ -208,19 +247,48 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
}
EXPORT_SYMBOL(clk_round_rate);
+/* Propagate rate to children */
+void propagate_rate(struct clk *tclk)
+{
+ struct clk *clkp;
+
+ if (tclk == NULL || IS_ERR(tclk))
+ return;
+
+ pr_debug("mxc clock: finding children of %s-%d\n", tclk->name,
+ tclk->id);
+ list_for_each_entry(clkp, &clocks, node) {
+ if (likely(clkp->parent != tclk))
+ continue;
+ pr_debug("mxc clock: %s-%d: recalculating rate: old = %lu, ",
+ clkp->name, clkp->id, clkp->rate);
+ if (likely((u32) clkp->recalc))
+ clkp->recalc(clkp);
+ else
+ clkp->rate = tclk->rate;
+ pr_debug("new = %lu\n", clkp->rate);
+ propagate_rate(clkp);
+ }
+}
+
/* Set the clock to the requested clock rate. The rate must
* match a supported rate exactly based on what clk_round_rate returns
*/
int clk_set_rate(struct clk *clk, unsigned long rate)
{
+ unsigned long flags;
int ret = -EINVAL;
if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0)
return ret;
- mutex_lock(&clocks_mutex);
+ spin_lock_irqsave(&clockfw_lock, flags);
+
ret = clk->set_rate(clk, rate);
- mutex_unlock(&clocks_mutex);
+ if (unlikely((ret == 0) && (clk->flags & RATE_PROPAGATES)))
+ propagate_rate(clk);
+
+ spin_unlock_irqrestore(&clockfw_lock, flags);
return ret;
}
@@ -229,17 +297,35 @@ EXPORT_SYMBOL(clk_set_rate);
/* Set the clock's parent to another clock source */
int clk_set_parent(struct clk *clk, struct clk *parent)
{
+ unsigned long flags;
int ret = -EINVAL;
+ struct clk *prev_parent = clk->parent;
if (clk == NULL || IS_ERR(clk) || parent == NULL ||
IS_ERR(parent) || clk->set_parent == NULL)
return ret;
- mutex_lock(&clocks_mutex);
+ if (clk->usecount != 0) {
+ clk_enable(parent);
+ }
+
+ spin_lock_irqsave(&clockfw_lock, flags);
ret = clk->set_parent(clk, parent);
- if (ret == 0)
+ if (ret == 0) {
clk->parent = parent;
- mutex_unlock(&clocks_mutex);
+ if (clk->recalc) {
+ clk->recalc(clk);
+ } else {
+ clk->rate = parent->rate;
+ }
+ if (unlikely(clk->flags & RATE_PROPAGATES))
+ propagate_rate(clk);
+ }
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ if (clk->usecount != 0) {
+ clk_disable(prev_parent);
+ }
return ret;
}
diff --git a/arch/arm/plat-mxc/cpu_common.c b/arch/arm/plat-mxc/cpu_common.c
new file mode 100644
index 000000000000..f9edd6b04404
--- /dev/null
+++ b/arch/arm/plat-mxc/cpu_common.c
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <asm/setup.h>
+extern int mxc_early_serial_console_init(char *);
+
+/*!
+ * @file plat-mxc/cpu_common.c
+ *
+ * @brief This file contains the common CPU initialization code.
+ *
+ * @ingroup MSL_MX31 MSL_MXC91321
+ */
+
+static void __init system_rev_setup(char **p)
+{
+ system_rev = simple_strtoul(*p, NULL, 16);
+}
+
+__early_param("system_rev=", system_rev_setup);
+
+int mxc_jtag_enabled; /* OFF: 0 (default), ON: 1 */
+
+/*
+ * Here are the JTAG options from the command line. By default JTAG
+ * is OFF which means JTAG is not connected and WFI is enabled
+ *
+ * "on" -- JTAG is connected, so WFI is disabled
+ * "off" -- JTAG is disconnected, so WFI is enabled
+ */
+
+static void __init jtag_wfi_setup(char **p)
+{
+ if (memcmp(*p, "on", 2) == 0) {
+ mxc_jtag_enabled = 1;
+ *p += 2;
+ } else if (memcmp(*p, "off", 3) == 0) {
+ mxc_jtag_enabled = 0;
+ *p += 3;
+ }
+}
+
+__early_param("jtag=", jtag_wfi_setup);
+
+void __init mxc_cpu_common_init(void)
+{
+ pr_info("CPU is %s%x Revision %u.%u\n",
+ (mxc_cpu() < 0x100) ? "i.MX" : "MXC",
+ mxc_cpu(), mxc_cpu_rev_major(), mxc_cpu_rev_minor());
+}
+
+/**
+ * early_console_setup - setup debugging console
+ *
+ * Consoles started here require little enough setup that we can start using
+ * them very early in the boot process, either right after the machine
+ * vector initialization, or even before if the drivers can detect their hw.
+ *
+ * Returns non-zero if a console couldn't be setup.
+ * This function is developed based on
+ * early_console_setup function as defined in arch/ia64/kernel/setup.c
+ */
+int __init early_console_setup(char *cmdline)
+{
+ int earlycons = 0;
+
+#ifdef CONFIG_SERIAL_MXC_CONSOLE
+ if (!mxc_early_serial_console_init(cmdline))
+ earlycons++;
+#endif
+
+ return (earlycons) ? 0 : -1;
+}
diff --git a/arch/arm/plat-mxc/cpufreq.c b/arch/arm/plat-mxc/cpufreq.c
new file mode 100644
index 000000000000..eacd6544fb92
--- /dev/null
+++ b/arch/arm/plat-mxc/cpufreq.c
@@ -0,0 +1,595 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file cpufreq.c
+ *
+ * @brief A driver for the Freescale Semiconductor i.MXC CPUfreq module.
+ *
+ * The CPUFREQ driver is for controling CPU frequency. It allows you to change
+ * the CPU clock speed on the fly.
+ *
+ * @ingroup PM
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/cpufreq.h>
+#include <linux/init.h>
+#include <linux/proc_fs.h>
+#include <linux/regulator/regulator.h>
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <asm/setup.h>
+#include <mach/clock.h>
+#include <asm/cacheflush.h>
+
+int low_bus_freq_mode;
+int high_bus_freq_mode;
+int cpu_freq_khz_min;
+int cpu_freq_khz_max;
+int arm_lpm_clk;
+int arm_normal_clk;
+char *gp_reg_id = "SW1";
+char *lp_reg_id = "SW2";
+int axi_c_clk_support;
+
+static struct clk *cpu_clk;
+static struct clk *main_bus_clk;
+static struct clk *pll2;
+static struct clk *axi_a_clk;
+static struct clk *axi_b_clk;
+static struct clk *axi_c_clk;
+static struct clk *emi_core_clk;
+static struct clk *nfc_clk;
+static struct clk *ahb_clk;
+static struct clk *vpu_clk;
+static struct clk *vpu_core_clk;
+static struct clk *arm_axi_clk;
+static struct clk *ddr_clk;
+static struct clk *ipu_clk;
+static struct clk *periph_apm_clk;
+static struct clk *lp_apm;
+static struct clk *osc;
+static struct regulator *gp_regulator;
+static struct regulator *lp_regulator;
+static struct cpu_wp *cpu_wp_tbl;
+static struct cpufreq_frequency_table imx_freq_table[4];
+
+extern int dvfs_core_is_active;
+extern int cpu_wp_nr;
+
+static int set_cpu_freq(int freq)
+{
+ int ret = 0;
+ int org_cpu_rate;
+ int gp_volt = 0;
+ int i;
+
+ org_cpu_rate = clk_get_rate(cpu_clk);
+
+ if (org_cpu_rate == freq)
+ return ret;
+
+ for (i = 0; i < cpu_wp_nr; i++) {
+ if (freq == cpu_wp_tbl[i].cpu_rate)
+ gp_volt = cpu_wp_tbl[i].cpu_voltage;
+ }
+
+ if (gp_volt == 0)
+ return ret;
+
+ /*Set the voltage for the GP domain. */
+ if (freq > org_cpu_rate) {
+ ret = regulator_set_voltage(gp_regulator, gp_volt);
+ if (ret < 0) {
+ printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!\n");
+ return ret;
+ }
+ }
+
+ ret = clk_set_rate(cpu_clk, freq);
+ if (ret != 0) {
+ printk(KERN_DEBUG "cannot set CPU clock rate\n");
+ return ret;
+ }
+
+ if (freq < org_cpu_rate) {
+ ret = regulator_set_voltage(gp_regulator, gp_volt);
+ if (ret < 0) {
+ printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!\n");
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+static int set_low_bus_freq(void)
+{
+ int ret = 0;
+ unsigned long lp_lpm_clk;
+
+ struct clk *p_clk;
+ struct clk *amode_parent_clk;
+
+ if (axi_c_clk_support == 0)
+ return 0;
+
+ lp_lpm_clk = clk_get_rate(lp_apm);
+ amode_parent_clk = lp_apm;
+ p_clk = clk_get_parent(periph_apm_clk);
+
+ /* Make sure osc_clk is the parent of lp_apm. */
+ if (clk_get_parent(amode_parent_clk) != osc)
+ clk_set_parent(amode_parent_clk, osc);
+
+ /* Set the parent of periph_apm_clk to be lp_apm */
+ clk_set_parent(periph_apm_clk, amode_parent_clk);
+ amode_parent_clk = periph_apm_clk;
+
+ p_clk = clk_get_parent(main_bus_clk);
+ /* Set the parent of main_bus_clk to be periph_apm_clk */
+ clk_set_parent(main_bus_clk, amode_parent_clk);
+
+ clk_set_rate(axi_a_clk, lp_lpm_clk);
+ clk_set_rate(axi_b_clk, lp_lpm_clk);
+ clk_set_rate(axi_c_clk, lp_lpm_clk);
+ clk_set_rate(emi_core_clk, lp_lpm_clk);
+ clk_set_rate(nfc_clk, 4800000);
+ clk_set_rate(ahb_clk, lp_lpm_clk);
+
+ amode_parent_clk = emi_core_clk;
+
+ p_clk = clk_get_parent(arm_axi_clk);
+ if (p_clk != amode_parent_clk)
+ clk_set_parent(arm_axi_clk, amode_parent_clk);
+
+ p_clk = clk_get_parent(vpu_clk);
+ if (p_clk != amode_parent_clk)
+ clk_set_parent(vpu_clk, amode_parent_clk);
+
+ p_clk = clk_get_parent(vpu_core_clk);
+ if (p_clk != amode_parent_clk)
+ clk_set_parent(vpu_core_clk, amode_parent_clk);
+
+ /* Set the voltage to 1.0v for the LP domain. */
+ ret = regulator_set_voltage(lp_regulator, 1000000);
+ if (ret < 0) {
+ printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!!!\n");
+ return ret;
+ }
+
+ low_bus_freq_mode = 1;
+ high_bus_freq_mode = 0;
+ return ret;
+}
+
+static int set_high_bus_freq(void)
+{
+ struct clk *p_clk;
+ struct clk *rmode_parent_clk;
+ int ret = 0;
+
+ if (axi_c_clk_support == 0)
+ return 0;
+
+ if (!low_bus_freq_mode)
+ return ret;
+
+ low_bus_freq_mode = 0;
+
+ /* Set the voltage to 1.2v for the LP domain. */
+ ret = regulator_set_voltage(lp_regulator, 1200000);
+ if (ret < 0) {
+ printk(KERN_DEBUG "COULD NOT SET LP VOLTAGE!!!!!!\n");
+ return ret;
+ }
+
+ rmode_parent_clk = pll2;
+
+ /* Set the dividers before setting the parent clock. */
+ clk_set_rate(axi_a_clk, 4800000);
+ clk_set_rate(axi_b_clk, 4000000);
+ clk_set_rate(axi_c_clk, 6000000);
+
+ clk_set_rate(emi_core_clk, 4800000);
+ clk_set_rate(ahb_clk, 4800000);
+
+ /* Set the parent of main_bus_clk to be pll2 */
+ p_clk = clk_get_parent(main_bus_clk);
+ clk_set_parent(main_bus_clk, rmode_parent_clk);
+ udelay(5);
+ high_bus_freq_mode = 1;
+ return ret;
+}
+
+static int low_freq_bus_used(void)
+{
+ if (axi_c_clk_support == 0)
+ return 0;
+
+ if ((clk_get_usecount(ipu_clk) == 0)
+ && (clk_get_usecount(vpu_clk) == 0))
+ return 1;
+ else
+ return 0;
+}
+
+static int mxc_verify_speed(struct cpufreq_policy *policy)
+{
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ return cpufreq_frequency_table_verify(policy, imx_freq_table);
+}
+
+static unsigned int mxc_get_speed(unsigned int cpu)
+{
+ if (cpu)
+ return 0;
+
+ return clk_get_rate(cpu_clk) / 1000;
+}
+
+static int calc_frequency_khz(int target, unsigned int relation)
+{
+ int i;
+
+ if (relation == CPUFREQ_RELATION_H) {
+ for (i = ARRAY_SIZE(imx_freq_table) - 1; i > 0; i--) {
+ if (imx_freq_table[i].frequency <= target)
+ return imx_freq_table[i].frequency;
+ }
+ } else if (relation == CPUFREQ_RELATION_L) {
+ for (i = 0; i < ARRAY_SIZE(imx_freq_table) - 1; i++) {
+ if (imx_freq_table[i].frequency >= target)
+ return imx_freq_table[i].frequency;
+ }
+ }
+ printk(KERN_ERR "Error: No valid cpufreq relation\n");
+ return cpu_freq_khz_max;
+}
+
+static int mxc_set_target(struct cpufreq_policy *policy,
+ unsigned int target_freq, unsigned int relation)
+{
+ struct cpufreq_freqs freqs;
+ long freq_Hz;
+ int low_freq_bus_ready = 0;
+ int ret = 0;
+
+ /*
+ * Some governors do not respects CPU and policy lower limits
+ * which leads to bad things (division by zero etc), ensure
+ * that such things do not happen.
+ */
+ if (target_freq < policy->cpuinfo.min_freq)
+ target_freq = policy->cpuinfo.min_freq;
+
+ if (target_freq < policy->min)
+ target_freq = policy->min;
+
+ freq_Hz = calc_frequency_khz(target_freq, relation) * 1000;
+
+ freqs.old = clk_get_rate(cpu_clk) / 1000;
+ freqs.new = freq_Hz / 1000;
+ freqs.cpu = 0;
+ freqs.flags = 0;
+
+ if ((freqs.old == freqs.new) && (freqs.new != cpu_freq_khz_min))
+ return 0;
+
+ low_freq_bus_ready = low_freq_bus_used();
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
+
+ if ((freq_Hz == arm_lpm_clk) && (!low_bus_freq_mode)
+ && (low_freq_bus_ready)) {
+ set_low_bus_freq();
+ if (!dvfs_core_is_active)
+ ret = set_cpu_freq(freq_Hz);
+ } else {
+ if (!high_bus_freq_mode)
+ set_high_bus_freq();
+
+ if (!dvfs_core_is_active)
+ ret = set_cpu_freq(freq_Hz);
+ if (low_bus_freq_mode) {
+ if (ret == 0)
+ set_high_bus_freq();
+ }
+ }
+
+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
+
+ return ret;
+}
+
+static int __init mxc_cpufreq_driver_init(struct cpufreq_policy *policy)
+{
+ int ret;
+ int i;
+
+ printk(KERN_INFO "i.MXC CPU frequency driver\n");
+
+ if (policy->cpu != 0)
+ return -EINVAL;
+
+ cpu_clk = clk_get(NULL, "cpu_clk");
+ if (IS_ERR(cpu_clk)) {
+ printk(KERN_ERR "%s: failed to get cpu clock\n", __func__);
+ return PTR_ERR(cpu_clk);
+ }
+
+ axi_c_clk = clk_get(NULL, "axi_c_clk");
+ if (IS_ERR(axi_c_clk)) {
+ axi_c_clk_support = 0;
+ printk(KERN_ERR "%s: failed to get axi_c_clk\n", __func__);
+ } else {
+ axi_c_clk_support = 1;
+ main_bus_clk = clk_get(NULL, "main_bus_clk");
+ if (IS_ERR(main_bus_clk)) {
+ printk(KERN_ERR "%s: failed to get main_bus_clk\n",
+ __func__);
+ return PTR_ERR(main_bus_clk);
+ }
+
+ pll2 = clk_get(NULL, "pll2");
+ if (IS_ERR(pll2)) {
+ printk(KERN_ERR "%s: failed to get pll2\n", __func__);
+ return PTR_ERR(pll2);
+ }
+
+ axi_a_clk = clk_get(NULL, "axi_a_clk");
+ if (IS_ERR(axi_a_clk)) {
+ printk(KERN_ERR "%s: failed to get axi_a_clk\n",
+ __func__);
+ return PTR_ERR(axi_a_clk);
+ }
+
+ axi_b_clk = clk_get(NULL, "axi_b_clk");
+ if (IS_ERR(axi_b_clk)) {
+ printk(KERN_ERR "%s: failed to get axi_b_clk\n",
+ __func__);
+ return PTR_ERR(axi_b_clk);
+ }
+
+ emi_core_clk = clk_get(NULL, "emi_core_clk");
+ if (IS_ERR(emi_core_clk)) {
+ printk(KERN_ERR "%s: failed to get emi_core_clk\n",
+ __func__);
+ return PTR_ERR(emi_core_clk);
+ }
+
+ nfc_clk = clk_get(NULL, "nfc_clk");
+ if (IS_ERR(nfc_clk)) {
+ printk(KERN_ERR "%s: failed to get nfc_clk\n",
+ __func__);
+ return PTR_ERR(nfc_clk);
+ }
+
+ ahb_clk = clk_get(NULL, "ahb_clk");
+ if (IS_ERR(ahb_clk)) {
+ printk(KERN_ERR "%s: failed to get ahb_clk\n",
+ __func__);
+ return PTR_ERR(ahb_clk);
+ }
+
+ vpu_core_clk = clk_get(NULL, "vpu_core_clk");
+ if (IS_ERR(vpu_core_clk)) {
+ printk(KERN_ERR "%s: failed to get vpu_core_clk\n",
+ __func__);
+ return PTR_ERR(vpu_core_clk);
+ }
+
+ arm_axi_clk = clk_get(NULL, "arm_axi_clk");
+ if (IS_ERR(arm_axi_clk)) {
+ printk(KERN_ERR "%s: failed to get arm_axi_clk\n",
+ __func__);
+ return PTR_ERR(arm_axi_clk);
+ }
+
+ ddr_clk = clk_get(NULL, "ddr_clk");
+ if (IS_ERR(ddr_clk)) {
+ printk(KERN_ERR "%s: failed to get ddr_clk\n",
+ __func__);
+ return PTR_ERR(ddr_clk);
+ }
+
+ ipu_clk = clk_get(NULL, "ipu_clk");
+ if (IS_ERR(ipu_clk)) {
+ printk(KERN_ERR "%s: failed to get ipu_clk\n",
+ __func__);
+ return PTR_ERR(ipu_clk);
+ }
+
+ vpu_clk = clk_get(NULL, "vpu_clk");
+ if (IS_ERR(vpu_clk)) {
+ printk(KERN_ERR "%s: failed to get vpu_clk\n",
+ __func__);
+ return PTR_ERR(vpu_clk);
+ }
+
+ periph_apm_clk = clk_get(NULL, "periph_apm_clk");
+ if (IS_ERR(periph_apm_clk)) {
+ printk(KERN_ERR "%s: failed to get periph_apm_clk\n",
+ __func__);
+ return PTR_ERR(periph_apm_clk);
+ }
+
+ lp_apm = clk_get(NULL, "lp_apm");
+ if (IS_ERR(lp_apm)) {
+ printk(KERN_ERR "%s: failed to get lp_apm\n", __func__);
+ return PTR_ERR(lp_apm);
+ }
+
+ osc = clk_get(NULL, "osc");
+ if (IS_ERR(osc)) {
+ printk(KERN_ERR "%s: failed to get osc\n", __func__);
+ return PTR_ERR(osc);
+ }
+ }
+
+ gp_regulator = regulator_get(NULL, gp_reg_id);
+ if (IS_ERR(gp_regulator)) {
+ clk_put(cpu_clk);
+ printk(KERN_ERR "%s: failed to get gp regulator\n", __func__);
+ return PTR_ERR(gp_regulator);
+ }
+
+ lp_regulator = regulator_get(NULL, lp_reg_id);
+ if (IS_ERR(lp_regulator)) {
+ clk_put(ahb_clk);
+ printk(KERN_ERR "%s: failed to get lp regulator\n", __func__);
+ return PTR_ERR(lp_regulator);
+ }
+
+ /* Set the current working point. */
+ cpu_wp_tbl = get_cpu_wp(&cpu_wp_nr);
+
+ cpu_freq_khz_min = cpu_wp_tbl[0].cpu_rate / 1000;
+ cpu_freq_khz_max = cpu_wp_tbl[0].cpu_rate / 1000;
+
+ for (i = 0; i < cpu_wp_nr; i++) {
+ imx_freq_table[cpu_wp_nr - 1 - i].index = cpu_wp_nr - i;
+ imx_freq_table[cpu_wp_nr - 1 - i].frequency =
+ cpu_wp_tbl[i].cpu_rate / 1000;
+
+ if ((cpu_wp_tbl[i].cpu_rate / 1000) < cpu_freq_khz_min)
+ cpu_freq_khz_min = cpu_wp_tbl[i].cpu_rate / 1000;
+
+ if ((cpu_wp_tbl[i].cpu_rate / 1000) > cpu_freq_khz_max)
+ cpu_freq_khz_max = cpu_wp_tbl[i].cpu_rate / 1000;
+ }
+
+ imx_freq_table[i].index = i + 1;
+ imx_freq_table[i].frequency = cpu_wp_tbl[i].cpu_rate / 1000;
+
+ if ((cpu_wp_tbl[i].cpu_rate / 1000) < cpu_freq_khz_min)
+ cpu_freq_khz_min = cpu_wp_tbl[i].cpu_rate / 1000;
+
+ if ((cpu_wp_tbl[i].cpu_rate / 1000) > cpu_freq_khz_max)
+ cpu_freq_khz_max = cpu_wp_tbl[i].cpu_rate / 1000;
+
+ imx_freq_table[i].index = 0;
+ imx_freq_table[i].frequency = CPUFREQ_TABLE_END;
+
+ policy->cur = policy->min = policy->max = clk_get_rate(cpu_clk) / 1000;
+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
+ policy->cpuinfo.min_freq = cpu_freq_khz_min;
+ policy->cpuinfo.max_freq = cpu_freq_khz_max;
+
+ arm_lpm_clk = cpu_freq_khz_min * 1000;
+ arm_normal_clk = cpu_freq_khz_max * 1000;
+
+ /* Manual states, that PLL stabilizes in two CLK32 periods */
+ policy->cpuinfo.transition_latency = 10;
+
+ ret = cpufreq_frequency_table_cpuinfo(policy, imx_freq_table);
+ if (ret < 0) {
+ clk_put(cpu_clk);
+ if (axi_c_clk_support != 0) {
+ clk_put(main_bus_clk);
+ clk_put(pll2);
+ clk_put(axi_a_clk);
+ clk_put(axi_b_clk);
+ clk_put(axi_c_clk);
+ clk_put(emi_core_clk);
+ clk_put(nfc_clk);
+ clk_put(ahb_clk);
+ clk_put(vpu_core_clk);
+ clk_put(arm_axi_clk);
+ clk_put(ddr_clk);
+ clk_put(ipu_clk);
+ clk_put(vpu_clk);
+ clk_put(periph_apm_clk);
+ clk_put(lp_apm);
+ clk_put(osc);
+ }
+
+ regulator_put(gp_regulator, NULL);
+ regulator_put(lp_regulator, NULL);
+ printk(KERN_ERR "%s: failed to register i.MXC CPUfreq\n",
+ __func__);
+ return ret;
+ }
+ cpufreq_frequency_table_get_attr(imx_freq_table, policy->cpu);
+
+ low_bus_freq_mode = 0;
+ high_bus_freq_mode = 0;
+ return 0;
+}
+
+static int mxc_cpufreq_driver_exit(struct cpufreq_policy *policy)
+{
+ cpufreq_frequency_table_put_attr(policy->cpu);
+
+ /* Reset CPU to 665MHz */
+ if (!dvfs_core_is_active)
+ set_cpu_freq(arm_normal_clk);
+
+ if (low_bus_freq_mode)
+ set_high_bus_freq();
+
+ clk_put(cpu_clk);
+ if (axi_c_clk_support != 0) {
+ clk_put(main_bus_clk);
+ clk_put(pll2);
+ clk_put(axi_a_clk);
+ clk_put(axi_b_clk);
+ clk_put(axi_c_clk);
+ clk_put(emi_core_clk);
+ clk_put(nfc_clk);
+ clk_put(ahb_clk);
+ clk_put(vpu_core_clk);
+ clk_put(arm_axi_clk);
+ clk_put(ddr_clk);
+ clk_put(ipu_clk);
+ clk_put(periph_apm_clk);
+ clk_put(lp_apm);
+ clk_put(osc);
+ }
+ regulator_put(gp_regulator, NULL);
+ regulator_put(lp_regulator, NULL);
+ return 0;
+}
+
+static struct cpufreq_driver mxc_driver = {
+ .flags = CPUFREQ_STICKY,
+ .verify = mxc_verify_speed,
+ .target = mxc_set_target,
+ .get = mxc_get_speed,
+ .init = mxc_cpufreq_driver_init,
+ .exit = mxc_cpufreq_driver_exit,
+ .name = "imx",
+};
+
+static int __devinit mxc_cpufreq_init(void)
+{
+ return cpufreq_register_driver(&mxc_driver);
+}
+
+static void mxc_cpufreq_exit(void)
+{
+ cpufreq_unregister_driver(&mxc_driver);
+}
+
+module_init(mxc_cpufreq_init);
+module_exit(mxc_cpufreq_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("CPUfreq driver for i.MX");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/dma_mx2.c b/arch/arm/plat-mxc/dma_mx2.c
new file mode 100644
index 000000000000..c8753b132405
--- /dev/null
+++ b/arch/arm/plat-mxc/dma_mx2.c
@@ -0,0 +1,1315 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/* Front-end to the DMA handling. This handles the allocation/freeing
+ * of DMA channels, and provides a unified interface to the machines
+ * DMA facilities.
+ */
+
+/*!
+ * @file plat-mxc/dma_mx2.c
+ * @brief This file contains functions for DMA API
+ *
+ * @ingroup DMA_MX27
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/sched.h>
+#include <linux/mman.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+
+#include <linux/proc_fs.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/dma.h>
+#include <asm/delay.h>
+
+#include <asm/atomic.h>
+
+/* commented temperily for mx27 compilation
+#define DMA_PM
+*/
+#ifdef DMA_PM
+#include <linux/pm.h>
+#include <mach/apmc.h>
+struct apmc_user *dma_apmc_user;
+struct pm_dev *dma_pm;
+#define DMA_PMST_RESUME 0
+#define DMA_PMST_STANDBY 1
+#define DMA_PMST_SUSPEND 2
+static unsigned int dma_pm_status = DMA_PMST_RESUME;
+#endif
+
+/*!
+ * This variable is used to controll the clock of DMA.
+ * It counts the number of actived channels
+ */
+static atomic_t g_dma_actived = ATOMIC_INIT(0);
+
+/*!
+ * This variable point a proc file which contains the information
+ * of DMA channels
+ */
+static struct proc_dir_entry *g_proc_dir;
+
+/*!
+ * The dma channels
+ */
+static mxc_dma_channel_t g_dma_channels[MAX_DMA_CHANNELS];
+static mx2_dma_priv_t g_dma_privates[MXC_DMA_CHANNELS];
+static mx2_dma_bd_t g_dma_bd_table[MXC_DMA_CHANNELS][MAX_BD_SIZE];
+
+static DEFINE_SPINLOCK(dma_list_lock);
+
+static struct clk *dma_clk;
+
+/*!@brief flush buffer descriptor ring*/
+#define flush_dma_bd(private) \
+ { \
+ atomic_set(&(private->bd_used), 0); \
+ private->bd_rd = private->bd_wr;\
+ }
+
+/*!@brief get next buffer discriptor */
+#define next_dma_bd(private) \
+ ({ \
+ int bd_next = (private->bd_rd+1)%MAX_BD_SIZE; \
+ (bd_next == private->bd_wr) ? NULL: private->bd_ring+bd_next;\
+ })
+
+static inline int consume_dma_bd(mxc_dma_channel_t * dma, int error);
+/*!
+ *@brief allocate a dma channel.
+ *
+ *@param idx Requested channel NO.
+ * @li MXC_INVLAID_CHANNEL System allocates a free channel which is not statically allocated.
+ * @li Others User requests a specific channel
+ *@return @li MXC_INVLAID_CHANNEL Failure
+ * @li Others Success
+ */
+static inline int get_dma_channel(int idx)
+{
+ int i;
+ mxc_dma_channel_t *p;
+
+ if ((idx >= MAX_DMA_CHANNELS) && (idx != MXC_DMA_DYNAMIC_CHANNEL)) {
+ return -1;
+ }
+ if (idx != MXC_DMA_DYNAMIC_CHANNEL) {
+ p = g_dma_channels + idx;
+ BUG_ON(p->dynamic != 0);
+ if (xchg(&p->lock, 1) != 0) {
+ return -1;
+ }
+ return idx;
+ }
+
+ p = g_dma_channels;
+ for (i = 0; (i < MAX_DMA_CHANNELS); i++, p++) {
+ if (p->dynamic && (xchg(&p->lock, 1) == 0)) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+/*!
+ *@brief release a dma channel.
+ *
+ *@param idx channel number
+ *@return none;
+ */
+static inline void put_dma_channel(int idx)
+{
+ mxc_dma_channel_t *p;
+
+ if ((idx < MAX_DMA_CHANNELS) && (idx >= 0)) {
+ p = g_dma_channels + idx;
+ (void)xchg(&p->lock, 0);
+ }
+}
+
+/*!
+ *@brief Get dma list for /proc/dma
+ */
+static int mxc_get_dma_list(char *buf)
+{
+ mxc_dma_channel_t *dma;
+ char *p = buf;
+ int i;
+
+ for (i = 0, dma = g_dma_channels; i < MAX_DMA_CHANNELS; i++, dma++) {
+ if (dma->lock) {
+ p += sprintf(p, "dma channel %2d: %s\n", i,
+ dma->dev_name ? dma->dev_name : "unknown");
+ } else {
+ p += sprintf(p, "dma channel %2d: unused\n", i);
+ }
+ }
+
+ return p - buf;
+}
+
+/*!@brief save the mask of dma interrupts*/
+#define save_dma_interrupt(flags) \
+ flags = __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DIMR)
+
+/*!@brief restore the mask of dma interrupts*/
+#define restore_dma_interrupt(flags) \
+ __raw_writel(flags, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DIMR)
+
+/*!@brief disable interrupt of dma channel*/
+static inline void mask_dma_interrupt(int channel)
+{
+ unsigned long reg;
+ save_dma_interrupt(reg);
+ reg |= 1 << channel; /*mask interrupt; */
+ restore_dma_interrupt(reg);
+}
+
+/*!@brief enable interrupt of dma channel */
+static inline void unmask_dma_interrupt(int channel)
+{
+ unsigned long reg;
+ save_dma_interrupt(reg);
+ reg &= ~(1 << channel); /*unmask interrupt; */
+ restore_dma_interrupt(reg);
+}
+
+/*!@brief get interrupt event of dma channel */
+static unsigned long inline __get_dma_interrupt(int channel)
+{
+ unsigned long mode;
+ mode = 0;
+ if (__raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DISR) & (1 << channel))
+ mode |= DMA_DONE;
+
+ if (__raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DBTOSR) &
+ (1 << channel))
+ mode |= DMA_BURST_TIMEOUT;
+ if (__raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DSESR) & (1 << channel))
+ mode |= DMA_TRANSFER_ERROR;
+
+ if (__raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DBOSR) & (1 << channel))
+ mode |= DMA_BUFFER_OVERFLOW;
+ if (__raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DRTOSR) &
+ (1 << channel))
+ mode |= DMA_REQUEST_TIMEOUT;
+ return mode;
+}
+
+/*!
+ *@brief clean all event of dma interrupt and return the valid event.
+ */
+static unsigned long inline __clear_dma_interrupt(int channel)
+{
+ unsigned long mode;
+ mode = __get_dma_interrupt(channel);
+ __raw_writel(1 << channel, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DISR);
+ __raw_writel(1 << channel, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DBTOSR);
+ __raw_writel(1 << channel, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DRTOSR);
+ __raw_writel(1 << channel, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DSESR);
+ __raw_writel(1 << channel, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DBOSR);
+
+ return mode;
+}
+
+/*!@brief This function enables dma clocks without lock */
+static void inline __enable_dma_clk(void)
+{
+ unsigned long reg;
+ clk_enable(dma_clk);
+ reg = __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DCR);
+ reg |= 0x1;
+ __raw_writel(reg, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DCR);
+}
+
+/*!@brief This function disables dma clocks without lock */
+static void inline __disable_dma_clk(void)
+{
+ unsigned long reg;
+ reg = __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DCR);
+ reg &= ~0x1;
+ __raw_writel(reg, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DCR);
+ clk_disable(dma_clk);
+}
+
+/*!@brief This function enables dma clocks with lock */
+static void inline enable_dma_clk(void)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&dma_list_lock, flags);
+ if (atomic_read(&g_dma_actived) == 0) {
+ __enable_dma_clk();
+ }
+ spin_unlock_irqrestore(&dma_list_lock, flags);
+ return;
+}
+
+/*!@brief This function disables dma clocks without locked */
+static void inline disable_dma_clk(void)
+{
+ unsigned long flags;
+ spin_lock_irqsave(&dma_list_lock, flags);
+ if (atomic_read(&g_dma_actived) == 0) {
+ __disable_dma_clk();
+ }
+ spin_unlock_irqrestore(&dma_list_lock, flags);
+ return;
+}
+
+/*!@brief select a buffer to transfer and
+ * setup dma channel for current transfer
+ */
+static void setup_dmac(mxc_dma_channel_t * dma)
+{
+ mx2_dma_priv_t *priv = (mx2_dma_priv_t *) dma->private;
+ dma_regs_t *dma_base = (dma_regs_t *) (priv->dma_base);
+ mx2_dma_bd_t *p, *q;
+ unsigned long ctrl_val;
+
+ if (dma->active == 0) {
+ printk(KERN_ERR
+ "dma channel %d is not enabled, when receiving this channel 's interrupt\n",
+ dma->channel);
+ return;
+ }
+ if (atomic_read(&(priv->bd_used)) <= 0) {
+ printk(KERN_ERR "dma channel %d is empty\n", dma->channel);
+ dma->active = 0;
+ atomic_dec(&g_dma_actived);
+ return;
+ }
+ /* BUSY: transfering
+ * PEND: Wait for set to DMAC.
+ * s1: no transfering:
+ * set first(one BUSY). if there are more than one tranfer. set second &repeat is enabled(two BUSY).
+ *
+ * s2: transfering & just on transfer
+ * one BUSY. set the tranesfer and set repeat bit(two BUSY)
+ * s3: transfering & repeat has set
+ * has two BUSY.
+ */
+ p = priv->bd_ring + priv->bd_rd;
+ q = next_dma_bd(priv);
+ if (!(p->state & DMA_BD_ST_BUSY)) {
+ /*NOTICE:: This is first buffer or dma chain does not support chain-buffer. So CEN must clear & set again */
+ ctrl_val =
+ __raw_readl(&(dma_base->Ctl)) &
+ (~(DMA_CTL_ACRPT | DMA_CTL_RPT | DMA_CTL_CEN));
+ __raw_writel(ctrl_val, &(dma_base->Ctl));
+ if (p->mode != dma->mode) {
+ dma->mode = p->mode; /* bi-dir channel do mode change */
+ if (dma->mode == MXC_DMA_MODE_READ) {
+ DMA_CTL_SET_SMOD(ctrl_val,
+ priv->dma_info->sourceType);
+ DMA_CTL_SET_SSIZ(ctrl_val,
+ priv->dma_info->sourcePort);
+ DMA_CTL_SET_DMOD(ctrl_val,
+ priv->dma_info->destType);
+ DMA_CTL_SET_DSIZ(ctrl_val,
+ priv->dma_info->destPort);
+ } else {
+ DMA_CTL_SET_SMOD(ctrl_val,
+ priv->dma_info->destType);
+ DMA_CTL_SET_SSIZ(ctrl_val,
+ priv->dma_info->destPort);
+ DMA_CTL_SET_DMOD(ctrl_val,
+ priv->dma_info->sourceType);
+ DMA_CTL_SET_DSIZ(ctrl_val,
+ priv->dma_info->sourcePort);
+ }
+ }
+ __raw_writel(p->src_addr, &(dma_base->SourceAddr));
+ __raw_writel(p->dst_addr, &(dma_base->DestAddr));
+ __raw_writel(p->count, &(dma_base->Count));
+ p->state |= DMA_BD_ST_BUSY;
+ p->state &= ~(DMA_BD_ST_PEND);
+ ctrl_val |= DMA_CTL_CEN;
+ __raw_writel(ctrl_val, &(dma_base->Ctl));
+ if (q && priv->dma_chaining) { /*DO chain-buffer */
+ __raw_writel(q->src_addr, &(dma_base->SourceAddr));
+ __raw_writel(q->dst_addr, &(dma_base->DestAddr));
+ __raw_writel(q->count, &(dma_base->Count));
+ q->state |= DMA_BD_ST_BUSY;
+ q->state &= ~(DMA_BD_ST_PEND);
+ ctrl_val |= DMA_CTL_ACRPT | DMA_CTL_RPT | DMA_CTL_CEN;
+ __raw_writel(ctrl_val, &(dma_base->Ctl));
+ }
+ } else { /* Just dma channel which supports dma buffer can run to there */
+ BUG_ON(!priv->dma_chaining);
+ if (q) { /* p is tranfering, then q must be set into dma controller */
+ /*WARNING:: [1] dangerous area begin.
+ * If the p is completed during MCU run in this erea, the dma channel is crashed.
+ */
+ __raw_writel(q->src_addr, &(dma_base->SourceAddr));
+ __raw_writel(q->dst_addr, &(dma_base->DestAddr));
+ __raw_writel(q->count, &(dma_base->Count));
+ /*WARNING:: [2] dangerous area end */
+ ctrl_val =
+ __raw_readl(&(dma_base->Ctl)) | (DMA_CTL_ACRPT |
+ DMA_CTL_RPT |
+ DMA_CTL_CEN);
+ __raw_writel(ctrl_val, &(dma_base->Ctl));
+
+ /* WARNING:: This is workaround and it is dangerous:
+ * the judgement is not safety.
+ */
+ if (!__get_dma_interrupt(dma->channel)) {
+ q->state |= DMA_BD_ST_BUSY;
+ q->state &= ~(DMA_BD_ST_PEND);
+ } else {
+ /*Waiting re-enable is in ISR */
+ printk(KERN_ERR
+ "Warning:: The privous transfer is completed. Maybe the chain buffer is stopped.");
+ }
+ } else { /* Last buffer is transfering: just clear RPT bit */
+ ctrl_val =
+ __raw_readl(&(dma_base->Ctl)) &
+ (~(DMA_CTL_ACRPT | DMA_CTL_RPT));
+ __raw_writel(ctrl_val, &(dma_base->Ctl));
+ }
+ }
+}
+
+/*!
+ * @brief interrupt handler of dma channel
+ */
+static irqreturn_t dma_irq_handler(int irq, void *dev_id)
+{
+ mxc_dma_channel_t *dma = (mxc_dma_channel_t *) dev_id;
+ mx2_dma_priv_t *priv = (mx2_dma_priv_t *) (dma ? dma->private : NULL);
+ dma_regs_t *dma_base;
+ int state, error = MXC_DMA_DONE;
+
+ BUG_ON(priv == NULL);
+
+ dma_base = (dma_regs_t *) priv->dma_base;
+
+ state = __clear_dma_interrupt(dma->channel);
+
+ priv->trans_bytes += dma_base->transferd;
+ if (state != DMA_DONE) {
+ if (state & DMA_REQUEST_TIMEOUT) {
+ error = MXC_DMA_REQUEST_TIMEOUT;
+ } else {
+ error = MXC_DMA_TRANSFER_ERROR;
+ }
+ }
+ if (consume_dma_bd(dma, error)) {
+ disable_dma_clk();
+ if (dma->cb_fn) {
+ dma->cb_fn(dma->cb_args, error, priv->trans_bytes);
+ }
+ priv->trans_bytes = 0;
+ } else {
+ disable_dma_clk();
+ }
+ return IRQ_HANDLED;
+}
+
+/*!
+ *@brief Set DMA channel parameters
+ *
+ *@param dma Requested channel NO.
+ *@param dma_info Channel configuration
+ *@return @li 0 Success
+ * @li others Failure
+ */
+static int setup_dma_channel(mxc_dma_channel_t * dma, mx2_dma_info_t * dma_info)
+{
+ mx2_dma_priv_t *priv = (mx2_dma_priv_t *) (dma ? dma->private : NULL);
+ dma_regs_t *dma_base;
+ unsigned long reg;
+
+ if (!dma_info || !priv) {
+ return -1;
+ }
+
+ if (dma_info->sourceType > 3) {
+ return -1;
+ }
+ if (dma_info->destType > 3) {
+ return -1;
+ }
+ if (dma_info->destPort > 3) {
+ return -1;
+ }
+ if (dma_info->sourcePort > 3) {
+ return -1;
+ }
+ if (dma_info->M2D_Valid) {
+ /*add for second dma */
+ if (dma_info->W < dma_info->X) {
+ return -1;
+ }
+ }
+
+ priv->dma_chaining = dma_info->dma_chaining;
+ priv->ren = dma_info->ren;
+
+ if (dma_info->sourceType != DMA_TYPE_FIFO
+ && dma_info->destType != DMA_TYPE_FIFO) {
+ if (dma_info->ren) {
+ printk(KERN_INFO
+ "Warning:request enable just affect source or destination port is FIFO !\n");
+ priv->ren = 0;
+ }
+ }
+
+ if (dma_info->M2D_Valid) {
+ if (dma_info->msel) {
+ __raw_writel(dma_info->W,
+ IO_ADDRESS(DMA_BASE_ADDR) + DMA_WSRB);
+ __raw_writel(dma_info->X,
+ IO_ADDRESS(DMA_BASE_ADDR) + DMA_XSRB);
+ __raw_writel(dma_info->Y,
+ IO_ADDRESS(DMA_BASE_ADDR) + DMA_YSRB);
+
+ } else {
+ __raw_writel(dma_info->W,
+ IO_ADDRESS(DMA_BASE_ADDR) + DMA_WSRA);
+ __raw_writel(dma_info->X,
+ IO_ADDRESS(DMA_BASE_ADDR) + DMA_XSRA);
+ __raw_writel(dma_info->Y,
+ IO_ADDRESS(DMA_BASE_ADDR) + DMA_YSRA);
+ }
+ }
+
+ dma_base = (dma_regs_t *) (priv->dma_base);
+
+ __raw_writel(dma_info->burstLength, &(dma_base->BurstLength));
+ __raw_writel(dma_info->request, &(dma_base->RequestSource));
+
+ if (dma_info->ren) {
+ reg = dma_info->busuntils & 0x1FFFF;
+ if (dma_info->rto_en) {
+ reg |= 0xE000;
+ }
+ __raw_writel(reg, &(dma_base->BusUtilt));
+ } else {
+ __raw_writel(dma_info->busuntils, &(dma_base->BusUtilt));
+ }
+
+ reg = __raw_readl(&(dma_base->Ctl)) & (~(DMA_CTL_ACRPT | DMA_CTL_RPT));
+
+ if (dma_info->dir) {
+ reg |= DMA_CTL_MDIR;
+ } else {
+ reg &= ~DMA_CTL_MDIR;
+ }
+
+ if (priv->ren) {
+ reg |= DMA_CTL_REN;
+ } else {
+ reg &= ~DMA_CTL_REN;
+ }
+
+ if ((dma_info->M2D_Valid) && (dma_info->msel)) {
+ reg |= DMA_CTL_MSEL;
+ } else {
+ reg &= ~DMA_CTL_MSEL;
+ }
+
+ if (dma_info->mode) {
+ DMA_CTL_SET_SMOD(reg, dma_info->destType);
+ DMA_CTL_SET_SSIZ(reg, dma_info->destPort);
+ DMA_CTL_SET_DMOD(reg, dma_info->sourceType);
+ DMA_CTL_SET_DSIZ(reg, dma_info->sourcePort);
+ } else {
+ DMA_CTL_SET_SMOD(reg, dma_info->sourceType);
+ DMA_CTL_SET_SSIZ(reg, dma_info->sourcePort);
+ DMA_CTL_SET_DMOD(reg, dma_info->destType);
+ DMA_CTL_SET_DSIZ(reg, dma_info->destPort);
+ }
+
+ __raw_writel(reg, &(dma_base->Ctl));
+
+ __clear_dma_interrupt(dma->channel);
+ unmask_dma_interrupt(dma->channel);
+
+ disable_dma_clk();
+ return 0;
+}
+
+/*!@brief setup interrupt and setup dma channel by dma parameter */
+static inline int __init_dma_channel(mxc_dma_channel_t * chan,
+ mx2_dma_info_t * dma_info)
+{
+ mx2_dma_priv_t *dma_private = (mx2_dma_priv_t *) chan->private;
+ dma_regs_t *dma_base;
+ int ret;
+
+ mask_dma_interrupt(chan->channel);
+ ret =
+ request_irq(dma_private->dma_irq, dma_irq_handler,
+ IRQF_DISABLED | IRQF_SHARED, chan->dev_name,
+ (void *)chan);
+ if (ret) {
+ printk(KERN_ERR
+ "%s: unable to request IRQ %d for DMA channel\n",
+ chan->dev_name, dma_private->dma_irq);
+ return ret;
+ }
+
+ enable_dma_clk();
+
+ dma_base = (dma_regs_t *) (dma_private->dma_base);
+ __raw_writel(0, &(dma_base->Ctl));
+
+ ret = 0;
+ if ((ret = setup_dma_channel(chan, dma_info))) {
+ free_irq(dma_private->dma_irq, (void *)chan);
+ }
+ disable_dma_clk();
+ return 0;
+}
+
+/*!@brief initialize buffer descriptor ring.*/
+static inline void init_dma_bd(mx2_dma_priv_t * private)
+{
+ int i;
+ mx2_dma_bd_t *pbd;
+ private->bd_rd = private->bd_wr = 0;
+ atomic_set(&(private->bd_used), 0);
+ for (i = 0, pbd = private->bd_ring; i < MAX_BD_SIZE; i++, pbd++) {
+ pbd->state = 0;
+ }
+}
+
+/*!@brief add dma buffer into buffer descriptor ring */
+static inline int fill_dma_bd(mxc_dma_channel_t * dma,
+ mxc_dma_requestbuf_t * buf, int num,
+ mxc_dma_mode_t mode)
+{
+ int i, wr;
+ unsigned long flags, mask;
+ mx2_dma_priv_t *priv = dma->private;
+ mx2_dma_bd_t *p, *q;
+
+ if ((atomic_read(&(priv->bd_used)) + num) > MAX_BD_SIZE) {
+ return -EBUSY;
+ }
+
+ for (i = 0; i < num; i++) {
+ wr = priv->bd_wr;
+ p = priv->bd_ring + wr;
+ p->mode = mode;
+ p->count = buf[i].num_of_bytes;
+ p->src_addr = buf[i].src_addr;
+ p->dst_addr = buf[i].dst_addr;
+ if (i == num - 1) {
+ p->state = DMA_BD_ST_LAST | DMA_BD_ST_PEND;
+ } else {
+ p->state = DMA_BD_ST_PEND;
+ }
+ priv->bd_wr = (wr + 1) % MAX_BD_SIZE;
+ atomic_inc(&(priv->bd_used));
+
+ if (atomic_read(&(priv->bd_used)) != 2)
+ continue;
+ /* Disable interrupt of this channel */
+ local_irq_save(flags);
+ local_irq_disable();
+ save_dma_interrupt(mask);
+ mask_dma_interrupt(dma->channel);
+ local_irq_restore(flags);
+ /*TODO ::
+ * If channel is transfering and supports chain_buffer,
+ * when the new buffer is 2st buffer , repeat must be enabled
+ */
+ if (priv->dma_chaining && dma->active) {
+ q = priv->bd_ring + priv->bd_rd;
+ if (q && (q->state & DMA_BD_ST_BUSY)) {
+ if (atomic_read(&(priv->bd_used)) == 2) {
+ setup_dmac(dma);
+ }
+ }
+ }
+ restore_dma_interrupt(mask);
+ }
+ return 0;
+}
+
+/*!@brief add sg-list into buffer descriptor ring */
+static inline int fill_dma_bd_by_sg(mxc_dma_channel_t * dma,
+ struct scatterlist *sg, int num,
+ int real_bytes, mxc_dma_mode_t mode)
+{
+ int i, wr, total_bytes = real_bytes;
+ unsigned long flags, mask;
+ mx2_dma_priv_t *priv = dma->private;
+ mx2_dma_bd_t *p, *q;
+ if ((atomic_read(&(priv->bd_used)) + num) > MAX_BD_SIZE) {
+ return -EBUSY;
+ }
+
+ for (i = 0; i < num && ((real_bytes <= 0) || (total_bytes > 0)); i++) {
+ wr = priv->bd_wr;
+ p = priv->bd_ring + wr;
+ p->mode = mode;
+ if (real_bytes > 0) {
+ if (sg[i].length >= total_bytes) {
+ p->count = total_bytes;
+ } else {
+ p->count = sg[i].length;
+ }
+ total_bytes -= p->count;
+ } else {
+ p->count = sg[i].length;
+ }
+ if (mode == MXC_DMA_MODE_READ) {
+ p->src_addr = priv->dma_info->per_address;
+ p->dst_addr = sg[i].dma_address;
+ } else {
+ p->dst_addr = priv->dma_info->per_address;
+ p->src_addr = sg[i].dma_address;
+ }
+ if ((i == num - 1) || ((real_bytes > 0) && (total_bytes == 0))) {
+ p->state = DMA_BD_ST_LAST | DMA_BD_ST_PEND;
+ } else {
+ p->state = DMA_BD_ST_PEND;
+ }
+ priv->bd_wr = (wr + 1) % MAX_BD_SIZE;
+ atomic_inc(&(priv->bd_used));
+
+ if (atomic_read(&(priv->bd_used)) != 2)
+ continue;
+ /* Disable interrupt of this channel */
+ local_irq_save(flags);
+ local_irq_disable();
+ save_dma_interrupt(mask);
+ mask_dma_interrupt(dma->channel);
+ local_irq_restore(flags);
+ /*TODO ::
+ * If channel is transfering and supports chain_buffer,
+ * when the new buffer is 2st buffer , repeat must be enabled
+ */
+ if (priv->dma_chaining && dma->active) {
+ q = next_dma_bd(priv);
+ if (q && (q->state & DMA_BD_ST_BUSY)) {
+ if ((atomic_read(&(priv->bd_used))) == 2) {
+ setup_dmac(dma);
+ }
+ }
+ }
+ restore_dma_interrupt(mask);
+ }
+ return 0;
+}
+
+/*!@brief select next buffer descripter to transfer.
+ * return 1: need call call-back function. 0: Not need call call-back.
+ * it just is called in ISR
+ */
+static inline int consume_dma_bd(mxc_dma_channel_t * dma, int error)
+{
+ mx2_dma_priv_t *priv = dma->private;
+ mx2_dma_bd_t *p;
+ int notify = 0;
+ if (priv == NULL) {
+ printk(KERN_ERR
+ "request dma channel %d which is not initialize completed.!\n",
+ dma->channel);
+ return 1;
+ }
+ if (error != MXC_DMA_DONE) {
+ for (p = priv->bd_ring + priv->bd_rd;
+ atomic_read(&(priv->bd_used)) > 0;) {
+ priv->bd_rd = (priv->bd_rd + 1) % MAX_BD_SIZE;
+ atomic_dec(&(priv->bd_used));
+ if (p->state & DMA_BD_ST_LAST) {
+ p->state = 0;
+ break;
+ }
+ p->state = 0;
+ }
+ notify = 1;
+ } else {
+ p = priv->bd_ring + priv->bd_rd;
+ priv->bd_rd = (priv->bd_rd + 1) % MAX_BD_SIZE;
+ atomic_dec(&(priv->bd_used));
+ notify = (p->state & DMA_BD_ST_LAST) == DMA_BD_ST_LAST;
+ }
+ if (atomic_read(&(priv->bd_used)) <= 0) {
+ dma->active = 0;
+ atomic_dec(&g_dma_actived);
+ } else {
+ setup_dmac(dma);
+ }
+ return notify;
+}
+
+/*!
+ * This function is generally called by the driver at open time.
+ * The DMA driver would do any initialization steps that is required
+ * to get the channel ready for data transfer.
+ *
+ * @param channel_id a pre-defined id. The peripheral driver would specify
+ * the id associated with its peripheral. This would be
+ * used by the DMA driver to identify the peripheral
+ * requesting DMA and do the necessary setup on the
+ * channel associated with the particular peripheral.
+ * The DMA driver could use static or dynamic DMA channel
+ * allocation.
+ * @param dev_name module name or device name
+ * @return returns a negative number on error if request for a DMA channel did not
+ * succeed, returns the channel number to be used on success.
+ */
+int mxc_dma_request(mxc_dma_device_t channel_id, char *dev_name)
+{
+ mxc_dma_channel_t *dma;
+ mx2_dma_priv_t *dma_private = NULL;
+ mx2_dma_info_t *dma_info = mxc_dma_get_info(channel_id);
+ int index;
+ int ret;
+
+ if (dma_info == NULL) {
+ return -EINVAL;
+ }
+
+ if ((index = get_dma_channel(dma_info->dma_chan)) < 0) {
+ return -ENODEV;
+ }
+
+ dma = g_dma_channels + index;
+ dma_private = (mx2_dma_priv_t *) dma->private;
+ if (dma_private == NULL) {
+ printk(KERN_ERR
+ "request dma channel %d which is not initialize completed.!\n",
+ index);
+ ret = -EFAULT;
+ goto exit;
+ }
+
+ dma->active = 0;
+ dma_private->dma_info = NULL;
+ dma->cb_fn = NULL;
+ dma->cb_args = NULL;
+ dma->dev_name = dev_name;
+ dma->mode = dma_info->mode ? MXC_DMA_MODE_WRITE : MXC_DMA_MODE_READ;
+ init_dma_bd(dma_private);
+
+ if (!(ret = __init_dma_channel(dma, dma_info))) {
+ dma_private->dma_info = dma_info;
+ return index;
+ }
+ exit:
+ put_dma_channel(index);
+ return ret;
+}
+
+/*!
+ * This function is generally called by the driver at close time. The DMA
+ * driver would do any cleanup associated with this channel.
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @return returns a negative number on error or 0 on success
+ */
+int mxc_dma_free(int channel_num)
+{
+ mxc_dma_channel_t *dma;
+ mx2_dma_priv_t *dma_private;
+
+ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+ return -EINVAL;
+ }
+
+ dma = g_dma_channels + channel_num;
+ dma_private = (mx2_dma_priv_t *) dma->private;
+ if (dma_private == NULL) {
+ printk(KERN_ERR
+ "Free dma %d which is not completed initialization \n",
+ channel_num);
+ return -EFAULT;
+ }
+ if (dma->lock) {
+ if (dma->active) { /*Channel is busy */
+ mxc_dma_disable(channel_num);
+ }
+
+ dma_private = (mx2_dma_priv_t *) dma->private;
+
+ enable_dma_clk();
+ mask_dma_interrupt(channel_num);
+ disable_dma_clk();
+
+ free_irq(dma_private->dma_irq, (void *)dma);
+ put_dma_channel(channel_num);
+ }
+ return 0;
+}
+
+/*!
+ * This function would just configure the buffers specified by the user into
+ * dma channel. The caller must call mxc_dma_enable to start this transfer.
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @param dma_buf an array of physical addresses to the user defined
+ * buffers. The caller must guarantee the dma_buf is
+ * available until the transfer is completed.
+ * @param num_buf number of buffers in the array
+ * @param mode specifies whether this is READ or WRITE operation
+ * @return This function returns a negative number on error if buffer could not be
+ * added with DMA for transfer. On Success, it returns 0
+ */
+int mxc_dma_config(int channel_num, mxc_dma_requestbuf_t * dma_buf, int num_buf,
+ mxc_dma_mode_t mode)
+{
+ mxc_dma_channel_t *dma;
+ mx2_dma_priv_t *dma_private;
+
+ if ((dma_buf == NULL) || (num_buf < 1)) {
+ return -EINVAL;
+ }
+
+ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+ return -EINVAL;
+ }
+
+ dma = g_dma_channels + channel_num;
+ dma_private = (mx2_dma_priv_t *) dma->private;
+ if (dma_private == NULL) {
+ printk(KERN_ERR
+ "config dma %d which is not completed initialization \n",
+ channel_num);
+ return -EFAULT;
+ }
+
+ if (dma->lock == 0) {
+ return -ENODEV;
+ }
+
+ /*TODO: dma chainning can not support on bi-dir channel */
+ if (dma_private->dma_chaining && (dma->mode != mode)) {
+ return -EINVAL;
+ }
+
+ /*TODO: fill dma buffer into driver .
+ * If driver is no enought buffer to save them , it will return -EBUSY
+ */
+ if (fill_dma_bd(dma, dma_buf, num_buf, mode)) {
+ return -EBUSY;
+ }
+
+ return 0;
+}
+
+/*!
+ * This function would just configure the scatterlist specified by the
+ * user into dma channel. This is a slight variation of mxc_dma_config(),
+ * it is provided for the convenience of drivers that have a scatterlist
+ * passed into them. It is the calling driver's responsibility to have the
+ * correct physical address filled in the "dma_address" field of the
+ * scatterlist.
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @param sg a scatterlist of buffers. The caller must guarantee
+ * the dma_buf is available until the transfer is
+ * completed.
+ * @param num_buf number of buffers in the array
+ * @param num_of_bytes total number of bytes to transfer. If set to 0, this
+ * would imply to use the length field of the scatterlist
+ * for each DMA transfer. Else it would calculate the size
+ * for each DMA transfer.
+ * @param mode specifies whether this is READ or WRITE operation
+ * @return This function returns a negative number on error if buffer could not
+ * be added with DMA for transfer. On Success, it returns 0
+ */
+int mxc_dma_sg_config(int channel_num, struct scatterlist *sg,
+ int num_buf, int num_of_bytes, mxc_dma_mode_t mode)
+{
+ mxc_dma_channel_t *dma;
+ mx2_dma_priv_t *dma_private;
+
+ if ((sg == NULL) || (num_buf < 1) || (num_of_bytes < 0)) {
+ return -EINVAL;
+ }
+
+ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+ return -EINVAL;
+ }
+
+ dma = g_dma_channels + channel_num;
+ dma_private = (mx2_dma_priv_t *) dma->private;
+ if (dma_private == NULL) {
+ printk(KERN_ERR
+ "config_sg dma %d which is not completed initialization \n",
+ channel_num);
+ return -EFAULT;
+ }
+
+ if (dma->lock == 0) {
+ return -ENODEV;
+ }
+
+ /*TODO: dma chainning can not support on bi-dir channel */
+ if (dma_private->dma_chaining && (dma->mode != mode)) {
+ return -EINVAL;
+ }
+
+ /*TODO: fill dma buffer into driver .
+ * If driver is no enought buffer to save them , it will return -EBUSY
+ */
+ if (fill_dma_bd_by_sg(dma, sg, num_buf, num_of_bytes, mode)) {
+ return -EBUSY;
+ }
+ return 0;
+}
+
+/*!
+ * This function is provided if the driver would like to set/change its
+ * callback function.
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @param callback a callback function to provide notification on transfer
+ * completion, user could specify NULL if he does not wish
+ * to be notified
+ * @param arg an argument that gets passed in to the callback
+ * function, used by the user to do any driver specific
+ * operations.
+ * @return this function returns an error if the callback could not be set
+ * for the channel
+ */
+int mxc_dma_callback_set(int channel_num, mxc_dma_callback_t callback,
+ void *arg)
+{
+ mxc_dma_channel_t *dma;
+
+ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+ return -EINVAL;
+ }
+ dma = g_dma_channels + channel_num;
+
+ if (!dma->lock) {
+ return -ENODEV;
+ }
+
+ if (dma->active) {
+ return -EBUSY;
+ }
+ dma->cb_fn = callback;
+ dma->cb_args = arg;
+ return 0;
+
+}
+
+/*!
+ * This stops the DMA channel and any ongoing transfers. Subsequent use of
+ * mxc_dma_enable() will restart the channel and restart the transfer.
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @return returns a negative number on error or 0 on success
+ */
+int mxc_dma_disable(int channel_num)
+{
+ mxc_dma_channel_t *dma;
+ mx2_dma_priv_t *priv;
+ unsigned long ctrl_val;
+
+ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+ return -EINVAL;
+ }
+
+ dma = g_dma_channels + channel_num;
+
+ if (dma->lock == 0) {
+ return -EINVAL;
+ }
+
+ if (!dma->active) {
+ return -EINVAL;
+ }
+
+ priv = (mx2_dma_priv_t *) dma->private;
+ if (priv == NULL) {
+ printk(KERN_ERR "disable a uncompleted dma channel %d\n",
+ channel_num);
+ return -EFAULT;
+ }
+
+ dma->active = 0;
+ enable_dma_clk();
+
+ __clear_dma_interrupt(channel_num);
+ ctrl_val =
+ __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_CCR(channel_num));
+ ctrl_val &= ~DMA_CTL_CEN; /* clear CEN bit */
+ __raw_writel(ctrl_val,
+ IO_ADDRESS(DMA_BASE_ADDR) + DMA_CCR(channel_num));
+ disable_dma_clk();
+ atomic_dec(&g_dma_actived);
+
+ /*TODO: Clear all request buffers */
+ flush_dma_bd(priv);
+ return 0;
+}
+
+/*!
+ * This starts DMA transfer. Or it restarts DMA on a stopped channel
+ * previously stopped with mxc_dma_disable().
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @return returns a negative number on error or 0 on success
+ */
+int mxc_dma_enable(int channel_num)
+{
+ mxc_dma_channel_t *dma;
+ mx2_dma_priv_t *priv;
+
+ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+ return -EINVAL;
+ }
+
+ dma = g_dma_channels + channel_num;
+
+ if (dma->lock == 0) {
+ return -EINVAL;
+ }
+
+ priv = (mx2_dma_priv_t *) dma->private;
+ if (priv == NULL) {
+ printk(KERN_ERR "enable a uncompleted dma channel %d\n",
+ channel_num);
+ return -EFAULT;
+ }
+
+ if (dma->active) {
+ return 0;
+ }
+ dma->active = 1;
+ priv->trans_bytes = 0;
+
+ enable_dma_clk();
+
+ atomic_inc(&g_dma_actived);
+ __clear_dma_interrupt(channel_num);
+
+ setup_dmac(dma);
+ disable_dma_clk();
+ return 0;
+}
+
+/*!
+*@brief Dump DMA registers
+*
+*@param channel Requested channel NO.
+*@return none
+*/
+
+void mxc_dump_dma_register(int channel)
+{
+ mxc_dma_channel_t *dma = &g_dma_channels[channel];
+ mx2_dma_priv_t *priv = (mx2_dma_priv_t *) dma->private;
+ dma_regs_t *dma_base;
+
+ printk(KERN_INFO "======== Dump dma channel %d \n", channel);
+ if ((unsigned)channel >= MXC_DMA_CHANNELS) {
+ printk(KERN_INFO "Channel number is invalid \n");
+ return;
+ }
+ if (!dma->lock) {
+ printk(KERN_INFO "Channel is not allocated \n");
+ return;
+ }
+
+ printk(KERN_INFO "g_dma_actived = %d\n", atomic_read(&g_dma_actived));
+
+ enable_dma_clk();
+ dma_base = (dma_regs_t *) (priv->dma_base);
+ printk(KERN_INFO "DMA COMMON REGISTER\n");
+ printk(KERN_INFO "DMA CONTROL DMA_DCR: %08x\n",
+ __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DCR));
+ printk(KERN_INFO "DMA Interrupt status DMA_DISR: %08x\n",
+ __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DISR));
+ printk(KERN_INFO "DMA Interrupt Mask DMA_DIMR: %08x\n",
+ __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DIMR));
+ printk(KERN_INFO "DMA Burst Time Out DMA_DBTOSR: %08x\n",
+ __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DBTOSR));
+ printk(KERN_INFO "DMA request Time Out DMA_DRTOSR: %08x\n",
+ __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DRTOSR));
+ printk(KERN_INFO "DMA Transfer Error DMA_DSESR: %08x\n",
+ __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DSESR));
+ printk(KERN_INFO "DMA DMA_Overflow DMA_DBOSR: %08x\n",
+ __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DBOSR));
+ printk(KERN_INFO "DMA Burst Time OutCtl DMA_BurstTOCtl: %08x\n",
+ __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_DBTOCR));
+
+ printk(KERN_INFO "DMA 2D X size: %08x\n",
+ __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_XSRA));
+ printk(KERN_INFO "DMA 2D Y size: %08x\n",
+ __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_YSRA));
+ printk(KERN_INFO "DMA 2D Z size: %08x\n",
+ __raw_readl(IO_ADDRESS(DMA_BASE_ADDR) + DMA_WSRA));
+
+ printk(KERN_INFO "DMA Chan %2d Sourc SourceAddr: %08x\n", channel,
+ __raw_readl(&(dma_base->SourceAddr)));
+ printk(KERN_INFO "DMA Chan %2d dest DestAddr: %08x\n", channel,
+ __raw_readl(&(dma_base->DestAddr)));
+ printk(KERN_INFO "DMA Chan %2d count Count: %08x\n", channel,
+ __raw_readl(&(dma_base->Count)));
+ printk(KERN_INFO "DMA Chan %2d Ctl Ctl: %08x\n", channel,
+ __raw_readl(&(dma_base->Ctl)));
+ printk(KERN_INFO "DMA Chan %2d request RequestSource: %08x\n",
+ channel, __raw_readl(&(dma_base->RequestSource)));
+ printk(KERN_INFO "DMA Chan %2d burstL BurstLength: %08x\n", channel,
+ __raw_readl(&(dma_base->BurstLength)));
+ printk(KERN_INFO "DMA Chan %2d requestTO ReqTimeout: %08x\n", channel,
+ __raw_readl(&(dma_base->ReqTimeout)));
+ printk(KERN_INFO "DMA Chan %2d BusUtilt BusUtilt: %08x\n", channel,
+ __raw_readl(&(dma_base->BusUtilt)));
+
+ disable_dma_clk();
+}
+
+#ifdef DMA_PM
+
+static int channel_in_use(void)
+{
+ int i;
+ for (i = 0; i < MXC_DMA_CHANNELS; i++) {
+ if (dma_chan[i].lock)
+ return 1;
+ }
+ return 0;
+}
+
+int mxc_dma_pm_standby(void)
+{
+ unsigned long reg;
+ if (dma_pm_status == DMA_PMST_STANDBY)
+ return 0;
+
+ if (!channel_in_use()) {
+ /*Disable DMA */
+ __disable_dma_clk();
+ dma_pm_status = DMA_PMST_STANDBY;
+ return 0;
+ }
+ return -1;
+}
+
+int mxc_dma_pm_resume(void)
+{
+ unsigned long reg;
+ if (dma_pm_status == DMA_PMST_RESUME)
+ return 0;
+
+ /*Enable HCLK_DMA and DMA(ipg clock) */
+ dma_pm_status = DMA_PMST_RESUME;
+ return 0;
+}
+
+int mxc_dma_pm_suspend(void)
+{
+ unsigned long reg;
+ if (dma_pm_status == DMA_PMST_SUSPEND)
+ return 0;
+
+ if (!channel_in_use()) {
+ /*Disable DMA */
+ __disable_dma_clk();
+ dma_pm_status = DMA_PMST_SUSPEND;
+ return 0;
+ }
+ return -1;
+}
+
+int mxc_dma_pm_handler(struct pm_dev *dev, pm_request_t rqst, void *data)
+{
+ int ret = 0;
+ switch (rqst) {
+ /*APM doesn't send PM_STANDBY and PM_STANDBY_RESUME request now. */
+ case PM_SUSPEND:
+ ret = dma_pm_suspend();
+ break;
+ case PM_RESUME:
+ ret = dma_pm_resume();
+ break;
+ }
+ return ret;
+}
+
+#endif /*DMA_PM */
+
+int __init mxc_dma_init(void)
+{
+ int i;
+ mxc_dma_channel_t *dma = g_dma_channels;
+ mx2_dma_priv_t *private = g_dma_privates;
+
+ memset(dma, 0, sizeof(mxc_dma_channel_t) * MXC_DMA_CHANNELS);
+ for (i = 0; i < MXC_DMA_CHANNELS; i++, dma++, private++) {
+ dma->channel = i;
+ dma->private = private;
+ private->dma_base =
+ (unsigned int)(IO_ADDRESS(DMA_BASE_ADDR + DMA_CH_BASE(i)));
+ private->dma_irq = i + MXC_DMA_INTR_0; /*Dma channel interrupt number */
+ private->bd_ring = &g_dma_bd_table[i][0];
+ }
+
+ mxc_dma_load_info(g_dma_channels);
+
+ dma_clk = clk_get(NULL, "dma_clk");
+ clk_enable(dma_clk);
+
+ __raw_writel(0x2, IO_ADDRESS(DMA_BASE_ADDR) + DMA_DCR); /*reset DMA; */
+
+ disable_dma_clk();
+
+ /*use module init because create_proc after init_dma */
+ g_proc_dir = create_proc_entry("dma", 0, NULL);
+ g_proc_dir->read_proc = (read_proc_t *) mxc_get_dma_list;
+ g_proc_dir->data = NULL;
+
+#ifdef DMA_PM
+ /* Register the device with power management. */
+ dma_pm = pm_register(PM_DMA_DEV, PM_SYS_UNKNOWN, dma_pm_handler);
+#endif
+
+ return 0;
+}
+
+arch_initcall(mxc_dma_init);
+
+EXPORT_SYMBOL(mxc_dma_request);
+EXPORT_SYMBOL(mxc_dma_free);
+EXPORT_SYMBOL(mxc_dma_callback_set);
+EXPORT_SYMBOL(mxc_dma_enable);
+EXPORT_SYMBOL(mxc_dma_disable);
+EXPORT_SYMBOL(mxc_dma_config);
+EXPORT_SYMBOL(mxc_dma_sg_config);
+EXPORT_SYMBOL(mxc_dump_dma_register);
diff --git a/arch/arm/plat-mxc/dptc.c b/arch/arm/plat-mxc/dptc.c
new file mode 100644
index 000000000000..0dd286c7a45a
--- /dev/null
+++ b/arch/arm/plat-mxc/dptc.c
@@ -0,0 +1,612 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file dptc.c
+ *
+ * @brief Driver for the Freescale Semiconductor MXC DPTC module.
+ *
+ * The DPTC driver is designed to control the MXC DPTC hardware.
+ * hardware. Upon initialization, the DPTC driver initializes the DPTC hardware
+ * sets up driver nodes attaches to the DPTC interrupt and initializes internal
+ * data structures. When the DPTC interrupt occurs the driver checks the cause
+ * of the interrupt (lower frequency, increase frequency or emergency) and changes
+ * the CPU voltage according to translation table that is loaded into the driver.
+ * The driver read method is used to read the log buffer.
+ * Driver ioctls are used to change driver parameters and enable/disable the
+ * DVFS operation.
+ *
+ * @ingroup PM
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/fs.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/jiffies.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/regulator/regulator.h>
+
+#include <mach/clock.h>
+#include <mach/gpio.h>
+#include <mach/hardware.h>
+#include <mach/mxc_dptc.h>
+
+enum {
+ DPTC_PTVAI_NOCHANGE = 0x0,
+ DPTC_PTVAI_DECREASE,
+ DPTC_PTVAI_INCREASE,
+ DPTC_PTVAI_EMERG,
+};
+
+struct device *dev_data0;
+struct device *dev_data1;
+
+/*!
+ * In case the MXC device has multiple DPTC modules, this structure is used to
+ * store information specific to each DPTC module.
+ */
+struct dptc_device {
+ /* DPTC delayed work */
+ struct delayed_work dptc_work;
+ /* DPTC spinlock */
+ spinlock_t lock;
+ /* DPTC regulator */
+ struct regulator *dptc_reg;
+ /* DPTC clock */
+ struct clk *dptc_clk;
+ /* DPTC is active flag */
+ int dptc_is_active;
+ /* turbo mode active flag */
+ int turbo_mode_active;
+ /* DPTC current working point */
+ int curr_wp;
+ /* DPTC vai bits */
+ u32 ptvai;
+ /* The interrupt number used by the DPTC device */
+ int irq;
+ /* DPTC platform data pointer */
+ struct mxc_dptc_data *dptc_platform_data;
+};
+
+static void update_dptc_wp(struct dptc_device *drv_data, u32 wp)
+{
+ struct mxc_dptc_data *dptc_data = drv_data->dptc_platform_data;
+ int voltage_uV;
+ int ret = 0;
+
+ voltage_uV = mV_to_uV(dptc_data->dptc_wp_allfreq[wp].voltage);
+
+ __raw_writel(dptc_data->dptc_wp_allfreq[wp].dcvr0,
+ dptc_data->dcvr0_reg_addr);
+ __raw_writel(dptc_data->dptc_wp_allfreq[wp].dcvr1,
+ dptc_data->dcvr0_reg_addr + 0x4);
+ __raw_writel(dptc_data->dptc_wp_allfreq[wp].dcvr2,
+ dptc_data->dcvr0_reg_addr + 0x8);
+ __raw_writel(dptc_data->dptc_wp_allfreq[wp].dcvr3,
+ dptc_data->dcvr0_reg_addr + 0xC);
+
+ /* Set the voltage */
+ ret = regulator_set_voltage(drv_data->dptc_reg, voltage_uV);
+ if (ret < 0)
+ printk(KERN_DEBUG "COULD NOT SET VOLTAGE!!!!!\n");
+
+ pr_debug("dcvr0-3: 0x%x, 0x%x, 0x%x, 0x%x; vol: %d\n",
+ dptc_data->dptc_wp_allfreq[wp].dcvr0,
+ dptc_data->dptc_wp_allfreq[wp].dcvr1,
+ dptc_data->dptc_wp_allfreq[wp].dcvr2,
+ dptc_data->dptc_wp_allfreq[wp].dcvr3,
+ dptc_data->dptc_wp_allfreq[wp].voltage);
+}
+
+static irqreturn_t dptc_irq(int irq, void *dev_id)
+{
+ struct device *dev = dev_id;
+ struct dptc_device *drv_data = dev->driver_data;
+ struct mxc_dptc_data *dptc_data = dev->platform_data;
+ u32 dptccr = __raw_readl(dptc_data->dptccr_reg_addr);
+ u32 gpc_cntr = __raw_readl(dptc_data->gpc_cntr_reg_addr);
+
+ gpc_cntr = (gpc_cntr & dptc_data->dptccr);
+
+ if (gpc_cntr) {
+ drv_data->ptvai =
+ (dptccr & dptc_data->vai_mask) >> dptc_data->vai_offset;
+ pr_debug("dptc_irq: vai = 0x%x (0x%x)!!!!!!!\n",
+ drv_data->ptvai, dptccr);
+
+ /* disable DPTC and mask its interrupt */
+ dptccr = (dptccr & ~(dptc_data->dptc_enable_bit)) |
+ (dptc_data->irq_mask);
+ dptccr = (dptccr & ~(dptc_data->dptc_nvcr_bit));
+ __raw_writel(dptccr, dptc_data->dptccr_reg_addr);
+
+ if (drv_data->turbo_mode_active == 1)
+ schedule_delayed_work(&drv_data->dptc_work, 0);
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+}
+
+static void dptc_workqueue_handler(struct work_struct *work1)
+{
+ struct delayed_work *dptc_work_tmp =
+ container_of(work1, struct delayed_work, work);
+ struct dptc_device *drv_data =
+ container_of(dptc_work_tmp, struct dptc_device, dptc_work);
+ struct mxc_dptc_data *dptc_data = drv_data->dptc_platform_data;
+ u32 dptccr = __raw_readl(dptc_data->dptccr_reg_addr);
+
+ switch (drv_data->ptvai) {
+ case DPTC_PTVAI_DECREASE:
+ drv_data->curr_wp++;
+ break;
+ case DPTC_PTVAI_INCREASE:
+ case DPTC_PTVAI_EMERG:
+ drv_data->curr_wp--;
+ if (drv_data->curr_wp < 0) {
+ /* already max voltage */
+ drv_data->curr_wp = 0;
+ printk(KERN_WARNING "dptc: already maximum voltage\n");
+ }
+ break;
+
+ /* Unknown interrupt cause */
+ default:
+ BUG();
+ }
+
+ if (drv_data->curr_wp > dptc_data->dptc_wp_supported
+ || drv_data->curr_wp < 0) {
+ panic("Can't support this working point: %d\n",
+ drv_data->curr_wp);
+ }
+ update_dptc_wp(drv_data, drv_data->curr_wp);
+
+ /* Enable DPTC and unmask its interrupt */
+ dptccr = (dptccr & ~(dptc_data->irq_mask)) |
+ dptc_data->dptc_nvcr_bit | dptc_data->dptc_enable_bit;
+ __raw_writel(dptccr, dptc_data->dptccr_reg_addr);
+}
+
+/* Start DPTC unconditionally */
+static int start_dptc(struct device *dev)
+{
+ struct mxc_dptc_data *dptc_data = dev->platform_data;
+ struct dptc_device *drv_data = dev->driver_data;
+ u32 dptccr;
+ unsigned long flags;
+ unsigned long clk_rate;
+ int voltage_mV;
+
+ /* Get the voltage */
+ voltage_mV = uV_to_mV(regulator_get_voltage(drv_data->dptc_reg));
+ drv_data->curr_wp =
+ (dptc_data->dptc_wp_allfreq[0].voltage - voltage_mV) / 25;
+
+ update_dptc_wp(drv_data, drv_data->curr_wp);
+
+ /* Set the voltage */
+ spin_lock_irqsave(&drv_data->lock, flags);
+
+ clk_rate = clk_get_rate(drv_data->dptc_clk);
+
+ if (clk_rate < dptc_data->clk_max_val)
+ goto err;
+
+ if (dptc_data->gpc_irq_bit != 0x0) {
+ /* Enable ARM domain frequency and/or voltage update needed
+ and enable ARM IRQ */
+ __raw_writel(dptc_data->gpc_irq_bit | dptc_data->gpc_adu,
+ dptc_data->gpc_cntr_reg_addr);
+ }
+
+ dptccr = __raw_readl(dptc_data->dptccr_reg_addr);
+
+ /* Enable DPTC and unmask its interrupt */
+ dptccr = ((dptccr & ~(dptc_data->irq_mask)) | dptc_data->enable_config);
+
+ __raw_writel(dptccr, dptc_data->dptccr_reg_addr);
+
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+
+ drv_data->dptc_is_active = 1;
+ drv_data->turbo_mode_active = 1;
+
+ pr_info("DPTC has been started \n");
+
+ return 0;
+
+err:
+ spin_unlock_irqrestore(&drv_data->lock, flags);
+ pr_info("DPTC is not enabled\n");
+ return -1;
+}
+
+/* Stop DPTC unconditionally */
+static void stop_dptc(struct device *dev)
+{
+ struct mxc_dptc_data *dptc_data = dev->platform_data;
+ struct dptc_device *drv_data = dev->driver_data;
+ u32 dptccr;
+
+ dptccr = __raw_readl(dptc_data->dptccr_reg_addr);
+
+ /* disable DPTC and mask its interrupt */
+ dptccr = ((dptccr & ~(dptc_data->dptc_enable_bit)) |
+ dptc_data->irq_mask) & (~dptc_data->dptc_nvcr_bit);
+
+ __raw_writel(dptccr, dptc_data->dptccr_reg_addr);
+
+ /* Restore Turbo Mode voltage to highest wp */
+ update_dptc_wp(drv_data, 0);
+ drv_data->curr_wp = 0;
+
+ regulator_put(drv_data->dptc_reg, NULL);
+
+ pr_info("DPTC has been stopped\n");
+}
+
+/*
+ This function does not change the working point. It can be
+ called from an interrupt context.
+*/
+void dptc_suspend(int id)
+{
+ struct mxc_dptc_data *dptc_data;
+ struct dptc_device *drv_data;
+ u32 dptccr;
+
+ switch (id) {
+ case DPTC_GP_ID:
+ dptc_data = dev_data0->platform_data;
+ drv_data = dev_data0->driver_data;
+ break;
+ case DPTC_LP_ID:
+ if (dev_data1 == NULL)
+ return;
+
+ dptc_data = dev_data1->platform_data;
+ drv_data = dev_data1->driver_data;
+ break;
+ /* Unknown DPTC ID */
+ default:
+ return;
+ }
+
+ if (!drv_data->dptc_is_active)
+ return;
+
+ dptccr = __raw_readl(dptc_data->dptccr_reg_addr);
+
+ /* Disable DPTC and mask its interrupt */
+ dptccr = (dptccr & ~(dptc_data->dptc_enable_bit)) | dptc_data->irq_mask;
+
+ __raw_writel(dptccr, dptc_data->dptccr_reg_addr);
+}
+EXPORT_SYMBOL(dptc_suspend);
+
+/*
+ This function does not change the working point. It can be
+ called from an interrupt context.
+*/
+void dptc_resume(int id)
+{
+ struct mxc_dptc_data *dptc_data;
+ struct dptc_device *drv_data;
+ u32 dptccr;
+
+ switch (id) {
+ case DPTC_GP_ID:
+ dptc_data = dev_data0->platform_data;
+ drv_data = dev_data0->driver_data;
+ break;
+ case DPTC_LP_ID:
+ if (dev_data1 == NULL)
+ return;
+
+ dptc_data = dev_data1->platform_data;
+ drv_data = dev_data1->driver_data;
+ break;
+ /* Unknown DPTC ID */
+ default:
+ return;
+ }
+
+ if (!drv_data->dptc_is_active)
+ return;
+
+ __raw_writel(dptc_data->dptc_wp_allfreq[0].dcvr0,
+ dptc_data->dcvr0_reg_addr);
+ __raw_writel(dptc_data->dptc_wp_allfreq[0].dcvr1,
+ dptc_data->dcvr0_reg_addr + 0x4);
+ __raw_writel(dptc_data->dptc_wp_allfreq[0].dcvr2,
+ dptc_data->dcvr0_reg_addr + 0x8);
+ __raw_writel(dptc_data->dptc_wp_allfreq[0].dcvr3,
+ dptc_data->dcvr0_reg_addr + 0xC);
+
+ dptccr = __raw_readl(dptc_data->dptccr_reg_addr);
+
+ /* Enable DPTC and unmask its interrupt */
+ dptccr = (dptccr & ~(dptc_data->irq_mask)) | dptc_data->dptc_enable_bit;
+
+ __raw_writel(dptccr, dptc_data->dptccr_reg_addr);
+}
+EXPORT_SYMBOL(dptc_resume);
+
+/*!
+ * This function is called to put the DPTC in a low power state.
+ *
+ */
+void dptc_disable(struct device *dev)
+{
+ struct dptc_device *drv_data = dev->driver_data;
+
+ if (!(drv_data->dptc_is_active))
+ return;
+
+ stop_dptc(dev);
+ drv_data->dptc_is_active = 0;
+ drv_data->turbo_mode_active = 0;
+}
+
+/*!
+ * This function is called to resume the DPTC from a low power state.
+ *
+ */
+int dptc_enable(struct device *dev)
+{
+ struct dptc_device *drv_data = dev->driver_data;
+
+ if (drv_data->dptc_is_active)
+ return 0;
+
+ return start_dptc(dev);
+}
+
+static ssize_t dptc_show(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct dptc_device *drv_data = dev->driver_data;
+
+ if (drv_data->dptc_is_active)
+ return sprintf(buf, "DPTC is enabled\n");
+ else
+ return sprintf(buf, "DPTC is disabled\n");
+}
+
+static ssize_t dptc_store(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ if (strstr(buf, "0") != NULL) {
+ dptc_disable(dev);
+ } else if (strstr(buf, "1") != NULL) {
+ dptc_enable(dev);
+ }
+
+ return size;
+}
+
+static DEVICE_ATTR(enable, 0644, dptc_show, dptc_store);
+
+/*!
+ * This is the probe routine for the DPTC driver.
+ *
+ * @param pdev The platform device structure
+ *
+ * @return The function returns 0 on success
+ *
+ */
+static int __devinit mxc_dptc_probe(struct platform_device *pdev)
+{
+ struct dptc_device *dptc_device_data;
+ int ret = 0;
+ struct resource *res;
+ u32 dptccr = 0;
+ struct clk *ckih_clk;
+ struct mxc_dptc_data *dptc_data = pdev->dev.platform_data;
+
+ if (dptc_data == NULL) {
+ printk(KERN_ERR "DPTC: Pointer to DPTC data is NULL\
+ not started\n");
+ return -1;
+ }
+
+ dptc_device_data = kzalloc(sizeof(struct dptc_device), GFP_KERNEL);
+ if (!dptc_device_data)
+ return -ENOMEM;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ ret = -ENODEV;
+ goto err1;
+ }
+
+ /*
+ * Request the DPTC interrupt
+ */
+ dptc_device_data->irq = platform_get_irq(pdev, 0);
+ if (dptc_device_data->irq < 0) {
+ ret = dptc_device_data->irq;
+ goto err1;
+ }
+
+ ret =
+ request_irq(dptc_device_data->irq, dptc_irq, IRQF_SHARED,
+ pdev->name, &pdev->dev);
+ if (ret) {
+ printk(KERN_ERR "DPTC: Unable to attach to DPTC interrupt\n");
+ goto err1;
+ }
+
+ dptc_device_data->curr_wp = 0;
+ dptc_device_data->dptc_is_active = 0;
+ dptc_device_data->turbo_mode_active = 0;
+ dptc_device_data->ptvai = 0;
+
+ dptccr = __raw_readl(dptc_data->dptccr_reg_addr);
+
+ printk(KERN_INFO "DPTC mxc_dptc_probe()\n");
+
+ spin_lock_init(&dptc_device_data->lock);
+
+ if (dptc_data->dptc_wp_allfreq == NULL) {
+ ckih_clk = clk_get(NULL, "ckih");
+ if (cpu_is_mx31() &
+ (mxc_cpu_is_rev(CHIP_REV_2_0) < 0) &
+ (clk_get_rate(ckih_clk) == 27000000))
+ printk(KERN_ERR "DPTC: DPTC not supported on TO1.x \
+ & ckih = 27M\n");
+ else
+ printk(KERN_ERR "DPTC: Pointer to DPTC table is NULL\
+ not started\n");
+ goto err1;
+ }
+
+ dptc_device_data->dptc_reg = regulator_get(NULL, dptc_data->reg_id);
+ if (IS_ERR(dptc_device_data->dptc_reg)) {
+ clk_put(dptc_device_data->dptc_clk);
+ printk(KERN_ERR "%s: failed to get regulator\n", __func__);
+ goto err1;
+ }
+
+ INIT_DELAYED_WORK(&dptc_device_data->dptc_work, dptc_workqueue_handler);
+
+ /* Enable Reference Circuits */
+ dptccr = (dptccr & ~(dptc_data->dcr_mask)) | dptc_data->init_config;
+ __raw_writel(dptccr, dptc_data->dptccr_reg_addr);
+
+ ret = sysfs_create_file(&pdev->dev.kobj, &dev_attr_enable.attr);
+ if (ret) {
+ printk(KERN_ERR
+ "DPTC: Unable to register sysdev entry for dptc");
+ goto err1;
+ }
+
+ if (ret != 0) {
+ printk(KERN_ERR "DPTC: Unable to start");
+ goto err1;
+ }
+
+ dptc_device_data->dptc_clk = clk_get(NULL, dptc_data->clk_id);
+
+ if (pdev->id == 0)
+ dev_data0 = &pdev->dev;
+ else
+ dev_data1 = &pdev->dev;
+
+ dptc_device_data->dptc_platform_data = pdev->dev.platform_data;
+
+ /* Set driver data */
+ platform_set_drvdata(pdev, dptc_device_data);
+
+ return 0;
+
+err1:
+ dev_err(&pdev->dev, "Failed to probe DPTC\n");
+ kfree(dptc_device_data);
+ return ret;
+}
+
+/*!
+ * This function is called to put DPTC in a low power state.
+ *
+ * @param pdev the device structure
+ * @param state the power state the device is entering
+ *
+ * @return The function always returns 0.
+ */
+static int mxc_dptc_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ struct dptc_device *drv_data = pdev->dev.driver_data;
+
+ if (drv_data->dptc_is_active)
+ stop_dptc(&pdev->dev);
+
+ return 0;
+}
+
+/*!
+ * This function is called to resume the MU from a low power state.
+ *
+ * @param dev the device structure
+ * @param level the stage in device suspension process that we want the
+ * device to be put in
+ *
+ * @return The function always returns 0.
+ */
+static int mxc_dptc_resume(struct platform_device *pdev)
+{
+ struct dptc_device *drv_data = pdev->dev.driver_data;
+
+ if (drv_data->dptc_is_active)
+ return start_dptc(&pdev->dev);
+
+ return 0;
+}
+
+static struct platform_driver mxc_dptc_driver = {
+ .driver = {
+ .name = "mxc_dptc",
+ .owner = THIS_MODULE,
+ },
+ .probe = mxc_dptc_probe,
+ .suspend = mxc_dptc_suspend,
+ .resume = mxc_dptc_resume,
+};
+
+/*!
+ * This function is called to resume the MU from a low power state.
+ *
+ * @param dev the device structure used to give information on which MU
+ * device (0 through 3 channels) to suspend
+ * @param level the stage in device suspension process that we want the
+ * device to be put in
+ *
+ * @return The function always returns 0.
+ */
+
+static int __init dptc_init(void)
+{
+ if (platform_driver_register(&mxc_dptc_driver) != 0) {
+ printk(KERN_ERR "mxc_dptc_driver register failed\n");
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "DPTC driver module loaded\n");
+
+ return 0;
+}
+
+static void __exit dptc_cleanup(void)
+{
+ /* Unregister the device structure */
+ platform_driver_unregister(&mxc_dptc_driver);
+
+ printk("DPTC driver module unloaded\n");
+}
+
+module_init(dptc_init);
+module_exit(dptc_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("DPTC driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/dvfs_core.c b/arch/arm/plat-mxc/dvfs_core.c
new file mode 100644
index 000000000000..d6a42527b149
--- /dev/null
+++ b/arch/arm/plat-mxc/dvfs_core.c
@@ -0,0 +1,576 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file dvfs_core.c
+ *
+ * @brief A simplied driver for the Freescale Semiconductor MXC DVFS module.
+ *
+ * Upon initialization, the DVFS driver initializes the DVFS hardware
+ * sets up driver nodes attaches to the DVFS interrupt and initializes internal
+ * data structures. When the DVFS interrupt occurs the driver checks the cause
+ * of the interrupt (lower frequency, increase frequency or emergency) and
+ * changes the CPU voltage according to translation table that is loaded into
+ * the driver.
+ *
+ * @ingroup PM
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/fs.h>
+#include <linux/interrupt.h>
+#include <linux/jiffies.h>
+#include <linux/device.h>
+#include <linux/sysdev.h>
+#include <linux/delay.h>
+#include <linux/clk.h>
+#include <linux/regulator/regulator.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+
+#define MXC_DVFSTHRS_UPTHR_MASK 0x0FC00000
+#define MXC_DVFSTHRS_UPTHR_OFFSET 22
+#define MXC_DVFSTHRS_DNTHR_MASK 0x003F0000
+#define MXC_DVFSTHRS_DNTHR_OFFSET 16
+#define MXC_DVFSTHRS_PNCTHR_MASK 0x0000003F
+#define MXC_DVFSTHRS_PNCTHR_OFFSET 0
+
+#define MXC_DVFSCOUN_DNCNT_MASK 0x00FF0000
+#define MXC_DVFSCOUN_DNCNT_OFFSET 16
+#define MXC_DVFSCOUN_UPCNT_MASK 0x000000FF
+#define MXC_DVFSCOUN_UPCNT_OFFSET 0
+
+#define MXC_DVFSEMAC_EMAC_MASK 0x000001FF
+#define MXC_DVFSEMAC_EMAC_OFFSET 0
+
+#define MXC_DVFSCNTR_DVFEV 0x10000000
+#define MXC_DVFSCNTR_LBMI 0x08000000
+#define MXC_DVFSCNTR_LBFL 0x06000000
+#define MXC_DVFSCNTR_DVFIS 0x01000000
+#define MXC_DVFSCNTR_FSVAIM 0x00400000
+#define MXC_DVFSCNTR_FSVAI_MASK 0x00300000
+#define MXC_DVFSCNTR_FSVAI_OFFSET 20
+#define MXC_DVFSCNTR_WFIM 0x00080000
+#define MXC_DVFSCNTR_WFIM_OFFSET 19
+#define MXC_DVFSCNTR_MAXF_MASK 0x00040000
+#define MXC_DVFSCNTR_MAXF_OFFSET 18
+#define MXC_DVFSCNTR_MINF_MASK 0x00020000
+#define MXC_DVFSCNTR_MINF_OFFSET 17
+#define MXC_DVFSCNTR_LTBRSR_MASK 0x00000018
+#define MXC_DVFSCNTR_LTBRSR_OFFSET 3
+#define MXC_DVFSCNTR_DVFEN 0x00000001
+
+#define MXC_GPCCNTR_GPCIRQ 0x00100000
+#define MXC_GPCCNTR_DVFS0CR 0x00010000
+#define MXC_GPCCNTR_ADU 0x00008000
+#define MXC_GPCCNTR_STRT 0x00004000
+#define MXC_GPCCNTR_FUPD 0x00002000
+#define MXC_GPCCNTR_HTRI_MASK 0x0000000F
+#define MXC_GPCCNTR_HTRI_OFFSET 0
+
+#define MXC_GPCVCR_VINC_MASK 0x00020000
+#define MXC_GPCVCR_VINC_OFFSET 17
+#define MXC_GPCVCR_VCNTU_MASK 0x00010000
+#define MXC_GPCVCR_VCNTU_OFFSET 16
+#define MXC_GPCVCR_VCNT_MASK 0x00007FFF
+#define MXC_GPCVCR_VCNT_OFFSET 0
+
+static struct delayed_work dvfs_core_work;
+static struct mxc_dvfs_platform_data *dvfs_data;
+static struct device *dvfs_dev;
+static struct cpu_wp *cpu_wp_tbl;
+int curr_wp;
+int dvfs_core_is_active;
+
+/*
+ * Clock structures
+ */
+static struct clk *cpu_clk;
+static struct clk *dvfs_clk;
+static struct regulator *core_regulator;
+
+enum {
+ FSVAI_FREQ_NOCHANGE = 0x0,
+ FSVAI_FREQ_INCREASE,
+ FSVAI_FREQ_DECREASE,
+ FSVAI_FREQ_EMERG,
+};
+
+/*
+ * Load tracking buffer source: 1 for ld_add; 0 for pre_ld_add; 2 for after EMA
+ */
+#define DVFS_LTBRSR (2 << MXC_DVFSCNTR_LTBRSR_OFFSET)
+
+DEFINE_SPINLOCK(mxc_dvfs_core_lock);
+
+static void dvfs_load_config(void)
+{
+ u32 reg;
+
+ reg = 0;
+ reg |= dvfs_data->upthr_val << MXC_DVFSTHRS_UPTHR_OFFSET;
+ reg |= dvfs_data->dnthr_val << MXC_DVFSTHRS_DNTHR_OFFSET;
+ reg |= dvfs_data->pncthr_val;
+ __raw_writel(reg, dvfs_data->dvfs_thrs_reg_addr);
+
+ reg = 0;
+ reg |= dvfs_data->dncnt_val << MXC_DVFSCOUN_DNCNT_OFFSET;
+ reg |= dvfs_data->upcnt_val << MXC_DVFSCOUN_UPCNT_OFFSET;
+ __raw_writel(reg, dvfs_data->dvfs_coun_reg_addr);
+}
+
+static int start_dvfs(void)
+{
+ u32 reg;
+ unsigned long flags;
+
+ if (dvfs_core_is_active)
+ return 0;
+
+ spin_lock_irqsave(&mxc_dvfs_core_lock, flags);
+
+ clk_enable(dvfs_clk);
+
+ /* config reg GPC_CNTR */
+ reg = __raw_readl(dvfs_data->gpc_cntr_reg_addr);
+
+ /* GPCIRQ=1, select ARM IRQ */
+ reg |= MXC_GPCCNTR_GPCIRQ;
+ /* ADU=1, select ARM domain */
+ reg |= MXC_GPCCNTR_ADU;
+ __raw_writel(reg, dvfs_data->gpc_cntr_reg_addr);
+
+ /* Enable DVFS interrupt */
+ reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr);
+ /* FSVAIM=0 */
+ reg = (reg & ~MXC_DVFSCNTR_FSVAIM);
+ /* Set MAXF, MINF */
+ reg = (reg & ~(MXC_DVFSCNTR_MAXF_MASK | MXC_DVFSCNTR_MINF_MASK));
+ reg |= 1 << MXC_DVFSCNTR_MAXF_OFFSET;
+ /* Select ARM domain */
+ reg |= MXC_DVFSCNTR_DVFIS;
+ /* Enable DVFS frequency adjustment interrupt */
+ reg = (reg & ~MXC_DVFSCNTR_FSVAIM);
+ /* Set load tracking buffer register source */
+ reg = (reg & ~MXC_DVFSCNTR_LTBRSR_MASK);
+ reg |= DVFS_LTBRSR;
+ /* Set DIV3CK */
+ reg = (reg & ~(dvfs_data->div3ck_mask));
+ reg |= (dvfs_data->div3ck_val) << (dvfs_data->div3ck_offset);
+ /* Enable DVFS */
+ reg |= MXC_DVFSCNTR_DVFEN;
+ __raw_writel(reg, dvfs_data->dvfs_cntr_reg_addr);
+
+ dvfs_core_is_active = 1;
+
+ spin_unlock_irqrestore(&mxc_dvfs_core_lock, flags);
+
+ printk(KERN_DEBUG "DVFS is started\n");
+
+ return 0;
+}
+
+/*!
+ * This function is called for module initialization.
+ * It sets up the DVFS hardware.
+ * It sets default values for DVFS thresholds and counters. The default
+ * values was chosen from a set of different reasonable values. They was tested
+ * and the default values in the driver gave the best results.
+ * More work should be done to find optimal values.
+ *
+ * @return 0 if successful; non-zero otherwise.
+ *
+ */
+static int init_dvfs_controller(void)
+{
+ /* DVFS loading config */
+ dvfs_load_config();
+
+ /* Set EMAC value */
+ __raw_writel((dvfs_data->emac_val << MXC_DVFSEMAC_EMAC_OFFSET),
+ dvfs_data->dvfs_emac_reg_addr);
+
+ return 0;
+}
+
+static irqreturn_t dvfs_irq(int irq, void *dev_id)
+{
+ u32 reg;
+
+ /* Check if DVFS0 (ARM) id requesting for freqency/voltage update */
+ if ((__raw_readl(dvfs_data->gpc_cntr_reg_addr) & MXC_GPCCNTR_DVFS0CR) ==
+ 0)
+ return IRQ_NONE;
+
+ /* Mask DVFS irq */
+ reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr);
+ /* FSVAIM=1 */
+ reg |= MXC_DVFSCNTR_FSVAIM;
+ __raw_writel(reg, dvfs_data->dvfs_cntr_reg_addr);
+
+ schedule_delayed_work(&dvfs_core_work, 0);
+
+ return IRQ_HANDLED;
+}
+
+static void dvfs_core_workqueue_handler(struct work_struct *work)
+{
+ u32 fsvai;
+ u32 reg;
+ u32 curr_cpu;
+ unsigned long rate = 0;
+ int ret = 0;
+ int uvol;
+ int maxf = 0, minf = 0;
+
+ /* Check DVFS frequency adjustment interrupt status */
+ reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr);
+ fsvai = (reg & MXC_DVFSCNTR_FSVAI_MASK) >> MXC_DVFSCNTR_FSVAI_OFFSET;
+
+ /* Check FSVAI, FSVAI=0 is error */
+ if (fsvai == FSVAI_FREQ_NOCHANGE) {
+ /* Do nothing. Freq change is not required */
+ goto END;
+ }
+
+ curr_cpu = clk_get_rate(cpu_clk);
+
+ /* If FSVAI indicate freq down,
+ check arm-clk is not in lowest frequency 200 MHz */
+ if (fsvai == FSVAI_FREQ_DECREASE) {
+ if (curr_cpu == cpu_wp_tbl[dvfs_data->num_wp - 1].cpu_rate) {
+ minf = 1;
+ goto END;
+ } else {
+ /* freq down */
+ curr_wp++;
+ if (curr_wp >= dvfs_data->num_wp) {
+ curr_wp = dvfs_data->num_wp - 1;
+ goto END;
+ }
+
+ rate = cpu_wp_tbl[curr_wp].cpu_rate;
+ uvol = cpu_wp_tbl[curr_wp].cpu_voltage;
+ if (curr_wp == dvfs_data->num_wp - 1)
+ minf = 1;
+
+ ret = clk_set_rate(cpu_clk, rate);
+ if (ret != 0) {
+ printk(KERN_DEBUG
+ "cannot set CPU clock rate\n");
+ goto END;
+ }
+
+ /* START the GPC main control FSM */
+ /* set VINC */
+ reg = __raw_readl(dvfs_data->gpc_vcr_reg_addr);
+ reg &=
+ ~(MXC_GPCVCR_VINC_MASK | MXC_GPCVCR_VCNTU_MASK |
+ MXC_GPCVCR_VCNT_MASK);
+ reg |=
+ (1 << MXC_GPCVCR_VCNTU_OFFSET) |
+ (100 << MXC_GPCVCR_VCNT_OFFSET);
+ __raw_writel(reg, dvfs_data->gpc_vcr_reg_addr);
+
+ /* Set the voltage for the GP domain. */
+ ret = regulator_set_voltage(core_regulator, uvol);
+ if (ret < 0) {
+ printk(KERN_DEBUG
+ "COULD NOT SET CORE VOLTAGE!!!!!\n");
+ goto END;
+ }
+ udelay(dvfs_data->delay_time);
+ }
+ } else {
+ if (curr_cpu == cpu_wp_tbl[0].cpu_rate) {
+ maxf = 1;
+ goto END;
+ } else {
+ /* freq up */
+ curr_wp = 0;
+ rate = cpu_wp_tbl[curr_wp].cpu_rate;
+ /* START the GPC main control FSM */
+ /* set VINC */
+ reg = __raw_readl(dvfs_data->gpc_vcr_reg_addr);
+ reg &=
+ ~(MXC_GPCVCR_VINC_MASK | MXC_GPCVCR_VCNTU_MASK |
+ MXC_GPCVCR_VCNT_MASK);
+ reg |=
+ (1 << MXC_GPCVCR_VCNTU_OFFSET) |
+ (100 << MXC_GPCVCR_VCNT_OFFSET);
+ __raw_writel(reg, dvfs_data->gpc_vcr_reg_addr);
+
+ ret = regulator_set_voltage(core_regulator,
+ cpu_wp_tbl[curr_wp].cpu_voltage);
+ if (ret < 0) {
+ printk(KERN_DEBUG
+ "COULD NOT SET CORE VOLTAGE!!!!\n");
+ goto END;
+ }
+ udelay(dvfs_data->delay_time);
+
+ ret = clk_set_rate(cpu_clk, cpu_wp_tbl[curr_wp].cpu_rate);
+ if (ret != 0)
+ printk(KERN_DEBUG
+ "cannot set CPU clock rate\n");
+ maxf = 1;
+ }
+ }
+
+END: /* Set MAXF, MINF */
+ reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr);
+ reg = (reg & ~(MXC_DVFSCNTR_MAXF_MASK | MXC_DVFSCNTR_MINF_MASK));
+ reg |= maxf << MXC_DVFSCNTR_MAXF_OFFSET;
+ reg |= minf << MXC_DVFSCNTR_MINF_OFFSET;
+
+ /* Enable FVFS interrupt */
+ /* FSVAIM=0 */
+ reg = (reg & ~MXC_DVFSCNTR_FSVAIM);
+ /* LBFL=1 */
+ reg = (reg & ~MXC_DVFSCNTR_LBFL);
+ reg |= MXC_DVFSCNTR_LBFL;
+ __raw_writel(reg, dvfs_data->dvfs_cntr_reg_addr);
+}
+
+/*!
+ * This function disables the DVFS module.
+ */
+static void stop_dvfs(void)
+{
+ u32 reg = 0;
+ unsigned long flags;
+ u32 curr_cpu;
+
+ if (dvfs_core_is_active) {
+ spin_lock_irqsave(&mxc_dvfs_core_lock, flags);
+
+ /* Mask dvfs irq, disable DVFS */
+ reg = __raw_readl(dvfs_data->dvfs_cntr_reg_addr);
+ /* FSVAIM=1 */
+ reg |= MXC_DVFSCNTR_FSVAIM;
+ reg = (reg & ~MXC_DVFSCNTR_DVFEN);
+ __raw_writel(reg, dvfs_data->dvfs_cntr_reg_addr);
+
+ dvfs_core_is_active = 0;
+ spin_unlock_irqrestore(&mxc_dvfs_core_lock, flags);
+
+ curr_wp = 0;
+ curr_cpu = clk_get_rate(cpu_clk);
+ if (curr_cpu != cpu_wp_tbl[curr_wp].cpu_rate) {
+ if (regulator_set_voltage(core_regulator,
+ cpu_wp_tbl[curr_wp].cpu_voltage) == 0)
+ clk_set_rate(cpu_clk, cpu_wp_tbl[curr_wp].cpu_rate);
+ }
+
+ clk_disable(dvfs_clk);
+ }
+
+ printk(KERN_DEBUG "DVFS is stopped\n");
+}
+
+static ssize_t dvfs_enable_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ if (dvfs_core_is_active)
+ return sprintf(buf, "DVFS is enabled\n");
+ else
+ return sprintf(buf, "DVFS is disabled\n");
+}
+
+
+static ssize_t dvfs_enable_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t size)
+{
+ if (strstr(buf, "1") != NULL) {
+ if (start_dvfs() != 0)
+ printk(KERN_ERR "Failed to start DVFS\n");
+ } else if (strstr(buf, "0") != NULL)
+ stop_dvfs();
+
+ return size;
+}
+
+static DEVICE_ATTR(enable, 0644, dvfs_enable_show, dvfs_enable_store);
+
+/*!
+ * This is the probe routine for the DVFS driver.
+ *
+ * @param pdev The platform device structure
+ *
+ * @return The function returns 0 on success
+ */
+static int __devinit mxc_dvfs_core_probe(struct platform_device *pdev)
+{
+ int err = 0;
+ struct resource *res;
+ int cpu_wp_nr;
+ int irq;
+
+ printk(KERN_INFO "mxc_dvfs_core_probe\n");
+ dvfs_dev = &pdev->dev;
+ dvfs_data = pdev->dev.platform_data;
+
+ INIT_DELAYED_WORK(&dvfs_core_work, dvfs_core_workqueue_handler);
+
+ cpu_clk = clk_get(NULL, dvfs_data->clk1_id);
+ if (IS_ERR(cpu_clk)) {
+ printk(KERN_ERR "%s: failed to get cpu clock\n", __func__);
+ return PTR_ERR(cpu_clk);
+ }
+
+ 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__);
+ return PTR_ERR(dvfs_clk);
+ }
+
+ core_regulator = regulator_get(NULL, dvfs_data->reg_id);
+ if (IS_ERR(core_regulator)) {
+ clk_put(cpu_clk);
+ clk_put(dvfs_clk);
+ printk(KERN_ERR "%s: failed to get gp regulator\n", __func__);
+ return PTR_ERR(core_regulator);
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ err = -ENODEV;
+ goto err1;
+ }
+
+ /*
+ * Request the DVFS interrupt
+ */
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0) {
+ err = irq;
+ goto err1;
+ }
+
+ /* request the DVFS interrupt */
+ err = request_irq(irq, dvfs_irq, IRQF_SHARED, "dvfs", dvfs_dev);
+ if (err)
+ printk(KERN_ERR
+ "DVFS: Unable to attach to DVFS interrupt,err = %d",
+ err);
+
+ clk_enable(dvfs_clk);
+ err = init_dvfs_controller();
+ if (err) {
+ printk(KERN_ERR "DVFS: Unable to initialize DVFS");
+ return err;
+ }
+ clk_disable(dvfs_clk);
+
+ err = sysfs_create_file(&dvfs_dev->kobj, &dev_attr_enable.attr);
+ if (err) {
+ printk(KERN_ERR
+ "DVFS: Unable to register sysdev entry for DVFS");
+ return err;
+ }
+
+ /* Set the current working point. */
+ cpu_wp_tbl = get_cpu_wp(&cpu_wp_nr);
+ curr_wp = 0;
+
+ return err;
+
+err1:
+ dev_err(&pdev->dev, "Failed to probe DVFS CORE\n");
+ return err;
+}
+
+/*!
+ * This function is called to put DPTC in a low power state.
+ *
+ * @param pdev the device structure
+ * @param state the power state the device is entering
+ *
+ * @return The function always returns 0.
+ */
+static int mxc_dvfs_core_suspend(struct platform_device *pdev,
+ pm_message_t state)
+{
+ if (dvfs_core_is_active)
+ stop_dvfs();
+
+ return 0;
+}
+
+/*!
+ * This function is called to resume the MU from a low power state.
+ *
+ * @param dev the device structure
+ * @param level the stage in device suspension process that we want the
+ * device to be put in
+ *
+ * @return The function always returns 0.
+ */
+static int mxc_dvfs_core_resume(struct platform_device *pdev)
+{
+ if (dvfs_core_is_active)
+ start_dvfs();
+
+ return 0;
+}
+
+static struct platform_driver mxc_dvfs_core_driver = {
+ .driver = {
+ .name = "mxc_dvfs_core",
+ },
+ .probe = mxc_dvfs_core_probe,
+ .suspend = mxc_dvfs_core_suspend,
+ .resume = mxc_dvfs_core_resume,
+};
+
+static int __init dvfs_init(void)
+{
+ if (platform_driver_register(&mxc_dvfs_core_driver) != 0) {
+ printk(KERN_ERR "mxc_dvfs_core_driver register failed\n");
+ return -ENODEV;
+ }
+
+ printk(KERN_INFO "DVFS driver module loaded\n");
+
+ return 0;
+}
+
+static void __exit dvfs_cleanup(void)
+{
+ stop_dvfs();
+
+ /* release the DVFS interrupt */
+ free_irq(MXC_INT_GPC1, NULL);
+
+ sysfs_remove_file(&dvfs_dev->kobj, &dev_attr_enable.attr);
+
+ /* Unregister the device structure */
+ platform_driver_unregister(&mxc_dvfs_core_driver);
+
+ clk_put(cpu_clk);
+ clk_put(dvfs_clk);
+
+ printk(KERN_INFO "DVFS driver module unloaded\n");
+
+}
+
+module_init(dvfs_init);
+module_exit(dvfs_cleanup);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("DVFS driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/entry-pm.S b/arch/arm/plat-mxc/entry-pm.S
new file mode 100644
index 000000000000..4a3af0e16191
--- /dev/null
+++ b/arch/arm/plat-mxc/entry-pm.S
@@ -0,0 +1,315 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file plat-mxc/entry-pm.S
+ *
+ * @brief This file contains common pm entry .
+ *
+ * @ingroup MXC_PM
+ */
+
+#include <asm/assembler.h>
+#include <asm/ptrace.h>
+#include <asm/memory.h>
+#include <asm/system.h>
+#include <mach/hardware.h>
+#include <asm/asm-offsets.h>
+#include <asm/thread_info.h>
+#include <asm/proc-fns.h>
+#include <asm/vfpmacros.h>
+
+#define WAIT_MODE 111
+#define DOZE_MODE 112
+#define STOP_MODE 113
+#define DSM_MODE 114
+
+#define PM_XLOAD_SIZE 0x04
+#define PM_XLOAD_ENTRY 0x08
+#define PM_XLOAD_SUSPEND_MODE 0x0C
+#define PM_XLOAD_CORE_SP 0x10
+
+#define PROCINFO_PROC_FNS 36
+#define PROC_FIN_FN 12
+#define PROC_IDLE_FN 20
+
+#ifdef CONFIG_FIQ
+#define ARM_CONTEXT_SIZE 12
+#else
+#define ARM_CONTEXT_SIZE 8
+#endif
+
+#ifdef CONFIG_PM_VERBOSE
+resume_str:
+ .string "Resume from DSM..."
+ .size resume_str, . - resume_str
+
+.macro show_resume_str
+ ldr r0, =resume_str
+ bl printk
+.endm
+
+#else
+.macro show_resume_str
+.endm
+#endif
+
+ .data
+ .align 3
+arm_core_context:
+ .rept ARM_CONTEXT_SIZE
+ .long 0
+ .endr
+
+#ifdef CONFIG_VFP
+ .text
+ .align 5
+arm_vfp_save:
+ mov ip, sp
+ stmdb sp!, {r0-r8, fp, ip, lr, pc}
+ sub fp, ip, #4
+ mov r1, #THREAD_SIZE
+ sub r1, r1, #1
+ bic r0, sp, r1
+ ldr r8, [r0, #TI_CPU]
+ add r4, r0, #TI_VFPSTATE
+
+ ldr r3, =last_VFP_context
+ VFPFMRX r2, FPEXC
+ tst r2, #FPEXC_EN
+ bne 1f
+
+ ldr r4, [r3, r8, lsl #2]
+ cmp r4, #0
+ beq dead_vfp
+1:
+ bic r1, r2, #FPEXC_EN
+ VFPFMXR FPEXC, r1
+ /*TODO: SMP */
+ VFPFSTMIA r4, r1
+ VFPFMRX r5, FPSCR
+ tst r2, #FPEXC_EX
+ VFPFMRX r6, FPINST, NE
+ tstne r2, #FPEXC_FP2V
+ VFPFMRX r7, FPINST2, NE
+ stmia r4, {r2, r5, r6, r7}
+
+ mov r1, #0
+ str r1, [r3, r8, lsl #2]
+dead_vfp:
+ ldmia sp, {r0-r8, fp, sp, pc}
+#endif
+/*
+ * The function just be called in this file
+ * Current r0 ~r4 are not saved.
+ * Otherwise, the working registers should be saved
+ */
+ .text
+ .align 5
+arm_core_save:
+ mov ip, sp
+ stmdb sp!, {r8, r9, sl, fp, ip, lr, pc}
+ sub fp, ip, #4
+ ldr r0, =arm_core_context
+ mov r3, r0
+ /* SVC mode */
+ mrs r1, spsr @Save spsr
+ mrs r2, cpsr @Save cpsr
+ stmia r0!, {r1, r2}
+ /* Abort mode */
+ msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | ABT_MODE
+ stmia r0!, {sp} @Save stack pointer for abort mode
+ msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | UND_MODE
+ stmia r0!, {sp} @Save stack pointer for undefine mode
+ msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | IRQ_MODE
+ stmia r0!, {sp} @Save stack pointer for irq mode
+#ifdef CONFIG_FIQ
+ msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | FIQ_MODE
+ /*Save general register and sp for fiq mode*/
+ stmia r0!, {r8-r9, sl, fp, ip, sp}
+#endif
+ ldr r0, [r3, #4]
+ msr cpsr_c, r0
+ ldmia sp, {r8-r9, sl, fp, sp, pc}
+
+/*
+ * The function just be called in this file
+ * Current r0 ~r4 are not saved.
+ * Otherwise, the working registers should be saved
+ */
+arm_core_restore:
+ mov ip, sp
+ stmdb sp!, {fp, ip, lr, pc}
+ sub fp, ip, #4
+ ldr r0, =arm_core_context
+ mov r3, r0
+ /* SVC mode */
+ add r0, r0, #8 @skip svc mode
+ /* Abort mode */
+ msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | ABT_MODE
+ ldmia r0!, {sp} @restore stack pointer for abort mode
+ msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | UND_MODE
+ ldmia r0!, {sp} @restore stack pointer for undefine mode
+ msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | IRQ_MODE
+ ldmia r0!, {sp} @restore stack pointer for irq mode
+#ifdef CONFIG_FIQ
+ msr cpsr_c, #PSR_F_BIT | PSR_I_BIT | FIQ_MODE
+ /*Save general register and sp for fiq mode*/
+ ldmia r0!, {r8-r9, sl, fp, ip, sp}
+#endif
+ ldmia r3!, {r1, r2}
+ msr cpsr, r2 @restore cpsr
+ msr spsr, r1 @restore spsr
+ ldmia sp, {fp, sp, pc}
+
+mxc_cp15_context:
+ .rept 16
+ .long 0
+ .endr
+
+ .align 5
+mxc_cp15_restore:
+ /* Physical address */
+ adr r0, mxc_cp15_context
+ ldmia r0, {r1-r9}
+#ifndef CONFIG_PM_DEBUG
+ @Add dynamic check to skip this block when debug
+ sub lr, lr, #PHYS_OFFSET
+ add lr, lr, #PAGE_OFFSET
+#endif
+ mcr p15, 0, r3, c1, c0, 2 @CP Access Register
+ mcr p15, 0, r2, c1, c0, 1 @Aux Control register
+
+#ifndef CONFIG_PM_DEBUG
+ mcr p15, 0, r0, c7, c5, 6 @flush BTAC/BTB
+ mcr p15, 0, r0, c7, c7, 0 @invalidate both caches
+ mcr p15, 0, r0, c8, c7, 0 @Inval TLBs
+#endif
+
+ mcr p15, 0, r4, c13, c0, 0 @PID
+ mcr p15, 0, r5, c13, c0, 1 @Context ID
+
+ mcr p15, 0, r6, c3, c0, 0 @Domain Access Register
+ mcr p15, 0, r7, c2, c0, 0 @TTB0
+ mcr p15, 0, r8, c2, c0, 1 @TTB1
+ mcr p15, 0, r9, c2, c0, 2 @TTBC
+
+ mcr p15, 0, r1, c1, c0, 0 @Control Register
+ /* mcu enabled */
+ mrc p15, 0, r0, c2, c0, 0
+
+ mov pc, lr
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+
+mxc_cp15_save:
+ mov ip, sp
+ stmdb sp!, {r8-r9, fp, ip, lr, pc}
+ sub fp, ip, #4
+ ldr r0, =mxc_cp15_context
+/* System Control Registers */
+ mrc p15, 0, r1, c1, c0, 0 @Control Register
+ mrc p15, 0, r2, c1, c0, 1 @Aux Control Register
+ mrc p15, 0, r3, c1, c0, 2 @CP access Register
+
+/* Memory management Registers */
+ mrc p15, 0, r4, c13, c0, 0 @PID
+ mrc p15, 0, r5, c13, c0, 1 @Context ID
+
+ mrc p15, 0, r6, c3, c0, 0 @Domain Access Register
+
+ mrc p15, 0, r7, c2, c0, 0 @TTB0
+ mrc p15, 0, r8, c2, c0, 1 @TTB1
+ mrc p15, 0, r9, c2, c0, 2 @TTBC
+ stmia r0, {r1-r9}
+ ldmia sp, {r8, r9, fp, sp, pc}
+
+/*
+ * int __mxc_pm_arch_entry(u32 entry, u32 size)
+ */
+ .align 5
+ .globl mxc_pm_arch_entry
+mxc_pm_arch_entry:
+ mov ip, sp
+ stmdb sp!, {r4-r9, sl, fp, ip, lr, pc}
+ sub fp, ip, #4
+ sub sp, sp, #4
+ mov r8, r0 @save entry
+ mov r9, r1 @save entry size
+#ifdef CONFIG_VFP
+ bl arm_vfp_save
+#endif
+ /* r0 ~r3, ip is dirty*/
+ bl arm_core_save @save arm context
+ bl mxc_cp15_save
+ mov r0, sp
+ mov r1, r8 @restore entry
+ mov r2, r9 @restore entry size
+ bl __mxc_pm_xload_setup
+1: bl cpu_v6_proc_fin
+ bl cpu_v6_do_idle
+ nop
+ nop
+ nop
+ nop
+__mxc_pm_arch_leave:
+ adr r0, __mxc_pm_xload_info
+ ldr sp, [r0, #PM_XLOAD_CORE_SP]
+
+#ifndef CONFIG_PM_DEBUG
+ sub sp, sp, #PAGE_OFFSET
+ add sp, sp, #PHYS_OFFSET
+#endif
+ bl mxc_cp15_restore
+#ifndef CONFIG_PM_DEBUG
+ sub sp, sp, #PHYS_OFFSET
+ add sp, sp, #PAGE_OFFSET
+#endif
+ show_resume_str
+ bl arm_core_restore
+ ldmib sp, {r4-r9, sl, fp, sp, pc}
+
+__mxc_pm_xload_info:
+ adr pc, __mxc_pm_xload_entry @Jump instruction
+ .long __mxc_pm_xload_end - __mxc_pm_xload_info @loader size
+ .long (__mxc_pm_arch_leave - PAGE_OFFSET + PHYS_OFFSET) @resume entry
+ .long 0 @suspend state
+ .long 0 @Core Stack pointer
+__mxc_pm_xload_entry:
+ adr r0, __mxc_pm_xload_info
+ ldr pc, [r0, #PM_XLOAD_ENTRY]
+__mxc_pm_xload_end:
+
+/*
+ * __mxc_pm_xload_setup(u32 sp, u32 entry, u32 size)
+ * r0~r6 is dirty
+ */
+__mxc_pm_xload_setup:
+ ldr r3, =__mxc_pm_xload_info
+ str r0, [r3, #PM_XLOAD_CORE_SP]
+ ldr r4, [r3, #PM_XLOAD_SIZE]
+ cmp r2, r4
+ blo 2f
+1: ldr r5, [r3], #4
+ str r5, [r1], #4
+ subs r4, r4, #4
+ bhi 1b
+ b 3f
+2: str r3, [r1]
+3: mov pc, lr
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index de5c4747453f..33e03058828e 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -1,253 +1,906 @@
/*
- * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- *
- * Based on code from Freescale,
- * Copyright 2004-2006 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.
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
*
- * 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.
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * Implementation based on omap gpio.c
*/
#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/irq.h>
-#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/interrupt.h>
+#include <linux/sysdev.h>
+#include <linux/ptrace.h>
#include <mach/hardware.h>
-#include <asm-generic/bug.h>
+#include <asm/irq.h>
+#include <mach/irqs.h>
+#include <asm/mach/irq.h>
+#include <linux/io.h>
+#include <mach/gpio.h>
+#include <asm/mach-types.h>
+
+/*!
+ * @file plat-mxc/gpio.c
+ *
+ * @brief This file contains the GPIO implementation details.
+ *
+ * @ingroup GPIO
+ */
+
+/* GPIO related defines */
+#if defined(CONFIG_ARCH_MX27) || defined(CONFIG_ARCH_MX21)
+enum gpio_reg {
+ GPIO_DR = 0x1C,
+ GPIO_GDIR = 0x00,
+ GPIO_PSR = 0x24,
+ GPIO_ICR1 = 0x028,
+ GPIO_ICR2 = 0x2C,
+ GPIO_IMR = 0x30,
+ GPIO_ISR = 0x34,
+};
+#else
+enum gpio_reg {
+ GPIO_DR = 0x00,
+ GPIO_GDIR = 0x04,
+ GPIO_PSR = 0x08,
+ GPIO_ICR1 = 0x0C,
+ GPIO_ICR2 = 0x10,
+ GPIO_IMR = 0x14,
+ GPIO_ISR = 0x18,
+};
+#endif
+
+extern struct mxc_gpio_port mxc_gpio_ports[];
+
+struct gpio_port {
+ u32 num; /*!< gpio port number */
+ u32 base; /*!< gpio port base VA */
+#ifdef MXC_GPIO_SPLIT_IRQ_2
+ u16 irq_0_15, irq_16_31;
+#else
+ u16 irq; /*!< irq number to the core */
+#endif
+ u16 virtual_irq_start; /*!< virtual irq start number */
+ u32 reserved_map; /*!< keep track of which pins are in use */
+ u32 irq_is_level_map; /*!< if a pin's irq is level sensitive. default is edge */
+ u32 suspend_wakeup;
+ u32 saved_wakeup;
+ spinlock_t lock; /*!< lock when operating on the port */
+};
+static struct gpio_port gpio_port[GPIO_PORT_NUM];
+
+/*
+ * Find the pointer to the gpio_port for a given pin.
+ * @param gpio a gpio pin number
+ * @return pointer to \b struc \b gpio_port
+ */
+static inline struct gpio_port *get_gpio_port(u32 gpio)
+{
+ return &gpio_port[GPIO_TO_PORT(gpio)];
+}
+
+/*
+ * Check if a gpio pin is within [0, MXC_MAX_GPIO_LINES -1].
+ * @param gpio a gpio pin number
+ * @return 0 if the pin number is valid; -1 otherwise
+ */
+static int check_gpio(u32 gpio)
+{
+ if (gpio >= MXC_MAX_GPIO_LINES) {
+ printk(KERN_ERR "mxc-gpio: invalid GPIO %d\n", gpio);
+ dump_stack();
+ return -1;
+ }
+ return 0;
+}
+
+/*
+ * Set a GPIO pin's direction
+ * @param port pointer to a gpio_port
+ * @param index gpio pin index value (0~31)
+ * @param is_input 0 for output; non-zero for input
+ */
+static void _set_gpio_direction(struct gpio_port *port, u32 index, int is_input)
+{
+ u32 reg = port->base + GPIO_GDIR;
+ u32 l;
+
+ l = __raw_readl(reg);
+ if (is_input)
+ l &= ~(1 << index);
+ else
+ l |= 1 << index;
+ __raw_writel(l, reg);
+}
+
+/*!
+ * Exported function to set a GPIO pin's direction
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param is_input 1 (or non-zero) for input; 0 for output
+ */
+void mxc_set_gpio_direction(iomux_pin_name_t pin, int is_input)
+{
+ struct gpio_port *port;
+ u32 gpio = IOMUX_TO_GPIO(pin);
+
+ if (check_gpio(gpio) < 0)
+ return;
+ port = get_gpio_port(gpio);
+ spin_lock(&port->lock);
+ _set_gpio_direction(port, GPIO_TO_INDEX(gpio), is_input);
+ spin_unlock(&port->lock);
+}
+
+/*
+ * Set a GPIO pin's data output
+ * @param port pointer to a gpio_port
+ * @param index gpio pin index value (0~31)
+ * @param data value to be set (only 0 or 1 is valid)
+ */
+static void _set_gpio_dataout(struct gpio_port *port, u32 index, u32 data)
+{
+ u32 reg = port->base + GPIO_DR;
+ u32 l = 0;
+
+ l = (__raw_readl(reg) & (~(1 << index))) | (data << index);
+ __raw_writel(l, reg);
+}
+
+/*!
+ * Exported function to set a GPIO pin's data output
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param data value to be set (only 0 or 1 is valid)
+ */
+void mxc_set_gpio_dataout(iomux_pin_name_t pin, u32 data)
+{
+ struct gpio_port *port;
+ u32 gpio = IOMUX_TO_GPIO(pin);
+
+ if (check_gpio(gpio) < 0)
+ return;
+
+ port = get_gpio_port(gpio);
+ spin_lock(&port->lock);
+ _set_gpio_dataout(port, GPIO_TO_INDEX(gpio), (data == 0) ? 0 : 1);
+ spin_unlock(&port->lock);
+}
+
+/*!
+ * Return the data value of a GPIO signal.
+ * @param pin a name defined by \b iomux_pin_name_t
+ *
+ * @return value (0 or 1) of the GPIO signal; -1 if pass in invalid pin
+ */
+int mxc_get_gpio_datain(iomux_pin_name_t pin)
+{
+ struct gpio_port *port;
+ u32 gpio = IOMUX_TO_GPIO(pin);
+
+ if (check_gpio(gpio) < 0)
+ return -1;
-static struct mxc_gpio_port *mxc_gpio_ports;
-static int gpio_table_size;
+ port = get_gpio_port(gpio);
-/* Note: This driver assumes 32 GPIOs are handled in one register */
+ /*
+ * SW workaround for the eSDHC1 Write Protected feature
+ * The PSR of CSPI1_SS0 (GPIO3_2) should be read.
+ */
+ if (machine_is_mx37_3ds() && (gpio == ((32 * 2) + 2)))
+ return (__raw_readl(port->base + GPIO_PSR) >>
+ GPIO_TO_INDEX(gpio)) & 1;
+ else
+ return (__raw_readl(port->base + GPIO_DR) >>
+ GPIO_TO_INDEX(gpio)) & 1;
+}
-static void _clear_gpio_irqstatus(struct mxc_gpio_port *port, u32 index)
+/*
+ * Clear a GPIO signal's interrupt status
+ *
+ * @param port pointer to a gpio_port
+ * @param index gpio pin index value (0~31)
+ */
+static inline void _clear_gpio_irqstatus(struct gpio_port *port, u32 index)
{
__raw_writel(1 << index, port->base + GPIO_ISR);
}
-static void _set_gpio_irqenable(struct mxc_gpio_port *port, u32 index,
- int enable)
+/*
+ * Set a GPIO pin's interrupt edge
+ * @param port pointer to a gpio_port
+ * @param index gpio pin index value (0~31)
+ * @param icr one of the values defined in \b gpio_edge_t
+ * to indicate how to generate an interrupt
+ */
+static void _set_gpio_edge_ctrl(struct gpio_port *port, u32 index,
+ gpio_edge_t edge)
{
+ u32 reg = port->base;
+ u32 l, sig;
+
+ reg += (index <= 15) ? GPIO_ICR1 : GPIO_ICR2;
+ sig = (index <= 15) ? index : (index - 16);
+ l = __raw_readl(reg);
+ l = (l & (~(0x3 << (sig * 2)))) | (edge << (sig * 2));
+ __raw_writel(l, reg);
+ _clear_gpio_irqstatus(port, index);
+}
+
+/*
+ * Enable/disable a GPIO signal's interrupt.
+ *
+ * @param port pointer to a gpio_port
+ * @param index gpio pin index value (0~31)
+ * @param enable \b #true for enabling the interrupt; \b #false otherwise
+ */
+static inline void _set_gpio_irqenable(struct gpio_port *port, u32 index,
+ bool enable)
+{
+ u32 reg = port->base + GPIO_IMR;
+ u32 mask = (!enable) ? 0 : 1;
u32 l;
- l = __raw_readl(port->base + GPIO_IMR);
- l = (l & (~(1 << index))) | (!!enable << index);
- __raw_writel(l, port->base + GPIO_IMR);
+ l = __raw_readl(reg);
+ l = (l & (~(1 << index))) | (mask << index);
+ __raw_writel(l, reg);
}
-static void gpio_ack_irq(u32 irq)
+static inline int _request_gpio(struct gpio_port *port, u32 index)
{
- u32 gpio = irq_to_gpio(irq);
- _clear_gpio_irqstatus(&mxc_gpio_ports[gpio / 32], gpio & 0x1f);
+ spin_lock(&port->lock);
+ if (port->reserved_map & (1 << index)) {
+ printk(KERN_ERR
+ "GPIO port %d (0-based), pin %d is already reserved!\n",
+ port->num, index);
+ dump_stack();
+ spin_unlock(&port->lock);
+ return -1;
+ }
+ port->reserved_map |= (1 << index);
+ spin_unlock(&port->lock);
+ return 0;
+}
+
+/*!
+ * Request ownership for a GPIO pin. The caller has to check the return value
+ * of this function to make sure it returns 0 before make use of that pin.
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @return 0 if successful; Non-zero otherwise
+ */
+int mxc_request_gpio(iomux_pin_name_t pin)
+{
+ struct gpio_port *port;
+ u32 index, gpio = IOMUX_TO_GPIO(pin);
+
+ if (check_gpio(gpio) < 0)
+ return -EINVAL;
+
+ port = get_gpio_port(gpio);
+ index = GPIO_TO_INDEX(gpio);
+
+ return _request_gpio(port, index);
+}
+
+/*!
+ * Release ownership for a GPIO pin
+ * @param pin a name defined by \b iomux_pin_name_t
+ */
+void mxc_free_gpio(iomux_pin_name_t pin)
+{
+ struct gpio_port *port;
+ u32 index, gpio = IOMUX_TO_GPIO(pin);
+
+ if (check_gpio(gpio) < 0)
+ return;
+
+ port = get_gpio_port(gpio);
+ index = GPIO_TO_INDEX(gpio);
+
+ spin_lock(&port->lock);
+ if ((!(port->reserved_map & (1 << index)))) {
+ printk(KERN_ERR "GPIO port %d, pin %d wasn't reserved!\n",
+ port->num, index);
+ dump_stack();
+ spin_unlock(&port->lock);
+ return;
+ }
+ port->reserved_map &= ~(1 << index);
+ port->irq_is_level_map &= ~(1 << index);
+ _set_gpio_direction(port, index, 1);
+ _set_gpio_irqenable(port, index, 0);
+ _clear_gpio_irqstatus(port, index);
+ spin_unlock(&port->lock);
}
+/*
+ * We need to unmask the GPIO port interrupt as soon as possible to
+ * avoid missing GPIO interrupts for other lines in the port.
+ * Then we need to mask-read-clear-unmask the triggered GPIO lines
+ * in the port to avoid missing nested interrupts for a GPIO line.
+ * If we wait to unmask individual GPIO lines in the port after the
+ * line's interrupt handler has been run, we may miss some nested
+ * interrupts.
+ */
+static void mxc_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 isr_reg = 0, imr_reg = 0, imr_val;
+ u32 int_valid;
+ u32 gpio_irq, mask = 0xFFFFFFFF;
+ struct gpio_port *port;
+
+ port = (struct gpio_port *)get_irq_data(irq);
+ isr_reg = port->base + GPIO_ISR;
+ imr_reg = port->base + GPIO_IMR;
+
+#ifdef MXC_GPIO_SPLIT_IRQ_2
+ if (irq == port->irq_0_15) {
+ mask = 0x0000FFFF;
+ } else {
+ mask = 0xFFFF0000;
+ }
+#endif
+
+ imr_val = __raw_readl(imr_reg) & mask;
+ int_valid = __raw_readl(isr_reg) & imr_val;
+
+ if (unlikely(!int_valid)) {
+ printk(KERN_DEBUG
+ "\nGPIO port: %d Spurious interrupt:0x%0x Mask: %x\n\n",
+ port->num, int_valid, imr_val);
+ return;
+ }
+
+ gpio_irq = port->virtual_irq_start;
+ for (; int_valid != 0; int_valid >>= 1, gpio_irq++) {
+ struct irq_desc *d;
+
+ if ((int_valid & 1) == 0)
+ continue;
+ d = irq_desc + gpio_irq;
+ if (unlikely(!(d->handle_irq))) {
+ printk(KERN_ERR "\nGPIO port: %d irq: %d unhandeled\n",
+ port->num, gpio_irq);
+ BUG(); /* oops */
+ }
+ d->handle_irq(gpio_irq, d);
+ }
+}
+
+#ifdef MXC_MUX_GPIO_INTERRUPTS
+static void mxc_gpio_mux_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ int i;
+ u32 isr_reg = 0, imr_reg = 0, imr_val;
+ u32 int_valid;
+ struct gpio_port *port;
+
+ for (i = 0; i < GPIO_PORT_NUM; i++) {
+ port = &gpio_port[i];
+ isr_reg = port->base + GPIO_ISR;
+ imr_reg = port->base + GPIO_IMR;
+
+ imr_val = __raw_readl(imr_reg);
+ int_valid = __raw_readl(isr_reg) & imr_val;
+
+ if (int_valid) {
+ set_irq_data(irq, (void *)port);
+ mxc_gpio_irq_handler(irq, desc);
+ }
+ }
+}
+#endif
+
+/*
+ * Disable a gpio pin's interrupt by setting the bit in the imr.
+ * @param irq a gpio virtual irq number
+ */
static void gpio_mask_irq(u32 irq)
{
- u32 gpio = irq_to_gpio(irq);
- _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 0);
+ u32 gpio = MXC_IRQ_TO_GPIO(irq);
+ struct gpio_port *port = get_gpio_port(gpio);
+
+ _set_gpio_irqenable(port, GPIO_TO_INDEX(gpio), 0);
+}
+
+/*
+ * Acknowledge a gpio pin's interrupt by clearing the bit in the isr.
+ * If the GPIO interrupt is level triggered, it also disables the interrupt.
+ * @param irq a gpio virtual irq number
+ */
+static void gpio_ack_irq(u32 irq)
+{
+ u32 gpio = MXC_IRQ_TO_GPIO(irq);
+ u32 index = GPIO_TO_INDEX(gpio);
+ struct gpio_port *port = get_gpio_port(gpio);
+
+ _clear_gpio_irqstatus(port, GPIO_TO_INDEX(gpio));
+ if (port->irq_is_level_map & (1 << index)) {
+ gpio_mask_irq(irq);
+ }
}
+/*
+ * Enable a gpio pin's interrupt by clearing the bit in the imr.
+ * @param irq a gpio virtual irq number
+ */
static void gpio_unmask_irq(u32 irq)
{
- u32 gpio = irq_to_gpio(irq);
- _set_gpio_irqenable(&mxc_gpio_ports[gpio / 32], gpio & 0x1f, 1);
+ u32 gpio = MXC_IRQ_TO_GPIO(irq);
+ struct gpio_port *port = get_gpio_port(gpio);
+
+ _set_gpio_irqenable(port, GPIO_TO_INDEX(gpio), 1);
}
+/*
+ * Enable a gpio pin's interrupt by clearing the bit in the imr.
+ * @param irq a gpio virtual irq number
+ */
static int gpio_set_irq_type(u32 irq, u32 type)
{
- u32 gpio = irq_to_gpio(irq);
- struct mxc_gpio_port *port = &mxc_gpio_ports[gpio / 32];
- u32 bit, val;
- int edge;
- void __iomem *reg = port->base;
+ u32 gpio = MXC_IRQ_TO_GPIO(irq);
+ struct gpio_port *port = get_gpio_port(gpio);
switch (type) {
- case IRQ_TYPE_EDGE_RISING:
- edge = GPIO_INT_RISE_EDGE;
+ case IRQF_TRIGGER_RISING:
+ _set_gpio_edge_ctrl(port, GPIO_TO_INDEX(gpio),
+ GPIO_INT_RISE_EDGE);
+ set_irq_handler(irq, handle_edge_irq);
+ port->irq_is_level_map &= ~(1 << GPIO_TO_INDEX(gpio));
break;
- case IRQ_TYPE_EDGE_FALLING:
- edge = GPIO_INT_FALL_EDGE;
+ case IRQF_TRIGGER_FALLING:
+ _set_gpio_edge_ctrl(port, GPIO_TO_INDEX(gpio),
+ GPIO_INT_FALL_EDGE);
+ set_irq_handler(irq, handle_edge_irq);
+ port->irq_is_level_map &= ~(1 << GPIO_TO_INDEX(gpio));
break;
- case IRQ_TYPE_LEVEL_LOW:
- edge = GPIO_INT_LOW_LEV;
+ case IRQF_TRIGGER_LOW:
+ _set_gpio_edge_ctrl(port, GPIO_TO_INDEX(gpio),
+ GPIO_INT_LOW_LEV);
+ set_irq_handler(irq, handle_level_irq);
+ port->irq_is_level_map |= 1 << GPIO_TO_INDEX(gpio);
break;
- case IRQ_TYPE_LEVEL_HIGH:
- edge = GPIO_INT_HIGH_LEV;
+ case IRQF_TRIGGER_HIGH:
+ _set_gpio_edge_ctrl(port, GPIO_TO_INDEX(gpio),
+ GPIO_INT_HIGH_LEV);
+ set_irq_handler(irq, handle_level_irq);
+ port->irq_is_level_map |= 1 << GPIO_TO_INDEX(gpio);
break;
- default: /* this includes IRQ_TYPE_EDGE_BOTH */
+ default:
return -EINVAL;
+ break;
}
+ return 0;
+}
- reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
- bit = gpio & 0xf;
- val = __raw_readl(reg) & ~(0x3 << (bit << 1));
- __raw_writel(val | (edge << (bit << 1)), reg);
- _clear_gpio_irqstatus(port, gpio & 0x1f);
-
+/*
+ * Set interrupt number "irq" in the GPIO as a wake-up source.
+ * While system is running all registered GPIO interrupts need to have
+ * wake-up enabled. When system is suspended, only selected GPIO interrupts
+ * need to have wake-up enabled.
+ * @param irq interrupt source number
+ * @param enable enable as wake-up if equal to non-zero
+ * @return This function returns 0 on success.
+ */
+static int gpio_set_wake_irq(u32 irq, u32 enable)
+{
+ u32 gpio = MXC_IRQ_TO_GPIO(irq);
+ u32 gpio_idx = GPIO_TO_INDEX(gpio);
+ struct gpio_port *port = get_gpio_port(gpio);
+
+ if (check_gpio(gpio) < 0)
+ return -ENODEV;
+
+ if (enable) {
+ port->suspend_wakeup |= (1 << gpio_idx);
+#ifdef MXC_GPIO_SPLIT_IRQ_2
+ if (gpio_idx < 16)
+ enable_irq_wake(port->irq_0_15);
+ else
+ enable_irq_wake(port->irq_16_31);
+#else
+ enable_irq_wake(port->irq);
+#endif
+ } else {
+ port->suspend_wakeup &= ~(1 << gpio_idx);
+#ifdef MXC_GPIO_SPLIT_IRQ_2
+ if (gpio_idx < 16)
+ disable_irq_wake(port->irq_0_15);
+ else
+ disable_irq_wake(port->irq_16_31);
+#else
+ disable_irq_wake(port->irq);
+#endif
+ }
return 0;
}
-/* handle n interrupts in one status register */
-static void mxc_gpio_irq_handler(struct mxc_gpio_port *port, u32 irq_stat)
+static struct irq_chip gpio_irq_chip = {
+ .name = "MXC_GPIO",
+ .ack = gpio_ack_irq,
+ .mask = gpio_mask_irq,
+ .unmask = gpio_unmask_irq,
+ .set_type = gpio_set_irq_type,
+ .set_wake = gpio_set_wake_irq,
+};
+
+/*!
+ * This function initializes the GPIO hardware and disables all the
+ * interrupts. It registers functions for core interrupt handling code,
+ * for irq-chip based architectures for each interrupt source.
+ */
+static int __init _mxc_gpio_init(void)
{
- u32 gpio_irq_no;
+ int i;
+ struct gpio_port *port;
- gpio_irq_no = port->virtual_irq_start;
- for (; irq_stat != 0; irq_stat >>= 1, gpio_irq_no++) {
+ printk(KERN_INFO "MXC GPIO hardware\n");
- if ((irq_stat & 1) == 0)
- continue;
+ for (i = 0; i < GPIO_PORT_NUM; i++) {
+ int j, gpio_count = GPIO_NUM_PIN;
+
+ port = &gpio_port[i];
+ port->base = mxc_gpio_ports[i].base;
+ port->num = mxc_gpio_ports[i].num;
+#ifdef MXC_GPIO_SPLIT_IRQ_2
+ port->irq_0_15 = mxc_gpio_ports[i].irq_0_15;
+ port->irq_16_31 = mxc_gpio_ports[i].irq_16_31;
+#else
+ port->irq = mxc_gpio_ports[i].irq;
+#endif
+ port->virtual_irq_start = mxc_gpio_ports[i].virtual_irq_start;
+
+ port->reserved_map = 0;
+ spin_lock_init(&port->lock);
- BUG_ON(!(irq_desc[gpio_irq_no].handle_irq));
- irq_desc[gpio_irq_no].handle_irq(gpio_irq_no,
- &irq_desc[gpio_irq_no]);
+ /* disable the interrupt and clear the status */
+ __raw_writel(0, port->base + GPIO_IMR);
+ __raw_writel(0xFFFFFFFF, port->base + GPIO_ISR);
+ for (j = port->virtual_irq_start;
+ j < port->virtual_irq_start + gpio_count; j++) {
+ set_irq_chip(j, &gpio_irq_chip);
+ set_irq_handler(j, handle_edge_irq);
+ set_irq_flags(j, IRQF_VALID);
+ }
+#ifndef MXC_MUX_GPIO_INTERRUPTS
+#ifdef MXC_GPIO_SPLIT_IRQ_2
+ set_irq_chained_handler(port->irq_0_15, mxc_gpio_irq_handler);
+ set_irq_data(port->irq_0_15, port);
+ set_irq_chained_handler(port->irq_16_31, mxc_gpio_irq_handler);
+ set_irq_data(port->irq_16_31, port);
+#else
+ set_irq_chained_handler(port->irq, mxc_gpio_irq_handler);
+ set_irq_data(port->irq, port);
+#endif
+#endif
}
+
+#ifdef MXC_MUX_GPIO_INTERRUPTS
+ set_irq_chained_handler(port->irq, mxc_gpio_mux_irq_handler);
+ set_irq_data(mxc_gpio_ports[0].irq, gpio_port);
+#endif
+
+ return 0;
}
-#ifdef CONFIG_ARCH_MX3
-/* MX3 has one interrupt *per* gpio port */
-static void mx3_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+#ifdef CONFIG_PM
+/*!
+ * This function puts the GPIO in low-power mode/state.
+ * All the interrupts that are enabled are first saved.
+ * Only those interrupts which registers as a wake source by calling
+ * enable_irq_wake are enabled. All other interrupts are disabled.
+ *
+ * @param dev the system device structure used to give information
+ * on GPIO to suspend
+ * @param mesg the power state the device is entering
+ *
+ * @return The function always returns 0.
+ */
+static int mxc_gpio_suspend(struct sys_device *dev, pm_message_t mesg)
{
- u32 irq_stat;
- struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq);
+ int i;
+
+ for (i = 0; i < GPIO_PORT_NUM; i++) {
+ struct gpio_port *port = &gpio_port[i];
+ u32 isr_reg;
+ u32 imr_reg;
+
+ isr_reg = port->base + GPIO_ISR;
+ imr_reg = port->base + GPIO_IMR;
+
+ if (__raw_readl(isr_reg) & port->suspend_wakeup) {
+ return -EPERM;
+ }
+ port->saved_wakeup = __raw_readl(imr_reg);
+ __raw_writel(port->suspend_wakeup, imr_reg);
+ }
- irq_stat = __raw_readl(port->base + GPIO_ISR) &
- __raw_readl(port->base + GPIO_IMR);
- BUG_ON(!irq_stat);
- mxc_gpio_irq_handler(port, irq_stat);
+ return 0;
}
-#endif
-#ifdef CONFIG_ARCH_MX2
-/* MX2 has one interrupt *for all* gpio ports */
-static void mx2_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+/*!
+ * This function brings the GPIO back from low-power state.
+ * All the interrupts enabled before suspension are re-enabled from
+ * the saved information.
+ *
+ * @param dev the system device structure used to give information
+ * on GPIO to resume
+ *
+ * @return The function always returns 0.
+ */
+static int mxc_gpio_resume(struct sys_device *dev)
{
int i;
- u32 irq_msk, irq_stat;
- struct mxc_gpio_port *port = (struct mxc_gpio_port *)get_irq_data(irq);
- /* walk through all interrupt status registers */
- for (i = 0; i < gpio_table_size; i++) {
- irq_msk = __raw_readl(port[i].base + GPIO_IMR);
- if (!irq_msk)
- continue;
+ for (i = 0; i < GPIO_PORT_NUM; i++) {
+ struct gpio_port *port = &gpio_port[i];
+ u32 isr_reg;
+ u32 imr_reg;
- irq_stat = __raw_readl(port[i].base + GPIO_ISR) & irq_msk;
- if (irq_stat)
- mxc_gpio_irq_handler(&port[i], irq_stat);
+ isr_reg = port->base + GPIO_ISR;
+ imr_reg = port->base + GPIO_IMR;
+
+ __raw_writel(port->saved_wakeup, imr_reg);
}
+
+ return 0;
}
-#endif
+#else
+#define mxc_gpio_suspend NULL
+#define mxc_gpio_resume NULL
+#endif /* CONFIG_PM */
-static struct irq_chip gpio_irq_chip = {
- .ack = gpio_ack_irq,
- .mask = gpio_mask_irq,
- .unmask = gpio_unmask_irq,
- .set_type = gpio_set_irq_type,
+/*!
+ * This structure contains pointers to the power management callback functions.
+ */
+static struct sysdev_class mxc_gpio_sysclass = {
+ .name = "mxc_gpio",
+ .suspend = mxc_gpio_suspend,
+ .resume = mxc_gpio_resume,
+};
+
+/*!
+ * This structure represents GPIO as a system device.
+ * System devices follow a slightly different driver model.
+ * They don't need to do dynammic driver binding, can't be probed,
+ * and don't reside on any type of peripheral bus.
+ * So, it is represented and treated a little differently.
+ */
+static struct sys_device mxc_gpio_device = {
+ .id = 0,
+ .cls = &mxc_gpio_sysclass,
};
-static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
- int dir)
+/*!
+ * This function registers GPIO hardware as a system device and
+ * intializes all the GPIO ports if not already done.
+ * System devices will only be suspended with interrupts disabled, and
+ * after all other devices have been suspended. On resume, they will be
+ * resumed before any other devices, and also with interrupts disabled.
+ * This may get called early from board specific init
+ *
+ * @return This function returns 0 on success.
+ */
+int __init mxc_gpio_init(void)
{
- struct mxc_gpio_port *port =
- container_of(chip, struct mxc_gpio_port, chip);
- u32 l;
+ int ret = 0;
- l = __raw_readl(port->base + GPIO_GDIR);
- if (dir)
- l |= 1 << offset;
- else
- l &= ~(1 << offset);
- __raw_writel(l, port->base + GPIO_GDIR);
+ ret = _mxc_gpio_init();
+
+ if (ret == 0) {
+ ret = sysdev_class_register(&mxc_gpio_sysclass);
+ if (ret == 0)
+ ret = sysdev_register(&mxc_gpio_device);
+ }
+
+ return ret;
}
-static void mxc_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+/*
+ * FIXME: The following functions are for backward-compatible.
+ * They will be removed at a future release.
+ */
+#define PORT_SIG_TO_GPIO(p, s) (p * 32 + s)
+
+/*!
+ * This function configures the GPIO signal to be either input or output. For
+ * input signals used for generating interrupts for the ARM core, how the
+ * interrupts being triggered is also passed in via \a icr. For output signals,
+ * the \a icr value doesn't matter.
+ * FIXED ME: for backward compatible. to be removed!
+ *
+ * @param port specified port with 0-GPIO port 1; 1-GPIO port 2
+ * @param sig_no specified GPIO signal (0 based)
+ * @param out #true for output, #false for input
+ * @param icr value defined in \b #gpio_edge_t
+ */
+void gpio_config(u32 port, u32 sig_no, bool out, gpio_edge_t icr)
{
- struct mxc_gpio_port *port =
- container_of(chip, struct mxc_gpio_port, chip);
- void __iomem *reg = port->base + GPIO_DR;
- u32 l;
+ u32 gpio = PORT_SIG_TO_GPIO(port, sig_no);
+ struct gpio_port *port_p;
- l = (__raw_readl(reg) & (~(1 << offset))) | (value << offset);
- __raw_writel(l, reg);
+ if (check_gpio(gpio) < 0)
+ return;
+
+ port_p = get_gpio_port(gpio);
+
+ if (!(port_p->reserved_map & (1 << sig_no)))
+ _request_gpio(port_p, sig_no);
+
+ if (!out) {
+ /* input */
+ _set_gpio_direction(port_p, sig_no, 1);
+ _set_gpio_edge_ctrl(port_p, sig_no, icr);
+ } else { /* output */
+ _set_gpio_direction(port_p, sig_no, 0);
+ }
}
-static int mxc_gpio_get(struct gpio_chip *chip, unsigned offset)
+/*!
+ * This function sets a GPIO signal value.
+ * FIXED ME: for backward compatible. to be removed!
+ *
+ * @param port specified port with 0 for GPIO port 1 and 1 for GPIO port 2
+ * @param sig_no specified GPIO signal (0 based)
+ * @param data value to be set (only 0 or 1 is valid)
+ */
+void gpio_set_data(u32 port, u32 sig_no, u32 data)
{
- struct mxc_gpio_port *port =
- container_of(chip, struct mxc_gpio_port, chip);
+ u32 gpio = PORT_SIG_TO_GPIO(port, sig_no);
+ struct gpio_port *port_p;
+
+ if (check_gpio(gpio) < 0)
+ return;
- return (__raw_readl(port->base + GPIO_PSR) >> offset) & 1;
+ port_p = get_gpio_port(gpio);
+
+ if (!(port_p->reserved_map & (1 << sig_no)))
+ _request_gpio(port_p, sig_no);
+
+ spin_lock(&port_p->lock);
+ _set_gpio_dataout(port_p, sig_no, (data == 0) ? 0 : 1);
+ spin_unlock(&port_p->lock);
}
-static int mxc_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+/*!
+ * This function returns the value of the GPIO signal.
+ * FIXED ME: for backward compatible. to be removed!
+ *
+ * @param port specified port with 0 for GPIO port 1 and 1 for GPIO port 2
+ * @param sig_no specified GPIO signal (0 based)
+ *
+ * @return Value of the GPIO signal
+ */
+u32 gpio_get_data(u32 port, u32 sig_no)
{
- _set_gpio_direction(chip, offset, 0);
- return 0;
+ u32 gpio = PORT_SIG_TO_GPIO(port, sig_no);
+ struct gpio_port *port_p;
+
+ if (check_gpio(gpio) < 0)
+ BUG();
+
+ port_p = get_gpio_port(gpio);
+
+ if (!(port_p->reserved_map & (1 << sig_no)))
+ _request_gpio(port_p, sig_no);
+
+ return (__raw_readl(port_p->base + GPIO_DR) >> sig_no) & 1;
}
-static int mxc_gpio_direction_output(struct gpio_chip *chip,
- unsigned offset, int value)
+/*!
+ * This function clears the GPIO interrupt for a signal on a port.
+ * FIXED ME: for backward compatible. to be removed!
+ *
+ * @param port specified port with 0 for GPIO port 1 and 1 for GPIO port 2
+ * @param sig_no specified GPIO signal (0 based) to clear
+ */
+void gpio_clear_int(u32 port, u32 sig_no)
{
- _set_gpio_direction(chip, offset, 1);
- mxc_gpio_set(chip, offset, value);
- return 0;
+ u32 gpio = PORT_SIG_TO_GPIO(port, sig_no);
+ struct gpio_port *port_p;
+
+ if (check_gpio(gpio) < 0)
+ return;
+
+ port_p = get_gpio_port(gpio);
+
+ if (!(port_p->reserved_map & (1 << sig_no)))
+ _request_gpio(port_p, sig_no);
+
+ _clear_gpio_irqstatus(port_p, sig_no);
}
-int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
+/*!
+ * This function is responsible for registering a GPIO signal's ISR.
+ * FIXED ME: for backward compatible. to be removed!
+ *
+ * @param port specified port with 0 for GPIO port 1 and 1 for GPIO port 2
+ * @param sig_no specified GPIO signal (0 based)
+ * @param prio priority as defined in \b enum \b #gpio_prio
+ * @param handler GPIO ISR function pointer for the GPIO signal
+ * @param irq_flags irq flags (not used)
+ * @param devname device name associated with the interrupt
+ * @param dev_id some unique information for the ISR
+ *
+ * @return 0 if successful; non-zero otherwise.
+ */
+int gpio_request_irq(u32 port, u32 sig_no, enum gpio_prio prio,
+ gpio_irq_handler handler, u32 irq_flags,
+ const char *devname, void *dev_id)
{
- int i, j;
+ u32 gpio = PORT_SIG_TO_GPIO(port, sig_no), ret;
+ struct gpio_port *port_p;
- /* save for local usage */
- mxc_gpio_ports = port;
- gpio_table_size = cnt;
+ if (check_gpio(gpio) < 0)
+ return -1;
- printk(KERN_INFO "MXC GPIO hardware\n");
+ port_p = get_gpio_port(gpio);
- for (i = 0; i < cnt; i++) {
- /* disable the interrupt and clear the status */
- __raw_writel(0, port[i].base + GPIO_IMR);
- __raw_writel(~0, port[i].base + GPIO_ISR);
- for (j = port[i].virtual_irq_start;
- j < port[i].virtual_irq_start + 32; j++) {
- set_irq_chip(j, &gpio_irq_chip);
- set_irq_handler(j, handle_edge_irq);
- set_irq_flags(j, IRQF_VALID);
- }
+ if (!(port_p->reserved_map & (1 << sig_no)))
+ _request_gpio(port_p, sig_no);
- /* register gpio chip */
- port[i].chip.direction_input = mxc_gpio_direction_input;
- port[i].chip.direction_output = mxc_gpio_direction_output;
- port[i].chip.get = mxc_gpio_get;
- port[i].chip.set = mxc_gpio_set;
- port[i].chip.base = i * 32;
- port[i].chip.ngpio = 32;
-
- /* its a serious configuration bug when it fails */
- BUG_ON( gpiochip_add(&port[i].chip) < 0 );
-
-#ifdef CONFIG_ARCH_MX3
- /* setup one handler for each entry */
- set_irq_chained_handler(port[i].irq, mx3_gpio_irq_handler);
- set_irq_data(port[i].irq, &port[i]);
-#endif
+ ret = request_irq(MXC_GPIO_TO_IRQ(gpio), handler, 0, "gpio", dev_id);
+ if (ret) {
+ printk(KERN_ERR "gpio: IRQ%d already in use.\n",
+ MXC_GPIO_TO_IRQ(gpio));
+ return ret;
}
-
-#ifdef CONFIG_ARCH_MX2
- /* setup one handler for all GPIO interrupts */
- set_irq_chained_handler(port[0].irq, mx2_gpio_irq_handler);
- set_irq_data(port[0].irq, port);
-#endif
return 0;
}
+
+/*!
+ * This function un-registers an ISR with the GPIO interrupt module.
+ * FIXED ME: for backward compatible. to be removed!
+ *
+ * @param port specified port with 0 for GPIO port 1 and 1 for GPIO port 2
+ * @param sig_no specified GPIO signal (0 based)
+ * @param prio priority as defined in \b enum \b #gpio_prio
+ */
+void gpio_free_irq(u32 port, u32 sig_no, enum gpio_prio prio)
+{
+ u32 gpio = PORT_SIG_TO_GPIO(port, sig_no);
+ struct gpio_port *port_p;
+
+ if (check_gpio(gpio) < 0)
+ return;
+
+ port_p = get_gpio_port(gpio);
+
+ free_irq(MXC_GPIO_TO_IRQ(gpio), NULL);
+
+ spin_lock(&port_p->lock);
+ if ((!(port_p->reserved_map & (1 << sig_no)))) {
+ printk(KERN_ERR "GPIO port %d, pin %d wasn't reserved!\n",
+ port_p->num, sig_no);
+ dump_stack();
+ spin_unlock(&port_p->lock);
+ return;
+ }
+ port_p->reserved_map &= ~(1 << sig_no);
+ _set_gpio_direction(port_p, sig_no, 1);
+ _set_gpio_irqenable(port_p, sig_no, 0);
+ _clear_gpio_irqstatus(port_p, sig_no);
+ spin_unlock(&port_p->lock);
+}
+
+EXPORT_SYMBOL(mxc_request_gpio);
+EXPORT_SYMBOL(mxc_free_gpio);
+EXPORT_SYMBOL(mxc_set_gpio_direction);
+EXPORT_SYMBOL(mxc_set_gpio_dataout);
+EXPORT_SYMBOL(mxc_get_gpio_datain);
+
+/* For backward compatible */
+EXPORT_SYMBOL(gpio_config);
+EXPORT_SYMBOL(gpio_set_data);
+EXPORT_SYMBOL(gpio_get_data);
+EXPORT_SYMBOL(gpio_clear_int);
+EXPORT_SYMBOL(gpio_request_irq);
+EXPORT_SYMBOL(gpio_free_irq);
diff --git a/arch/arm/plat-mxc/include/mach/arc_otg.h b/arch/arm/plat-mxc/include/mach/arc_otg.h
new file mode 100644
index 000000000000..91f0906fe0a5
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/arc_otg.h
@@ -0,0 +1,329 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_MXC_ARC_OTG_H__
+#define __ASM_ARCH_MXC_ARC_OTG_H__
+
+#define USB_OTGREGS_BASE (OTG_BASE_ADDR + 0x000)
+#define USB_H1REGS_BASE (OTG_BASE_ADDR + 0x200)
+#define USB_H2REGS_BASE (OTG_BASE_ADDR + 0x400)
+#ifdef CONFIG_ARCH_MX51
+#define USB_H3REGS_BASE (OTG_BASE_ADDR + 0x600)
+#define USB_OTHERREGS_BASE (OTG_BASE_ADDR + 0x800)
+#else
+#define USB_OTHERREGS_BASE (OTG_BASE_ADDR + 0x600)
+#endif
+
+
+#define USBOTG_REG32(offset) (*((volatile u32 *)(IO_ADDRESS(USB_OTGREGS_BASE + (offset)))))
+#define USBOTG_REG16(offset) (*((volatile u16 *)(IO_ADDRESS(USB_OTGREGS_BASE + (offset)))))
+
+#define USBH1_REG32(offset) (*((volatile u32 *)(IO_ADDRESS(USB_H1REGS_BASE + (offset)))))
+#define USBH1_REG16(offset) (*((volatile u16 *)(IO_ADDRESS(USB_H1REGS_BASE + (offset)))))
+
+#define USBH2_REG32(offset) (*((volatile u32 *)(IO_ADDRESS(USB_H2REGS_BASE + (offset)))))
+#define USBH2_REG16(offset) (*((volatile u16 *)(IO_ADDRESS(USB_H2REGS_BASE + (offset)))))
+
+#define USBOTHER_REG(offset) (*((volatile u32 *)(IO_ADDRESS(USB_OTHERREGS_BASE + (offset)))))
+
+/*
+ * OTG registers
+ */
+#define UOG_ID USBOTG_REG32(0x00) /* Host ID */
+#define UOG_HWGENERAL USBOTG_REG32(0x04) /* Host General */
+#define UOG_HWHOST USBOTG_REG32(0x08) /* Host h/w params */
+#define UOG_HWTXBUF USBOTG_REG32(0x10) /* TX buffer h/w params */
+#define UOG_HWRXBUF USBOTG_REG32(0x14) /* RX buffer h/w params */
+#define UOG_CAPLENGTH USBOTG_REG16(0x100) /* Capability register length */
+#define UOG_HCIVERSION USBOTG_REG16(0x102) /* Host Interface version */
+#define UOG_HCSPARAMS USBOTG_REG32(0x104) /* Host control structural params */
+#define UOG_HCCPARAMS USBOTG_REG32(0x108) /* control capability params */
+#define UOG_DCIVERSION USBOTG_REG32(0x120) /* device interface version */
+/* start EHCI registers: */
+#define UOG_USBCMD USBOTG_REG32(0x140) /* USB command register */
+#define UOG_USBSTS USBOTG_REG32(0x144) /* USB status register */
+#define UOG_USBINTR USBOTG_REG32(0x148) /* interrupt enable register */
+#define UOG_FRINDEX USBOTG_REG32(0x14c) /* USB frame index */
+/* segment (0x150) addr bits 63:32 if needed */
+#define UOG_PERIODICLISTBASE USBOTG_REG32(0x154) /* host crtlr frame list base addr */
+#define UOG_DEVICEADDR USBOTG_REG32(0x154) /* device crtlr device address */
+#define UOG_ASYNCLISTADDR USBOTG_REG32(0x158) /* host ctrlr next async addr */
+#define UOG_EPLISTADDR USBOTG_REG32(0x158) /* device ctrlr endpoint list addr */
+#define UOG_BURSTSIZE USBOTG_REG32(0x160) /* host ctrlr embedded TT async buf status */
+#define UOG_TXFILLTUNING USBOTG_REG32(0x164) /* TX FIFO fill tuning */
+#define UOG_ULPIVIEW USBOTG_REG32(0x170) /* ULPI viewport */
+#define UOG_CFGFLAG USBOTG_REG32(0x180) /* configflag (supports HS) */
+#define UOG_PORTSC1 USBOTG_REG32(0x184) /* port status and control */
+/* end EHCI registers: */
+#define UOG_OTGSC USBOTG_REG32(0x1a4) /* OTG status and control */
+#define UOG_USBMODE USBOTG_REG32(0x1a8) /* USB device mode */
+#define UOG_ENDPTSETUPSTAT USBOTG_REG32(0x1ac) /* endpoint setup status */
+#define UOG_ENDPTPRIME USBOTG_REG32(0x1b0) /* endpoint initialization */
+#define UOG_ENDPTFLUSH USBOTG_REG32(0x1b4) /* endpoint de-initialize */
+#define UOG_ENDPTSTAT USBOTG_REG32(0x1b8) /* endpoint status */
+#define UOG_ENDPTCOMPLETE USBOTG_REG32(0x1bc) /* endpoint complete */
+#define UOG_EPCTRL0 USBOTG_REG32(0x1c0) /* endpoint control0 */
+#define UOG_EPCTRL1 USBOTG_REG32(0x1c4) /* endpoint control1 */
+#define UOG_EPCTRL2 USBOTG_REG32(0x1c8) /* endpoint control2 */
+#define UOG_EPCTRL3 USBOTG_REG32(0x1cc) /* endpoint control3 */
+#define UOG_EPCTRL4 USBOTG_REG32(0x1d0) /* endpoint control4 */
+#define UOG_EPCTRL5 USBOTG_REG32(0x1d4) /* endpoint control5 */
+#define UOG_EPCTRL6 USBOTG_REG32(0x1d8) /* endpoint control6 */
+#define UOG_EPCTRL7 USBOTG_REG32(0x1dc) /* endpoint control7 */
+
+/*
+ * Host 1 registers
+ */
+#define UH1_ID USBH1_REG32(0x00) /* Host ID */
+#define UH1_HWGENERAL USBH1_REG32(0x04) /* Host General */
+#define UH1_HWHOST USBH1_REG32(0x08) /* Host h/w params */
+#define UH1_HWTXBUF USBH1_REG32(0x10) /* TX buffer h/w params */
+#define UH1_HWRXBUF USBH1_REG32(0x14) /* RX buffer h/w params */
+#define UH1_CAPLENGTH USBH1_REG16(0x100) /* Capability register length */
+#define UH1_HCIVERSION USBH1_REG16(0x102) /* Host Interface version */
+#define UH1_HCSPARAMS USBH1_REG32(0x104) /* Host control structural params */
+#define UH1_HCCPARAMS USBH1_REG32(0x108) /* control capability params */
+/* start EHCI registers: */
+#define UH1_USBCMD USBH1_REG32(0x140) /* USB command register */
+#define UH1_USBSTS USBH1_REG32(0x144) /* USB status register */
+#define UH1_USBINTR USBH1_REG32(0x148) /* interrupt enable register */
+#define UH1_FRINDEX USBH1_REG32(0x14c) /* USB frame index */
+/* segment (0x150) addr bits 63:32 if needed */
+#define UH1_PERIODICLISTBASE USBH1_REG32(0x154) /* host crtlr frame list base addr */
+#define UH1_ASYNCLISTADDR USBH1_REG32(0x158) /* host ctrlr nest async addr */
+#define UH1_BURSTSIZE USBH1_REG32(0x160) /* host ctrlr embedded TT async buf status */
+#define UH1_TXFILLTUNING USBH1_REG32(0x164) /* TX FIFO fill tuning */
+/* configured_flag (0x180) configflag (supports HS) */
+#define UH1_PORTSC1 USBH1_REG32(0x184) /* port status and control */
+/* end EHCI registers: */
+#define UH1_USBMODE USBH1_REG32(0x1a8) /* USB device mode */
+
+/*
+ * Host 2 registers
+ */
+#define UH2_ID USBH2_REG32(0x00) /* Host ID */
+#define UH2_HWGENERAL USBH2_REG32(0x04) /* Host General */
+#define UH2_HWHOST USBH2_REG32(0x08) /* Host h/w params */
+#define UH2_HWTXBUF USBH2_REG32(0x10) /* TX buffer h/w params */
+#define UH2_HWRXBUF USBH2_REG32(0x14) /* RX buffer h/w params */
+#define UH2_CAPLENGTH USBH2_REG16(0x100) /* Capability register length */
+#define UH2_HCIVERSION USBH2_REG16(0x102) /* Host Interface version */
+#define UH2_HCSPARAMS USBH2_REG32(0x104) /* Host control structural params */
+#define UH2_HCCPARAMS USBH2_REG32(0x108) /* control capability params */
+/* start EHCI registers: */
+#define UH2_USBCMD USBH2_REG32(0x140) /* USB command register */
+#define UH2_USBSTS USBH2_REG32(0x144) /* USB status register */
+#define UH2_USBINTR USBH2_REG32(0x148) /* interrupt enable register */
+#define UH2_FRINDEX USBH2_REG32(0x14c) /* USB frame index */
+/* segment (0x150) addr bits 63:32 if needed */
+#define UH2_PERIODICLISTBASE USBH2_REG32(0x154) /* host crtlr frame list base addr */
+#define UH2_ASYNCLISTADDR USBH2_REG32(0x158) /* host ctrlr nest async addr */
+#define UH2_BURSTSIZE USBH2_REG32(0x160) /* host ctrlr embedded TT async buf status */
+#define UH2_TXFILLTUNING USBH2_REG32(0x164) /* TX FIFO fill tuning */
+#define UH2_ULPIVIEW USBH2_REG32(0x170) /* ULPI viewport */
+/* configured_flag (0x180) configflag (supports HS) */
+#define UH2_PORTSC1 USBH2_REG32(0x184) /* port status and control */
+/* end EHCI registers */
+#define UH2_USBMODE USBH2_REG32(0x1a8) /* USB device mode */
+
+/*
+ * other regs (not part of ARC core)
+ */
+#define USBCTRL USBOTHER_REG(0x00) /* USB Control register */
+#define USB_OTG_MIRROR USBOTHER_REG(0x04) /* USB OTG mirror register */
+#define USB_PHY_CTR_FUNC USBOTHER_REG(0x08) /* OTG UTMI PHY Function Control register */
+#define USB_PHY_CTR_FUNC2 USBOTHER_REG(0x0c) /* OTG UTMI PHY Function Control register */
+#define USB_CTRL_1 USBOTHER_REG(0x10) /* USB Cotrol Register 1*/
+
+/*
+ * register bits
+ */
+
+/* x_PORTSCx */
+#define PORTSC_PTS_MASK (3 << 30) /* parallel xcvr select mask */
+#define PORTSC_PTS_UTMI (0 << 30) /* UTMI/UTMI+ */
+#define PORTSC_PTS_PHILIPS (1 << 30) /* Philips classic */
+#define PORTSC_PTS_ULPI (2 << 30) /* ULPI */
+#define PORTSC_PTS_SERIAL (3 << 30) /* serial */
+#define PORTSC_STS (1 << 29) /* serial xcvr select */
+#define PORTSC_PTW (1 << 28) /* UTMI width */
+#define PORTSC_PORT_POWER (1 << 12) /* port power */
+#define PORTSC_LS_MASK (3 << 10) /* Line State mask */
+#define PORTSC_LS_SE0 (0 << 10) /* SE0 */
+#define PORTSC_LS_K_STATE (1 << 10) /* K-state */
+#define PORTSC_LS_J_STATE (2 << 10) /* J-state */
+#define PORTSC_PORT_RESET (1 << 8) /* Port reset */
+#define PORTSC_PORT_SUSPEND (1 << 7) /* Suspend */
+#define PORTSC_PORT_FORCE_RESUME (1 << 6) /* Force port resume */
+#define PORTSC_OVER_CURRENT_CHG (1 << 5) /* over current change */
+#define PORTSC_OVER_CURRENT_ACT (1 << 4) /* over currrent active */
+#define PORTSC_PORT_EN_DIS_CHANGE (1 << 3) /* port {en,dis}able change */
+#define PORTSC_PORT_ENABLE (1 << 2) /* port enabled */
+#define PORTSC_CONNECT_STATUS_CHANGE (1 << 1) /* connect status change */
+#define PORTSC_CURRENT_CONNECT_STATUS (1 << 0) /* current connect status */
+
+#define PORTSC_W1C_BITS \
+ ( PORTSC_CONNECT_STATUS_CHANGE | \
+ PORTSC_PORT_EN_DIS_CHANGE | \
+ PORTSC_OVER_CURRENT_CHG )
+
+/* UOG_OTGSC Register Bits */
+/* control bits: */
+#define OTGSC_CTRL_VBUS_DISCHARGE (1 << 0)
+#define OTGSC_CTRL_VBUS_CHARGE (1 << 1)
+#define OTGSC_CTRL_OTG_TERM (1 << 3) /* controls DM pulldown */
+#define OTGSC_CTRL_DATA_PULSING (1 << 4)
+#define OTGSC_CTRL_USB_ID_PU (1 << 5) /* enable ID pullup */
+/* current status: (R/O) */
+#define OTGSC_STS_USB_ID (1 << 8) /* 0=A-device 1=B-device */
+#define OTGSC_STS_A_VBUS_VALID (1 << 9)
+#define OTGSC_STS_A_SESSION_VALID (1 << 10)
+#define OTGSC_STS_B_SESSION_VALID (1 << 11)
+#define OTGSC_STS_B_SESSION_END (1 << 12)
+#define OTGSC_STS_1ms_TIMER (1 << 13)
+#define OTGSC_STS_DATA_PULSE (1 << 14)
+/* interrupt status: (write to clear) */
+#define OTGSC_IS_MASK (0x7f << 16)
+#define OTGSC_IS_USB_ID (1 << 16)
+#define OTGSC_IS_A_VBUS_VALID (1 << 17)
+#define OTGSC_IS_A_SESSION_VALID (1 << 18)
+#define OTGSC_IS_B_SESSION_VALID (1 << 19)
+#define OTGSC_IS_B_SESSION_END (1 << 20)
+#define OTGSC_IS_1ms_TIMER (1 << 21)
+#define OTGSC_IS_DATA_PULSE (1 << 22)
+/* interrupt enables: */
+#define OTGSC_IE_MASK (0x7f << 24)
+#define OTGSC_IE_USB_ID (1 << 24)
+#define OTGSC_IE_A_VBUS_VALID (1 << 25)
+#define OTGSC_IE_A_SESSION_VALID (1 << 26)
+#define OTGSC_IE_B_SESSION_VALID (1 << 27)
+#define OTGSC_IE_B_SESSION_END (1 << 28)
+#define OTGSC_IE_1ms_TIMER (1 << 29)
+#define OTGSC_IE_DATA_PULSE (1 << 30)
+
+#if 1 /* FIXME these here for compatibility between my names and Leo's */
+/* OTG interrupt enable bit masks */
+#define OTGSC_INTERRUPT_ENABLE_BITS_MASK OTGSC_IE_MASK
+#define OTGSC_INTSTS_MASK OTGSC_IS_MASK
+
+/* OTG interrupt status bit masks */
+#define OTGSC_INTERRUPT_STATUS_BITS_MASK OTGSC_IS_MASK
+#endif
+
+/* x_USBMODE */
+#define USBMODE_SLOM (1 << 3) /* setup lockout mode */
+#define USBMODE_ES (1 << 2) /* (big) endian select */
+#define USBMODE_CM_MASK (3 << 0) /* controller mode mask */
+#define USBMODE_CM_HOST (3 << 0) /* host */
+#define USBMODE_CM_DEVICE (2 << 0) /* device */
+#define USBMODE_CM_reserved (1 << 0) /* reserved */
+
+/* USBCTRL */
+#define UCTRL_OWIR (1 << 31) /* OTG wakeup intr request received */
+#define UCTRL_OSIC_MASK (3 << 29) /* OTG Serial Interface Config: */
+#define UCTRL_OSIC_DU6 (0 << 29) /* Differential/unidirectional 6 wire */
+#define UCTRL_OSIC_DB4 (1 << 29) /* Differential/bidirectional 4 wire */
+#define UCTRL_OSIC_SU6 (2 << 29) /* single-ended/unidirectional 6 wire */
+#define UCTRL_OSIC_SB3 (3 << 29) /* single-ended/bidirectional 3 wire */
+
+#define UCTRL_OUIE (1 << 28) /* OTG ULPI intr enable */
+#define UCTRL_OWIE (1 << 27) /* OTG wakeup intr enable */
+#define UCTRL_OBPVAL_RXDP (1 << 26) /* OTG RxDp status in bypass mode */
+#define UCTRL_OBPVAL_RXDM (1 << 25) /* OTG RxDm status in bypass mode */
+#define UCTRL_OPM (1 << 24) /* OTG power mask */
+#define UCTRL_H2WIR (1 << 23) /* HOST2 wakeup intr request received */
+#define UCTRL_H2SIC_MASK (3 << 21) /* HOST2 Serial Interface Config: */
+#define UCTRL_H2SIC_DU6 (0 << 21) /* Differential/unidirectional 6 wire */
+#define UCTRL_H2SIC_DB4 (1 << 21) /* Differential/bidirectional 4 wire */
+#define UCTRL_H2SIC_SU6 (2 << 21) /* single-ended/unidirectional 6 wire */
+#define UCTRL_H2SIC_SB3 (3 << 21) /* single-ended/bidirectional 3 wire */
+
+#define UCTRL_H2UIE (1 << 20) /* HOST2 ULPI intr enable */
+#define UCTRL_H2WIE (1 << 19) /* HOST2 wakeup intr enable */
+#define UCTRL_H2PP (1 << 18) /* Power Polarity for uh2 */
+#define UCTRL_H2PM (1 << 16) /* HOST2 power mask */
+
+#define UCTRL_H1WIR (1 << 15) /* HOST1 wakeup intr request received */
+#define UCTRL_H1SIC_MASK (3 << 13) /* HOST1 Serial Interface Config: */
+#define UCTRL_H1SIC_DU6 (0 << 13) /* Differential/unidirectional 6 wire */
+#define UCTRL_H1SIC_DB4 (1 << 13) /* Differential/bidirectional 4 wire */
+#define UCTRL_H1SIC_SU6 (2 << 13) /* single-ended/unidirectional 6 wire */
+#define UCTRL_H1SIC_SB3 (3 << 13) /* single-ended/bidirectional 3 wire */
+#define UCTRL_OLOCKD (1 << 13) /* otg lock disable */
+#define UCTRL_H2LOCKD (1 << 12) /* HOST2 lock disable */
+#define UCTRL_H1UIE (1 << 12) /* Host1 ULPI interrupt enable */
+
+#define UCTRL_PP (1 << 11) /* power polarity bit */
+#define UCTRL_H1WIE (1 << 11) /* HOST1 wakeup intr enable */
+#define UCTRL_H1BPVAL_RXDP (1 << 10) /* HOST1 RxDp status in bypass mode */
+#define UCTRL_XCSO (1 << 10) /* Xcvr Clock Select for OTG port */
+#define UCTRL_H1BPVAL_RXDM (1 << 9) /* HOST1 RxDm status in bypass mode */
+#define UCTRL_XCSH2 (1 << 9) /* Xcvr Clock Select for Host port */
+#define UCTRL_H1PM (1 << 8) /* HOST1 power mask */
+#define UCTRL_IP_PULIDP (1 << 8) /* Ipp_Puimpel_Pullup_Dp */
+
+#define UCTRL_IP_PUE_UP (1 << 7) /* ipp_pue_pullup_dp */
+#define UCTRL_IP_PUE_DOWN (1 << 6) /* ipp_pue_pulldwn_dpdm */
+#define UCTRL_H2DT (1 << 5) /* HOST2 TLL disabled */
+#define UCTRL_H1DT (1 << 4) /* HOST1 TLL disabled */
+#define UCTRL_USBTE (1 << 4) /* USBT Transceiver enable */
+#define UCTRL_OCPOL (1 << 3) /* OverCurrent Polarity */
+#define UCTRL_OCE (1 << 2) /* OverCurrent Enable */
+#define UCTRL_H2OCPOL (1 << 2) /* OverCurrent Polarity of Host2 */
+#define UCTRL_H2OCS (1 << 1) /* Host OverCurrent State */
+#define UCTRL_BPE (1 << 0) /* bypass mode enable */
+#define UCTRL_OTD (1 << 0) /* OTG TLL Disable */
+#define UCTRL_OOCS (1 << 0) /* OTG OverCurrent State */
+
+/* USBCMD */
+#define UCMD_RUN_STOP (1 << 0) /* controller run/stop */
+#define UCMD_RESET (1 << 1) /* controller reset */
+#define UCMD_ITC_NO_THRESHOLD ~(0xff << 16) /* Interrupt Threshold Control */
+
+/* OTG_MIRROR */
+#define OTGM_SESEND (1 << 4) /* B device session end */
+#define OTGM_VBUSVAL (1 << 3) /* Vbus valid */
+#define OTGM_BSESVLD (1 << 2) /* B session Valid */
+#define OTGM_ASESVLD (1 << 1) /* A session Valid */
+#define OTGM_IDIDG (1 << 0) /* OTG ID pin status */
+ /* 1=high: Operate as B-device */
+ /* 0=low : Operate as A-device */
+
+/* USB_PHY_CTRL_FUNC */
+#define USB_UTMI_PHYCTRL_UTMI_ENABLE 0x01000000
+#define USB_UTMI_PHYCTRL_OC_POL (1 << 9) /* OTG Polarity of Overcurrent */
+#define USB_UTMI_PHYCTRL_OC_DIS (1 << 8) /* OTG Disable Overcurrent Event */
+
+/* USB_PHY_CTRL_FUNC2*/
+#define USB_UTMI_PHYCTRL2_PLLDIV_MASK 0x3
+#define USB_UTMI_PHYCTRL2_PLLDIV_SHIFT 0
+
+/* USB_CTRL_1 */
+#define USB_CTRL_UH1_EXT_CLK_EN (1 << 25)
+
+/* ULPIVIEW register bits */
+#define ULPIVW_OFF (0x170)
+#define ULPIVW_WU (1 << 31) /* Wakeup */
+#define ULPIVW_RUN (1 << 30) /* read/write run */
+#define ULPIVW_WRITE (1 << 29) /* 0=read 1=write */
+#define ULPIVW_SS (1 << 27) /* SyncState */
+#define ULPIVW_PORT_MASK 0x07 /* Port field */
+#define ULPIVW_PORT_SHIFT 24
+#define ULPIVW_ADDR_MASK 0xFF /* data address field */
+#define ULPIVW_ADDR_SHIFT 16
+#define ULPIVW_RDATA_MASK 0xFF /* read data field */
+#define ULPIVW_RDATA_SHIFT 8
+#define ULPIVW_WDATA_MASK 0xFF /* write data field */
+#define ULPIVW_WDATA_SHIFT 0
+
+#define HCSPARAMS_PPC (0x1<<4) /* Port Power Control */
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/audio_controls.h b/arch/arm/plat-mxc/include/mach/audio_controls.h
new file mode 100644
index 000000000000..810bf50b16a8
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/audio_controls.h
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+ /*!
+ * @file include/asm-arm/arch-mxc/audio_controls.h
+ * @brief this file implements the mxc sound driver interface to OSS framework
+ * @ingroup SOUND_DRV
+ */
+#ifndef __ASM_ARCH_MXC_AUDIO_CONTROLS_H__
+#define __ASM_ARCH_MXC_AUDIO_CONTROLS_H__
+
+/*!
+ * This ioctl can be used to get the adder configuration, use the audio control
+ * SNDCTL_MC13783_READ_OUT_MIXER.\n
+ * Possible returned values are :
+ * @see MC13783_AUDIO_ADDER_STEREO
+ * @see MC13783_AUDIO_ADDER_STEREO_OPPOSITE
+ * @see MC13783_AUDIO_ADDER_MONO
+ * @see MC13783_AUDIO_ADDER_MONO_OPPOSITE
+ *
+ */
+#define SNDCTL_MC13783_READ_OUT_ADDER _SIOR('Z', 6, int)
+
+/*!
+ * To set the adder configuration, use the audio control
+ * SNDCTL_MC13783_WRITE_OUT_MIXER. Possible arguments are : \n
+ * @see MC13783_AUDIO_ADDER_STEREO
+ * @see MC13783_AUDIO_ADDER_STEREO_OPPOSITE
+ * @see MC13783_AUDIO_ADDER_MONO
+ * @see MC13783_AUDIO_ADDER_MONO_OPPOSITE
+ *
+ */
+#define SNDCTL_MC13783_WRITE_OUT_ADDER _SIOWR('Z', 7, int)
+
+/*!
+ * To get the codec balance configuration, use the audio control
+ * SNDCTL_MC13783_READ_OUT_BALANCE.\n
+ * Range is 0 (-21 dB left) to 100 (-21 dB right), linear, 3dB step ;
+ * 50 is no balance.
+ * \n Examples:
+ * \n 0 : -21dB left 50 : balance deactivated 100 : -21 dB right
+ *
+ */
+#define SNDCTL_MC13783_READ_OUT_BALANCE _SIOR('Z', 8, int)
+
+/*!
+ * To set the codec balance configuration, use the audio control
+ * SNDCTL_MC13783_WRITE_OUT_BALANCE.\n
+ * Range is 0 (-21 dB left) to 100 (-21 dB right), linear, 3dB step ;
+ * 50 is no balance.
+ * \n Examples:
+ * \n 0 : -21dB left 50 : balance deactivated 100 : -21 dB right
+ *
+ */
+#define SNDCTL_MC13783_WRITE_OUT_BALANCE _SIOWR('Z', 9, int)
+
+/*!
+ * To set the codec filter configuration, use the audio control
+ * SNDCTL_MC13783_WRITE_CODEC_FILTER.
+ * The new configuration replaces the old one.\n
+ * Possible arguments are :
+ * @see MC13783_CODEC_FILTER_DISABLE
+ * @see MC13783_CODEC_FILTER_HIGH_PASS_IN
+ * @see MC13783_CODEC_FILTER_HIGH_PASS_OUT
+ * @see MC13783_CODEC_FILTER_DITHERING \n
+ *
+ */
+#define SNDCTL_MC13783_WRITE_CODEC_FILTER _SIOWR('Z', 20, int)
+
+/*!
+ * To get the codec filter configuration, use the audio control :
+ * SNDCTL_MC13783_READ_CODEC_FILTER.
+ * The new configuration replaces the old one.\n
+ * Possible returned values are :
+ * @see MC13783_CODEC_FILTER_DISABLE
+ * @see MC13783_CODEC_FILTER_HIGH_PASS_IN
+ * @see MC13783_CODEC_FILTER_HIGH_PASS_OUT
+ * @see MC13783_CODEC_FILTER_DITHERING \n
+ *
+ */
+#define SNDCTL_MC13783_READ_CODEC_FILTER _SIOR('Z', 21, int)
+
+/*
+ * To set the clock configuration, use the audio control
+ * SNDCTL_MC13783_WRITE_MASTER_CLOCK. \n
+ * Possible arguments are : \n
+ * 1 : to MCU master \n
+ * 2 : to MC13783 master
+ */
+#define SNDCTL_MC13783_WRITE_MASTER_CLOCK _SIOR('Z', 30, int)
+
+/*!
+ * To set the output port, use the audio control
+ * SNDCTL_MC13783_WRITE_PORT.\n
+ * Possible returned values are :
+ * \n 1 : to port 4
+ * \n 2 : to port 5
+ * Possible returned values are :
+ * \n 1 : port 4
+ * \n 2 : port 5
+ */
+#define SNDCTL_MC13783_WRITE_PORT _SIOR('Z', 31, int)
+
+/*!
+ * Argument for the mc13783 adder configuration
+ * @see SNDCTL_MC13783_WRITE_OUT_ADDER
+ * @see SNDCTL_MC13783_READ_OUT_ADDER
+ */
+#define MC13783_AUDIO_ADDER_STEREO 0x1
+/*!
+ * Argument for the mc13783 adder configuration
+ * @see SNDCTL_MC13783_WRITE_OUT_ADDER
+ * @see SNDCTL_MC13783_READ_OUT_ADDER
+ */
+#define MC13783_AUDIO_ADDER_STEREO_OPPOSITE 0x2
+/*!
+ * Argument for the mc13783 adder configuration
+ * @see SNDCTL_MC13783_WRITE_OUT_ADDER
+ * @see SNDCTL_MC13783_READ_OUT_ADDER
+ */
+#define MC13783_AUDIO_ADDER_MONO 0x4
+/*!
+ * Argument for the mc13783 adder configuration
+ * @see SNDCTL_MC13783_WRITE_OUT_ADDER
+ * @see SNDCTL_MC13783_READ_OUT_ADDER
+ */
+#define MC13783_AUDIO_ADDER_MONO_OPPOSITE 0x8
+
+/*!
+ * Argument for the mc13783 codec filter configuration
+ * @see SNDCTL_MC13783_WRITE_CODEC_FILTER
+ * @see SNDCTL_MC13783_READ_CODEC_FILTER
+ */
+#define MC13783_CODEC_FILTER_DISABLE 0x0
+/*!
+ * Argument for the mc13783 codec filter configuration
+ * @see SNDCTL_MC13783_WRITE_CODEC_FILTER
+ * @see SNDCTL_MC13783_READ_CODEC_FILTER
+ */
+#define MC13783_CODEC_FILTER_HIGH_PASS_IN 0x1
+/*!
+ * Argument for the mc13783 codec filter configuration
+ * @see SNDCTL_MC13783_WRITE_CODEC_FILTER
+ * @see SNDCTL_MC13783_READ_CODEC_FILTER
+ */
+#define MC13783_CODEC_FILTER_HIGH_PASS_OUT 0x2
+/*!
+ * Argument for the mc13783 codec filter configuration
+ * @see SNDCTL_MC13783_WRITE_CODEC_FILTER
+ * @see SNDCTL_MC13783_READ_CODEC_FILTER
+ */
+#define MC13783_CODEC_FILTER_DITHERING 0x4
+
+/*!
+ * Argument for the system audio clocking selection
+ * @see MXC_AUDIO_CLOCKING_MCU_MASTER
+ * @see SNDCTL_CLK_SET_MASTER
+ */
+#define MXC_AUDIO_CLOCKING_MC13783_MASTER 0x0
+
+/*!
+ * Argument for the system audio clocking selection
+ * @see MXC_AUDIO_CLOCKING_MC13783_MASTER
+ * @see SNDCTL_CLK_SET_MASTER
+ */
+#define MXC_AUDIO_CLOCKING_MCU_MASTER 0x1
+
+/*!
+ * Argument for the DAM output port selection
+ * @see SNDCTL_DAM_SET_OUT_PORT
+ * @see MXC_DAM_OUT_PORT_AD2
+ */
+#define MXC_DAM_OUT_PORT_AD1 0x0
+
+/*!
+ * Argument for the DAM output port selection
+ * @see SNDCTL_DAM_SET_OUT_PORT
+ * @see MXC_DAM_OUT_PORT_AD1
+ */
+#define MXC_DAM_OUT_PORT_AD2 0x1
+
+/*!
+ * Argument for the mc13783 codec filter configuration
+ * @see SNDCTL_MC13783_WRITE_CODEC_FILTER
+ * @see SNDCTL_MC13783_READ_CODEC_FILTER
+ */
+#define MC13783_CODEC_FILTER_DISABLE 0x0
+
+/*!
+ * Argument for the mc13783 codec filter configuration
+ * @see SNDCTL_MC13783_WRITE_CODEC_FILTER
+ * @see SNDCTL_MC13783_READ_CODEC_FILTER
+ */
+#define MC13783_CODEC_FILTER_HIGH_PASS_IN 0x1
+
+/*!
+ * Argument for the mc13783 codec filter configuration
+ * @see SNDCTL_MC13783_WRITE_CODEC_FILTER
+ * @see SNDCTL_MC13783_READ_CODEC_FILTER
+ */
+#define MC13783_CODEC_FILTER_HIGH_PASS_OUT 0x2
+
+/*!
+ * Argument for the mc13783 codec filter configuration
+ * @see SNDCTL_MC13783_WRITE_CODEC_FILTER
+ * @see SNDCTL_MC13783_READ_CODEC_FILTER
+ */
+#define MC13783_CODEC_FILTER_DITHERING 0x4
+
+#endif /* __ASM_ARCH_MXC_AUDIO_CONTROLS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/clock.h b/arch/arm/plat-mxc/include/mach/clock.h
index d21f78e78819..abcfe7d5c6b3 100644
--- a/arch/arm/plat-mxc/include/mach/clock.h
+++ b/arch/arm/plat-mxc/include/mach/clock.h
@@ -34,6 +34,8 @@ struct clk {
struct clk *parent;
/* Secondary clock to enable/disable with this clock */
struct clk *secondary;
+ /* Current clock rate */
+ unsigned long rate;
/* Reference count of clock enable/disable */
__s8 usecount;
/* Register bit position for clock's enable/disable control. */
@@ -41,8 +43,9 @@ struct clk {
/* Register address for clock's enable/disable control. */
void __iomem *enable_reg;
u32 flags;
- /* get the current clock rate (always a fresh value) */
- unsigned long (*get_rate) (struct clk *);
+ /* Function ptr to recalculate the clock's rate based on parent
+ clock's rate */
+ void (*recalc) (struct clk *);
/* Function ptr to set the clock to a new rate. The rate must match a
supported rate returned from round_rate. Leave blank if clock is not
programmable */
@@ -62,6 +65,14 @@ struct clk {
int clk_register(struct clk *clk);
void clk_unregister(struct clk *clk);
+int clk_get_usecount(struct clk *clk);
+int clk_set_pll_dither(struct clk *clk, unsigned int pll_ppm);
+/* Clock flags */
+#define RATE_PROPAGATES (1 << 0) /* Program children too */
+#define ALWAYS_ENABLED (1 << 1) /* Clock cannot be disabled */
+#define RATE_FIXED (1 << 2) /* Fixed clock rate */
+#define CPU_FREQ_TRIG_UPDATE (1 << 3) /* CPUFREQ trig update */
+
#endif /* __ASSEMBLY__ */
#endif /* __ASM_ARCH_MXC_CLOCK_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/common.h b/arch/arm/plat-mxc/include/mach/common.h
index 6350287a59b9..01a770c794e7 100644
--- a/arch/arm/plat-mxc/include/mach/common.h
+++ b/arch/arm/plat-mxc/include/mach/common.h
@@ -16,7 +16,11 @@ struct platform_device;
extern void mxc_map_io(void);
extern void mxc_init_irq(void);
extern void mxc_timer_init(const char *clk_timer);
-extern int mxc_clocks_init(unsigned long fref);
+extern int __init mxc_clocks_init(unsigned long ckil, unsigned long osc, unsigned long ckih1, unsigned long ckih2);
+extern int mxc_init_devices(void);
+extern void mxc_cpu_init(void) __init;
+extern void mxc_cpu_common_init(void);
+extern void __init early_console_setup(char *);
extern int mxc_register_gpios(void);
extern int mxc_register_device(struct platform_device *pdev, void *data);
diff --git a/arch/arm/plat-mxc/include/mach/dma.h b/arch/arm/plat-mxc/include/mach/dma.h
index c822d569a05e..b52b2fc2730b 100644
--- a/arch/arm/plat-mxc/include/mach/dma.h
+++ b/arch/arm/plat-mxc/include/mach/dma.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -11,4 +11,253 @@
#ifndef __ASM_ARCH_MXC_DMA_H__
#define __ASM_ARCH_MXC_DMA_H__
+#define MXC_DMA_DYNAMIC_CHANNEL 255
+
+#define MXC_DMA_DONE 0x0
+#define MXC_DMA_REQUEST_TIMEOUT 0x1
+#define MXC_DMA_TRANSFER_ERROR 0x2
+
+/*! This defines the list of device ID's for DMA */
+typedef enum mxc_dma_device {
+ MXC_DMA_UART1_RX,
+ MXC_DMA_UART1_TX,
+ MXC_DMA_UART2_RX,
+ MXC_DMA_UART2_TX,
+ MXC_DMA_UART3_RX,
+ MXC_DMA_UART3_TX,
+ MXC_DMA_UART4_RX,
+ MXC_DMA_UART4_TX,
+ MXC_DMA_UART5_RX,
+ MXC_DMA_UART5_TX,
+ MXC_DMA_UART6_RX,
+ MXC_DMA_UART6_TX,
+ MXC_DMA_MMC1_WIDTH_1,
+ MXC_DMA_MMC1_WIDTH_4,
+ MXC_DMA_MMC2_WIDTH_1,
+ MXC_DMA_MMC2_WIDTH_4,
+ MXC_DMA_SSI1_8BIT_RX0,
+ MXC_DMA_SSI1_8BIT_TX0,
+ MXC_DMA_SSI1_16BIT_RX0,
+ MXC_DMA_SSI1_16BIT_TX0,
+ MXC_DMA_SSI1_24BIT_RX0,
+ MXC_DMA_SSI1_24BIT_TX0,
+ MXC_DMA_SSI1_8BIT_RX1,
+ MXC_DMA_SSI1_8BIT_TX1,
+ MXC_DMA_SSI1_16BIT_RX1,
+ MXC_DMA_SSI1_16BIT_TX1,
+ MXC_DMA_SSI1_24BIT_RX1,
+ MXC_DMA_SSI1_24BIT_TX1,
+ MXC_DMA_SSI2_8BIT_RX0,
+ MXC_DMA_SSI2_8BIT_TX0,
+ MXC_DMA_SSI2_16BIT_RX0,
+ MXC_DMA_SSI2_16BIT_TX0,
+ MXC_DMA_SSI2_24BIT_RX0,
+ MXC_DMA_SSI2_24BIT_TX0,
+ MXC_DMA_SSI2_8BIT_RX1,
+ MXC_DMA_SSI2_8BIT_TX1,
+ MXC_DMA_SSI2_16BIT_RX1,
+ MXC_DMA_SSI2_16BIT_TX1,
+ MXC_DMA_SSI2_24BIT_RX1,
+ MXC_DMA_SSI2_24BIT_TX1,
+ MXC_DMA_FIR_RX,
+ MXC_DMA_FIR_TX,
+ MXC_DMA_CSPI1_RX,
+ MXC_DMA_CSPI1_TX,
+ MXC_DMA_CSPI2_RX,
+ MXC_DMA_CSPI2_TX,
+ MXC_DMA_CSPI3_RX,
+ MXC_DMA_CSPI3_TX,
+ MXC_DMA_ATA_RX,
+ MXC_DMA_ATA_TX,
+ MXC_DMA_MEMORY,
+ MXC_DMA_FIFO_MEMORY,
+ MXC_DMA_DSP_PACKET_DATA0_RD,
+ MXC_DMA_DSP_PACKET_DATA0_WR,
+ MXC_DMA_DSP_PACKET_DATA1_RD,
+ MXC_DMA_DSP_PACKET_DATA1_WR,
+ MXC_DMA_DSP_LOG0_CHNL,
+ MXC_DMA_DSP_LOG1_CHNL,
+ MXC_DMA_DSP_LOG2_CHNL,
+ MXC_DMA_DSP_LOG3_CHNL,
+ MXC_DMA_CSI_RX,
+ MXC_DMA_SPDIF_16BIT_TX,
+ MXC_DMA_SPDIF_16BIT_RX,
+ MXC_DMA_SPDIF_32BIT_TX,
+ MXC_DMA_SPDIF_32BIT_RX,
+ MXC_DMA_ASRC_A_RX,
+ MXC_DMA_ASRC_A_TX,
+ MXC_DMA_ASRC_B_RX,
+ MXC_DMA_ASRC_B_TX,
+ MXC_DMA_ASRC_C_RX,
+ MXC_DMA_ASRC_C_TX,
+ MXC_DMA_ESAI_16BIT_RX,
+ MXC_DMA_ESAI_16BIT_TX,
+ MXC_DMA_ESAI_24BIT_RX,
+ MXC_DMA_ESAI_24BIT_TX,
+ MXC_DMA_TEST_RAM2D2RAM,
+ MXC_DMA_TEST_RAM2RAM2D,
+ MXC_DMA_TEST_RAM2D2RAM2D,
+ MXC_DMA_TEST_RAM2RAM,
+ MXC_DMA_TEST_HW_CHAINING,
+ MXC_DMA_TEST_SW_CHAINING
+} mxc_dma_device_t;
+
+/*! This defines the prototype of callback funtion registered by the drivers */
+typedef void (*mxc_dma_callback_t) (void *arg, int error_status,
+ unsigned int count);
+
+/*! This defines the type of DMA transfer requested */
+typedef enum mxc_dma_mode {
+ MXC_DMA_MODE_READ,
+ MXC_DMA_MODE_WRITE,
+} mxc_dma_mode_t;
+
+/*! This defines the DMA channel parameters */
+typedef struct mxc_dma_channel {
+ unsigned int active:1; /*!< When there has a active tranfer, it is set to 1 */
+ unsigned int lock; /*!< Defines the channel is allocated or not */
+ int curr_buf; /*!< Current buffer */
+ mxc_dma_mode_t mode; /*!< Read or Write */
+ unsigned int channel; /*!< Channel info */
+ unsigned int dynamic:1; /*!< Channel not statically allocated when 1 */
+ char *dev_name; /*!< Device name */
+ void *private; /*!< Private structure for platform */
+ mxc_dma_callback_t cb_fn; /*!< The callback function */
+ void *cb_args; /*!< The argument of callback function */
+} mxc_dma_channel_t;
+
+/*! This structure contains the information about a dma transfer */
+typedef struct mxc_dma_requestbuf {
+ dma_addr_t src_addr; /*!< source address */
+ dma_addr_t dst_addr; /*!< destination address */
+ int num_of_bytes; /*!< the length of this transfer : bytes */
+} mxc_dma_requestbuf_t;
+
+#if defined(CONFIG_ARCH_MX27) || defined(CONFIG_ARCH_MX21)
+#include <mach/mx2_dma.h>
+#else
+#include <mach/sdma.h>
+#endif
+
+/*!
+ * This function is generally called by the driver at open time.
+ * The DMA driver would do any initialization steps that is required
+ * to get the channel ready for data transfer.
+ *
+ * @param channel_id a pre-defined id. The peripheral driver would specify
+ * the id associated with its peripheral. This would be
+ * used by the DMA driver to identify the peripheral
+ * requesting DMA and do the necessary setup on the
+ * channel associated with the particular peripheral.
+ * The DMA driver could use static or dynamic DMA channel
+ * allocation.
+ * @param dev_name module name or device name
+ * @return returns a negative number on error if request for a DMA channel did not
+ * succeed, returns the channel number to be used on success.
+ */
+extern int mxc_dma_request(mxc_dma_device_t channel_id, char *dev_name);
+
+/*!
+ * This function is generally called by the driver at close time. The DMA
+ * driver would do any cleanup associated with this channel.
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @return returns a negative number on error or 0 on success
+ */
+extern int mxc_dma_free(int channel_num);
+
+/*!
+ * This function would just configure the buffers specified by the user into
+ * dma channel. The caller must call mxc_dma_enable to start this transfer.
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @param dma_buf an array of physical addresses to the user defined
+ * buffers. The caller must guarantee the dma_buf is
+ * available until the transfer is completed.
+ * @param num_buf number of buffers in the array
+ * @param mode specifies whether this is READ or WRITE operation
+ * @return This function returns a negative number on error if buffer could not be
+ * added with DMA for transfer. On Success, it returns 0
+ */
+extern int mxc_dma_config(int channel_num, mxc_dma_requestbuf_t * dma_buf,
+ int num_buf, mxc_dma_mode_t mode);
+
+/*!
+ * This function would just configure the scatterlist specified by the
+ * user into dma channel. This is a slight variation of mxc_dma_config(),
+ * it is provided for the convenience of drivers that have a scatterlist
+ * passed into them. It is the calling driver's responsibility to have the
+ * correct physical address filled in the "dma_address" field of the
+ * scatterlist.
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @param sg a scatterlist of buffers. The caller must guarantee
+ * the dma_buf is available until the transfer is
+ * completed.
+ * @param num_buf number of buffers in the array
+ * @param num_of_bytes total number of bytes to transfer. If set to 0, this
+ * would imply to use the length field of the scatterlist
+ * for each DMA transfer. Else it would calculate the size
+ * for each DMA transfer.
+ * @param mode specifies whether this is READ or WRITE operation
+ * @return This function returns a negative number on error if buffer could not
+ * be added with DMA for transfer. On Success, it returns 0
+ */
+extern int mxc_dma_sg_config(int channel_num, struct scatterlist *sg,
+ int num_buf, int num_of_bytes,
+ mxc_dma_mode_t mode);
+
+/*!
+ * This function is provided if the driver would like to set/change its
+ * callback function.
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @param callback a callback function to provide notification on transfer
+ * completion, user could specify NULL if he does not wish
+ * to be notified
+ * @param arg an argument that gets passed in to the callback
+ * function, used by the user to do any driver specific
+ * operations.
+ * @return this function returns a negative number on error if the callback
+ * could not be set for the channel or 0 on success
+ */
+extern int mxc_dma_callback_set(int channel_num, mxc_dma_callback_t callback,
+ void *arg);
+
+/*!
+ * This stops the DMA channel and any ongoing transfers. Subsequent use of
+ * mxc_dma_enable() will restart the channel and restart the transfer.
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @return returns a negative number on error or 0 on success
+ */
+extern int mxc_dma_disable(int channel_num);
+
+/*!
+ * This starts DMA transfer. Or it restarts DMA on a stopped channel
+ * previously stopped with mxc_dma_disable().
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @return returns a negative number on error or 0 on success
+ */
+extern int mxc_dma_enable(int channel_num);
+
#endif
diff --git a/arch/arm/plat-mxc/include/mach/dptc.h b/arch/arm/plat-mxc/include/mach/dptc.h
new file mode 100644
index 000000000000..ac897bbea2a7
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/dptc.h
@@ -0,0 +1,186 @@
+
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_DPTC_H__
+#define __ASM_ARCH_MXC_DPTC_H__
+
+#include <mach/dvfs_dptc_struct.h>
+
+/*!
+ * DPTC proc file system entry name
+ */
+#define PROC_NODE_NAME "dptc"
+
+int __init init_dptc_controller(dvfs_dptc_params_s * params);
+
+/*!
+ * This function enables the DPTC module. this function updates the DPTC
+ * thresholds, updates the PMIC, unmasks the DPTC interrupt and enables
+ * the DPTC module
+ *
+ * @param params pointer to the DVFS & DPTC driver parameters structure.
+ *
+ * @return 0 if DPTC module was enabled else returns -EINVAL.
+ */
+int start_dptc(dvfs_dptc_params_s * params);
+/*!
+ * This function disables the DPTC module.
+ *
+ * @param params pointer to the DVFS & DPTC driver parameters structure.
+ *
+ * @return 0 if DPTC module was disabled else returns -EINVAL.
+ */
+int stop_dptc(dvfs_dptc_params_s * params);
+/*!
+ * This function updates the drivers current working point index. This index is
+ * used for access the current DTPC table entry and it corresponds to the
+ * current CPU working point measured by the DPTC hardware.
+ *
+ * @param params pointer to the DVFS & DPTC driver parameters structure.
+ * @param new_wp New working point index value to be set.
+ *
+ */
+void set_dptc_wp(dvfs_dptc_params_s * params, int new_wp);
+/*!
+ * This function updates the DPTC threshold registers.
+ *
+ * @param dvfs_dptc_tables_ptr pointer to the DPTC translation table.
+ * @param wp current wp value.
+ * @param freq_index translation table index of the current CPU
+ * frequency.
+ *
+ */
+void update_dptc_thresholds(dvfs_dptc_tables_s * dptc_tables_ptr,
+ int wp, int freq_index);
+/*!
+ * This function adds a new entry to the DPTC log buffer.
+ *
+ * @param params pointer to the DVFS & DPTC driver parameters structure.
+ * @param dptc_log pointer to the DPTC log buffer structure.
+ * @param wp value of the working point index written
+ * to the log buffer.
+ * @param freq_index value of the frequency index written to
+ * the log buffer.
+ *
+ * @return number of log buffer entries.
+ *
+ */
+
+void add_dptc_log_entry(dvfs_dptc_params_s * params,
+ dptc_log_s * dptc_log, int wp, int freq_index);
+
+/*!
+ * This function updates the CPU voltage, produced by PMIC, by calling PMIC
+ * driver functions.
+ *
+ * @param dptc_tables_ptr pointer to the DPTC translation table.
+ * @param wp current wp value.
+ */
+void set_pmic_voltage(dvfs_dptc_tables_s * dptc_tables_ptr, int wp);
+
+/*!
+ * This function enables the DPTC reference circuits.
+ *
+ * @param params pointer to the DVFS & DPTC driver parameters structure.
+ * @param rc_state each high bit specifies which
+ * reference circuite to enable.
+ * @return 0 on success, error code on failure
+ */
+int enable_ref_circuits(dvfs_dptc_params_s * params, unsigned char rc_state);
+
+/*!
+ * This function disables the DPTC reference circuits.
+ *
+ * @param params pointer to the DVFS & DPTC driver parameters structure.
+ * @param rc_state each high bit specifies which
+ * reference circuite to disable
+ * @return 0 on success, error code on failure
+ */
+int disable_ref_circuits(dvfs_dptc_params_s * params, unsigned char rc_state);
+
+/*!
+ * This function is the DPTC Interrupt handler.
+ * This function wakes-up the dptc_workqueue_handler function that handles the
+ * DPTC interrupt.
+ */
+void dptc_irq(void);
+
+/*!
+ * This function updates the drivers current frequency index.This index is
+ * used for access the current DTPC table entry and it corresponds to the
+ * current CPU frequency (each CPU frequency has a separate index number
+ * according to the loaded DPTC table).
+ *
+ * @param params pointer to the DVFS & DPTC driver parameters structure.
+ * @param freq_index New frequency index value to be set.
+ *
+ * @return 0 if the frequency index was updated (the new index is a
+ * valid index and the DPTC module isn't active) else returns
+ * -EINVAL.
+ *
+ */
+int set_dptc_curr_freq(dvfs_dptc_params_s * params, unsigned int freq_index);
+
+#ifdef CONFIG_MXC_DVFS_SDMA
+/*
+ * DPTC SDMA callback.
+ * Updates the PMIC voltage
+ *
+ * @param params pointer to the DVFS & DPTC driver parameters structure.
+ */
+void dptc_sdma_callback(dvfs_dptc_params_s * params);
+#endif
+
+/*!
+ * This function is called to put the DPTC in a low power state.
+ *
+ * @param pdev the device structure used to give information on which
+ * device to suspend (not relevant for DPTC)
+ * @param state the power state the device is entering
+ *
+ * @return The function always returns 0.
+ */
+int mxc_dptc_suspend(struct platform_device *pdev, pm_message_t state);
+
+/*!
+ * This function is called to put the DPTC in a low power state.
+ *
+ */
+void dptc_suspend(void);
+
+/*!
+ * This function is called to resume the DPTC from a low power state.
+ *
+ * @param pdev the device structure used to give information on which
+ * device to suspend (not relevant for DPTC)
+ *
+ * @return The function always returns 0.
+ */
+int mxc_dptc_resume(struct platform_device *dev);
+
+/*!
+ * This function is called to resume the DPTC from a low power state.
+ *
+ */
+void dptc_resume(void);
+
+/*!
+ * This function initializes DPTC according to turbo mode status
+ *
+ * @param status Turbo mode disable, 1 - turbo mode enabled
+ *
+ */
+void dptc_set_turbo_mode(unsigned int status);
+
+#endif /* __ASM_ARCH_MXC_DPTC_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/dvfs_dptc_struct.h b/arch/arm/plat-mxc/include/mach/dvfs_dptc_struct.h
new file mode 100644
index 000000000000..006bcf293d63
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/dvfs_dptc_struct.h
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file arch-mxc/dvfs_dptc_struct.h
+ *
+ * @brief MXC dvfs & dptc structure definitions file.
+ *
+ * @ingroup PM_MX27 PM_MX31 PM_MXC91321 PM_MXC91311
+ */
+#ifndef __ASM_ARCH_MXC_DVFS_DPTC_STRUCT_H__
+#define __ASM_ARCH_MXC_DVFS_DPTC_STRUCT_H__
+
+#include <linux/semaphore.h>
+#include <mach/pm_api.h>
+
+/*!
+ * Number of entries in the DPTC log buffer
+ */
+#define LOG_ENTRIES 1024
+
+/*!
+ * Log buffer Structure.\n
+ * This structure records the DPTC changes. \n
+ * This structure can be read by the user using the proc file system DPTC read entry.
+ */
+typedef struct {
+ /*!
+ * Index to the head of the log buffer
+ */
+ int head;
+
+ /*!
+ * Index to the tail of the log buffer
+ */
+ int tail;
+
+ /*!
+ * Mutex to allow access to the log buffer
+ */
+ struct semaphore mutex;
+
+ /*!
+ * Array of log buffer entries
+ */
+ dptc_log_entry_s entries[LOG_ENTRIES];
+} dptc_log_s;
+
+/*!
+ * DPTC driver data structure.\n
+ * Holds all driver parameters and data structures.
+ */
+typedef struct {
+ /*!
+ * This variable holds the current frequency index
+ */
+ int current_freq_index;
+
+ /*!
+ * Boolean variable, if TRUE the DPTC module is enabled
+ * if FALSE the DPTC module is disabled
+ */
+ int dptc_is_active;
+
+ /*!
+ * Boolean variable, if TRUE turbo mode enable
+ * if FALSE turbo mode disabled
+ */
+ int turbo_mode_active;
+
+ /*!
+ * Boolean variable, if TRUE the DVFS module is enabled
+ * if FALSE the DPTC module is disabled
+ */
+ int dvfs_is_active;
+
+ /*!
+ * Boolean variable, if TRUE the DPTC module is suspended
+ */
+ int suspended;
+
+ unsigned char rc_state;
+
+ /*!
+ * Pointer to the DVFS & DPTC translation table
+ */
+ dvfs_dptc_tables_s *dvfs_dptc_tables_ptr;
+
+ /*!
+ * The DPTC log buffer
+ */
+ dptc_log_s dptc_log_buffer;
+
+ /*!
+ * The DVFS log buffer
+ */
+ unsigned char *dvfs_log_buffer;
+
+ /*!
+ * The DVFS log buffer physical address (for SDMA)
+ */
+ dma_addr_t dvfs_log_buffer_phys;
+
+#ifdef CONFIG_MXC_DVFS_SDMA
+ /*!
+ * SDMA channel number
+ */
+ int sdma_channel;
+
+ /*!
+ * This holds the previous working point
+ */
+ int prev_wp;
+
+ /*!
+ * Wait entry for predictive DVFS
+ */
+ wait_queue_head_t dvfs_pred_wait;
+#endif
+
+ /*!
+ * This holds the current DVFS mode
+ */
+ unsigned int dvfs_mode;
+
+ /*!
+ * Log buffer read pointer
+ */
+ unsigned char *read_ptr;
+
+ /*
+ * Number of characters in log buffer
+ */
+ int chars_in_buffer;
+} dvfs_dptc_params_s;
+
+/*!
+ * This struct contains the array with values of supported frequencies in Hz
+ */
+typedef struct {
+ /*
+ * Number of supported states
+ */
+ unsigned int num_of_states;
+ /*!
+ * Array of frequencies
+ */
+ unsigned int *freqs;
+} dvfs_states_table;
+
+/*
+ * if not defined define TREU and FALSE values.
+ */
+#ifndef TRUE
+#define TRUE 1
+#define FALSE 0
+#endif /* TRUE */
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/entry-macro.S b/arch/arm/plat-mxc/include/mach/entry-macro.S
index 11632028f7d1..92f553baf447 100644
--- a/arch/arm/plat-mxc/include/mach/entry-macro.S
+++ b/arch/arm/plat-mxc/include/mach/entry-macro.S
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2007 Lennert Buytenhek <buytenh@wantstofly.org>
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -9,6 +9,8 @@
* published by the Free Software Foundation.
*/
+#include <mach/hardware.h>
+
#define AVIC_NIMASK 0x04
@ this macro disables fast irq (not implemented)
@@ -16,10 +18,14 @@
.endm
.macro get_irqnr_preamble, base, tmp
+#ifdef CONFIG_MXC_TZIC
+ ldr \base, =TZIC_IO_ADDRESS(TZIC_BASE_ADDR)
+#else
ldr \base, =AVIC_IO_ADDRESS(AVIC_BASE_ADDR)
#ifdef CONFIG_MXC_IRQ_PRIOR
ldr r4, [\base, #AVIC_NIMASK]
#endif
+#endif
.endm
.macro arch_ret_to_user, tmp1, tmp2
@@ -29,6 +35,32 @@
@ and returns its number in irqnr
@ and returns if an interrupt occured in irqstat
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+#ifdef CONFIG_MXC_TZIC
+ @ Load offset & priority of the highest priority
+ @ interrupt pending.
+ @ 0xD80 is HIPND0 register
+ ldr \irqnr, =0
+ ldr \irqstat, =0x0D80
+1000:
+ ldr \tmp, [\irqstat, \base]
+ cmp \tmp, #0
+ bne 1001f
+ addeq \irqnr, \irqnr, #32
+ addeq \irqstat, \irqstat, #4
+ cmp \irqnr, #128
+ blo 1000b
+ b 2001f
+1001: ldr \irqstat, =1
+1002: tst \tmp, \irqstat
+ bne 2002f
+ movs \tmp, \tmp, lsr #1
+ addne \irqnr, \irqnr, #1
+ bne 1002b
+2001:
+ ldr \irqnr, =0
+2002:
+ movs \irqnr, \irqnr
+#else
@ Load offset & priority of the highest priority
@ interrupt pending from AVIC_NIVECSR
ldr \irqstat, [\base, #0x40]
@@ -42,6 +74,7 @@
strne \tmp, [\base, #AVIC_NIMASK]
streq r4, [\base, #AVIC_NIMASK]
#endif
+#endif
.endm
@ irq priority table (not used)
diff --git a/arch/arm/plat-mxc/include/mach/fsl_usb.h b/arch/arm/plat-mxc/include/mach/fsl_usb.h
new file mode 100644
index 000000000000..0ee6ea0e7b1f
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/fsl_usb.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * USB Host side, platform-specific functionality.
+ */
+
+#include <linux/usb/fsl_xcvr.h>
+#include <mach/arc_otg.h>
+
+/* ehci_arc_hc_driver.flags value */
+#define FSL_PLATFORM_HC_FLAGS (HCD_USB2 | HCD_MEMORY)
+
+static void fsl_setup_phy(struct ehci_hcd *ehci,
+ enum fsl_usb2_phy_modes phy_mode,
+ int port_offset);
+
+static inline void fsl_platform_usb_setup(struct ehci_hcd *ehci)
+{
+ struct fsl_usb2_platform_data *pdata;
+
+ pdata = ehci_to_hcd(ehci)->self.controller->platform_data;
+ fsl_setup_phy(ehci, pdata->phy_mode, 0);
+}
+
+static inline void fsl_platform_set_host_mode(struct usb_hcd *hcd)
+{
+ unsigned int temp;
+ struct fsl_usb2_platform_data *pdata;
+
+ pdata = hcd->self.controller->platform_data;
+
+ if (pdata->xcvr_ops && pdata->xcvr_ops->set_host)
+ pdata->xcvr_ops->set_host();
+
+ /* set host mode */
+ temp = readl(hcd->regs + 0x1a8);
+ writel(temp | USBMODE_CM_HOST, hcd->regs + 0x1a8);
+}
+
+/* Needed for i2c/serial transceivers */
+static inline void
+fsl_platform_set_vbus_power(struct fsl_usb2_platform_data *pdata, int on)
+{
+ if (pdata->xcvr_ops && pdata->xcvr_ops->set_vbus_power)
+ pdata->xcvr_ops->set_vbus_power(pdata->xcvr_ops, pdata, on);
+}
+
+/* Set USB AHB burst length for host */
+static inline void fsl_platform_set_ahb_burst(struct usb_hcd *hcd)
+{
+ struct fsl_usb2_platform_data *pdata;
+ unsigned int temp;
+
+ pdata = hcd->self.controller->platform_data;
+ if (pdata->change_ahb_burst) {
+ temp = readl(hcd->regs + FSL_SOC_USB_SBUSCFG);
+ writel((temp & (~(0x7))) | pdata->ahb_burst_mode,
+ hcd->regs + FSL_SOC_USB_SBUSCFG);
+ }
+
+ /* Increase TX fifo threshold for USB+ATA for i.mx35 2.0 */
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) >= 1) {
+ temp = readl(hcd->regs + FSL_SOC_USB_TXFILLTUNING);
+ /* Change TX FIFO threshold to be 0x20 */
+ writel((temp & (~(0x3f << 16))) | (0x20 << 16),
+ hcd->regs + FSL_SOC_USB_TXFILLTUNING);
+ }
+}
diff --git a/arch/arm/plat-mxc/include/mach/fsl_usb_gadget.h b/arch/arm/plat-mxc/include/mach/fsl_usb_gadget.h
new file mode 100644
index 000000000000..d3c581e70765
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/fsl_usb_gadget.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2005-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * USB Gadget side, platform-specific functionality.
+ */
+
+#include <linux/usb/fsl_xcvr.h>
+
+/* Needed for i2c/serial transceivers */
+static inline void
+fsl_platform_set_device_mode(struct fsl_usb2_platform_data *pdata)
+{
+ if (pdata->xcvr_ops && pdata->xcvr_ops->set_device)
+ pdata->xcvr_ops->set_device();
+}
+
+static inline void
+fsl_platform_pullup_enable(struct fsl_usb2_platform_data *pdata)
+{
+ if (pdata->xcvr_ops && pdata->xcvr_ops->pullup)
+ pdata->xcvr_ops->pullup(1);
+}
+
+static inline void
+fsl_platform_pullup_disable(struct fsl_usb2_platform_data *pdata)
+{
+ if (pdata->xcvr_ops && pdata->xcvr_ops->pullup)
+ pdata->xcvr_ops->pullup(0);
+}
diff --git a/arch/arm/plat-mxc/include/mach/gpio.h b/arch/arm/plat-mxc/include/mach/gpio.h
index 65eedc0d196f..07e936ac5e2b 100644
--- a/arch/arm/plat-mxc/include/mach/gpio.h
+++ b/arch/arm/plat-mxc/include/mach/gpio.h
@@ -1,42 +1,167 @@
/*
- * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- *
- * 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.
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
*/
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
#ifndef __ASM_ARCH_MXC_GPIO_H__
#define __ASM_ARCH_MXC_GPIO_H__
-#include <mach/hardware.h>
-#include <asm-generic/gpio.h>
+/*!
+ * @defgroup GPIO General Purpose Input Output (GPIO)
+ */
-/* use gpiolib dispatchers */
-#define gpio_get_value __gpio_get_value
-#define gpio_set_value __gpio_set_value
-#define gpio_cansleep __gpio_cansleep
+/*!
+ * @file arch-mxc/gpio.h
+ * @brief This file contains the GPIO API functions.
+ *
+ * @ingroup GPIO
+ */
-#define gpio_to_irq(gpio) (MXC_MAX_INT_LINES + (gpio))
-#define irq_to_gpio(irq) ((irq) - MXC_MAX_INT_LINES)
+#include <linux/interrupt.h>
+#include <asm/sizes.h>
-struct mxc_gpio_port {
- void __iomem *base;
- int irq;
- int virtual_irq_start;
- struct gpio_chip chip;
-};
+typedef unsigned int iomux_pin_name_t;
-int mxc_gpio_init(struct mxc_gpio_port*, int);
+/* gpio related defines */
+
+/*!
+ * There are two queues for registered GPIO ISRs. One is for high priority and
+ * the other is for low priority. The ISRs in the high priority queue will be
+ * called first before the low priority queue if more than one GPIO interrupt
+ * occurs at the same time.
+ */
+enum gpio_prio {
+ GPIO_HIGH_PRIO = 0, /*!< high priority queue */
+ GPIO_LOW_PRIO /*!< low priority queue */
+};
+/*!
+ * This enumeration data type defines various different ways for interrupting
+ * the ARM core from GPIO signals. The way to interrupt the core is dictated
+ * by the external hardware.
+ */
+typedef enum gpio_int_cfg {
+#if defined(CONFIG_ARCH_MX21) || defined(CONFIG_ARCH_MX27)
+ GPIO_INT_LOW_LEV = 0x3, /*!< low level sensitive */
+ GPIO_INT_HIGH_LEV = 0x2, /*!< high level sensitive */
+ GPIO_INT_RISE_EDGE = 0x0, /*!< rising edge sensitive */
+ GPIO_INT_FALL_EDGE = 0x1, /*!< falling edge sensitive */
+ GPIO_INT_NONE = 0x4 /*!< No interrupt */
+#else
+ GPIO_INT_LOW_LEV = 0x0, /*!< low level sensitive */
+ GPIO_INT_HIGH_LEV = 0x1, /*!< high level sensitive */
+ GPIO_INT_RISE_EDGE = 0x2, /*!< rising edge sensitive */
+ GPIO_INT_FALL_EDGE = 0x3, /*!< falling edge sensitive */
+ GPIO_INT_NONE = 0x4 /*!< No interrupt */
#endif
+} gpio_edge_t;
+
+typedef irqreturn_t(*gpio_irq_handler) (int, void *);
+
+/*!
+ * This function configures the GPIO signal to be either input or output. For
+ * input signals used for generating interrupts for the ARM core, how the
+ * interrupts being triggered is also passed in via \a icr. For output signals,
+ * the \a icr value doesn't matter.
+ *
+ * @param port specified port with 0-GPIO port 1; 1-GPIO port 2
+ * @param sig_no specified GPIO signal (0 based)
+ * @param out #true for output, #false for input
+ * @param icr value defined in \b #gpio_int_cfg
+ */
+void gpio_config(__u32 port, __u32 sig_no, bool out, enum gpio_int_cfg icr);
+
+/*!
+ * This function sets a GPIO signal value.
+ *
+ * @param port specified port with 0-GPIO port 1; 1-GPIO port 2
+ * @param sig_no specified GPIO signal (0 based)
+ * @param data value to be set (only 0 or 1 is valid)
+ */
+void gpio_set_data(__u32 port, __u32 sig_no, __u32 data);
+
+/*!
+ * This function returns the value of the GPIO signal.
+ *
+ * @param port specified port with 0-GPIO port 1; 1-GPIO port 2
+ * @param sig_no specified GPIO signal (0 based)
+ *
+ * @return Value of the GPIO signal
+ */
+__u32 gpio_get_data(__u32 port, __u32 sig_no);
+
+/*!
+ * This function is responsible for registering a GPIO signal's ISR.
+ *
+ * @param port specified port with 0-GPIO port 1; 1-GPIO port 2
+ * @param sig_no specified GPIO signal (0 based)
+ * @param prio priority as defined in \b enum \b #gpio_prio
+ * @param handler GPIO ISR function pointer for the GPIO signal
+ * @param irq_flags irq flags (not used)
+ * @param devname device name associated with the interrupt
+ * @param dev_id some unique information for the ISR
+ *
+ * @return 0 if successful; non-zero otherwise.
+ */
+int gpio_request_irq(__u32 port, __u32 sig_no, enum gpio_prio prio,
+ gpio_irq_handler handler, __u32 irq_flags,
+ const char *devname, void *dev_id);
+
+/*!
+ * This function un-registers an ISR with the GPIO interrupt module.
+ *
+ * @param port specified port with 0-GPIO port 1; 1-GPIO port 2
+ * @param sig_no specified GPIO signal (0 based)
+ * @param prio priority as defined in \b enum \b #gpio_prio
+ */
+void gpio_free_irq(__u32 port, __u32 sig_no, enum gpio_prio prio);
+
+/*!
+ * Request ownership for a GPIO pin. The caller has to check the return value
+ * of this function to make sure it returns 0 before make use of that pin.
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @return 0 if successful; Non-zero otherwise
+ */
+int mxc_request_gpio(iomux_pin_name_t pin);
+
+/*!
+ * Exported function to set a GPIO pin's direction
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param is_input 1 (or non-zero) for input; 0 for output
+ */
+void mxc_set_gpio_direction(iomux_pin_name_t pin, int is_input);
+
+/*!
+ * Exported function to set a GPIO pin's data output
+ * @param pin a name defined by \b iomux_pin_name_t
+ * @param data value to be set (only 0 or 1 is valid)
+ */
+void mxc_set_gpio_dataout(iomux_pin_name_t pin, u32 data);
+
+/*!
+ * Return the data value of a GPIO signal.
+ * @param pin a name defined by \b iomux_pin_name_t
+ *
+ * @return value (0 or 1) of the GPIO signal; -1 if pass in invalid pin
+ */
+int mxc_get_gpio_datain(iomux_pin_name_t pin);
+
+/*!
+ * Release ownership for a GPIO pin
+ * @param pin a name defined by \b iomux_pin_name_t
+ */
+void mxc_free_gpio(iomux_pin_name_t pin);
+
+/*!
+ * GPIO driver initialization
+ * @return always 0
+ */
+int mxc_gpio_init(void);
+#endif /* __ASM_ARCH_MXC_GPIO_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/hardware.h b/arch/arm/plat-mxc/include/mach/hardware.h
index 3caadeeda701..469b7fc6a2d6 100644
--- a/arch/arm/plat-mxc/include/mach/hardware.h
+++ b/arch/arm/plat-mxc/include/mach/hardware.h
@@ -1,20 +1,11 @@
/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
- * Copyright 2008 Juergen Beisert, kernel@pengutronix.de
- *
- * 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.
+ * Copyright 2004-2008 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
+ * published by the Free Software Foundation.
*/
#ifndef __ASM_ARCH_MXC_HARDWARE_H__
@@ -22,16 +13,139 @@
#include <asm/sizes.h>
+/*
+ * ---------------------------------------------------------------------------
+ * Processor specific defines
+ * ---------------------------------------------------------------------------
+ */
+#define CHIP_REV_1_0 0x10
+#define CHIP_REV_1_1 0x11
+#define CHIP_REV_1_2 0x12
+#define CHIP_REV_1_3 0x13
+#define CHIP_REV_2_0 0x20
+#define CHIP_REV_2_1 0x21
+#define CHIP_REV_2_2 0x22
+#define CHIP_REV_2_3 0x23
+#define CHIP_REV_3_0 0x30
+#define CHIP_REV_3_1 0x31
+#define CHIP_REV_3_2 0x32
+
+#define BOARD_REV_2 0x100
+
+#ifndef __ASSEMBLY__
+extern unsigned int system_rev;
+#endif
+#define mxc_set_system_rev(part, rev) { \
+ system_rev = (part << 12) | rev; \
+}
+
+#define mxc_cpu() (system_rev >> 12)
+#define mxc_is_cpu(part) ((mxc_cpu() == part) ? 1 : 0)
+#define mxc_cpu_rev() (system_rev & 0xFF)
+#define mxc_cpu_rev_major() ((system_rev >> 4) & 0xF)
+#define mxc_cpu_rev_minor() (system_rev & 0xF)
+#define mxc_cpu_is_rev(rev) \
+ ((mxc_cpu_rev() == rev) ? 1 : ((mxc_cpu_rev() < rev) ? -1 : 2))
+#define MXC_REV(type) \
+static inline int type## _rev (int rev) \
+{ \
+ return (type() ? mxc_cpu_is_rev(rev) : 0); \
+}
+
#ifdef CONFIG_ARCH_MX3
# include <mach/mx31.h>
+#define cpu_is_mx31() (mxc_is_cpu(0x31)) /*system_rev got from Redboot */
+#define cpu_is_mx32() (mxc_is_cpu(0x32)) /*system_rev got from Redboot */
+#else
+#define cpu_is_mx31() (0)
+#define cpu_is_mx32() (0)
+#endif
+
+#ifdef CONFIG_ARCH_MX35
+#include <mach/mx35.h>
+#define cpu_is_mx35() (1)
+#define board_is_mx35(rev) ((system_rev & rev) ? 1 : 0)
+#else
+#define cpu_is_mx35() (0)
+#define board_is_mx35(rev) (0)
+#endif
+
+#ifdef CONFIG_ARCH_MX37
+#include <mach/mx37.h>
+#define cpu_is_mx37() (1)
+#define board_is_mx37(rev) ((system_rev & rev) ? 1 : 0)
+#else
+#define cpu_is_mx37() (0)
+#define board_is_mx37(rev) (0)
#endif
-#ifdef CONFIG_ARCH_MX2
-# ifdef CONFIG_MACH_MX27
-# include <mach/mx27.h>
-# endif
+#ifdef CONFIG_ARCH_MX51
+#include <mach/mx51.h>
+#define cpu_is_mx51() (1)
+#else
+#define cpu_is_mx51() (0)
#endif
+#ifdef CONFIG_ARCH_MX21
+#include <mach/mx21.h>
+#define cpu_is_mx21() (1)
+#else
+#define cpu_is_mx21() (0)
+#endif
+
+#ifdef CONFIG_ARCH_MX25
+#include <mach/mx25.h>
+#define cpu_is_mx25() (1)
+#else
+#define cpu_is_mx25() (0)
+#endif
+
+#ifdef CONFIG_ARCH_MX27
+#include <mach/mx27.h>
+#define cpu_is_mx27() (1)
+#else
+#define cpu_is_mx27() (0)
+#endif
+
+#ifndef __ASSEMBLY__
+/*
+ * Create inline functions to test for cpu revision
+ * Function name is cpu_is_<cpu name>_rev(rev)
+ *
+ * Returns:
+ * 0 - not the cpu queried
+ * 1 - cpu and revision match
+ * 2 - cpu matches, but cpu revision is greater than queried rev
+ * -1 - cpu matches, but cpu revision is less than queried rev
+ */
+MXC_REV(cpu_is_mx21);
+MXC_REV(cpu_is_mx25);
+MXC_REV(cpu_is_mx27);
+MXC_REV(cpu_is_mx31);
+MXC_REV(cpu_is_mx32);
+MXC_REV(cpu_is_mx35);
+MXC_REV(cpu_is_mx37);
+MXC_REV(cpu_is_mx51);
+#endif
#include <mach/mxc.h>
+#define MXC_MAX_GPIO_LINES (GPIO_NUM_PIN * GPIO_PORT_NUM)
+
+#define MXC_EXP_IO_BASE (MXC_MAX_INT_LINES + MXC_MAX_GPIO_LINES)
+#define MXC_MAX_EXP_IO_LINES 16
+
+#ifdef CONFIG_MXC_PSEUDO_IRQS
+#define MXC_PSEUDO_IO_BASE (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES)
+#define MXC_MAX_PSEUDO_IO_LINES 16
+#else
+#define MXC_MAX_PSEUDO_IO_LINES 0
+#endif
+
+#ifndef MXC_INT_FORCE
+#define MXC_INT_FORCE -1
+#endif
+#define MXC_MAX_INTS (MXC_MAX_INT_LINES + \
+ MXC_MAX_GPIO_LINES + \
+ MXC_MAX_EXP_IO_LINES + \
+ MXC_MAX_PSEUDO_IO_LINES)
#endif /* __ASM_ARCH_MXC_HARDWARE_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/hw_events.h b/arch/arm/plat-mxc/include/mach/hw_events.h
new file mode 100644
index 000000000000..f0aa3ad7a266
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/hw_events.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2007-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * hw_events.h
+ * include the headset/cvbs interrupt detect
+ */
+
+#ifndef HW_EVENT_H
+#define HW_EVENT_H
+
+#define HW_EVENT_GROUP 2
+#define HWE_DEF_PRIORITY 1
+#define HWE_HIGH_PRIORITY 0
+
+typedef enum {
+
+ HWE_PHONEJACK_PLUG = 0,
+ HWE_BAT_CHARGER_PLUG,
+ HWE_BAT_CHARGER_OVERVOLTAGE,
+ HWE_BAT_BATTERY_LOW,
+ HWE_BAT_POWER_FAILED,
+ HWE_BAT_CHARGER_FULL,
+ HWE_POWER_KEY,
+} HW_EVENT_T;
+
+typedef enum {
+
+ PJT_NONE = 0,
+ PJT_CVBS,
+ PJT_HEADSET,
+} PHONEJACK_TYPE;
+
+typedef enum {
+
+ PWRK_UNPRESS = 0,
+ PWRK_PRESS,
+} POWERKEY_TYPE;
+
+typedef enum {
+
+ UNPLUG = 0,
+ PLUGGED,
+} PLUG_TYPE;
+
+struct mxc_hw_event {
+ unsigned int event;
+ int args;
+};
+
+#ifdef __KERNEL__
+extern int hw_event_send(int priority, struct mxc_hw_event *new_event);
+#endif
+
+#endif /* HW_EVENT_H */
diff --git a/arch/arm/plat-mxc/include/mach/imx_adc.h b/arch/arm/plat-mxc/include/mach/imx_adc.h
new file mode 100644
index 000000000000..5c0e2462b1ef
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/imx_adc.h
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+#ifndef __ASM_ARCH_IMX_ADC_H__
+#define __ASM_ARCH_IMX_ADC_H__
+
+/*!
+ * @defgroup IMX_ADC Digitizer Driver
+ * @ingroup IMX_DRVRS
+ */
+
+/*!
+ * @file arch-mxc/imx_adc.h
+ * @brief This is the header of IMX ADC driver.
+ *
+ * @ingroup IMX_ADC
+ */
+
+#include <linux/ioctl.h>
+
+/*!
+ * @enum IMX_ADC_STATUS
+ * @brief Define return values for all IMX_ADC APIs.
+ *
+ * These return values are used by all of the IMX_ADC APIs.
+ *
+ * @ingroup IMX_ADC
+ */
+enum IMX_ADC_STATUS {
+ /*! The requested operation was successfully completed. */
+ IMX_ADC_SUCCESS = 0,
+ /*! The requested operation could not be completed due to an error. */
+ IMX_ADC_ERROR = -1,
+ /*!
+ * The requested operation failed because one or more of the
+ * parameters was invalid.
+ */
+ IMX_ADC_PARAMETER_ERROR = -2,
+ /*!
+ * The requested operation could not be completed because the ADC
+ * hardware does not support it.
+ */
+ IMX_ADC_NOT_SUPPORTED = -3,
+ /*! Error in malloc function */
+ IMX_ADC_MALLOC_ERROR = -5,
+ /*! Error in un-subscribe event */
+ IMX_ADC_UNSUBSCRIBE_ERROR = -6,
+ /*! Event occur and not subscribed */
+ IMX_ADC_EVENT_NOT_SUBSCRIBED = -7,
+ /*! Error - bad call back */
+ IMX_ADC_EVENT_CALL_BACK = -8,
+ /*!
+ * The requested operation could not be completed because there
+ * are too many ADC client requests
+ */
+ IMX_ADC_CLIENT_NBOVERFLOW = -9,
+};
+
+/*
+ * Macros implementing error handling
+ */
+#define CHECK_ERROR(a) \
+do { \
+ int ret = (a); \
+ if (ret != IMX_ADC_SUCCESS) \
+ return ret; \
+} while (0)
+
+#define CHECK_ERROR_KFREE(func, freeptrs) \
+do { \
+ int ret = (func); \
+ if (ret != IMX_ADC_SUCCESS) { \
+ freeptrs; \
+ return ret; \
+ } \
+} while (0)
+
+#define MOD_NAME "mxcadc"
+
+/*!
+ * @name IOCTL user space interface
+ */
+
+/*!
+ * Initialize ADC.
+ * Argument type: none.
+ */
+#define IMX_ADC_INIT _IO('p', 0xb0)
+/*!
+ * De-initialize ADC.
+ * Argument type: none.
+ */
+#define IMX_ADC_DEINIT _IO('p', 0xb1)
+/*!
+ * Convert one channel.
+ * Argument type: pointer to t_adc_convert_param.
+ */
+#define IMX_ADC_CONVERT _IOWR('p', 0xb2, int)
+/*!
+ * Convert multiple channels.
+ * Argument type: pointer to t_adc_convert_param.
+ */
+#define IMX_ADC_CONVERT_MULTICHANNEL _IOWR('p', 0xb4, int)
+
+/*! @{ */
+/*!
+ * @name Touch Screen minimum and maximum values
+ */
+#define IMX_ADC_DEVICE "/dev/imx_adc"
+
+/*
+ * Maximun allowed variation in the three X/Y co-ordinates acquired from
+ * touch screen
+ */
+#define DELTA_Y_MAX 100
+#define DELTA_X_MAX 100
+
+/* Upon clearing the filter, this is the delay in restarting the filter */
+#define FILTER_MIN_DELAY 4
+
+/* Length of X and Y touch screen filters */
+#define FILTLEN 3
+
+#define TS_X_MAX 1000
+#define TS_Y_MAX 1000
+
+#define TS_X_MIN 80
+#define TS_Y_MIN 80
+
+/*! @} */
+/*!
+ * This enumeration defines input channels for IMX ADC
+ */
+
+enum t_channel {
+ TS_X_POS,
+ TS_Y_POS,
+ GER_PURPOSE_ADC0,
+ GER_PURPOSE_ADC1,
+ GER_PURPOSE_ADC2,
+ GER_PURPOSE_MULTICHNNEL,
+};
+
+/*!
+ * This structure is used to report touch screen value.
+ */
+struct t_touch_screen {
+ /* Touch Screen X position */
+ unsigned int x_position;
+ /* Touch Screen X position1 */
+ unsigned int x_position1;
+ /* Touch Screen X position2 */
+ unsigned int x_position2;
+ /* Touch Screen X position3 */
+ unsigned int x_position3;
+ /* Touch Screen Y position */
+ unsigned int y_position;
+ /* Touch Screen Y position1 */
+ unsigned int y_position1;
+ /* Touch Screen Y position2 */
+ unsigned int y_position2;
+ /* Touch Screen Y position3 */
+ unsigned int y_position3;
+ /* Touch Screen contact value */
+ unsigned int contact_resistance;
+ /* Flag indicate the data usability */
+ unsigned int valid_flag;
+};
+
+/*!
+ * This structure is used with IOCTL code \a IMX_ADC_CONVERT,
+ * \a IMX_ADC_CONVERT_8X and \a IMX_ADC_CONVERT_MULTICHANNEL.
+ */
+
+struct t_adc_convert_param {
+ /* channel or channels to be sampled. */
+ enum t_channel channel;
+ /* holds up to 16 sampling results */
+ unsigned short result[16];
+};
+
+/* EXPORTED FUNCTIONS */
+
+#ifdef __KERNEL__
+/* Driver data */
+struct imx_adc_data {
+ u32 irq;
+ struct clk *adc_clk;
+};
+
+/*!
+ * This function initializes all ADC registers with default values. This
+ * function also registers the interrupt events.
+ *
+ * @return This function returns IMX_ADC_SUCCESS if successful.
+ */
+enum IMX_ADC_STATUS imx_adc_init(void);
+
+/*!
+ * This function disables the ADC, de-registers the interrupt events.
+ *
+ * @return This function returns IMX_ADC_SUCCESS if successful.
+ */
+enum IMX_ADC_STATUS imx_adc_deinit(void);
+
+/*!
+ * This function triggers a conversion and returns one sampling result of one
+ * channel.
+ *
+ * @param channel The channel to be sampled
+ * @param result The pointer to the conversion result. The memory
+ * should be allocated by the caller of this function.
+ *
+ * @return This function returns IMX_ADC_SUCCESS if successful.
+ */
+
+enum IMX_ADC_STATUS imx_adc_convert(enum t_channel channel,
+ unsigned short *result);
+
+/*!
+ * This function triggers a conversion and returns sampling results of each
+ * specified channel.
+ *
+ * @param channels This input parameter is bitmap to specify channels
+ * to be sampled.
+ * @param result The pointer to array to store sampling result.
+ * The order of the result in the array is from lowest
+ * channel number to highest channel number of the
+ * sampled channels.
+ * The memory should be allocated by the caller of this
+ * function.
+ * Note that the behavior of this function might differ
+ * from one platform to another regarding especially
+ * channels order.
+ *
+ * @return This function returns IMX_ADC_SUCCESS if successful.
+ */
+
+enum IMX_ADC_STATUS imx_adc_convert_multichnnel(enum t_channel channels,
+ unsigned short *result);
+
+/*!
+ * This function retrieves the current touch screen operation mode.
+ *
+ * @param touch_sample Pointer to touch sample.
+ * @param wait_tsi if true, we wait until interrupt occurs
+ * @return This function returns IMX_ADC_SUCCESS if successful.
+ */
+enum IMX_ADC_STATUS imx_adc_get_touch_sample(struct t_touch_screen *ts_value,
+ int wait_tsi);
+
+/*!
+ * This function read the touch screen value.
+ *
+ * @param touch_sample return value of touch screen
+ * @param wait_tsi if true, we need wait until interrupt occurs
+ * @return This function returns 0.
+ */
+enum IMX_ADC_STATUS imx_adc_read_ts(struct t_touch_screen *touch_sample,
+ int wait_tsi);
+
+int is_imx_adc_ready(void);
+
+#endif /* _KERNEL */
+#endif /* __ASM_ARCH_IMX_ADC_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/io.h b/arch/arm/plat-mxc/include/mach/io.h
index 5d4cb1196441..d1df347b1497 100644
--- a/arch/arm/plat-mxc/include/mach/io.h
+++ b/arch/arm/plat-mxc/include/mach/io.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -14,29 +14,34 @@
/* Allow IO space to be anywhere in the memory */
#define IO_SPACE_LIMIT 0xffffffff
-#ifdef CONFIG_ARCH_MX3
-#define __arch_ioremap __mx3_ioremap
-#define __arch_iounmap __iounmap
-
-static inline void __iomem *
-__mx3_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype)
-{
- if (mtype == MT_DEVICE) {
- /* Access all peripherals below 0x80000000 as nonshared device
- * but leave l2cc alone.
- */
- if ((phys_addr < 0x80000000) && ((phys_addr < L2CC_BASE_ADDR) ||
- (phys_addr >= L2CC_BASE_ADDR + L2CC_SIZE)))
- mtype = MT_DEVICE_NONSHARED;
- }
-
- return __arm_ioremap(phys_addr, size, mtype);
-}
-#endif
+extern void __iomem *__mxc_ioremap(unsigned long cookie, size_t size,
+ unsigned int mtype);
+extern void __mxc_iounmap(void __iomem *addr);
+
+#define __arch_ioremap(a, s, f) __mxc_ioremap(a, s, f)
+#define __arch_iounmap(a) __mxc_iounmap(a)
/* io address mapping macro */
#define __io(a) ((void __iomem *)(a))
#define __mem_pci(a) (a)
+/*!
+ * This function is called to read a CPLD register over CSPI.
+ *
+ * @param offset number of the cpld register to be read
+ *
+ * @return Returns 0 on success -1 on failure.
+ */
+unsigned int spi_cpld_read(unsigned int offset);
+
+/*!
+ * This function is called to write to a CPLD register over CSPI.
+ *
+ * @param offset number of the cpld register to be written
+ * @param reg_val value to be written
+ *
+ * @return Returns 0 on success -1 on failure.
+ */
+unsigned int spi_cpld_write(unsigned int offset, unsigned int reg_val);
#endif
diff --git a/arch/arm/plat-mxc/include/mach/ipu.h b/arch/arm/plat-mxc/include/mach/ipu.h
new file mode 100644
index 000000000000..09a4bfcd7522
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/ipu.h
@@ -0,0 +1,1162 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+/*!
+ * @defgroup IPU MXC Image Processing Unit (IPU) Driver
+ */
+/*!
+ * @file arch-mxc/ipu.h
+ *
+ * @brief This file contains the IPU driver API declarations.
+ *
+ * @ingroup IPU
+ */
+
+#ifndef __ASM_ARCH_IPU_H__
+#define __ASM_ARCH_IPU_H__
+
+#include <linux/types.h>
+#ifdef __KERNEL__
+#include <linux/interrupt.h>
+#else
+#define bool char
+#define irqreturn_t int
+#define dma_addr_t int
+#define u32 unsigned int
+#define __u32 u32
+#endif
+
+/*!
+ * Enumeration of IPU rotation modes
+ */
+typedef enum {
+ /* Note the enum values correspond to BAM value */
+ IPU_ROTATE_NONE = 0,
+ IPU_ROTATE_VERT_FLIP = 1,
+ IPU_ROTATE_HORIZ_FLIP = 2,
+ IPU_ROTATE_180 = 3,
+ IPU_ROTATE_90_RIGHT = 4,
+ IPU_ROTATE_90_RIGHT_VFLIP = 5,
+ IPU_ROTATE_90_RIGHT_HFLIP = 6,
+ IPU_ROTATE_90_LEFT = 7,
+} ipu_rotate_mode_t;
+
+/*!
+ * Enumeration of Post Filter modes
+ */
+typedef enum {
+ PF_DISABLE_ALL = 0,
+ PF_MPEG4_DEBLOCK = 1,
+ PF_MPEG4_DERING = 2,
+ PF_MPEG4_DEBLOCK_DERING = 3,
+ PF_H264_DEBLOCK = 4,
+} pf_operation_t;
+
+/*!
+ * Enumeration of Synchronous (Memory-less) panel types
+ */
+typedef enum {
+ IPU_PANEL_SHARP_TFT,
+ IPU_PANEL_TFT,
+} ipu_panel_t;
+
+/* IPU Pixel format definitions */
+/* Four-character-code (FOURCC) */
+#define fourcc(a, b, c, d)\
+ (((__u32)(a)<<0)|((__u32)(b)<<8)|((__u32)(c)<<16)|((__u32)(d)<<24))
+
+/*!
+ * @name IPU Pixel Formats
+ *
+ * Pixel formats are defined with ASCII FOURCC code. The pixel format codes are
+ * the same used by V4L2 API.
+ */
+
+/*! @{ */
+/*! @name Generic or Raw Data Formats */
+/*! @{ */
+#define IPU_PIX_FMT_GENERIC fourcc('I', 'P', 'U', '0') /*!< IPU Generic Data */
+#define IPU_PIX_FMT_GENERIC_32 fourcc('I', 'P', 'U', '1') /*!< IPU Generic Data */
+/*! @} */
+/*! @name RGB Formats */
+/*! @{ */
+#define IPU_PIX_FMT_RGB332 fourcc('R', 'G', 'B', '1') /*!< 8 RGB-3-3-2 */
+#define IPU_PIX_FMT_RGB555 fourcc('R', 'G', 'B', 'O') /*!< 16 RGB-5-5-5 */
+#define IPU_PIX_FMT_RGB565 fourcc('R', 'G', 'B', 'P') /*!< 1 6 RGB-5-6-5 */
+#define IPU_PIX_FMT_RGB666 fourcc('R', 'G', 'B', '6') /*!< 18 RGB-6-6-6 */
+#define IPU_PIX_FMT_BGR666 fourcc('B', 'G', 'R', '6') /*!< 18 BGR-6-6-6 */
+#define IPU_PIX_FMT_BGR24 fourcc('B', 'G', 'R', '3') /*!< 24 BGR-8-8-8 */
+#define IPU_PIX_FMT_RGB24 fourcc('R', 'G', 'B', '3') /*!< 24 RGB-8-8-8 */
+#define IPU_PIX_FMT_BGR32 fourcc('B', 'G', 'R', '4') /*!< 32 BGR-8-8-8-8 */
+#define IPU_PIX_FMT_BGRA32 fourcc('B', 'G', 'R', 'A') /*!< 32 BGR-8-8-8-8 */
+#define IPU_PIX_FMT_RGB32 fourcc('R', 'G', 'B', '4') /*!< 32 RGB-8-8-8-8 */
+#define IPU_PIX_FMT_RGBA32 fourcc('R', 'G', 'B', 'A') /*!< 32 RGB-8-8-8-8 */
+#define IPU_PIX_FMT_ABGR32 fourcc('A', 'B', 'G', 'R') /*!< 32 ABGR-8-8-8-8 */
+/*! @} */
+/*! @name YUV Interleaved Formats */
+/*! @{ */
+#define IPU_PIX_FMT_YUYV fourcc('Y', 'U', 'Y', 'V') /*!< 16 YUV 4:2:2 */
+#define IPU_PIX_FMT_UYVY fourcc('U', 'Y', 'V', 'Y') /*!< 16 YUV 4:2:2 */
+#define IPU_PIX_FMT_Y41P fourcc('Y', '4', '1', 'P') /*!< 12 YUV 4:1:1 */
+#define IPU_PIX_FMT_YUV444 fourcc('Y', '4', '4', '4') /*!< 24 YUV 4:4:4 */
+/* two planes -- one Y, one Cb + Cr interleaved */
+#define IPU_PIX_FMT_NV12 fourcc('N', 'V', '1', '2') /* 12 Y/CbCr 4:2:0 */
+/*! @} */
+/*! @name YUV Planar Formats */
+/*! @{ */
+#define IPU_PIX_FMT_GREY fourcc('G', 'R', 'E', 'Y') /*!< 8 Greyscale */
+#define IPU_PIX_FMT_YVU410P fourcc('Y', 'V', 'U', '9') /*!< 9 YVU 4:1:0 */
+#define IPU_PIX_FMT_YUV410P fourcc('Y', 'U', 'V', '9') /*!< 9 YUV 4:1:0 */
+#define IPU_PIX_FMT_YVU420P fourcc('Y', 'V', '1', '2') /*!< 12 YVU 4:2:0 */
+#define IPU_PIX_FMT_YUV420P fourcc('I', '4', '2', '0') /*!< 12 YUV 4:2:0 */
+#define IPU_PIX_FMT_YUV420P2 fourcc('Y', 'U', '1', '2') /*!< 12 YUV 4:2:0 */
+#define IPU_PIX_FMT_YVU422P fourcc('Y', 'V', '1', '6') /*!< 16 YVU 4:2:2 */
+#define IPU_PIX_FMT_YUV422P fourcc('4', '2', '2', 'P') /*!< 16 YUV 4:2:2 */
+/*! @} */
+
+/* IPU Driver channels definitions. */
+/* Note these are different from IDMA channels */
+#ifdef CONFIG_MXC_IPU_V1
+#define _MAKE_CHAN(num, in, out, sec) ((num << 24) | (sec << 16) | (out << 8) | in)
+#define IPU_CHAN_ID(ch) (ch >> 24)
+#define IPU_CHAN_SEC_DMA(ch) ((uint32_t) (ch >> 16) & 0xFF)
+#define IPU_CHAN_OUT_DMA(ch) ((uint32_t) (ch >> 8) & 0xFF)
+#define IPU_CHAN_IN_DMA(ch) ((uint32_t) (ch & 0xFF))
+
+#else
+#define IPU_MAX_CH 32
+#define _MAKE_CHAN(num, v_in, g_in, a_in, out) \
+ ((num << 24) | (v_in << 18) | (g_in << 12) | (a_in << 6) | out)
+#define _MAKE_ALT_CHAN(ch) (ch | (IPU_MAX_CH << 24))
+#define IPU_CHAN_ID(ch) (ch >> 24)
+#define IPU_CHAN_ALT(ch) (ch & 0x02000000)
+#define IPU_CHAN_ALPHA_IN_DMA(ch) ((uint32_t) (ch >> 6) & 0x3F)
+#define IPU_CHAN_GRAPH_IN_DMA(ch) ((uint32_t) (ch >> 12) & 0x3F)
+#define IPU_CHAN_VIDEO_IN_DMA(ch) ((uint32_t) (ch >> 18) & 0x3F)
+#define IPU_CHAN_OUT_DMA(ch) ((uint32_t) (ch & 0x3F))
+#define NO_DMA 0x3F
+#define ALT 1
+#endif
+/*!
+ * Enumeration of IPU logical channels. An IPU logical channel is defined as a
+ * combination of an input (memory to IPU), output (IPU to memory), and/or
+ * secondary input IDMA channels and in some cases an Image Converter task.
+ * Some channels consist of only an input or output.
+ */
+typedef enum {
+ CHAN_NONE = -1,
+#ifdef CONFIG_MXC_IPU_V1
+ CSI_MEM = _MAKE_CHAN(1, 0xFF, 7, 0xFF), /*!< CSI raw sensor data to memory */
+
+ CSI_PRP_ENC_MEM = _MAKE_CHAN(2, 0xFF, 0, 0xFF), /*!< CSI to IC Encoder PreProcessing to Memory */
+ MEM_PRP_ENC_MEM = _MAKE_CHAN(3, 6, 0, 0xFF), /*!< Memory to IC Encoder PreProcessing to Memory */
+ MEM_ROT_ENC_MEM = _MAKE_CHAN(4, 10, 8, 0xFF), /*!< Memory to IC Encoder Rotation to Memory */
+
+ CSI_PRP_VF_MEM = _MAKE_CHAN(5, 0xFF, 1, 0xFF), /*!< CSI to IC Viewfinder PreProcessing to Memory */
+ CSI_PRP_VF_ADC = _MAKE_CHAN(6, 0xFF, 1, 0xFF), /*!< CSI to IC Viewfinder PreProcessing to ADC */
+ MEM_PRP_VF_MEM = _MAKE_CHAN(7, 6, 1, 3), /*!< Memory to IC Viewfinder PreProcessing to Memory */
+ MEM_PRP_VF_ADC = _MAKE_CHAN(8, 6, 1, 3), /*!< Memory to IC Viewfinder PreProcessing to ADC */
+ MEM_ROT_VF_MEM = _MAKE_CHAN(9, 11, 9, 0xFF), /*!< Memory to IC Viewfinder Rotation to Memory */
+
+ MEM_PP_MEM = _MAKE_CHAN(10, 5, 2, 4), /*!< Memory to IC PostProcessing to Memory */
+ MEM_ROT_PP_MEM = _MAKE_CHAN(11, 13, 12, 0xFF), /*!< Memory to IC PostProcessing Rotation to Memory */
+ MEM_PP_ADC = _MAKE_CHAN(12, 5, 2, 4), /*!< Memory to IC PostProcessing to ADC */
+
+ MEM_SDC_BG = _MAKE_CHAN(14, 14, 0xFF, 0xFF), /*!< Memory to SDC Background plane */
+ MEM_SDC_FG = _MAKE_CHAN(15, 15, 0xFF, 0xFF), /*!< Memory to SDC Foreground plane */
+ MEM_SDC_MASK = _MAKE_CHAN(16, 16, 0xFF, 0xFF), /*!< Memory to SDC Mask */
+
+ MEM_BG_SYNC = MEM_SDC_BG,
+ MEM_FG_SYNC = MEM_SDC_FG,
+
+ ADC_SYS1 = _MAKE_CHAN(17, 18, 22, 20), /*!< Memory to ADC System Channel 1 */
+ ADC_SYS2 = _MAKE_CHAN(18, 19, 23, 21), /*!< Memory to ADC System Channel 2 */
+
+ MEM_PF_Y_MEM = _MAKE_CHAN(19, 26, 29, 24), /*!< Y and PF Memory to Post-filter to Y Memory */
+ MEM_PF_U_MEM = _MAKE_CHAN(20, 27, 30, 25), /*!< U and PF Memory to Post-filter to U Memory */
+ MEM_PF_V_MEM = _MAKE_CHAN(21, 28, 31, 0xFF), /*!< V Memory to Post-filter to V Memory */
+
+ MEM_DC_SYNC = CHAN_NONE,
+ DIRECT_ASYNC0 = CHAN_NONE,
+ DIRECT_ASYNC1 = CHAN_NONE,
+#else
+ MEM_ROT_ENC_MEM = _MAKE_CHAN(1, 45, NO_DMA, NO_DMA, 48),
+ MEM_ROT_VF_MEM = _MAKE_CHAN(2, 46, NO_DMA, NO_DMA, 49),
+ MEM_ROT_PP_MEM = _MAKE_CHAN(3, 47, NO_DMA, NO_DMA, 50),
+
+ MEM_PRP_ENC_MEM = _MAKE_CHAN(4, 12, 14, 17, 20),
+ MEM_PRP_VF_MEM = _MAKE_CHAN(5, 12, 14, 17, 21),
+ MEM_PP_MEM = _MAKE_CHAN(6, 11, 15, 18, 22),
+
+ MEM_DC_SYNC = _MAKE_CHAN(7, 28, NO_DMA, NO_DMA, NO_DMA),
+ MEM_DC_ASYNC = _MAKE_CHAN(8, 41, NO_DMA, NO_DMA, NO_DMA),
+ MEM_BG_SYNC = _MAKE_CHAN(9, 23, NO_DMA, 51, NO_DMA),
+ MEM_FG_SYNC = _MAKE_CHAN(10, 27, NO_DMA, 31, NO_DMA),
+
+ MEM_BG_ASYNC0 = _MAKE_CHAN(11, 24, NO_DMA, 52, NO_DMA),
+ MEM_FG_ASYNC0 = _MAKE_CHAN(12, 29, NO_DMA, 33, NO_DMA),
+ MEM_BG_ASYNC1 = _MAKE_ALT_CHAN(MEM_BG_ASYNC0),
+ MEM_FG_ASYNC1 = _MAKE_ALT_CHAN(MEM_FG_ASYNC0),
+
+ DIRECT_ASYNC0 = _MAKE_CHAN(13, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
+ DIRECT_ASYNC1 = _MAKE_CHAN(14, NO_DMA, NO_DMA, NO_DMA, NO_DMA),
+
+ CSI_MEM0 = _MAKE_CHAN(15, NO_DMA, NO_DMA, NO_DMA, 0),
+ CSI_MEM1 = _MAKE_CHAN(16, NO_DMA, NO_DMA, NO_DMA, 1),
+ CSI_MEM2 = _MAKE_CHAN(17, NO_DMA, NO_DMA, NO_DMA, 2),
+ CSI_MEM3 = _MAKE_CHAN(18, NO_DMA, NO_DMA, NO_DMA, 3),
+
+ CSI_MEM = CSI_MEM0,
+
+ CSI_PRP_ENC_MEM = _MAKE_CHAN(19, NO_DMA, NO_DMA, NO_DMA, 20),
+ CSI_PRP_VF_MEM = _MAKE_CHAN(20, NO_DMA, NO_DMA, NO_DMA, 21),
+
+ MEM_PP_ADC = CHAN_NONE,
+ ADC_SYS2 = CHAN_NONE,
+#endif
+
+} ipu_channel_t;
+
+/*!
+ * Enumeration of types of buffers for a logical channel.
+ */
+typedef enum {
+ IPU_OUTPUT_BUFFER = 0, /*!< Buffer for output from IPU */
+ IPU_ALPHA_IN_BUFFER = 1, /*!< Buffer for input to IPU */
+ IPU_GRAPH_IN_BUFFER = 2, /*!< Buffer for input to IPU */
+ IPU_VIDEO_IN_BUFFER = 3, /*!< Buffer for input to IPU */
+ IPU_INPUT_BUFFER = IPU_VIDEO_IN_BUFFER,
+ IPU_SEC_INPUT_BUFFER = IPU_GRAPH_IN_BUFFER,
+} ipu_buffer_t;
+
+#define IPU_PANEL_SERIAL 1
+#define IPU_PANEL_PARALLEL 2
+
+/*!
+ * Enumeration of DI ports for ADC.
+ */
+typedef enum {
+ DISP0,
+ DISP1,
+ DISP2,
+ DISP3
+} display_port_t;
+
+/*!
+ * Enumeration of ADC channel operation mode.
+ */
+typedef enum {
+ Disable,
+ WriteTemplateNonSeq,
+ ReadTemplateNonSeq,
+ WriteTemplateUnCon,
+ ReadTemplateUnCon,
+ WriteDataWithRS,
+ WriteDataWoRS,
+ WriteCmd
+} mcu_mode_t;
+
+/*!
+ * Enumeration of ADC channel addressing mode.
+ */
+typedef enum {
+ FullWoBE,
+ FullWithBE,
+ XY
+} display_addressing_t;
+
+/*!
+ * Union of initialization parameters for a logical channel.
+ */
+typedef union {
+ struct {
+ uint32_t csi;
+ bool mipi_en;
+ uint32_t mipi_id;
+ } csi_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ uint32_t csi;
+ } csi_prp_enc_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ } mem_prp_enc_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ } mem_rot_enc_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ bool graphics_combine_en;
+ bool global_alpha_en;
+ bool key_color_en;
+ uint32_t csi;
+ } csi_prp_vf_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ bool graphics_combine_en;
+ bool global_alpha_en;
+ bool key_color_en;
+ display_port_t disp;
+ uint32_t out_left;
+ uint32_t out_top;
+ } csi_prp_vf_adc;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ bool graphics_combine_en;
+ bool global_alpha_en;
+ bool key_color_en;
+ } mem_prp_vf_mem;
+ struct {
+ uint32_t temp;
+ } mem_prp_vf_adc;
+ struct {
+ uint32_t temp;
+ } mem_rot_vf_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ bool graphics_combine_en;
+ bool global_alpha_en;
+ bool key_color_en;
+ } mem_pp_mem;
+ struct {
+ uint32_t temp;
+ } mem_rot_mem;
+ struct {
+ uint32_t in_width;
+ uint32_t in_height;
+ uint32_t in_pixel_fmt;
+ uint32_t out_width;
+ uint32_t out_height;
+ uint32_t out_pixel_fmt;
+ bool graphics_combine_en;
+ bool global_alpha_en;
+ bool key_color_en;
+ display_port_t disp;
+ uint32_t out_left;
+ uint32_t out_top;
+ } mem_pp_adc;
+ struct {
+ pf_operation_t operation;
+ } mem_pf_mem;
+ struct {
+ uint32_t di;
+ bool interlaced;
+ } mem_dc_sync;
+ struct {
+ uint32_t temp;
+ } mem_sdc_fg;
+ struct {
+ uint32_t di;
+ bool interlaced;
+ uint32_t in_pixel_fmt;
+ uint32_t out_pixel_fmt;
+ } mem_dp_bg_sync;
+ struct {
+ uint32_t temp;
+ } mem_sdc_bg;
+ struct {
+ uint32_t di;
+ bool interlaced;
+ uint32_t in_pixel_fmt;
+ uint32_t out_pixel_fmt;
+ } mem_dp_fg_sync;
+ struct {
+ uint32_t di;
+ } direct_async;
+ struct {
+ display_port_t disp;
+ mcu_mode_t ch_mode;
+ uint32_t out_left;
+ uint32_t out_top;
+ } adc_sys1;
+ struct {
+ display_port_t disp;
+ mcu_mode_t ch_mode;
+ uint32_t out_left;
+ uint32_t out_top;
+ } adc_sys2;
+} ipu_channel_params_t;
+
+/*!
+ * Enumeration of IPU interrupt sources.
+ */
+enum ipu_irq_line {
+#ifdef CONFIG_MXC_IPU_V1
+ IPU_IRQ_DC_FC_1 = -1,
+
+ IPU_IRQ_PRP_ENC_OUT_EOF = 0,
+ IPU_IRQ_PRP_VF_OUT_EOF = 1,
+ IPU_IRQ_PP_OUT_EOF = 2,
+ IPU_IRQ_PRP_GRAPH_IN_EOF = 3,
+ IPU_IRQ_PP_GRAPH_IN_EOF = 4,
+ IPU_IRQ_PP_IN_EOF = 5,
+ IPU_IRQ_PRP_IN_EOF = 6,
+ IPU_IRQ_SENSOR_OUT_EOF = 7,
+ IPU_IRQ_PRP_ENC_ROT_OUT_EOF = 8,
+ IPU_IRQ_PRP_VF_ROT_OUT_EOF = 9,
+ IPU_IRQ_PRP_ENC_ROT_IN_EOF = 10,
+ IPU_IRQ_PRP_VF_ROT_IN_EOF = 11,
+ IPU_IRQ_PP_ROT_OUT_EOF = 12,
+ IPU_IRQ_PP_ROT_IN_EOF = 13,
+ IPU_IRQ_BG_SYNC_EOF = 14,
+ IPU_IRQ_SDC_BG_EOF = IPU_IRQ_BG_SYNC_EOF,
+ IPU_IRQ_FG_SYNC_EOF = 15,
+ IPU_IRQ_SDC_FG_EOF = IPU_IRQ_FG_SYNC_EOF,
+ IPU_IRQ_SDC_MASK_EOF = 16,
+ IPU_IRQ_SDC_BG_PART_EOF = 17,
+ IPU_IRQ_ADC_SYS1_WR_EOF = 18,
+ IPU_IRQ_ADC_SYS2_WR_EOF = 19,
+ IPU_IRQ_ADC_SYS1_CMD_EOF = 20,
+ IPU_IRQ_ADC_SYS2_CMD_EOF = 21,
+ IPU_IRQ_ADC_SYS1_RD_EOF = 22,
+ IPU_IRQ_ADC_SYS2_RD_EOF = 23,
+ IPU_IRQ_PF_QP_IN_EOF = 24,
+ IPU_IRQ_PF_BSP_IN_EOF = 25,
+ IPU_IRQ_PF_Y_IN_EOF = 26,
+ IPU_IRQ_PF_U_IN_EOF = 27,
+ IPU_IRQ_PF_V_IN_EOF = 28,
+ IPU_IRQ_PF_Y_OUT_EOF = 29,
+ IPU_IRQ_PF_U_OUT_EOF = 30,
+ IPU_IRQ_PF_V_OUT_EOF = 31,
+
+ IPU_IRQ_PRP_ENC_OUT_NF = 32,
+ IPU_IRQ_PRP_VF_OUT_NF = 33,
+ IPU_IRQ_PP_OUT_NF = 34,
+ IPU_IRQ_PRP_GRAPH_IN_NF = 35,
+ IPU_IRQ_PP_GRAPH_IN_NF = 36,
+ IPU_IRQ_PP_IN_NF = 37,
+ IPU_IRQ_PRP_IN_NF = 38,
+ IPU_IRQ_SENSOR_OUT_NF = 39,
+ IPU_IRQ_PRP_ENC_ROT_OUT_NF = 40,
+ IPU_IRQ_PRP_VF_ROT_OUT_NF = 41,
+ IPU_IRQ_PRP_ENC_ROT_IN_NF = 42,
+ IPU_IRQ_PRP_VF_ROT_IN_NF = 43,
+ IPU_IRQ_PP_ROT_OUT_NF = 44,
+ IPU_IRQ_PP_ROT_IN_NF = 45,
+ IPU_IRQ_SDC_FG_NF = 46,
+ IPU_IRQ_SDC_BG_NF = 47,
+ IPU_IRQ_SDC_MASK_NF = 48,
+ IPU_IRQ_SDC_BG_PART_NF = 49,
+ IPU_IRQ_ADC_SYS1_WR_NF = 50,
+ IPU_IRQ_ADC_SYS2_WR_NF = 51,
+ IPU_IRQ_ADC_SYS1_CMD_NF = 52,
+ IPU_IRQ_ADC_SYS2_CMD_NF = 53,
+ IPU_IRQ_ADC_SYS1_RD_NF = 54,
+ IPU_IRQ_ADC_SYS2_RD_NF = 55,
+ IPU_IRQ_PF_QP_IN_NF = 56,
+ IPU_IRQ_PF_BSP_IN_NF = 57,
+ IPU_IRQ_PF_Y_IN_NF = 58,
+ IPU_IRQ_PF_U_IN_NF = 59,
+ IPU_IRQ_PF_V_IN_NF = 60,
+ IPU_IRQ_PF_Y_OUT_NF = 61,
+ IPU_IRQ_PF_U_OUT_NF = 62,
+ IPU_IRQ_PF_V_OUT_NF = 63,
+
+ IPU_IRQ_BREAKRQ = 64,
+ IPU_IRQ_SDC_BG_OUT_EOF = 65,
+ IPU_IRQ_BG_SF_END = IPU_IRQ_SDC_BG_OUT_EOF,
+ IPU_IRQ_SDC_FG_OUT_EOF = 66,
+ IPU_IRQ_SDC_MASK_OUT_EOF = 67,
+ IPU_IRQ_ADC_SERIAL_DATA_OUT = 68,
+ IPU_IRQ_SENSOR_NF = 69,
+ IPU_IRQ_SENSOR_EOF = 70,
+ IPU_IRQ_SDC_DISP3_VSYNC = 80,
+ IPU_IRQ_ADC_DISP0_VSYNC = 81,
+ IPU_IRQ_ADC_DISP12_VSYNC = 82,
+ IPU_IRQ_ADC_PRP_EOF = 83,
+ IPU_IRQ_ADC_PP_EOF = 84,
+ IPU_IRQ_ADC_SYS1_EOF = 85,
+ IPU_IRQ_ADC_SYS2_EOF = 86,
+
+ IPU_IRQ_PRP_ENC_OUT_NFB4EOF_ERR = 96,
+ IPU_IRQ_PRP_VF_OUT_NFB4EOF_ERR = 97,
+ IPU_IRQ_PP_OUT_NFB4EOF_ERR = 98,
+ IPU_IRQ_PRP_GRAPH_IN_NFB4EOF_ERR = 99,
+ IPU_IRQ_PP_GRAPH_IN_NFB4EOF_ERR = 100,
+ IPU_IRQ_PP_IN_NFB4EOF_ERR = 101,
+ IPU_IRQ_PRP_IN_NFB4EOF_ERR = 102,
+ IPU_IRQ_SENSOR_OUT_NFB4EOF_ERR = 103,
+ IPU_IRQ_PRP_ENC_ROT_OUT_NFB4EOF_ERR = 104,
+ IPU_IRQ_PRP_VF_ROT_OUT_NFB4EOF_ERR = 105,
+ IPU_IRQ_PRP_ENC_ROT_IN_NFB4EOF_ERR = 106,
+ IPU_IRQ_PRP_VF_ROT_IN_NFB4EOF_ERR = 107,
+ IPU_IRQ_PP_ROT_OUT_NFB4EOF_ERR = 108,
+ IPU_IRQ_PP_ROT_IN_NFB4EOF_ERR = 109,
+ IPU_IRQ_SDC_FG_NFB4EOF_ERR = 110,
+ IPU_IRQ_SDC_BG_NFB4EOF_ERR = 111,
+ IPU_IRQ_SDC_MASK_NFB4EOF_ERR = 112,
+ IPU_IRQ_SDC_BG_PART_NFB4EOF_ERR = 113,
+ IPU_IRQ_ADC_SYS1_WR_NFB4EOF_ERR = 114,
+ IPU_IRQ_ADC_SYS2_WR_NFB4EOF_ERR = 115,
+ IPU_IRQ_ADC_SYS1_CMD_NFB4EOF_ERR = 116,
+ IPU_IRQ_ADC_SYS2_CMD_NFB4EOF_ERR = 117,
+ IPU_IRQ_ADC_SYS1_RD_NFB4EOF_ERR = 118,
+ IPU_IRQ_ADC_SYS2_RD_NFB4EOF_ERR = 119,
+ IPU_IRQ_PF_QP_IN_NFB4EOF_ERR = 120,
+ IPU_IRQ_PF_BSP_IN_NFB4EOF_ERR = 121,
+ IPU_IRQ_PF_Y_IN_NFB4EOF_ERR = 122,
+ IPU_IRQ_PF_U_IN_NFB4EOF_ERR = 123,
+ IPU_IRQ_PF_V_IN_NFB4EOF_ERR = 124,
+ IPU_IRQ_PF_Y_OUT_NFB4EOF_ERR = 125,
+ IPU_IRQ_PF_U_OUT_NFB4EOF_ERR = 126,
+ IPU_IRQ_PF_V_OUT_NFB4EOF_ERR = 127,
+
+ IPU_IRQ_BAYER_BUFOVF_ERR = 128,
+ IPU_IRQ_ENC_BUFOVF_ERR = 129,
+ IPU_IRQ_VF_BUFOVF_ERR = 130,
+ IPU_IRQ_ADC_PP_TEAR_ERR = 131,
+ IPU_IRQ_ADC_SYS1_TEAR_ERR = 132,
+ IPU_IRQ_ADC_SYS2_TEAR_ERR = 133,
+ IPU_IRQ_SDC_BGD_ERR = 134,
+ IPU_IRQ_SDC_FGD_ERR = 135,
+ IPU_IRQ_SDC_MASKD_ERR = 136,
+ IPU_IRQ_BAYER_FRM_LOST_ERR = 137,
+ IPU_IRQ_ENC_FRM_LOST_ERR = 138,
+ IPU_IRQ_VF_FRM_LOST_ERR = 139,
+ IPU_IRQ_ADC_LOCK_ERR = 140,
+ IPU_IRQ_DI_LLA_LOCK_ERR = 141,
+ IPU_IRQ_AHB_M1_ERR = 142,
+ IPU_IRQ_AHB_M12_ERR = 143,
+#else
+ IPU_IRQ_CSI0_OUT_EOF = 0,
+ IPU_IRQ_CSI1_OUT_EOF = 1,
+ IPU_IRQ_CSI2_OUT_EOF = 2,
+ IPU_IRQ_CSI3_OUT_EOF = 3,
+ IPU_IRQ_PP_IN_EOF = 11,
+ IPU_IRQ_PRP_IN_EOF = 12,
+ IPU_IRQ_PRP_GRAPH_IN_EOF = 14,
+ IPU_IRQ_PP_GRAPH_IN_EOF = 15,
+ IPU_IRQ_PRP_ALPHA_IN_EOF = 17,
+ IPU_IRQ_PP_ALPHA_IN_EOF = 18,
+ IPU_IRQ_PRP_ENC_OUT_EOF = 20,
+ IPU_IRQ_PRP_VF_OUT_EOF = 21,
+ IPU_IRQ_PP_OUT_EOF = 22,
+ IPU_IRQ_BG_SYNC_EOF = 23,
+ IPU_IRQ_BG_ASYNC_EOF = 24,
+ IPU_IRQ_FG_SYNC_EOF = 27,
+ IPU_IRQ_DC_SYNC_EOF = 28,
+ IPU_IRQ_FG_ASYNC_EOF = 29,
+ IPU_IRQ_FG_ALPHA_SYNC_EOF = 31,
+
+ IPU_IRQ_FG_ALPHA_ASYNC_EOF = 33,
+ IPU_IRQ_DC_READ_EOF = 40,
+ IPU_IRQ_DC_ASYNC_EOF = 41,
+ IPU_IRQ_DC_CMD1_EOF = 42,
+ IPU_IRQ_DC_CMD2_EOF = 43,
+ IPU_IRQ_DC_MASK_EOF = 44,
+ IPU_IRQ_PRP_ENC_ROT_OUT_EOF = 45,
+ IPU_IRQ_PRP_VF_ROT_OUT_EOF = 46,
+ IPU_IRQ_PP_ROT_OUT_EOF = 47,
+ IPU_IRQ_PRP_ENC_ROT_IN_EOF = 48,
+ IPU_IRQ_PRP_VF_ROT_IN_EOF = 49,
+ IPU_IRQ_PP_ROT_IN_EOF = 50,
+ IPU_IRQ_BG_ALPHA_SYNC_EOF = 51,
+ IPU_IRQ_BG_ALPHA_ASYNC_EOF = 52,
+
+ IPU_IRQ_DP_SF_START = 448 + 2,
+ IPU_IRQ_DP_SF_END = 448 + 3,
+ IPU_IRQ_BG_SF_END = IPU_IRQ_DP_SF_END,
+ IPU_IRQ_DC_FC_0 = 448 + 8,
+ IPU_IRQ_DC_FC_1 = 448 + 9,
+ IPU_IRQ_DC_FC_2 = 448 + 10,
+ IPU_IRQ_DC_FC_3 = 448 + 11,
+ IPU_IRQ_DC_FC_4 = 448 + 12,
+ IPU_IRQ_DC_FC_6 = 448 + 13,
+ IPU_IRQ_VSYNC_PRE_0 = 448 + 14,
+ IPU_IRQ_VSYNC_PRE_1 = 448 + 15,
+#endif
+
+ IPU_IRQ_COUNT
+};
+
+/*!
+ * Bitfield of Display Interface signal polarities.
+ */
+typedef struct {
+ unsigned datamask_en:1;
+ unsigned ext_clk:1;
+ unsigned interlaced:1;
+ unsigned odd_field_first:1;
+ unsigned clksel_en:1;
+ unsigned clkidle_en:1;
+ unsigned data_pol:1; /* true = inverted */
+ unsigned clk_pol:1; /* true = rising edge */
+ unsigned enable_pol:1;
+ unsigned Hsync_pol:1; /* true = active high */
+ unsigned Vsync_pol:1;
+} ipu_di_signal_cfg_t;
+
+/*!
+ * Bitfield of CSI signal polarities and modes.
+ */
+
+typedef struct {
+ unsigned data_width:4;
+ unsigned clk_mode:3;
+ unsigned ext_vsync:1;
+ unsigned Vsync_pol:1;
+ unsigned Hsync_pol:1;
+ unsigned pixclk_pol:1;
+ unsigned data_pol:1;
+ unsigned sens_clksrc:1;
+ unsigned pack_tight:1;
+ unsigned force_eof:1;
+ unsigned data_en_pol:1;
+ unsigned data_fmt;
+ unsigned csi;
+ unsigned mclk;
+} ipu_csi_signal_cfg_t;
+
+/*!
+ * Enumeration of CSI data bus widths.
+ */
+enum {
+ IPU_CSI_DATA_WIDTH_4,
+ IPU_CSI_DATA_WIDTH_8,
+ IPU_CSI_DATA_WIDTH_10,
+ IPU_CSI_DATA_WIDTH_16,
+};
+
+/*!
+ * Enumeration of CSI clock modes.
+ */
+enum {
+ IPU_CSI_CLK_MODE_GATED_CLK,
+ IPU_CSI_CLK_MODE_NONGATED_CLK,
+ IPU_CSI_CLK_MODE_CCIR656_PROGRESSIVE,
+ IPU_CSI_CLK_MODE_CCIR656_INTERLACED,
+ IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_DDR,
+ IPU_CSI_CLK_MODE_CCIR1120_PROGRESSIVE_SDR,
+ IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_DDR,
+ IPU_CSI_CLK_MODE_CCIR1120_INTERLACED_SDR,
+};
+
+enum {
+ IPU_CSI_MIPI_DI0,
+ IPU_CSI_MIPI_DI1,
+ IPU_CSI_MIPI_DI2,
+ IPU_CSI_MIPI_DI3,
+};
+
+typedef enum {
+ RGB,
+ YCbCr,
+ YUV
+} ipu_color_space_t;
+
+/*!
+ * Enumeration of ADC vertical sync mode.
+ */
+typedef enum {
+ VsyncNone,
+ VsyncInternal,
+ VsyncCSI,
+ VsyncExternal
+} vsync_t;
+
+typedef enum {
+ DAT,
+ CMD
+} cmddata_t;
+
+/*!
+ * Enumeration of ADC display update mode.
+ */
+typedef enum {
+ IPU_ADC_REFRESH_NONE,
+ IPU_ADC_AUTO_REFRESH,
+ IPU_ADC_AUTO_REFRESH_SNOOP,
+ IPU_ADC_SNOOPING,
+} ipu_adc_update_mode_t;
+
+/*!
+ * Enumeration of ADC display interface types (serial or parallel).
+ */
+enum {
+ IPU_ADC_IFC_MODE_SYS80_TYPE1,
+ IPU_ADC_IFC_MODE_SYS80_TYPE2,
+ IPU_ADC_IFC_MODE_SYS68K_TYPE1,
+ IPU_ADC_IFC_MODE_SYS68K_TYPE2,
+ IPU_ADC_IFC_MODE_3WIRE_SERIAL,
+ IPU_ADC_IFC_MODE_4WIRE_SERIAL,
+ IPU_ADC_IFC_MODE_5WIRE_SERIAL_CLK,
+ IPU_ADC_IFC_MODE_5WIRE_SERIAL_CS,
+};
+
+enum {
+ IPU_ADC_IFC_WIDTH_8,
+ IPU_ADC_IFC_WIDTH_16,
+};
+
+/*!
+ * Enumeration of ADC display interface burst mode.
+ */
+enum {
+ IPU_ADC_BURST_WCS,
+ IPU_ADC_BURST_WBLCK,
+ IPU_ADC_BURST_NONE,
+ IPU_ADC_BURST_SERIAL,
+};
+
+/*!
+ * Enumeration of ADC display interface RW signal timing modes.
+ */
+enum {
+ IPU_ADC_SER_NO_RW,
+ IPU_ADC_SER_RW_BEFORE_RS,
+ IPU_ADC_SER_RW_AFTER_RS,
+};
+
+/*!
+ * Bitfield of ADC signal polarities and modes.
+ */
+typedef struct {
+ unsigned data_pol:1;
+ unsigned clk_pol:1;
+ unsigned cs_pol:1;
+ unsigned rs_pol:1;
+ unsigned addr_pol:1;
+ unsigned read_pol:1;
+ unsigned write_pol:1;
+ unsigned Vsync_pol:1;
+ unsigned burst_pol:1;
+ unsigned burst_mode:2;
+ unsigned ifc_mode:3;
+ unsigned ifc_width:5;
+ unsigned ser_preamble_len:4;
+ unsigned ser_preamble:8;
+ unsigned ser_rw_mode:2;
+} ipu_adc_sig_cfg_t;
+
+/*!
+ * Enumeration of ADC template commands.
+ */
+enum {
+ RD_DATA,
+ RD_ACK,
+ RD_WAIT,
+ WR_XADDR,
+ WR_YADDR,
+ WR_ADDR,
+ WR_CMND,
+ WR_DATA,
+};
+
+/*!
+ * Enumeration of ADC template command flow control.
+ */
+enum {
+ SINGLE_STEP,
+ PAUSE,
+ STOP,
+};
+
+/*Define template constants*/
+#define ATM_ADDR_RANGE 0x20 /*offset address of DISP */
+#define TEMPLATE_BUF_SIZE 0x20 /*size of template */
+
+/*!
+ * Define to create ADC template command entry.
+ */
+#define ipu_adc_template_gen(oc, rs, fc, dat) ( ((rs) << 29) | ((fc) << 27) | \
+ ((oc) << 24) | (dat) )
+
+typedef struct {
+ u32 reg;
+ u32 value;
+} ipu_lpmc_reg_t;
+
+#define IPU_LPMC_REG_READ 0x80000000L
+
+#define CSI_MCLK_VF 1
+#define CSI_MCLK_ENC 2
+#define CSI_MCLK_RAW 4
+#define CSI_MCLK_I2C 8
+
+/* Common IPU API */
+int32_t ipu_init_channel(ipu_channel_t channel, ipu_channel_params_t * params);
+void ipu_uninit_channel(ipu_channel_t channel);
+
+static inline bool ipu_can_rotate_in_place(ipu_rotate_mode_t rot)
+{
+#ifdef CONFIG_MXC_IPU_V1
+ return (rot < IPU_ROTATE_90_RIGHT);
+#else
+ return (rot < IPU_ROTATE_HORIZ_FLIP);
+#endif
+}
+
+int32_t ipu_init_channel_buffer(ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t pixel_fmt,
+ uint16_t width, uint16_t height,
+ uint32_t stride,
+ ipu_rotate_mode_t rot_mode,
+ dma_addr_t phyaddr_0, dma_addr_t phyaddr_1,
+ uint32_t u_offset, uint32_t v_offset);
+
+int32_t ipu_update_channel_buffer(ipu_channel_t channel, ipu_buffer_t type,
+ uint32_t bufNum, dma_addr_t phyaddr);
+
+int32_t ipu_select_buffer(ipu_channel_t channel,
+ ipu_buffer_t type, uint32_t bufNum);
+
+int32_t ipu_link_channels(ipu_channel_t src_ch, ipu_channel_t dest_ch);
+int32_t ipu_unlink_channels(ipu_channel_t src_ch, ipu_channel_t dest_ch);
+
+int32_t ipu_enable_channel(ipu_channel_t channel);
+int32_t ipu_disable_channel(ipu_channel_t channel, bool wait_for_stop);
+
+int ipu_lowpwr_display_enable(void);
+int ipu_lowpwr_display_disable(void);
+
+void ipu_enable_irq(uint32_t irq);
+void ipu_disable_irq(uint32_t irq);
+void ipu_clear_irq(uint32_t irq);
+int ipu_request_irq(uint32_t irq,
+ irqreturn_t(*handler) (int, void *),
+ uint32_t irq_flags, const char *devname, void *dev_id);
+void ipu_free_irq(uint32_t irq, void *dev_id);
+bool ipu_get_irq_status(uint32_t irq);
+void ipu_set_csc_coefficients(ipu_channel_t channel, int32_t param[][3]);
+
+/* SDC API */
+int32_t ipu_sdc_init_panel(ipu_panel_t panel,
+ uint32_t pixel_clk,
+ uint16_t width, uint16_t height,
+ uint32_t pixel_fmt,
+ uint16_t hStartWidth, uint16_t hSyncWidth,
+ uint16_t hEndWidth, uint16_t vStartWidth,
+ uint16_t vSyncWidth, uint16_t vEndWidth,
+ ipu_di_signal_cfg_t sig);
+
+int32_t ipu_sdc_set_global_alpha(bool enable, uint8_t alpha);
+int32_t ipu_sdc_set_color_key(ipu_channel_t channel, bool enable,
+ uint32_t colorKey);
+int32_t ipu_sdc_set_brightness(uint8_t value);
+
+int32_t ipu_init_sync_panel(int disp,
+ uint32_t pixel_clk,
+ uint16_t width, uint16_t height,
+ uint32_t pixel_fmt,
+ uint16_t h_start_width, uint16_t h_sync_width,
+ uint16_t h_end_width, uint16_t v_start_width,
+ uint16_t v_sync_width, uint16_t v_end_width,
+ uint32_t v_to_h_sync, ipu_di_signal_cfg_t sig);
+
+int32_t ipu_disp_set_window_pos(ipu_channel_t channel, int16_t x_pos,
+ int16_t y_pos);
+int32_t ipu_disp_set_global_alpha(ipu_channel_t channel, bool enable,
+ uint8_t alpha);
+int32_t ipu_disp_set_color_key(ipu_channel_t channel, bool enable,
+ uint32_t colorKey);
+
+int ipu_init_async_panel(int disp, int type, uint32_t cycle_time,
+ uint32_t pixel_fmt, ipu_adc_sig_cfg_t sig);
+void ipu_disp_direct_write(ipu_channel_t channel, u32 value, u32 offset);
+void ipu_reset_disp_panel(void);
+
+/* ADC API */
+int32_t ipu_adc_write_template(display_port_t disp, uint32_t * pCmd,
+ bool write);
+
+int32_t ipu_adc_set_update_mode(ipu_channel_t channel,
+ ipu_adc_update_mode_t mode,
+ uint32_t refresh_rate, unsigned long addr,
+ uint32_t * size);
+
+int32_t ipu_adc_get_snooping_status(uint32_t * statl, uint32_t * stath);
+
+int32_t ipu_adc_write_cmd(display_port_t disp, cmddata_t type,
+ uint32_t cmd, const uint32_t * params,
+ uint16_t numParams);
+
+int32_t ipu_adc_init_panel(display_port_t disp,
+ uint16_t width, uint16_t height,
+ uint32_t pixel_fmt,
+ uint32_t stride,
+ ipu_adc_sig_cfg_t sig,
+ display_addressing_t addr,
+ uint32_t vsync_width, vsync_t mode);
+
+int32_t ipu_adc_init_ifc_timing(display_port_t disp, bool read,
+ uint32_t cycle_time,
+ uint32_t up_time,
+ uint32_t down_time,
+ uint32_t read_latch_time, uint32_t pixel_clk);
+
+/* CMOS Sensor Interface API */
+int32_t ipu_csi_init_interface(uint16_t width, uint16_t height,
+ uint32_t pixel_fmt, ipu_csi_signal_cfg_t sig);
+
+int32_t ipu_csi_enable_mclk(int src, bool flag, bool wait);
+
+static inline int32_t ipu_csi_enable_mclk_if(int src, uint32_t csi,
+ bool flag, bool wait)
+{
+#ifdef CONFIG_MXC_IPU_V1
+ return ipu_csi_enable_mclk(src, flag, wait);
+#else
+ return ipu_csi_enable_mclk(csi, flag, wait);
+#endif
+}
+
+int ipu_csi_read_mclk_flag(void);
+
+void ipu_csi_flash_strobe(bool flag);
+
+void ipu_csi_get_window_size(uint32_t *width, uint32_t *height, uint32_t csi);
+
+void ipu_csi_set_window_size(uint32_t width, uint32_t height, uint32_t csi);
+
+void ipu_csi_set_window_pos(uint32_t left, uint32_t top, uint32_t csi);
+
+/* Post Filter functions */
+int32_t ipu_pf_set_pause_row(uint32_t pause_row);
+
+uint32_t bytes_per_pixel(uint32_t fmt);
+
+/* New added for IPU-lib functionality*/
+int ipu_open(void);
+int ipu_register_generic_isr(int irq, void *dev);
+void ipu_close(void);
+
+typedef struct _ipu_channel_parm {
+ ipu_channel_t channel;
+ ipu_channel_params_t params;
+ bool flag;
+} ipu_channel_parm;
+
+typedef struct _ipu_channel_buf_parm {
+ ipu_channel_t channel;
+ ipu_buffer_t type;
+ uint32_t pixel_fmt;
+ uint16_t width;
+ uint16_t height;
+ uint16_t stride;
+ ipu_rotate_mode_t rot_mode;
+ dma_addr_t phyaddr_0;
+ dma_addr_t phyaddr_1;
+ uint32_t u_offset;
+ uint32_t v_offset;
+ uint32_t bufNum;
+} ipu_channel_buf_parm;
+
+typedef struct _ipu_channel_link {
+ ipu_channel_t src_ch;
+ ipu_channel_t dest_ch;
+} ipu_channel_link;
+
+typedef struct _ipu_channel_info {
+ ipu_channel_t channel;
+ bool stop;
+} ipu_channel_info;
+
+typedef struct ipu_irq_info {
+ uint32_t irq;
+ irqreturn_t(*handler) (int, void *);
+ uint32_t irq_flags;
+ char *devname;
+ void *dev_id;
+} ipu_irq_info;
+
+typedef struct _ipu_sdc_panel_info {
+ ipu_panel_t panel;
+ uint32_t pixel_clk;
+ uint16_t width;
+ uint16_t height;
+ uint32_t pixel_fmt;
+ uint16_t hStartWidth;
+ uint16_t hSyncWidth;
+ uint16_t hEndWidth;
+ uint16_t vStartWidth;
+ uint16_t vSyncWidth;
+ uint16_t vEndWidth;
+ ipu_di_signal_cfg_t signal;
+} ipu_sdc_panel_info;
+
+typedef struct _ipu_sdc_window_pos {
+ ipu_channel_t channel;
+ int16_t x_pos;
+ int16_t y_pos;
+} ipu_sdc_window_pos;
+
+typedef struct _ipu_sdc_global_alpha {
+ bool enable;
+ uint8_t alpha;
+} ipu_sdc_global_alpha;
+
+typedef struct _ipu_sdc_color_key {
+ ipu_channel_t channel;
+ bool enable;
+ uint32_t colorKey;
+} ipu_sdc_color_key;
+
+typedef struct _ipu_adc_template {
+ display_port_t disp;
+ uint32_t *pCmd;
+ bool write;
+} ipu_adc_template;
+
+typedef struct _ipu_adc_update {
+ ipu_channel_t channel;
+ ipu_adc_update_mode_t mode;
+ uint32_t refresh_rate;
+ unsigned long addr;
+ uint32_t *size;
+} ipu_adc_update;
+
+typedef struct _ipu_adc_snoop {
+ uint32_t *statl;
+ uint32_t *stath;
+} ipu_adc_snoop;
+
+typedef struct _ipu_adc_cmd {
+ display_port_t disp;
+ cmddata_t type;
+ uint32_t cmd;
+ uint32_t *params;
+ uint16_t numParams;
+} ipu_adc_cmd;
+
+typedef struct _ipu_adc_panel {
+ display_port_t disp;
+ uint16_t width;
+ uint16_t height;
+ uint32_t pixel_fmt;
+ uint32_t stride;
+ ipu_adc_sig_cfg_t signal;
+ display_addressing_t addr;
+ uint32_t vsync_width;
+ vsync_t mode;
+} ipu_adc_panel;
+
+typedef struct _ipu_adc_ifc_timing {
+ display_port_t disp;
+ bool read;
+ uint32_t cycle_time;
+ uint32_t up_time;
+ uint32_t down_time;
+ uint32_t read_latch_time;
+ uint32_t pixel_clk;
+} ipu_adc_ifc_timing;
+
+typedef struct _ipu_csi_interface {
+ uint16_t width;
+ uint16_t height;
+ uint16_t pixel_fmt;
+ ipu_csi_signal_cfg_t signal;
+} ipu_csi_interface;
+
+typedef struct _ipu_csi_mclk {
+ int src;
+ bool flag;
+ bool wait;
+} ipu_csi_mclk;
+
+typedef struct _ipu_csi_window {
+ uint32_t left;
+ uint32_t top;
+} ipu_csi_window;
+
+typedef struct _ipu_csi_window_size {
+ uint32_t width;
+ uint32_t height;
+} ipu_csi_window_size;
+
+typedef struct _ipu_event_info {
+ int irq;
+ void *dev;
+} ipu_event_info;
+
+typedef struct _ipu_mem_info {
+ dma_addr_t paddr;
+ void *vaddr;
+ int size;
+} ipu_mem_info;
+
+/* IOCTL commands */
+
+#define IPU_INIT_CHANNEL _IOW('I',0x1,ipu_channel_parm)
+#define IPU_UNINIT_CHANNEL _IOW('I',0x2,ipu_channel_t)
+#define IPU_INIT_CHANNEL_BUFFER _IOW('I',0x3,ipu_channel_buf_parm)
+#define IPU_UPDATE_CHANNEL_BUFFER _IOW('I',0x4,ipu_channel_buf_parm)
+#define IPU_SELECT_CHANNEL_BUFFER _IOW('I',0x5,ipu_channel_buf_parm)
+#define IPU_LINK_CHANNELS _IOW('I',0x6,ipu_channel_link)
+#define IPU_UNLINK_CHANNELS _IOW('I',0x7,ipu_channel_link)
+#define IPU_ENABLE_CHANNEL _IOW('I',0x8,ipu_channel_t)
+#define IPU_DISABLE_CHANNEL _IOW('I',0x9,ipu_channel_info)
+#define IPU_ENABLE_IRQ _IOW('I',0xA,int)
+#define IPU_DISABLE_IRQ _IOW('I',0xB,int)
+#define IPU_CLEAR_IRQ _IOW('I',0xC,int)
+#define IPU_FREE_IRQ _IOW('I',0xD,ipu_irq_info)
+#define IPU_REQUEST_IRQ_STATUS _IOW('I',0xE,int)
+#define IPU_SDC_INIT_PANEL _IOW('I',0xF,ipu_sdc_panel_info)
+#define IPU_SDC_SET_WIN_POS _IOW('I',0x10,ipu_sdc_window_pos)
+#define IPU_SDC_SET_GLOBAL_ALPHA _IOW('I',0x11,ipu_sdc_global_alpha)
+#define IPU_SDC_SET_COLOR_KEY _IOW('I',0x12,ipu_sdc_color_key)
+#define IPU_SDC_SET_BRIGHTNESS _IOW('I',0x13,int)
+#define IPU_ADC_WRITE_TEMPLATE _IOW('I',0x14,ipu_adc_template)
+#define IPU_ADC_UPDATE _IOW('I',0x15,ipu_adc_update)
+#define IPU_ADC_SNOOP _IOW('I',0x16,ipu_adc_snoop)
+#define IPU_ADC_CMD _IOW('I',0x17,ipu_adc_cmd)
+#define IPU_ADC_INIT_PANEL _IOW('I',0x18,ipu_adc_panel)
+#define IPU_ADC_IFC_TIMING _IOW('I',0x19,ipu_adc_ifc_timing)
+#define IPU_CSI_INIT_INTERFACE _IOW('I',0x1A,ipu_csi_interface)
+#define IPU_CSI_ENABLE_MCLK _IOW('I',0x1B,ipu_csi_mclk)
+#define IPU_CSI_READ_MCLK_FLAG _IOR('I',0x1C,ipu_csi_mclk)
+#define IPU_CSI_FLASH_STROBE _IOW('I',0x1D,ipu_csi_mclk)
+#define IPU_CSI_GET_WIN_SIZE _IOR('I',0x1E,ipu_csi_window_size)
+#define IPU_CSI_SET_WIN_SIZE _IOW('I',0x1F,ipu_csi_window_size)
+#define IPU_CSI_SET_WINDOW _IOW('I',0x20,ipu_csi_window)
+#define IPU_PF_SET_PAUSE_ROW _IOW('I',0x21, uint32_t)
+#define IPU_REGISTER_GENERIC_ISR _IOW('I',0x22,ipu_event_info)
+#define IPU_GET_EVENT _IOR('I',0x23,ipu_event_info)
+#define IPU_ALOC_MEM _IOWR('I', 0x24, ipu_mem_info)
+#define IPU_FREE_MEM _IOW('I', 0x25, ipu_mem_info)
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index b55bba35e18a..467ab895b6e4 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -14,4 +14,21 @@
#include <mach/hardware.h>
extern void imx_irq_set_priority(unsigned char irq, unsigned char prio);
+#define MXC_IRQ_TO_EXPIO(irq) ((irq) - MXC_EXP_IO_BASE)
+
+#define MXC_IRQ_TO_GPIO(irq) ((irq) - MXC_GPIO_INT_BASE)
+#define MXC_GPIO_TO_IRQ(x) (MXC_GPIO_INT_BASE + (x))
+
+/* Number of normal interrupts */
+#define NR_IRQS MXC_MAX_INTS
+
+/* Number of fast interrupts */
+#define NR_FIQS MXC_MAX_INTS
+
+/*
+ * This function is used to get the AVIC Lo and Hi interrupts
+ * that are enabled as wake up sources to wake up the core from suspend
+ */
+void mxc_get_wake_irq(u32 * wake_src[]);
+
#endif /* __ASM_ARCH_MXC_IRQS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/memory.h b/arch/arm/plat-mxc/include/mach/memory.h
index d7a8d3ebed57..3658da2721ce 100644
--- a/arch/arm/plat-mxc/include/mach/memory.h
+++ b/arch/arm/plat-mxc/include/mach/memory.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -11,7 +11,57 @@
#ifndef __ASM_ARCH_MXC_MEMORY_H__
#define __ASM_ARCH_MXC_MEMORY_H__
-#include <mach/hardware.h>
+#include <asm/page.h>
+#include <asm/sizes.h>
+
+/* Start of physical RAM */
+#if defined(CONFIG_MACH_MX35EVB) || defined(CONFIG_MACH_MX51_3DS)
+#define PHYS_OFFSET UL(0x90000000)
+#endif
+
+#ifdef CONFIG_MACH_MX27ADS
+#define PHYS_OFFSET UL(0xA0000000)
+#endif
+
+#ifdef CONFIG_MACH_MX37_3DS
+#define PHYS_OFFSET UL(0x40000000)
+#endif
+
+#ifndef PHYS_OFFSET
+#define PHYS_OFFSET UL(0x80000000)
+#endif
+
+/* Size of contiguous memory for DMA and other h/w blocks */
+#ifdef CONFIG_ARCH_MX51
+#define CONSISTENT_DMA_SIZE (64 * SZ_1M)
+#else
+#define CONSISTENT_DMA_SIZE (32 * SZ_1M)
+#endif
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_DMA_ZONE_SIZE
+#define MXC_DMA_ZONE_SIZE ((CONFIG_DMA_ZONE_SIZE * SZ_1M) >> PAGE_SHIFT)
+#else
+#define MXC_DMA_ZONE_SIZE ((12 * SZ_1M) >> PAGE_SHIFT)
+#endif
+
+static inline void __arch_adjust_zones(int node, unsigned long *zone_size,
+ unsigned long *zhole_size)
+{
+ if (node != 0)
+ return;
+ /* Create separate zone to reserve memory for DMA */
+ zone_size[1] = zone_size[0] - MXC_DMA_ZONE_SIZE;
+ zone_size[0] = MXC_DMA_ZONE_SIZE;
+ zhole_size[1] = zhole_size[0];
+ zhole_size[0] = 0;
+}
+
+#define arch_adjust_zones(node, size, holes) \
+ __arch_adjust_zones(node, size, holes)
+
+#endif
/*
* Virtual view <-> DMA view memory address translations
diff --git a/arch/arm/plat-mxc/include/mach/mmc.h b/arch/arm/plat-mxc/include/mach/mmc.h
new file mode 100644
index 000000000000..cf76cceacb3b
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mmc.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2007-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_MXC_MMC_H__
+#define __ASM_ARCH_MXC_MMC_H__
+
+#include <linux/mmc/host.h>
+
+struct mxc_mmc_platform_data {
+ unsigned int ocr_mask; /* available voltages */
+ unsigned int vendor_ver;
+ unsigned int caps;
+ unsigned int min_clk;
+ unsigned int max_clk;
+ unsigned int clk_flg; /* 1 clock enable, 0 not */
+ unsigned int reserved:16;
+ unsigned int card_fixed:1;
+ unsigned int card_inserted_state:1;
+// u32 (*translate_vdd)(struct device *, unsigned int);
+ unsigned int (*status) (struct device *);
+ int (*wp_status) (struct device *);
+ char *power_mmc;
+ char *clock_mmc;
+};
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/mtd-xip.h b/arch/arm/plat-mxc/include/mach/mtd-xip.h
new file mode 100644
index 000000000000..340bb9c1562c
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mtd-xip.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * MTD primitives for XIP support. Architecture specific functions
+ *
+ * Do not include this file directly. It's included from linux/mtd/xip.h
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ARCH_MXC_MTD_XIP_H__
+#define __ARCH_MXC_MTD_XIP_H__
+
+#include <linux/clocksource.h>
+#include <mach/hardware.h>
+#include <mach/system.h>
+
+#define xip_irqpending() \
+ ((__raw_readl(AVIC_NIVECSR) & __raw_readl(AVIC_FIVECSR)) != 0xFFFFFFFF)
+
+extern struct clocksource *mtd_xip_clksrc;
+
+#define xip_currtime() (unsigned long)clocksource_read(mtd_xip_clksrc)
+
+#if CLOCK_TICK_RATE > 1000000
+#define NUMERATOR 1
+#define DENOMINATOR (CLOCK_TICK_RATE/1000000 + 1)
+#else
+#define NUMERATOR (1000000/CLOCK_TICK_RATE)
+#define DENOMINATOR 1
+#endif
+
+static inline unsigned long xip_elapsed_since(unsigned long x)
+{
+ return (((xip_currtime() - x) * NUMERATOR) / DENOMINATOR);
+}
+
+/*
+ * Wait For Interrupt command for XIP kernel to put CPU in Idle mode
+ */
+#define xip_cpu_idle() arch_idle()
+
+#endif /* __ARCH_MXC_MTD_XIP_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx21.h b/arch/arm/plat-mxc/include/mach/mx21.h
new file mode 100644
index 000000000000..01dce93e90d7
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx21.h
@@ -0,0 +1,303 @@
+/*
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup MSL Machine Specific Layer (MSL)
+ */
+
+/*!
+ * @defgroup System System-wide Misc Files for MSL
+ * @ingroup MSL
+ */
+
+/*!
+ * @file arch-mxc/mx21.h
+ * @brief This file contains register definitions.
+ *
+ * @ingroup System
+ */
+
+#ifndef __ASM_ARCH_MXC_MX21_H__
+#define __ASM_ARCH_MXC_MX21_H__
+
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#error "Do not include directly."
+#endif
+
+/*!
+ * defines the OS clock tick rate
+ */
+#define CLOCK_TICK_RATE 13300000
+
+/*!
+ * UART Chip level Configuration that a user may not have to edit. These
+ * configuration vary depending on how the UART module is integrated with
+ * the ARM core
+ */
+#define MXC_UART_NR 4
+/*!
+ * 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
+/*!
+ * 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
+
+/*
+ * IRAM
+ */
+#define IRAM_BASE_ADDR 0xFFFFD800 /* internal ram */
+#define IRAM_BASE_ADDR_VIRT 0xD0000000
+#define IRAM_SIZE (SZ_4K + SZ_1K*2)
+
+/*
+ * Register offests.
+ */
+#define AIPI_BASE_ADDR 0x10000000
+#define AIPI_BASE_ADDR_VIRT 0xD4000000
+#define AIPI_SIZE SZ_1M
+
+#define DMA_BASE_ADDR (AIPI_BASE_ADDR + 0x01000)
+#define WDOG_BASE_ADDR (AIPI_BASE_ADDR + 0x02000)
+#define GPT1_BASE_ADDR (AIPI_BASE_ADDR + 0x03000)
+#define GPT2_BASE_ADDR (AIPI_BASE_ADDR + 0x04000)
+#define GPT3_BASE_ADDR (AIPI_BASE_ADDR + 0x05000)
+#define PWM_BASE_ADDR (AIPI_BASE_ADDR + 0x06000)
+#define RTC_BASE_ADDR (AIPI_BASE_ADDR + 0x07000)
+#define KPP_BASE_ADDR (AIPI_BASE_ADDR + 0x08000)
+#define OWIRE_BASE_ADDR (AIPI_BASE_ADDR + 0x09000)
+#define UART1_BASE_ADDR (AIPI_BASE_ADDR + 0x0A000)
+#define UART2_BASE_ADDR (AIPI_BASE_ADDR + 0x0B000)
+#define UART3_BASE_ADDR (AIPI_BASE_ADDR + 0x0C000)
+#define UART4_BASE_ADDR (AIPI_BASE_ADDR + 0x0D000)
+#define CSPI1_BASE_ADDR (AIPI_BASE_ADDR + 0x0E000)
+#define CSPI2_BASE_ADDR (AIPI_BASE_ADDR + 0x0F000)
+#define SSI1_BASE_ADDR (AIPI_BASE_ADDR + 0x10000)
+#define SSI2_BASE_ADDR (AIPI_BASE_ADDR + 0x11000)
+#define I2C_BASE_ADDR (AIPI_BASE_ADDR + 0x12000)
+#define SDHC1_BASE_ADDR (AIPI_BASE_ADDR + 0x13000)
+#define SDHC2_BASE_ADDR (AIPI_BASE_ADDR + 0x14000)
+#define GPIO_BASE_ADDR (AIPI_BASE_ADDR + 0x15000)
+#define AUDMUX_BASE_ADDR (AIPI_BASE_ADDR + 0x16000)
+#define CSPI3_BASE_ADDR (AIPI_BASE_ADDR + 0x17000)
+#define LCDC_BASE_ADDR (AIPI_BASE_ADDR + 0x21000)
+#define SLCDC_BASE_ADDR (AIPI_BASE_ADDR + 0x22000)
+#define USBOTG_BASE_ADDR (AIPI_BASE_ADDR + 0x24000)
+#define EMMA_BASE_ADDR (AIPI_BASE_ADDR + 0x26000)
+#define CCM_BASE_ADDR (AIPI_BASE_ADDR + 0x27000)
+#define FIRI_BASE_ADDR (AIPI_BASE_ADDR + 0x28000)
+#define JAM_BASE_ADDR (AIPI_BASE_ADDR + 0x3E000)
+#define MAX_BASE_ADDR (AIPI_BASE_ADDR + 0x3F000)
+
+/*
+ * ROMP and AVIC
+ */
+#define ROMP_BASE_ADDR 0x10041000
+
+#define AVIC_BASE_ADDR 0x10040000
+
+#define SAHB1_BASE_ADDR 0x80000000
+#define SAHB1_BASE_ADDR_VIRT 0xD4100000
+#define SAHB1_SIZE SZ_1M
+
+#define CSI_BASE_ADDR (SAHB1_BASE_ADDR + 0x0000)
+
+/*
+ * NAND, SDRAM, WEIM, M3IF, EMI controllers
+ */
+#define X_MEMC_BASE_ADDR 0xDF000000
+#define X_MEMC_BASE_ADDR_VIRT 0xD4320000
+#define X_MEMC_SIZE SZ_64K
+
+#define SDRAMC_BASE_ADDR (X_MEMC_BASE_ADDR)
+#define WEIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000)
+#define PCMCIA_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000)
+#define NFC_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000)
+
+/*
+ * Memory regions and CS
+ */
+#define SDRAM_BASE_ADDR 0xC0000000
+#define CSD1_BASE_ADDR 0xC4000000
+
+#define CS0_BASE_ADDR 0xC8000000
+
+#define CS1_BASE_ADDR 0xCC000000
+#define CS1_BASE_ADDR_VIRT 0xEB000000
+#define CS1_SIZE SZ_16M
+
+#define CS2_BASE_ADDR 0xD0000000
+#define CS3_BASE_ADDR 0xD1000000
+
+#define CS4_BASE_ADDR 0xD2000000
+
+#define CS5_BASE_ADDR 0xD2000000
+#define PCMCIA_MEM_BASE_ADDR 0xD4000000
+
+/*!
+ * This macro defines the physical to virtual address mapping for all the
+ * peripheral modules. It is used by passing in the physical address as x
+ * and returning the virtual address. If the physical address is not mapped,
+ * it returns 0xDEADBEEF
+ */
+#define IO_ADDRESS(x) \
+ (((x >= AIPI_BASE_ADDR) && (x < (AIPI_BASE_ADDR + AIPI_SIZE))) ? AIPI_IO_ADDRESS(x):\
+ ((x >= SAHB1_BASE_ADDR) && (x < (SAHB1_BASE_ADDR + SAHB1_SIZE))) ? SAHB1_IO_ADDRESS(x):\
+ ((x >= CS1_BASE_ADDR) && (x < (CS1_BASE_ADDR + CS1_SIZE))) ? CS1_IO_ADDRESS(x):\
+ ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? X_MEMC_IO_ADDRESS(x):\
+ 0xDEADBEEF)
+
+/*
+ * define the address mapping macros: in physical address order
+ */
+
+#define AIPI_IO_ADDRESS(x) \
+ (((x) - AIPI_BASE_ADDR) + AIPI_BASE_ADDR_VIRT)
+
+#define AVIC_IO_ADDRESS(x) AIPI_IO_ADDRESS(x)
+
+#define SAHB1_IO_ADDRESS(x) \
+ (((x) - SAHB1_BASE_ADDR) + SAHB1_BASE_ADDR_VIRT)
+
+#define CS1_IO_ADDRESS(x) \
+ (((x) - CS1_BASE_ADDR) + CS1_BASE_ADDR_VIRT)
+
+#define X_MEMC_IO_ADDRESS(x) \
+ (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+
+#define PCMCIA_IO_ADDRESS(x) \
+ (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+
+#define IS_MEM_DEVICE_NONSHARED(x) 0
+
+/*
+ * MX21 ADS Interrupt numbers
+ */
+#define MXC_INT_CSPI3 6
+#define MXC_INT_GPIO 8
+#define MXC_INT_FIRI 9
+#define MXC_INT_SDHC2 10
+#define MXC_INT_SDHC1 11
+#define MXC_INT_I2C 12
+#define MXC_INT_SSI2 13
+#define MXC_INT_SSI1 14
+#define MXC_INT_CSPI2 15
+#define MXC_INT_CSPI1 16
+#define MXC_INT_UART4 17
+#define MXC_INT_UART3 18
+#define MXC_INT_UART2 19
+#define MXC_INT_UART1 20
+#define MXC_INT_KPP 21
+#define MXC_INT_RTC 22
+#define MXC_INT_PWM 23
+#define MXC_INT_GPT3 24
+#define MXC_INT_GPT2 25
+#define MXC_INT_GPT1 26
+#define MXC_INT_GPT INT_GPT1
+#define MXC_INT_WDOG 27
+#define MXC_INT_PCMCIA 28
+#define MXC_INT_NANDFC 29
+#define MXC_INT_BMI 30
+#define MXC_INT_CSI 31
+#define MXC_INT_DMACH0 32
+#define MXC_INT_DMACH1 33
+#define MXC_INT_DMACH2 34
+#define MXC_INT_DMACH3 35
+#define MXC_INT_DMACH4 36
+#define MXC_INT_DMACH5 37
+#define MXC_INT_DMACH6 38
+#define MXC_INT_DMACH7 39
+#define MXC_INT_DMACH8 40
+#define MXC_INT_DMACH9 41
+#define MXC_INT_DMACH10 42
+#define MXC_INT_DMACH11 43
+#define MXC_INT_DMACH12 44
+#define MXC_INT_DMACH13 45
+#define MXC_INT_DMACH14 46
+#define MXC_INT_DMACH15 47
+#define MXC_INT_EMMAENC 49
+#define MXC_INT_EMMADEC 50
+#define MXC_INT_EMMAPRP 51
+#define MXC_INT_EMMAPP 52
+#define MXC_INT_USBWKUP 53
+#define MXC_INT_USBDMA 54
+#define MXC_INT_USBHOST 55
+#define MXC_INT_USBFUNC 56
+#define MXC_INT_USBHNP 57
+#define MXC_INT_USBCTRL 58
+#define MXC_INT_SAHARA 59
+#define MXC_INT_SLCDC 60
+#define MXC_INT_LCDC 61
+
+#define MXC_MAX_INT_LINES 64
+#define MXC_MAX_EXT_LINES 0
+
+#define MXC_MUX_GPIO_INTERRUPTS 1
+#define MXC_GPIO_BASE (MXC_MAX_INT_LINES)
+
+/*!
+ * Number of GPIO port as defined in the IC Spec
+ */
+#define GPIO_PORT_NUM 6
+/*!
+ * Number of GPIO pins per port
+ */
+#define GPIO_NUM_PIN 32
+
+#define DMA_REQ_CSI_RX 31
+#define DMA_REQ_CSI_STAT 30
+#define DMA_REQ_BMI_RX 29
+#define DMA_REQ_BMI_TX 28
+#define DMA_REQ_UART1_TX 27
+#define DMA_REQ_UART1_RX 26
+#define DMA_REQ_UART2_TX 25
+#define DMA_REQ_UART2_RX 24
+#define DMA_REQ_UART3_TX 23
+#define DMA_REQ_UART3_RX 22
+#define DMA_REQ_UART4_TX 21
+#define DMA_REQ_UART4_RX 20
+#define DMA_REQ_CSPI1_TX 19
+#define DMA_REQ_CSPI1_RX 18
+#define DMA_REQ_CSPI2_TX 17
+#define DMA_REQ_CSPI2_RX 16
+#define DMA_REQ_SSI1_TX1 15
+#define DMA_REQ_SSI1_RX1 14
+#define DMA_REQ_SSI1_TX0 13
+#define DMA_REQ_SSI1_RX0 12
+#define DMA_REQ_SSI2_TX1 11
+#define DMA_REQ_SSI2_RX1 10
+#define DMA_REQ_SSI2_TX0 9
+#define DMA_REQ_SSI2_RX0 8
+#define DMA_REQ_SDHC1 7
+#define DMA_REQ_SDHC2 6
+#define DMA_FIRI_TX 5
+#define DMA_FIRI_RX 4
+#define DMA_EX 3
+#define DMA_REQ_CSPI3_TX 2
+#define DMA_REQ_CSPI3_RX 1
+
+#define MXC_TIMER_GPT1 1
+#define MXC_TIMER_GPT2 2
+#define MXC_TIMER_GPT3 3
+
+/*!
+ * NFMS bit in FMCR register for pagesize of nandflash
+ */
+#define NFMS (*((volatile u32 *)IO_ADDRESS(CCM_BASE_ADDR+0x814)))
+
+#define NFMS_BIT 5
+
+#endif /* __ASM_ARCH_MXC_MX21_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx27.h b/arch/arm/plat-mxc/include/mach/mx27.h
index a86db64744a1..2116025c8dbe 100644
--- a/arch/arm/plat-mxc/include/mach/mx27.h
+++ b/arch/arm/plat-mxc/include/mach/mx27.h
@@ -24,6 +24,35 @@
#error "Do not include directly."
#endif
+/*!
+ * defines the OS clock tick rate
+ */
+#define CLOCK_TICK_RATE 13300000
+
+/*!
+ * Register an interrupt handler for the SMN as well as the SCC. In some
+ * implementations, the SMN is not connected at all, and in others, it is
+ * on the same interrupt line as the SCM. Comment this line out accordingly
+ */
+#define USE_SMN_INTERRUPT
+
+/*!
+ * UART Chip level Configuration that a user may not have to edit. These
+ * configuration vary depending on how the UART module is integrated with
+ * the ARM core
+ */
+#define MXC_UART_NR 6
+/*!
+ * 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
+/*!
+ * 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
+
/* IRAM */
#define IRAM_BASE_ADDR 0xFFFF4C00 /* internal ram */
@@ -33,7 +62,7 @@
#define AIPI_SIZE SZ_1M
#define DMA_BASE_ADDR (AIPI_BASE_ADDR + 0x01000)
-#define WDOG_BASE_ADDR (AIPI_BASE_ADDR + 0x02000)
+#define WDOG1_BASE_ADDR (AIPI_BASE_ADDR + 0x02000)
#define GPT1_BASE_ADDR (AIPI_BASE_ADDR + 0x03000)
#define GPT2_BASE_ADDR (AIPI_BASE_ADDR + 0x04000)
#define GPT3_BASE_ADDR (AIPI_BASE_ADDR + 0x05000)
@@ -118,6 +147,8 @@
#define CS2_BASE_ADDR 0xD0000000
#define CS3_BASE_ADDR 0xD2000000
#define CS4_BASE_ADDR 0xD4000000
+#define CS4_BASE_ADDR_VIRT 0xF4300000
+#define CS4_SIZE SZ_1M
#define CS5_BASE_ADDR 0xD6000000
#define PCMCIA_MEM_BASE_ADDR 0xDC000000
@@ -154,6 +185,11 @@
#define PCMCIA_IO_ADDRESS(x) \
(((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+#define IS_MEM_DEVICE_NONSHARED(x) 0
+
+/*
+ * MX27 ADS Interrupt numbers
+ */
/* fixed interrput numbers */
#define MXC_INT_CCM 63
#define MXC_INT_IIM 62
@@ -195,7 +231,7 @@
#define MXC_INT_GPT1 26
#define MXC_INT_GPT2 25
#define MXC_INT_GPT3 24
-#define MXC_INT_GPT INT_GPT1
+#define MXC_INT_GPT MXC_INT_GPT1
#define MXC_INT_PWM 23
#define MXC_INT_RTC 22
#define MXC_INT_KPP 21
@@ -220,6 +256,21 @@
#define MXC_INT_GPT6 2
#define MXC_INT_I2C2 1
+#define MXC_MAX_INT_LINES 64
+#define MXC_MAX_EXT_LINES 0
+
+#define MXC_MUX_GPIO_INTERRUPTS 1
+#define MXC_GPIO_INT_BASE (MXC_MAX_INT_LINES)
+
+/*!
+ * Number of GPIO port as defined in the IC Spec
+ */
+#define GPIO_PORT_NUM 6
+/*!
+ * Number of GPIO pins per port
+ */
+#define GPIO_NUM_PIN 32
+
/* fixed DMA request numbers */
#define DMA_REQ_NFC 37
#define DMA_REQ_SDHC3 36
@@ -258,44 +309,19 @@
#define DMA_REQ_CSPI3_TX 2
#define DMA_REQ_CSPI3_RX 1
-/* silicon revisions specific to i.MX27 */
-#define CHIP_REV_1_0 0x00
-#define CHIP_REV_2_0 0x01
+#define MXC_TIMER_GPT1 1
+#define MXC_TIMER_GPT2 2
+#define MXC_TIMER_GPT3 3
+#define MXC_TIMER_GPT4 4
+#define MXC_TIMER_GPT5 5
+#define MXC_TIMER_GPT6 6
-#ifndef __ASSEMBLY__
-extern int mx27_revision(void);
-#endif
-
-/* gpio and gpio based interrupt handling */
-#define GPIO_DR 0x1C
-#define GPIO_GDIR 0x00
-#define GPIO_PSR 0x24
-#define GPIO_ICR1 0x28
-#define GPIO_ICR2 0x2C
-#define GPIO_IMR 0x30
-#define GPIO_ISR 0x34
-#define GPIO_INT_LOW_LEV 0x3
-#define GPIO_INT_HIGH_LEV 0x2
-#define GPIO_INT_RISE_EDGE 0x0
-#define GPIO_INT_FALL_EDGE 0x1
-#define GPIO_INT_NONE 0x4
-
-/* Mandatory defines used globally */
-
-/* this is an i.MX27 CPU */
-#define cpu_is_mx27() (1)
-
-/* this CPU supports up to 192 GPIOs (don't forget the baseboard!) */
-#define ARCH_NR_GPIOS (192 + 16)
-
-/* OS clock tick rate */
-#define CLOCK_TICK_RATE 13300000
-
-/* Start of RAM */
-#define PHYS_OFFSET SDRAM_BASE_ADDR
+/*!
+ * NFMS bit in FMCR register for pagesize of nandflash
+ */
+#define NFMS (*((volatile u32 *)IO_ADDRESS(SYSCTRL_BASE_ADDR+0x14)))
-/* max interrupt lines count */
-#define NR_IRQS 256
+#define NFMS_BIT 5
/* count of internal interrupt sources */
#define MXC_MAX_INT_LINES 64
diff --git a/arch/arm/plat-mxc/include/mach/mx2_dma.h b/arch/arm/plat-mxc/include/mach/mx2_dma.h
new file mode 100644
index 000000000000..8f5ae658f96b
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx2_dma.h
@@ -0,0 +1,261 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_MX2_H__
+#define __ASM_ARCH_MXC_MX2_H__
+
+/*!
+ * @defgroup DMA_MX27 DMA driver for i.MX27
+ */
+
+/*!
+ *@file arch-mxc/mx2_dma.h
+ *@brief DMA driver header file
+ *
+ * @ingroup DMA_MX27
+ *
+ */
+
+#include <mach/hardware.h>
+#include <asm/dma.h>
+#include <stdarg.h>
+
+#define MXC_DMA_INTR_0 32
+
+#define DMA_DCR 0x000 /* 32bit dma control reg */
+#define DMA_DISR 0x004 /* 32bit dma interrupt status reg */
+#define DMA_DIMR 0x008 /* 32bit dma interrupt mask reg */
+#define DMA_DBTOSR 0x00c /* 32bit dma burst timeout stat reg */
+#define DMA_DRTOSR 0x010 /* 32bit dma req timeout status reg */
+#define DMA_DSESR 0x014 /* 32bit dma transfer err status reg */
+#define DMA_DBOSR 0x018 /* 32bit dma buffer overflow stat reg */
+#define DMA_DBTOCR 0x01c /* 32bit dma burst timeout ctrl reg */
+
+#define DMA_WSRA 0x040 /* 32bit dma W-size A reg */
+#define DMA_XSRA 0x044 /* 32bit dma X-size A reg */
+#define DMA_YSRA 0x048 /* 32bit dma Y-size A reg */
+#define DMA_WSRB 0x04C /* 32bit dma W-size B reg */
+#define DMA_XSRB 0x050 /* 32bit dma X-size B reg */
+#define DMA_YSRB 0x054 /* 32bit dma Y-size B reg */
+
+#define DMA_CH_BASE(x) (0x080+0x040*(x))
+
+#define DMA_SAR(x) (DMA_CH_BASE(x)+0x000)
+#define DMA_DAR(x) (DMA_CH_BASE(x)+0x004)
+#define DMA_CNTR(x) (DMA_CH_BASE(x)+0x008)
+#define DMA_CCR(x) (DMA_CH_BASE(x)+0x00C) /* 32bit dma ch0 control reg */
+#define DMA_RSSR(x) (DMA_CH_BASE(x)+0x010) /* 32bit dma ch0 req source sel reg */
+#define DMA_BLR(x) (DMA_CH_BASE(x)+0x014) /* 32bit dma ch0 burst lenght reg */
+#define DMA_RTOR(x) (DMA_CH_BASE(x)+0x018) /* 32bit dma ch0 req time out reg */
+#define DMA_BUCR(x) (DMA_CH_BASE(x)+0x018) /* 32bit dma ch0 bus utilization reg */
+#define DMA_CCNR(x) (DMA_CH_BASE(x)+0x01C) /* 32bit dma ch0 */
+
+#define DMA_TCR 0x480 /*32bit dma test control reg */
+#define DMA_TFIFOA 0x484 /* 32bit dma test fifo A reg */
+#define DMA_TDRR 0x488 /* 32bit dma test request reg */
+#define DMA_TDIPR 0x48c /* 32bit dma test in progress reg */
+#define DMA_TFIFOB 0x490 /* 32bit dma test fifo B reg */
+
+/*!
+ * This defines maximum DMA address
+ */
+#define MAX_DMA_ADDRESS 0xffffffff
+
+#define MXC_DMA_CHANNELS 16
+#define MAX_DMA_CHANNELS MXC_DMA_CHANNELS
+
+#define MX_DMA_CHANNELS MXC_DMA_CHANNELS
+
+/*!@def DMA_MEM_SIZE_8 DMA access port size, 8 bit*/
+/*!@def DMA_MEM_SIZE_16 DMA access port size, 16 bit*/
+/*!@def DMA_MEM_SIZE_32 DMA access port size, 32 bit*/
+#define DMA_MEM_SIZE_8 0x1
+#define DMA_MEM_SIZE_16 0x2
+#define DMA_MEM_SIZE_32 0x0
+
+/*!@def DMA_TYPE_LINEAR DMA transfer type, linear*/
+/*!@def DMA_TYPE_2D DMA transfer type, 2D*/
+/*!@def DMA_TYPE_FIFO DMA transfer type, FIFO*/
+/*!@def DMA_TYPE_EBE DMA transfer type, end-of-burst enable FIFO*/
+#define DMA_TYPE_LINEAR 0x0
+#define DMA_TYPE_2D 0x01
+#define DMA_TYPE_FIFO 0x2
+#define DMA_TYPE_EBE 0x3
+
+/*!@def DMA_DONE DMA transfer done*/
+/*!@def DMA_BURST_TIMEOUT DMA transfer timeout error*/
+/*!@def DMA_REQUEST_TIMEOUT DMA transfer request timeout error*/
+/*!@def DMA_TRANSFER_ERROR DMA transfer error*/
+/*!@def DMA_BUFFER_OVERFLOW DMA transfer buffer overflow error*/
+#define DMA_DONE 0x1000
+#define DMA_BURST_TIMEOUT 0x1
+#define DMA_REQUEST_TIMEOUT 0x2
+#define DMA_TRANSFER_ERROR 0x4
+#define DMA_BUFFER_OVERFLOW 0x8
+
+/*!@brief DMA control register*/
+typedef struct {
+ volatile u32 CEN:1; /*!< Dma channel enable */
+ volatile u32 FRC:1; /*!< Force a dma cycle bit */
+ volatile u32 RPT:1; /*!< Repeat bit */
+ volatile u32 REN:1; /*!< Request enable bit */
+ volatile u32 SSIZ:2; /*!< Source port size, 2 bit in length */
+ volatile u32 DSIZ:2; /*!< Dest port size, 2 bit in length */
+ volatile u32 MSEL:1; /*!< 2D memory register set bit */
+ volatile u32 MDIR:1; /*!< Transfer direction, inversed or normal */
+ volatile u32 SMOD:2; /*!< Source mode, 2 bit in length */
+ volatile u32 DMOD:2; /*!< Dest mode, 2 bit in length */
+ volatile u32 ACRPT:1; /*!< Auto clear repeat bit */
+ volatile u32 Reserver:17; /*!< Reserved bits */
+
+} dma_regs_control;
+
+#define DMA_CTL_CEN 0x1
+#define DMA_CTL_FRC 0x2
+#define DMA_CTL_RPT 0x4
+#define DMA_CTL_REN 0x8
+
+#define DMA_CTL_MSEL 0x100
+#define DMA_CTL_MDIR 0x200
+#define DMA_CTL_ACRPT 0x4000
+
+#define DMA_CTL_GET_SSIZ(x) (((x)>>4)&0x3)
+#define DMA_CTL_GET_DSIZ(x) (((x)>>6)&0x3)
+#define DMA_CTL_GET_SMOD(x) (((x)>>10)&0x3)
+#define DMA_CTL_GET_DMOD(x) (((x)>>12)&0x3)
+
+#define DMA_CTL_SET_SSIZ(x,value) do{ \
+ (x)&=~(0x3<<4); \
+ (x)|=(value)<<4; \
+ }while(0)
+
+#define DMA_CTL_SET_DSIZ(x,value) do{ \
+ (x)&=~(0x3<<6); \
+ (x)|=(value)<<6; \
+ }while(0)
+
+#define DMA_CTL_SET_SMOD(x,value) do{ \
+ (x)&=~(0x3<<10); \
+ (x)|=(value)<<10; \
+ }while(0)
+
+#define DMA_CTL_SET_DMOD(x,value) do{ \
+ (x)&=~(0x3<<12); \
+ (x)|=(value)<<12; \
+ }while(0)
+
+typedef struct {
+ volatile u32 SourceAddr;
+ volatile u32 DestAddr;
+ volatile u32 Count;
+ volatile u32 Ctl;
+ volatile u32 RequestSource;
+ volatile u32 BurstLength;
+ union {
+ volatile u32 ReqTimeout;
+ volatile u32 BusUtilt;
+ };
+ volatile u32 transferd;
+} dma_regs_t;
+
+#ifndef TRANSFER_32BIT
+/*!
+ * This defines DMA access data size
+ */
+
+#define TRANSFER_8BIT DMA_MEM_SIZE_8
+#define TRANSFER_16BIT DMA_MEM_SIZE_16
+#define TRANSFER_32BIT DMA_MEM_SIZE_32
+
+#endif
+
+/*!
+ * This defines maximum device name length passed during mxc_request_dma().
+ */
+#define MAX_DEVNAME_LENGTH 32
+#define MAX_BD_SIZE 32
+
+/*!
+ * Structure containing dma channel parameters.
+ */
+typedef struct {
+ unsigned long dma_chan; /*!< the dma channel information: dynamic or channel number */
+ u32 mode:1; /*!< the initialized dma mode, 0 for dma read, 1 for dma write */
+ u32 rto_en:1; /*!< enable request-timeout. It is valid when REN=1 */
+ u32 dir:1; /*!< Transfer direction, 0 for increment, 1 for decrement */
+ u32 dma_chaining:1; /*!< Autoclear bit for chainbuffer */
+ u32 ren:1; /*!< enable transfer based request signal */
+ u32 M2D_Valid:1; /*!< enable 2D address module. 0 for disable it. 1 for enabled it */
+ u32 msel:1; /*!<2D memory selection, 0 for set A, 1 for set B */
+ u32 burstLength; /*!< Channel burst length */
+ u32 request; /*!< Request source. */
+ u32 busuntils; /*!< when REN=0, Bus utilization, otherwise it it request timeout */
+ u32 sourceType; /*!< Source type, see DMA_TYPE_* */
+ u32 sourcePort; /*!< Source port size, see DMA_MEM_SIZE_* */
+ u32 destType; /*!< Destination type, see DMA_TYPE_* */
+ u32 destPort; /*!< Destination port size, see DMA_MEM_SIZE_* */
+ __u32 per_address; /*< Peripheral source/destination
+ * physical address
+ */
+ u32 W; /*!< 2D Wide-size */
+ u32 X; /*!< 2D X-size */
+ u32 Y; /*!< 2D Y-size */
+} mx2_dma_info_t;
+
+/*!
+ * Structure of dma buffer descriptor
+ */
+typedef struct {
+ unsigned long state; /*!< dma bd state */
+ int mode; /*!< the dma mode of this bd */
+ unsigned long count; /*!< the length of the dma transfer */
+ unsigned long src_addr; /*!< the source address of the dma transfer */
+ unsigned long dst_addr; /*!< the destination address of the dma transfer */
+} mx2_dma_bd_t;
+
+/*!
+ * the states of dma buffer descriptor
+ */
+#define DMA_BD_ST_BUSY 0x20000000 /*!< dma bd is transfering or has be configured into controller */
+#define DMA_BD_ST_PEND 0x10000000 /*!< dma bd is waiting to be configured into controller */
+#define DMA_BD_ST_LAST 0x08000000 /*!< dma bd is the last dma bd which is built in one dma transfer request
+ * When completed this bd, the callback function must be called.
+ */
+
+/*!
+ * This structure containing the private information for MX2
+ */
+typedef struct mx2_dma_priv_s {
+ unsigned int dma_chaining:1; /* 1: using headware dma chaining feature */
+ unsigned int ren:1; /* 1: dma start besed on request signal */
+ unsigned long trans_bytes; /* To store the transfered data bytes in this transfer */
+ mx2_dma_info_t *dma_info; /* To store the pointer for dma parameter for reading and wirting */
+ int bd_rd; /* the read index of bd ring */
+ int bd_wr; /* the write index of bd ring */
+ atomic_t bd_used; /* the valid bd number in bd ring */
+ mx2_dma_bd_t *bd_ring; /* the pointer of bd ring */
+ unsigned long dma_base; /* register base address of this channel */
+ int dma_irq; /* irq number of this channel */
+} mx2_dma_priv_t;
+
+/*!
+ * @brief get the dma info by channel_id
+ */
+extern mx2_dma_info_t *mxc_dma_get_info(mxc_dma_device_t channel_id);
+
+/*!
+ * @brief: scan dma parameter list . And collect information about which channels are dynamic .
+ */
+extern void mxc_dma_load_info(mxc_dma_channel_t * dma);
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/mx31.h b/arch/arm/plat-mxc/include/mach/mx31.h
index 0536f8917bc0..a1053aef07b1 100644
--- a/arch/arm/plat-mxc/include/mach/mx31.h
+++ b/arch/arm/plat-mxc/include/mach/mx31.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
*/
/*
@@ -20,6 +20,36 @@
*/
#define CLOCK_TICK_RATE 16625000
+/*!
+ * Register an interrupt handler for the SMN as well as the SCC. In some
+ * implementations, the SMN is not connected at all, and in others, it is
+ * on the same interrupt line as the SCM. Comment this line out accordingly
+ */
+#define USE_SMN_INTERRUPT
+
+/*
+ * UART Chip level Configuration that a user may not have to edit. These
+ * configuration vary depending on how the UART module is integrated with
+ * the ARM core
+ */
+#define MXC_UART_NR 5
+/*!
+ * 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
+/*!
+ * 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
+
+/*!
+ * This option is used to set or clear the dspdma bit in the SDMA config
+ * register.
+ */
+#define MXC_SDMA_DSPDMA 0
+
/*
* MX31 memory map:
*
@@ -44,32 +74,24 @@
* FC320000 B8000000 64K NAND, SDRAM, WEIM, M3IF, EMI controllers
* C0000000 64M PCMCIA/CF
*/
-
-#define CS0_BASE_ADDR 0xA0000000
-#define CS1_BASE_ADDR 0xA8000000
-#define CS2_BASE_ADDR 0xB0000000
-#define CS3_BASE_ADDR 0xB2000000
-
-#define CS4_BASE_ADDR 0xB4000000
-#define CS4_BASE_ADDR_VIRT 0xF4000000
-#define CS4_SIZE SZ_32M
-
-#define CS5_BASE_ADDR 0xB6000000
-#define PCMCIA_MEM_BASE_ADDR 0xBC000000
-
/*
* IRAM
*/
#define IRAM_BASE_ADDR 0x1FFC0000 /* internal ram */
-#define IRAM_BASE_ADDR_VIRT 0xF8000000
+#define IRAM_BASE_ADDR_VIRT 0xF80C0000
#define IRAM_SIZE SZ_16K
+#define USB_IRAM_BASE_ADDR (IRAM_BASE_ADDR)
+#ifdef CONFIG_USB_STATIC_IRAM
+#define USB_IRAM_SIZE (2*SZ_8K)
+#else
+#define USB_IRAM_SIZE 0
+#endif
+
/*
* L2CC
*/
#define L2CC_BASE_ADDR 0x30000000
-#define L2CC_BASE_ADDR_VIRT 0xF9000000
-#define L2CC_SIZE SZ_1M
/*
* AIPS 1
@@ -120,6 +142,59 @@
#define MSHC2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00024000)
#define SPBA_CTRL_BASE_ADDR (SPBA0_BASE_ADDR + 0x0003C000)
+/*!
+ * defines for SPBA modules
+ */
+#define SPBA_SDHC1 0x04
+#define SPBA_SDHC2 0x08
+#define SPBA_UART3 0x0C
+#define SPBA_CSPI2 0x10
+#define SPBA_SSI2 0x14
+#define SPBA_SIM 0x18
+#define SPBA_IIM 0x1C
+#define SPBA_ATA 0x20
+
+/*!
+ * Defines for modules using static and dynamic DMA channels
+ */
+
+#ifdef CONFIG_SDMA_IRAM
+#define MXC_DMA_CHANNEL_IRAM 30
+#endif /*CONFIG_SDMA_IRAM */
+
+#define MXC_DMA_CHANNEL_UART1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART2_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART2_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART3_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART3_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART4_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART4_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART5_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART5_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_MMC1 MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_MMC2 MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_SSI1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_SSI1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_SSI2_RX MXC_DMA_DYNAMIC_CHANNEL
+
+#ifdef CONFIG_SDMA_IRAM
+#define MXC_DMA_CHANNEL_SSI2_TX (MXC_DMA_CHANNEL_IRAM + 1)
+#else /*CONFIG_SDMA_IRAM */
+#define MXC_DMA_CHANNEL_SSI2_TX MXC_DMA_DYNAMIC_CHANNEL
+#endif /*CONFIG_SDMA_IRAM */
+
+#define MXC_DMA_CHANNEL_FIR_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_FIR_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI2_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI2_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_ATA_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_ATA_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_MEMORY MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_FIFO_MEMORY MXC_DMA_DYNAMIC_CHANNEL
+
/*
* AIPS 2
*/
@@ -140,11 +215,12 @@
#define IPU_CTRL_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C0000)
#define AUDMUX_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C4000)
#define MPEG4_ENC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C8000)
+#define VPU_BASE_ADDR MPEG4_ENC_BASE_ADDR
#define GPIO1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000CC000)
#define GPIO2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D0000)
#define SDMA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D4000)
#define RTC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D8000)
-#define WDOG_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DC000)
+#define WDOG1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DC000)
#define PWM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000E0000)
#define RTIC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000EC000)
@@ -191,6 +267,11 @@
#define CS5_BASE_ADDR 0xB6000000
#define PCMCIA_MEM_BASE_ADDR 0xBC000000
+/*
+ * VL2CC for i.MX32
+ */
+#define VL2CC_BASE_ADDR 0xE0000000
+
/*!
* This macro defines the physical to virtual address mapping for all the
* peripheral modules. It is used by passing in the physical address as x
@@ -198,9 +279,7 @@
* it returns 0xDEADBEEF
*/
#define IO_ADDRESS(x) \
- (void __iomem *) \
(((x >= IRAM_BASE_ADDR) && (x < (IRAM_BASE_ADDR + IRAM_SIZE))) ? IRAM_IO_ADDRESS(x):\
- ((x >= L2CC_BASE_ADDR) && (x < (L2CC_BASE_ADDR + L2CC_SIZE))) ? L2CC_IO_ADDRESS(x):\
((x >= AIPS1_BASE_ADDR) && (x < (AIPS1_BASE_ADDR + AIPS1_SIZE))) ? AIPS1_IO_ADDRESS(x):\
((x >= SPBA0_BASE_ADDR) && (x < (SPBA0_BASE_ADDR + SPBA0_SIZE))) ? SPBA0_IO_ADDRESS(x):\
((x >= AIPS2_BASE_ADDR) && (x < (AIPS2_BASE_ADDR + AIPS2_SIZE))) ? AIPS2_IO_ADDRESS(x):\
@@ -217,9 +296,6 @@
#define IRAM_IO_ADDRESS(x) \
(((x) - IRAM_BASE_ADDR) + IRAM_BASE_ADDR_VIRT)
-#define L2CC_IO_ADDRESS(x) \
- (((x) - L2CC_BASE_ADDR) + L2CC_BASE_ADDR_VIRT)
-
#define AIPS1_IO_ADDRESS(x) \
(((x) - AIPS1_BASE_ADDR) + AIPS1_BASE_ADDR_VIRT)
@@ -244,8 +320,47 @@
#define PCMCIA_IO_ADDRESS(x) \
(((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
-/* Start of physical RAM - On many MX31 platforms, this is the first SDRAM bank (CSD0) */
-#define PHYS_OFFSET CSD0_BASE_ADDR
+/*
+ * DMA request assignments
+ */
+#define DMA_REQ_ECT 31
+#define DMA_REQ_NFC 30
+#define DMA_REQ_SSI1_TX1 29
+#define DMA_REQ_SSI1_RX1 28
+#define DMA_REQ_SSI1_TX2 27
+#define DMA_REQ_SSI1_RX2 26
+#define DMA_REQ_SSI2_TX1 25
+#define DMA_REQ_SSI2_RX1 24
+#define DMA_REQ_SSI2_TX2 23
+#define DMA_REQ_SSI2_RX2 22
+#define DMA_REQ_SDHC2 21
+#define DMA_REQ_SDHC1 20
+#define DMA_REQ_UART1_TX 19
+#define DMA_REQ_UART1_RX 18
+#define DMA_REQ_FIRI_TX 17
+#define DMA_REQ_FIRI_RX 16
+#define DMA_REQ_UART2_TX 17
+#define DMA_REQ_UART2_RX 16
+#define DMA_REQ_EXTREQ1 15
+#define DMA_REQ_EXTREQ2 14
+#define DMA_REQ_UART4_TX 13
+#define DMA_REQ_UART4_RX 12
+#define DMA_REQ_CSPI3_TX 11
+#define DMA_REQ_CSPI3_RX 10
+#define DMA_REQ_UART5_TX 11
+#define DMA_REQ_UART5_RX 10
+#define DMA_REQ_CSPI1_TX 9
+#define DMA_REQ_CSPI1_RX 8
+#define DMA_REQ_UART3_TX 9
+#define DMA_REQ_UART3_RX 8
+#define DMA_REQ_CSPI2_TX 7
+#define DMA_REQ_CSPI2_RX 6
+#define DMA_REQ_SIM 5
+#define DMA_REQ_ATA_RX 4
+#define DMA_REQ_ATA_TX 3
+#define DMA_REQ_ATA_TX_END 2
+#define DMA_REQ_CCM 1
+#define DMA_REQ_EXTREQ0 0
/*
* Interrupt numbers
@@ -255,7 +370,7 @@
#define MXC_INT_CS8900A 2
#define MXC_INT_I2C3 3
#define MXC_INT_I2C2 4
-#define MXC_INT_MPEG4_ENCODER 5
+#define MXC_INT_MPEG4_ENC 5
#define MXC_INT_RTIC 6
#define MXC_INT_FIRI 7
#define MXC_INT_MMC_SDHC2 8
@@ -267,12 +382,13 @@
#define MXC_INT_CSPI1 14
#define MXC_INT_ATA 15
#define MXC_INT_MBX 16
+#define MXC_INT_VPU MXC_INT_MBX
#define MXC_INT_CSPI3 17
#define MXC_INT_UART3 18
#define MXC_INT_IIM 19
#define MXC_INT_SIM2 20
#define MXC_INT_SIM1 21
-#define MXC_INT_RNGA 22
+#define MXC_INT_RNG 22
#define MXC_INT_EVTMON 23
#define MXC_INT_KPP 24
#define MXC_INT_RTC 25
@@ -281,7 +397,7 @@
#define MXC_INT_EPIT1 28
#define MXC_INT_GPT 29
#define MXC_INT_RESV30 30
-#define MXC_INT_RESV31 31
+#define MXC_INT_DVFS 31
#define MXC_INT_UART2 32
#define MXC_INT_NANDFC 33
#define MXC_INT_SDMA 34
@@ -318,10 +434,11 @@
#define MXC_MAX_INT_LINES 64
#define MXC_GPIO_INT_BASE MXC_MAX_INT_LINES
-#define MXC_MAX_GPIO_LINES (GPIO_NUM_PIN * GPIO_PORT_NUM)
-#define MXC_MAX_VIRTUAL_INTS 16
-#define NR_IRQS (MXC_MAX_INT_LINES + MXC_MAX_GPIO_LINES + MXC_MAX_VIRTUAL_INTS)
+/*!
+ * Interrupt Number for ARM11 PMU
+ */
+#define ARM11_PMU_IRQ MXC_INT_EVTMON
/*!
* Number of GPIO port as defined in the IC Spec
@@ -332,54 +449,12 @@
*/
#define GPIO_NUM_PIN 32
-#define PROD_SIGNATURE 0x1 /* For MX31 */
-
-/* silicon revisions specific to i.MX31 */
-#define CHIP_REV_1_0 0x10
-#define CHIP_REV_1_1 0x11
-#define CHIP_REV_1_2 0x12
-#define CHIP_REV_1_3 0x13
-#define CHIP_REV_2_0 0x20
-#define CHIP_REV_2_1 0x21
-#define CHIP_REV_2_2 0x22
-#define CHIP_REV_2_3 0x23
-#define CHIP_REV_3_0 0x30
-#define CHIP_REV_3_1 0x31
-#define CHIP_REV_3_2 0x32
-
-#define SYSTEM_REV_MIN CHIP_REV_1_0
-#define SYSTEM_REV_NUM 3
-
-/* gpio and gpio based interrupt handling */
-#define GPIO_DR 0x00
-#define GPIO_GDIR 0x04
-#define GPIO_PSR 0x08
-#define GPIO_ICR1 0x0C
-#define GPIO_ICR2 0x10
-#define GPIO_IMR 0x14
-#define GPIO_ISR 0x18
-#define GPIO_INT_LOW_LEV 0x0
-#define GPIO_INT_HIGH_LEV 0x1
-#define GPIO_INT_RISE_EDGE 0x2
-#define GPIO_INT_FALL_EDGE 0x3
-#define GPIO_INT_NONE 0x4
-
-/* Mandatory defines used globally */
-
-/* this CPU supports up to 96 GPIOs */
-#define ARCH_NR_GPIOS 96
-
-#if !defined(__ASSEMBLY__) && !defined(__MXC_BOOT_UNCOMPRESS)
-
-/* this is a i.MX31 CPU */
-#define cpu_is_mx31() (1)
-
-extern unsigned int system_rev;
-
-static inline int mx31_revision(void)
-{
- return system_rev;
-}
-#endif
+/*!
+ * NFMS bit in RCSR register for pagesize of nandflash
+ */
+#define NFMS (*((volatile u32 *)IO_ADDRESS(CCM_BASE_ADDR+0xc)))
+#define NFMS_BIT 30
+#define NFMS_NF_DWIDTH 31
+#define NFMS_NF_PG_SZ 30
#endif /* __ASM_ARCH_MXC_MX31_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx35.h b/arch/arm/plat-mxc/include/mach/mx35.h
new file mode 100644
index 000000000000..9a26edbfc8b5
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx35.h
@@ -0,0 +1,455 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_MXC_MX35_H__
+#define __ASM_ARCH_MXC_MX35_H__
+
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#error "Do not include directly."
+#endif
+
+/*!
+ * @file arch-mxc/mx35.h
+ * @brief This file contains register definitions.
+ *
+ * @ingroup MSL_MX35
+ */
+/*!
+ * defines the OS clock tick rate
+ */
+#define CLOCK_TICK_RATE 16625000
+
+/*!
+ * Register an interrupt handler for the SMN as well as the SCC. In some
+ * implementations, the SMN is not connected at all, and in others, it is
+ * on the same interrupt line as the SCM. Comment this line out accordingly
+ */
+#define USE_SMN_INTERRUPT
+
+/*
+ * UART Chip level Configuration that a user may not have to edit. These
+ * configuration vary depending on how the UART module is integrated with
+ * the ARM core
+ */
+#define MXC_UART_NR 3
+/*!
+ * 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
+/*!
+ * 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
+
+/*!
+ * This option is used to set or clear the dspdma bit in the SDMA config
+ * register.
+ */
+#define MXC_SDMA_DSPDMA 0
+
+/*!
+ * Define this option to specify we are using the newer SDMA module.
+ */
+#define MXC_SDMA_V2
+
+/*
+ * IRAM
+ */
+#define IRAM_BASE_ADDR 0x10000000 /* internal ram */
+#define IRAM_BASE_ADDR_VIRT 0xF8400000
+#define IRAM_SIZE SZ_128K
+
+#ifndef CONFIG_SDMA_IRAM
+#define CONFIG_SDMA_IRAM_SIZE 0
+#endif
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+#define SND_RAM_SIZE 0x10000
+#else
+#define SND_RAM_SIZE 0
+#endif
+
+#define SND_RAM_BASE_ADDR (IRAM_BASE_ADDR + CONFIG_SDMA_IRAM_SIZE)
+#define MLB_IRAM_ADDR_OFFSET CONFIG_SDMA_IRAM_SIZE + SND_RAM_SIZE
+
+/*
+ * L2CC
+ */
+#define L2CC_BASE_ADDR 0x30000000
+
+/*
+ * AIPS 1
+ */
+#define AIPS1_BASE_ADDR 0x43F00000
+#define AIPS1_BASE_ADDR_VIRT 0xF8500000
+#define AIPS1_SIZE SZ_1M
+
+#define MAX_BASE_ADDR (AIPS1_BASE_ADDR + 0x00004000)
+#define EVTMON_BASE_ADDR (AIPS1_BASE_ADDR + 0x00008000)
+#define CLKCTL_BASE_ADDR (AIPS1_BASE_ADDR + 0x0000C000)
+#define ETB_SLOT4_BASE_ADDR (AIPS1_BASE_ADDR + 0x00010000)
+#define ETB_SLOT5_BASE_ADDR (AIPS1_BASE_ADDR + 0x00014000)
+#define ECT_CTIO_BASE_ADDR (AIPS1_BASE_ADDR + 0x00018000)
+#define I2C_BASE_ADDR (AIPS1_BASE_ADDR + 0x00080000)
+#define I2C3_BASE_ADDR (AIPS1_BASE_ADDR + 0x00084000)
+#define UART1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00090000)
+#define UART2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00094000)
+#define I2C2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00098000)
+#define OWIRE_BASE_ADDR (AIPS1_BASE_ADDR + 0x0009C000)
+#define SSI1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A0000)
+#define CSPI1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A4000)
+#define KPP_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A8000)
+#define IOMUXC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000AC000)
+#define ECT_IP1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B8000)
+#define ECT_IP2_BASE_ADDR (AIPS1_BASE_ADDR + 0x000BC000)
+
+/*
+ * SPBA global module enabled #0
+ */
+#define SPBA0_BASE_ADDR 0x50000000
+#define SPBA0_BASE_ADDR_VIRT 0xF8600000
+#define SPBA0_SIZE SZ_1M
+
+#define UART3_BASE_ADDR (SPBA0_BASE_ADDR + 0x0000C000)
+#define CSPI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00010000)
+#define SSI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00014000)
+#define ATA_BASE_ADDR (SPBA0_BASE_ADDR + 0x00020000)
+#define ATA_DMA_BASE_ADDR (SPBA0_BASE_ADDR + 0x00020000)
+#define MSHC1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00024000)
+#define SPDIF_BASE_ADDR (SPBA0_BASE_ADDR + 0x00028000)
+#define ASRC_BASE_ADDR (SPBA0_BASE_ADDR + 0x0002C000)
+#define ESAI_BASE_ADDR (SPBA0_BASE_ADDR + 0x00034000)
+#define FEC_BASE_ADDR (SPBA0_BASE_ADDR + 0x00038000)
+#define SPBA_CTRL_BASE_ADDR (SPBA0_BASE_ADDR + 0x0003C000)
+
+/*!
+ * defines for SPBA modules
+ */
+#define SPBA_UART3 0x0C
+#define SPBA_CSPI2 0x10
+#define SPBA_SSI2 0x14
+#define SPBA_ATA 0x20
+#define SPBA_MSHC 0x24
+#define SPBA_SPDIR 0x28
+#define SPBA_ASRC 0x2C
+#define SPBA_ESAI 0x34
+#define SPBA_FEC 0x38
+
+/*!
+ * Defines for modules using static and dynamic DMA channels
+ */
+#define MXC_DMA_CHANNEL_IRAM 30
+#define MXC_DMA_CHANNEL_UART1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART2_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART2_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART3_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART3_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_MMC1 MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_MMC2 MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_MMC3 MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_SSI1_RX MXC_DMA_DYNAMIC_CHANNEL
+#ifdef CONFIG_SDMA_IRAM
+#define MXC_DMA_CHANNEL_SSI1_TX (MXC_DMA_CHANNEL_IRAM + 1)
+#else
+#define MXC_DMA_CHANNEL_SSI1_TX MXC_DMA_DYNAMIC_CHANNEL
+#endif
+#define MXC_DMA_CHANNEL_SSI2_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_SSI2_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI2_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI2_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_ATA_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_ATA_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_MEMORY MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_SPDIF_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_SPDIF_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_ASRCA_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_ASRCA_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_ASRCB_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_ASRCB_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_ASRCC_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_ASRCC_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_ESAI_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_ESAI_TX MXC_DMA_DYNAMIC_CHANNEL
+
+/*
+ * AIPS 2
+ */
+#define AIPS2_BASE_ADDR 0x53F00000
+#define AIPS2_BASE_ADDR_VIRT 0xF8700000
+#define AIPS2_SIZE SZ_1M
+#define CCM_BASE_ADDR (AIPS2_BASE_ADDR + 0x00080000)
+#define GPT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00090000)
+#define EPIT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00094000)
+#define EPIT2_BASE_ADDR (AIPS2_BASE_ADDR + 0x00098000)
+#define GPIO3_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A4000)
+#define SCC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AC000)
+#define RNGC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B0000)
+#define MMC_SDHC1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B4000)
+#define MMC_SDHC2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B8000)
+#define MMC_SDHC3_BASE_ADDR (AIPS2_BASE_ADDR + 0x000BC000)
+#define IPU_CTRL_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C0000)
+#define AUDMUX_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C4000)
+#define GPIO1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000CC000)
+#define GPIO2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D0000)
+#define SDMA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D4000)
+#define RTC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D8000)
+#define WDOG1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DC000)
+#define PWM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000E0000)
+#define CAN1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000E4000)
+#define CAN2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000E8000)
+#define RTIC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000EC000)
+#define IIM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000F0000)
+#define OTG_BASE_ADDR (AIPS2_BASE_ADDR + 0x000F4000)
+#define MLB_BASE_ADDR (AIPS2_BASE_ADDR + 0x000F8000)
+
+/*
+ * ROMP and AVIC
+ */
+#define ROMP_BASE_ADDR 0x60000000
+#define ROMP_BASE_ADDR_VIRT 0xF8800000
+#define ROMP_SIZE SZ_1M
+
+#define AVIC_BASE_ADDR 0x68000000
+#define AVIC_BASE_ADDR_VIRT 0xF8900000
+#define AVIC_SIZE SZ_1M
+
+/*
+ * SDRAM, WEIM, M3IF, EMI controllers
+ */
+#define X_MEMC_BASE_ADDR 0xB8000000
+#define X_MEMC_BASE_ADDR_VIRT 0xF8A00000
+#define X_MEMC_SIZE SZ_1M
+
+#define ESDCTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x1000)
+#define WEIM_BASE_ADDR (X_MEMC_BASE_ADDR + 0x2000)
+#define M3IF_BASE_ADDR (X_MEMC_BASE_ADDR + 0x3000)
+#define EMI_CTL_BASE_ADDR (X_MEMC_BASE_ADDR + 0x4000)
+
+/*
+ * NFC controller
+ */
+#define NFC_BASE_ADDR 0xBB000000
+#define NFC_BASE_ADDR_VIRT 0xF8B00000
+#define NFC_SIZE SZ_1M
+
+/*
+ * Memory regions and CS
+ */
+/* MX35 ADS SDRAM is from 0x80000000, 64M */
+#define IPU_MEM_BASE_ADDR 0x70000000
+#define CSD0_BASE_ADDR 0x80000000
+#define CSD1_BASE_ADDR 0x90000000
+
+#define SDRAM_BASE_ADDR CSD0_BASE_ADDR
+
+#define CS0_BASE_ADDR 0xA0000000
+#define CS1_BASE_ADDR 0xA8000000
+#define CS2_BASE_ADDR 0xB0000000
+#define CS3_BASE_ADDR 0xB2000000
+#define CS4_BASE_ADDR 0xB4000000
+#define CS5_BASE_ADDR 0xB6000000
+
+/*!
+ * This macro defines the physical to virtual address mapping for all the
+ * peripheral modules. It is used by passing in the physical address as x
+ * and returning the virtual address. If the physical address is not mapped,
+ * it returns 0xDEADBEEF
+ */
+#define IO_ADDRESS(x) \
+ (((x >= IRAM_BASE_ADDR) && (x < (IRAM_BASE_ADDR + IRAM_SIZE))) ? IRAM_IO_ADDRESS(x):\
+ ((x >= AIPS1_BASE_ADDR) && (x < (AIPS1_BASE_ADDR + AIPS1_SIZE))) ? AIPS1_IO_ADDRESS(x):\
+ ((x >= SPBA0_BASE_ADDR) && (x < (SPBA0_BASE_ADDR + SPBA0_SIZE))) ? SPBA0_IO_ADDRESS(x):\
+ ((x >= AIPS2_BASE_ADDR) && (x < (AIPS2_BASE_ADDR + AIPS2_SIZE))) ? AIPS2_IO_ADDRESS(x):\
+ ((x >= ROMP_BASE_ADDR) && (x < (ROMP_BASE_ADDR + ROMP_SIZE))) ? ROMP_IO_ADDRESS(x):\
+ ((x >= AVIC_BASE_ADDR) && (x < (AVIC_BASE_ADDR + AVIC_SIZE))) ? AVIC_IO_ADDRESS(x):\
+ ((x >= NFC_BASE_ADDR) && (x < (NFC_BASE_ADDR + NFC_SIZE))) ? NFC_IO_ADDRESS(x):\
+ ((x >= X_MEMC_BASE_ADDR) && (x < (X_MEMC_BASE_ADDR + X_MEMC_SIZE))) ? X_MEMC_IO_ADDRESS(x):\
+ 0xDEADBEEF)
+
+/*
+ * define the address mapping macros: in physical address order
+ */
+
+#define IRAM_IO_ADDRESS(x) \
+ (((x) - IRAM_BASE_ADDR) + IRAM_BASE_ADDR_VIRT)
+
+#define AIPS1_IO_ADDRESS(x) \
+ (((x) - AIPS1_BASE_ADDR) + AIPS1_BASE_ADDR_VIRT)
+
+#define SPBA0_IO_ADDRESS(x) \
+ (((x) - SPBA0_BASE_ADDR) + SPBA0_BASE_ADDR_VIRT)
+
+#define AIPS2_IO_ADDRESS(x) \
+ (((x) - AIPS2_BASE_ADDR) + AIPS2_BASE_ADDR_VIRT)
+
+#define ROMP_IO_ADDRESS(x) \
+ (((x) - ROMP_BASE_ADDR) + ROMP_BASE_ADDR_VIRT)
+
+#define AVIC_IO_ADDRESS(x) \
+ (((x) - AVIC_BASE_ADDR) + AVIC_BASE_ADDR_VIRT)
+
+#define X_MEMC_IO_ADDRESS(x) \
+ (((x) - X_MEMC_BASE_ADDR) + X_MEMC_BASE_ADDR_VIRT)
+
+#define NFC_IO_ADDRESS(x) \
+ (((x) - NFC_BASE_ADDR) + NFC_BASE_ADDR_VIRT)
+
+/*
+ * DMA request assignments
+ */
+#define DMA_REQ_ASRC_DMA6 41
+#define DMA_REQ_ASRC_DMA5 40
+#define DMA_REQ_ASRC_DMA4 39
+#define DMA_REQ_ASRC_DMA3 38
+#define DMA_REQ_ASRC_DMA2 37
+#define DMA_REQ_ASRC_DMA1 36
+#define DMA_REQ_RSVD3 35
+#define DMA_REQ_RSVD2 34
+#define DMA_REQ_ESAI_TX 33
+#define DMA_REQ_ESAI_RX 32
+#define DMA_REQ_ECT 31
+#define DMA_REQ_NFC 30
+#define DMA_REQ_SSI1_TX1 29
+#define DMA_REQ_SSI1_RX1 28
+#define DMA_REQ_SSI1_TX2 27
+#define DMA_REQ_SSI1_RX2 26
+#define DMA_REQ_SSI2_TX1 25
+#define DMA_REQ_SSI2_RX1 24
+#define DMA_REQ_SSI2_TX2 23
+#define DMA_REQ_SSI2_RX2 22
+#define DMA_REQ_IPU 21
+#define DMA_REQ_RSVD1 20
+#define DMA_REQ_UART1_TX 19
+#define DMA_REQ_UART1_RX 18
+#define DMA_REQ_UART2_TX 17
+#define DMA_REQ_UART2_RX 16
+#define DMA_REQ_EXTREQ1 15
+#define DMA_REQ_EXTREQ2 14
+#define DMA_REQ_SPDIF_TX 13
+#define DMA_REQ_SPDIF_RX 12
+#define DMA_REQ_UART3_TX 11
+#define DMA_REQ_UART3_RX 10
+#define DMA_REQ_CSPI1_TX 9
+#define DMA_REQ_CSPI1_RX 8
+#define DMA_REQ_CSPI2_TX 7
+#define DMA_REQ_CSPI2_RX 6
+#define DMA_REQ_MSHC 5
+#define DMA_REQ_ATA_RX 4
+#define DMA_REQ_ATA_TX 3
+#define DMA_REQ_ATA_TX_END 2
+#define DMA_REQ_DPTC 1
+#define DMA_REQ_DVFS 1
+#define DMA_REQ_EXTREQ0 0
+
+/*
+ * Interrupt numbers
+ */
+#define MXC_INT_BASE 0
+#define MXC_INT_RESV0 0
+#define MXC_INT_RESV1 1
+#define MXC_INT_OWIRE 2
+#define MXC_INT_I2C3 3
+#define MXC_INT_I2C2 4
+#define MXC_INT_RESV2 5
+#define MXC_INT_RTIC 6
+#define MXC_INT_MMC_SDHC1 7
+#define MXC_INT_MMC_SDHC2 8
+#define MXC_INT_MMC_SDHC3 9
+#define MXC_INT_I2C 10
+#define MXC_INT_SSI1 11
+#define MXC_INT_SSI2 12
+#define MXC_INT_CSPI2 13
+#define MXC_INT_CSPI1 14
+#define MXC_INT_ATA 15
+#define MXC_INT_GPU2D 16
+#define MXC_INT_ASRC 17
+#define MXC_INT_UART3 18
+#define MXC_INT_IIM 19
+#define MXC_INT_RESV20 20
+#define MXC_INT_RESV21 21
+#define MXC_INT_RNG 22
+#define MXC_INT_EVTMON 23
+#define MXC_INT_KPP 24
+#define MXC_INT_RTC 25
+#define MXC_INT_PWM 26
+#define MXC_INT_EPIT2 27
+#define MXC_INT_EPIT1 28
+#define MXC_INT_GPT 29
+#define MXC_INT_POWERFAIL 30
+#define MXC_INT_CCM 31
+#define MXC_INT_UART2 32
+#define MXC_INT_NANDFC 33
+#define MXC_INT_SDMA 34
+#define MXC_INT_USB_HS 35
+#define MXC_INT_RESV36 36
+#define MXC_INT_USB_OTG 37
+#define MXC_INT_RESV38 38
+#define MXC_INT_MSHC1 39
+#define MXC_INT_ESAI 40
+#define MXC_INT_IPU_ERR 41
+#define MXC_INT_IPU_SYN 42
+#define MXC_INT_CAN1 43
+#define MXC_INT_CAN2 44
+#define MXC_INT_UART1 45
+#define MXC_INT_MLB 46
+#define MXC_INT_SPDIF 47
+#define MXC_INT_ECT 48
+#define MXC_INT_SCC_SCM 49
+#define MXC_INT_SCC_SMN 50
+#define MXC_INT_GPIO2 51
+#define MXC_INT_GPIO1 52
+#define MXC_INT_RESV53 53
+#define MXC_INT_RESV54 54
+#define MXC_INT_WDOG 55
+#define MXC_INT_GPIO3 56
+#define MXC_INT_FEC 57
+#define MXC_INT_EXT_POWER 58
+#define MXC_INT_EXT_TEMPER 59
+#define MXC_INT_EXT_SENSOR60 60
+#define MXC_INT_EXT_SENSOR61 61
+#define MXC_INT_EXT_WDOG 62
+#define MXC_INT_EXT_TV 63
+
+#define MXC_MAX_INT_LINES 64
+
+#define MXC_INT_FORCE MXC_INT_RESV0
+/*!
+ * Interrupt Number for ARM11 PMU
+ */
+#define ARM11_PMU_IRQ MXC_INT_EVTMON
+/* DVFS interrupt*/
+#define MXC_INT_DVFS MXC_INT_CCM
+
+#define MXC_GPIO_INT_BASE (MXC_MAX_INT_LINES)
+
+/*!
+ * Number of GPIO port as defined in the IC Spec
+ */
+#define GPIO_PORT_NUM 3
+/*!
+ * Number of GPIO pins per port
+ */
+#define GPIO_NUM_PIN 32
+
+/*!
+ * NFMS bit in RCSR register for pagesize of nandflash
+ */
+#define NFMS (*((volatile u32 *)IO_ADDRESS(CCM_BASE_ADDR+0x18)))
+#define NFMS_BIT 8
+#define NFMS_NF_DWIDTH 14
+#define NFMS_NF_PG_SZ 8
+
+#endif /* __ASM_ARCH_MXC_MX35_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx37.h b/arch/arm/plat-mxc/include/mach/mx37.h
new file mode 100644
index 000000000000..eb0870ce669d
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx37.h
@@ -0,0 +1,509 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_MXC_MX37_H__
+#define __ASM_ARCH_MXC_MX37_H__
+
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#error "Do not include directly."
+#endif
+
+/*!
+ * @file arch-mxc/mx37.h
+ * @brief This file contains register definitions.
+ *
+ * @ingroup MSL_MX37
+ */
+/*!
+ * defines the hardware clock tick rate
+ */
+
+#define CLOCK_TICK_RATE 8000000
+
+/*!
+ * Register an interrupt handler for the SMN as well as the SCC. In some
+ * implementations, the SMN is not connected at all, and in others, it is
+ * on the same interrupt line as the SCM. Comment this line out accordingly
+ */
+#define USE_SMN_INTERRUPT
+
+/*
+ * UART Chip level Configuration that a user may not have to edit. These
+ * configuration vary depending on how the UART module is integrated with
+ * the ARM core
+ */
+#define MXC_UART_NR 3
+/*!
+ * 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
+/*!
+ * 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
+
+/*!
+ * This option is used to set or clear the dspdma bit in the SDMA config
+ * register.
+ */
+#define MXC_SDMA_DSPDMA 0
+
+/*!
+ * Define this option to specify we are using the newer SDMA module.
+ */
+#define MXC_SDMA_V2
+
+/*
+ * IRAM
+ */
+#define IRAM_BASE_ADDR 0x10000000 /* internal ram */
+#define IRAM_BASE_ADDR_VIRT 0xF8000000
+#define IRAM_SIZE (9*SZ_8K) /* 72KB */
+
+#if defined(CONFIG_MXC_SECURITY_SCC2) \
+ || defined(CONFIG_MXC_SECURITY_SCC2_MODULE)
+#define SCC_IRAM_SIZE SZ_16K
+#else
+#define SCC_IRAM_SIZE 0
+#endif
+
+/*#ifndef CONFIG_SDMA_IRAM
+#define CONFIG_SDMA_IRAM_SIZE 0
+#endif*/
+#ifdef CONFIG_SDMA_IRAM
+#define SDMA_IRAM_SIZE CONFIG_SDMA_IRAM_SIZE
+#else
+#define SDMA_IRAM_SIZE 0
+#endif
+
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+#define SND_RAM_SIZE 0x6000
+#else
+#define SND_RAM_SIZE 0
+#endif
+
+#ifdef CONFIG_USB_STATIC_IRAM
+#define USB_IRAM_SIZE SZ_8K
+#else
+#define USB_IRAM_SIZE 0
+#endif
+
+#if (IRAM_SIZE < (SCC_IRAM_SIZE + SDMA_IRAM_SIZE + SND_RAM_SIZE + \
+ USB_IRAM_SIZE))
+#error "IRAM size exceeded"
+#endif
+
+#ifdef CONFIG_MXC_VPU_IRAM
+#define VPU_IRAM_SIZE (IRAM_BASE_ADDR + IRAM_SIZE - VPU_IRAM_BASE_ADDR)
+#else
+#define VPU_IRAM_SIZE 0
+#endif
+
+#define SCC_IRAM_BASE_ADDR (IRAM_BASE_ADDR + IRAM_SIZE - SCC_IRAM_SIZE)
+#define SDMA_RAM_BASE_ADDR (IRAM_BASE_ADDR)
+#define SND_RAM_BASE_ADDR (IRAM_BASE_ADDR + SDMA_IRAM_SIZE)
+#define USB_IRAM_BASE_ADDR (SND_RAM_BASE_ADDR + SND_RAM_SIZE)
+#define VPU_IRAM_BASE_ADDR (USB_IRAM_BASE_ADDR + USB_IRAM_SIZE)
+
+/*
+ * NFC
+ */
+#define NFC_BASE_ADDR_AXI 0x7FFF0000 /* NAND flash AXI */
+#define NFC_BASE_ADDR_AXI_VIRT 0xF9000000
+#define NFC_AXI_SIZE SZ_64K
+
+/*
+ * L2CC
+ */
+#define L2CC_BASE_ADDR 0xB0000000
+
+#define PLATFORM_BASE_ADDR 0xB0400000
+#define PLATFORM_BASE_ADDR_VIRT 0xFA000000
+#define PLATFORM_SIZE SZ_1M
+#define EVTMON_BASE_ADDR (PLATFORM_BASE_ADDR + 0x00000000)
+#define ARM1176_BASE_ADDR (PLATFORM_BASE_ADDR + 0x00004000)
+
+#define TZIC_BASE_ADDR 0xB0800000
+#define TZIC_BASE_ADDR_VIRT 0xFA100000
+#define TZIC_SIZE SZ_1M
+
+#define DEBUG_BASE_ADDR 0xB0C00000
+#define DEBUG_BASE_ADDR_VIRT 0xFA200000
+#define DEBUG_SIZE SZ_1M
+#define ETB_BASE_ADDR (DEBUG_BASE_ADDR + 0x00001000)
+#define ETM_BASE_ADDR (DEBUG_BASE_ADDR + 0x00002000)
+#define TPIU_BASE_ADDR (DEBUG_BASE_ADDR + 0x00003000)
+#define CTI0_BASE_ADDR (DEBUG_BASE_ADDR + 0x00004000)
+#define CTI1_BASE_ADDR (DEBUG_BASE_ADDR + 0x00005000)
+#define CTI2_BASE_ADDR (DEBUG_BASE_ADDR + 0x00006000)
+
+/*
+ * AIPS 1
+ */
+#define AIPS1_BASE_ADDR 0xC3F00000
+#define AIPS1_BASE_ADDR_VIRT 0xFC000000
+#define AIPS1_SIZE SZ_1M
+
+#define MAX_BASE_ADDR (AIPS1_BASE_ADDR + 0x00080000)
+#define GPIO1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00084000)
+#define GPIO2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00088000)
+#define GPIO3_BASE_ADDR (AIPS1_BASE_ADDR + 0x0008C000)
+#define KPP_BASE_ADDR (AIPS1_BASE_ADDR + 0x00094000)
+#define WDOG1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00098000)
+#define WDOG2_BASE_ADDR (AIPS1_BASE_ADDR + 0x0009C000)
+#define GPT1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A0000)
+#define SRTC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A4000)
+#define IOMUXC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A8000)
+#define IIM_BASE_ADDR (AIPS1_BASE_ADDR + 0x000AC000)
+#define CSU_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B0000)
+#define SDMA_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B4000)
+#define SCC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000BC000)
+#define ROMCP_BASE_ADDR (AIPS1_BASE_ADDR + 0x000C0000)
+#define RTIC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000C4000)
+#define VPU_BASE_ADDR (AIPS1_BASE_ADDR + 0x000D0000)
+#define OTG_BASE_ADDR (AIPS1_BASE_ADDR + 0x000D4000)
+#define ATA_BASE_ADDR (AIPS1_BASE_ADDR + 0x000D8000)
+#define MSHC1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000E0000)
+#define FEC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000E8000)
+#define RNGC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000EC000)
+#define TVE_BASE_ADDR (AIPS1_BASE_ADDR + 0x000F0000)
+
+/*
+ * SPBA global module enabled #0
+ */
+#define SPBA0_BASE_ADDR 0xC0000000
+#define SPBA0_BASE_ADDR_VIRT 0xFC100000
+#define SPBA0_SIZE SZ_1M
+
+#define MMC_SDHC1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00004000)
+#define MMC_SDHC2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00008000)
+#define UART3_BASE_ADDR (SPBA0_BASE_ADDR + 0x0000C000)
+#define CSPI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00010000)
+#define SSI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00014000)
+#define MMC_SDHC3_BASE_ADDR (SPBA0_BASE_ADDR + 0x00020000)
+#define SPDIF_BASE_ADDR (SPBA0_BASE_ADDR + 0x00028000)
+#define ATA_DMA_BASE_ADDR (SPBA0_BASE_ADDR + 0x00034000)
+#define SPBA_CTRL_BASE_ADDR (SPBA0_BASE_ADDR + 0x0003C000)
+
+/*!
+ * defines for SPBA modules
+ */
+#define SPBA_SDHC1 0x04
+#define SPBA_SDHC2 0x08
+#define SPBA_UART3 0x0C
+#define SPBA_CSPI2 0x10
+#define SPBA_SSI2 0x14
+#define SPBA_SDHC3 0x20
+#define SPBA_SPDIF 0x28
+#define SPBA_ATA 0x34
+
+/*!
+ * Defines for modules using static and dynamic DMA channels
+ */
+#define MXC_DMA_CHANNEL_IRAM 30
+#define MXC_DMA_CHANNEL_SPDIF_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART2_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART2_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART3_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART3_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_MMC1 MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_MMC2 MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_SSI1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_SSI1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_SSI2_RX MXC_DMA_DYNAMIC_CHANNEL
+#ifdef CONFIG_SDMA_IRAM
+#define MXC_DMA_CHANNEL_SSI2_TX (MXC_DMA_CHANNEL_IRAM + 1)
+#else /*CONFIG_SDMA_IRAM */
+#define MXC_DMA_CHANNEL_SSI2_TX MXC_DMA_DYNAMIC_CHANNEL
+#endif /*CONFIG_SDMA_IRAM */
+#define MXC_DMA_CHANNEL_CSPI1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI2_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI2_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI3_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI3_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_ATA_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_ATA_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_MEMORY MXC_DMA_DYNAMIC_CHANNEL
+
+/*
+ * AIPS 2
+ */
+#define AIPS2_BASE_ADDR 0xE3F00000
+#define AIPS2_BASE_ADDR_VIRT 0xFC200000
+#define AIPS2_SIZE SZ_1M
+
+#define PLL0_BASE_ADDR (AIPS2_BASE_ADDR + 0x00080000)
+#define PLL1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00084000)
+#define PLL2_BASE_ADDR (AIPS2_BASE_ADDR + 0x00088000)
+#define CCM_BASE_ADDR (AIPS2_BASE_ADDR + 0x0008C000)
+#define GPC_BASE_ADDR (AIPS2_BASE_ADDR + 0x00090000)
+#define SRC_BASE_ADDR (AIPS2_BASE_ADDR + 0x00094000)
+#define EPIT1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00098000)
+#define EPIT2_BASE_ADDR (AIPS2_BASE_ADDR + 0x0009C000)
+#define PWM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A0000)
+#define OWIRE_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A4000)
+#define CSPI3_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A8000)
+#define CSPI1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AC000)
+#define UART1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B0000)
+#define UART2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000BC000)
+#define I2C3_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C0000)
+#define I2C2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C4000)
+#define I2C_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C8000)
+#define SSI1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000CC000)
+#define AUDMUX_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D0000)
+#define EMI_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DBF00)
+
+#define M4IF_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D8000)
+#define ESDCTL_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D9000)
+#define WEIM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DA000)
+#define NFC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DB000)
+
+/*
+ * Memory regions and CS
+ */
+#define IPU_CTRL_BASE_ADDR 0x80000000
+#define CSD0_BASE_ADDR 0x40000000
+#define CSD1_BASE_ADDR 0x50000000
+
+#define CS0_BASE_ADDR 0x60000000
+#define CS1_BASE_ADDR 0x68000000
+#define CS2_BASE_ADDR 0x70000000
+
+/*!
+ * This macro defines the physical to virtual address mapping for all the
+ * peripheral modules. It is used by passing in the physical address as x
+ * and returning the virtual address. If the physical address is not mapped,
+ * it returns 0xDEADBEEF
+ */
+#define IO_ADDRESS(x) \
+ (((x >= (unsigned long)IRAM_BASE_ADDR) && (x < (unsigned long)IRAM_BASE_ADDR + IRAM_SIZE)) ? IRAM_IO_ADDRESS(x):\
+ ((x >= (unsigned long)PLATFORM_BASE_ADDR) && (x < (unsigned long)PLATFORM_BASE_ADDR + PLATFORM_SIZE)) ? PLATFORM_IO_ADDRESS(x):\
+ ((x >= (unsigned long)TZIC_BASE_ADDR) && (x < (unsigned long)TZIC_BASE_ADDR + TZIC_SIZE)) ? TZIC_IO_ADDRESS(x):\
+ ((x >= (unsigned long)DEBUG_BASE_ADDR) && (x < (unsigned long)DEBUG_BASE_ADDR + DEBUG_SIZE)) ? DEBUG_IO_ADDRESS(x):\
+ ((x >= (unsigned long)SPBA0_BASE_ADDR) && (x < (unsigned long)SPBA0_BASE_ADDR + SPBA0_SIZE)) ? SPBA0_IO_ADDRESS(x):\
+ ((x >= (unsigned long)AIPS1_BASE_ADDR) && (x < (unsigned long)AIPS1_BASE_ADDR + AIPS1_SIZE)) ? AIPS1_IO_ADDRESS(x):\
+ ((x >= (unsigned long)AIPS2_BASE_ADDR) && (x < (unsigned long)AIPS2_BASE_ADDR + AIPS2_SIZE)) ? AIPS2_IO_ADDRESS(x):\
+ ((x >= (unsigned long)NFC_BASE_ADDR_AXI) && (x < (unsigned long)NFC_BASE_ADDR_AXI + NFC_AXI_SIZE)) ? NFC_BASE_ADDR_AXI_IO_ADDRESS(x):\
+ 0xDEADBEEF)
+
+/*
+ * define the address mapping macros: in physical address order
+ */
+
+#define IRAM_IO_ADDRESS(x) \
+ (((x) - IRAM_BASE_ADDR) + IRAM_BASE_ADDR_VIRT)
+
+#define PLATFORM_IO_ADDRESS(x) \
+ (((x) - PLATFORM_BASE_ADDR) + PLATFORM_BASE_ADDR_VIRT)
+
+#define TZIC_IO_ADDRESS(x) \
+ (((x) - TZIC_BASE_ADDR) + TZIC_BASE_ADDR_VIRT)
+
+#define DEBUG_IO_ADDRESS(x) \
+ (((x) - DEBUG_BASE_ADDR) + DEBUG_BASE_ADDR_VIRT)
+
+#define SPBA0_IO_ADDRESS(x) \
+ (((x) - SPBA0_BASE_ADDR) + SPBA0_BASE_ADDR_VIRT)
+
+#define AIPS1_IO_ADDRESS(x) \
+ (((x) - AIPS1_BASE_ADDR) + AIPS1_BASE_ADDR_VIRT)
+
+#define AIPS2_IO_ADDRESS(x) \
+ (((x) - AIPS2_BASE_ADDR) + AIPS2_BASE_ADDR_VIRT)
+
+#define NFC_BASE_ADDR_AXI_IO_ADDRESS(x) \
+ (((x) - NFC_BASE_ADDR_AXI) + NFC_BASE_ADDR_AXI_VIRT)
+
+#define IS_MEM_DEVICE_NONSHARED(x) ((x) >= 0x80000000)
+
+/*
+ * DMA request assignments
+ */
+#define DMA_REQ_RESV47 47
+#define DMA_REQ_VPU 46
+#define DMA_REQ_SPDIF_TX 45
+#define DMA_REQ_UART3_TX 44
+#define DMA_REQ_UART3_RX 43
+#define DMA_REQ_I2C2 42
+#define DMA_REQ_I2C1 41
+#define DMA_REQ_SDHC3 40
+#define DMA_REQ_CSPI3_TX 39
+#define DMA_REQ_CSPI3_RX 38
+#define DMA_REQ_RESV37 37
+#define DMA_REQ_IPU 36
+#define DMA_REQ_RESV35 35
+#define DMA_REQ_EPIT2 34
+#define DMA_REQ_RESV33 33
+#define DMA_REQ_RESV32 32
+#define DMA_REQ_ECT 31
+#define DMA_REQ_NFC 30
+#define DMA_REQ_SSI1_TX1 29
+#define DMA_REQ_SSI1_RX1 28
+#define DMA_REQ_SSI1_TX2 27
+#define DMA_REQ_SSI1_RX2 26
+#define DMA_REQ_SSI2_TX1 25
+#define DMA_REQ_SSI2_RX1 24
+#define DMA_REQ_SSI2_TX2 23
+#define DMA_REQ_SSI2_RX2 22
+#define DMA_REQ_SDHC2 21
+#define DMA_REQ_SDHC1 20
+#define DMA_REQ_UART1_TX 19
+#define DMA_REQ_UART1_RX 18
+#define DMA_REQ_UART2_TX 17
+#define DMA_REQ_UART2_RX 16
+#define DMA_REQ_GPIO1_0 15
+#define DMA_REQ_GPIO1_1 14
+#define DMA_REQ_RESV13 13
+#define DMA_REQ_RESV12 12
+#define DMA_REQ_RESV11 11
+#define DMA_REQ_RESV10 10
+#define DMA_REQ_CSPI1_TX 9
+#define DMA_REQ_CSPI1_RX 8
+#define DMA_REQ_CSPI2_TX 7
+#define DMA_REQ_CSPI2_RX 6
+#define DMA_REQ_RESV5 5
+#define DMA_REQ_ATA_TX_END 4
+#define DMA_REQ_ATA_TX 3
+#define DMA_REQ_ATA_RX 2
+#define DMA_REQ_GPC 1
+#define DMA_REQ_RESV0 0
+
+/*
+ * Interrupt numbers
+ */
+#define MXC_INT_BASE 0
+#define MXC_INT_RESV0 0
+#define MXC_INT_MMC_SDHC1 1
+#define MXC_INT_MMC_SDHC2 2
+#define MXC_INT_MMC_SDHC3 3
+#define MXC_INT_RESV4 4
+#define MXC_INT_RESV5 5
+#define MXC_INT_SDMA 6
+#define MXC_INT_IOMUX 7
+#define MXC_INT_RESV8 8
+#define MXC_INT_VPU 9
+#define MXC_INT_IPU_ERR 10
+#define MXC_INT_IPU_SYN 11
+#define MXC_INT_RESV12 12
+#define MXC_INT_RESV13 13
+#define MXC_INT_RNG 14
+#define MXC_INT_EMI 15
+#define MXC_INT_RESV16 16
+#define MXC_INT_RESV17 17
+#define MXC_INT_USB_OTG 18
+#define MXC_INT_RESV19 19
+#define MXC_INT_RESV20 20
+#define MXC_INT_SCC_SMN 21
+#define MXC_INT_SCC_STZ 22
+#define MXC_INT_SCC_SCM 23
+#define MXC_INT_SRTC_NTZ 24
+#define MXC_INT_SRTC_TZ 25
+#define MXC_INT_RTIC 26
+#define MXC_INT_CSU 27
+#define MXC_INT_RESV28 28
+#define MXC_INT_SSI1 29
+#define MXC_INT_SSI2 30
+#define MXC_INT_UART1 31
+#define MXC_INT_UART2 32
+#define MXC_INT_UART3 33
+#define MXC_INT_RESV34 34
+#define MXC_INT_RESV35 35
+#define MXC_INT_CSPI1 36
+#define MXC_INT_CSPI2 37
+#define MXC_INT_CSPI3 38
+#define MXC_INT_GPT 39
+#define MXC_INT_EPIT1 40
+#define MXC_INT_EPIT2 41
+#define MXC_INT_GPIO1_INT7 42
+#define MXC_INT_GPIO1_INT6 43
+#define MXC_INT_GPIO1_INT5 44
+#define MXC_INT_GPIO1_INT4 45
+#define MXC_INT_GPIO1_INT3 46
+#define MXC_INT_GPIO1_INT2 47
+#define MXC_INT_GPIO1_INT1 48
+#define MXC_INT_GPIO1_INT0 49
+#define MXC_INT_GPIO1_LOW 50
+#define MXC_INT_GPIO1_HIGH 51
+#define MXC_INT_GPIO2_LOW 52
+#define MXC_INT_GPIO2_HIGH 53
+#define MXC_INT_GPIO3_LOW 54
+#define MXC_INT_GPIO3_HIGH 55
+#define MXC_INT_RESV56 56
+#define MXC_INT_RESV57 57
+#define MXC_INT_WDOG1 58
+#define MXC_INT_WDOG2 59
+#define MXC_INT_KPP 60
+#define MXC_INT_PWM 61
+#define MXC_INT_I2C 62
+#define MXC_INT_I2C2 63
+#define MXC_INT_I2C3 64
+#define MXC_INT_MSHC1 65
+#define MXC_INT_RESV66 66
+#define MXC_INT_RESV67 67
+#define MXC_INT_RESV68 68
+#define MXC_INT_IIM 69
+#define MXC_INT_ATA 70
+#define MXC_INT_CCM1 71
+#define MXC_INT_CCM2 72
+#define MXC_INT_GPC1 73
+#define MXC_INT_GPC2 74
+#define MXC_INT_SRC 75
+#define MXC_INT_EVTMON 76
+#define MXC_INT_PER_MEASURE 77
+#define MXC_INT_DECODE_ERR 78
+#define MXC_INT_EVT_COUNT 79
+#define MXC_INT_SLAVE_ERR 80
+#define MXC_INT_RESV81 81
+#define MXC_INT_RESV82 82
+#define MXC_INT_RESV83 83
+#define MXC_INT_RESV84 84
+#define MXC_INT_RESV85 85
+#define MXC_INT_RESV86 86
+#define MXC_INT_FEC 87
+#define MXC_INT_OWIRE 88
+#define MXC_INT_CTI0 89
+#define MXC_INT_CTM0 90
+#define MXC_INT_SPDIF 91
+#define MXC_INT_TVOUT 92
+
+#define MXC_MAX_INT_LINES 128
+
+/*!
+ * Interrupt Number for ARM11 PMU
+ */
+#define ARM11_PMU_IRQ MXC_INT_EVTMON
+
+#define MXC_GPIO_INT_BASE (MXC_MAX_INT_LINES)
+
+/*!
+ * Number of GPIO port as defined in the IC Spec
+ */
+#define GPIO_PORT_NUM 3
+/*!
+ * Number of GPIO pins per port
+ */
+#define GPIO_NUM_PIN 32
+
+#define MXC_GPIO_SPLIT_IRQ_2
+
+/*!
+ * Macro to convert elv, llv, ulv to a data which is used to set DCVR0, DCVR1,
+ * DCVR2, or DCVR3.
+ */
+#define DCVR(elv, llv, ulv) ((elv << 0) | (llv << 10) | (ulv << 21))
+
+#endif /* __ASM_ARCH_MXC_MX37_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mx51.h b/arch/arm/plat-mxc/include/mach/mx51.h
new file mode 100644
index 000000000000..eba247830c15
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mx51.h
@@ -0,0 +1,520 @@
+/*
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_MX51_H__
+#define __ASM_ARCH_MXC_MX51_H__
+
+#ifndef __ASM_ARCH_MXC_HARDWARE_H__
+#error "Do not include directly."
+#endif
+
+/*!
+ * @file arch-mxc/mx51.h
+ * @brief This file contains register definitions.
+ *
+ * @ingroup MSL_MX51
+ */
+/*!
+ * defines the hardware clock tick rate
+ */
+#define CLOCK_TICK_RATE 8000000
+
+/*!
+ * Register an interrupt handler for the SMN as well as the SCC. In some
+ * implementations, the SMN is not connected at all, and in others, it is
+ * on the same interrupt line as the SCM. Comment this line out accordingly
+ */
+#define USE_SMN_INTERRUPT
+
+/*
+ * UART Chip level Configuration that a user may not have to edit. These
+ * configuration vary depending on how the UART module is integrated with
+ * the ARM core
+ */
+#define MXC_UART_NR 3
+/*!
+ * 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
+/*!
+ * 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
+
+/*!
+ * This option is used to set or clear the dspdma bit in the SDMA config
+ * register.
+ */
+#define MXC_SDMA_DSPDMA 0
+
+/*!
+ * Define this option to specify we are using the newer SDMA module.
+ */
+#define MXC_SDMA_V2
+
+ /*
+ * IRAM
+ */
+#define IRAM_BASE_ADDR 0x1FFE0000 /* internal ram */
+#define IRAM_BASE_ADDR_VIRT 0xFA3E0000
+#define IRAM_PARTITIONS 16
+#define IRAM_PARTITIONS_TO1 12
+#define IRAM_SIZE (IRAM_PARTITIONS*SZ_8K) /* 128KB */
+
+#if defined(CONFIG_MXC_SECURITY_SCC2) \
+ || defined(CONFIG_MXC_SECURITY_SCC2_MODULE)
+#define SCC_IRAM_SIZE SZ_16K
+#else
+#define SCC_IRAM_SIZE 0
+#endif
+
+#ifdef CONFIG_SDMA_IRAM
+#define SDMA_IRAM_SIZE CONFIG_SDMA_IRAM_SIZE
+#else
+#define SDMA_IRAM_SIZE 0
+#endif
+
+#ifdef CONFIG_SND_MXC_SOC_IRAM
+#define SND_RAM_SIZE 0x6000
+#else
+#define SND_RAM_SIZE 0
+#endif
+
+#ifdef CONFIG_MXC_VPU_IRAM
+#define VPU_IRAM_SIZE 0x7000
+#else
+#define VPU_IRAM_SIZE 0
+#endif
+
+#if (IRAM_SIZE < (SDMA_IRAM_SIZE + SND_RAM_SIZE + VPU_IRAM_SIZE + \
+ SCC_IRAM_SIZE))
+#error "IRAM size exceeded"
+#endif
+
+#define SCC_IRAM_BASE_ADDR (IRAM_BASE_ADDR + IRAM_SIZE - SCC_IRAM_SIZE)
+#define VPU_IRAM_BASE_ADDR (SCC_IRAM_BASE_ADDR - VPU_IRAM_SIZE)
+#define SND_RAM_BASE_ADDR (VPU_IRAM_BASE_ADDR - SND_RAM_SIZE)
+#define SDMA_IRAM_BASE_ADDR (SND_RAM_BASE_ADDR - SDMA_IRAM_SIZE)
+#define IDLE_IRAM_BASE_ADDR (SDMA_IRAM_BASE_ADDR - SZ_4K)
+
+/*
+ * NFC
+ */
+#define NFC_BASE_ADDR_AXI 0xCFFF0000 /* NAND flash AXI */
+#define NFC_BASE_ADDR_AXI_VIRT 0xF9000000
+#define NFC_AXI_SIZE SZ_64K
+
+/*
+ * Graphics Memory of GPU
+ */
+#define GPU_BASE_ADDR 0x20000000
+
+#define TZIC_BASE_ADDR 0x8FFFC000
+#define TZIC_BASE_ADDR_VIRT 0xFA100000
+#define TZIC_SIZE SZ_16K
+
+#define DEBUG_BASE_ADDR 0x60000000
+#define DEBUG_BASE_ADDR_VIRT 0xFA200000
+#define DEBUG_SIZE SZ_1M
+#define ETB_BASE_ADDR (DEBUG_BASE_ADDR + 0x00001000)
+#define ETM_BASE_ADDR (DEBUG_BASE_ADDR + 0x00002000)
+#define TPIU_BASE_ADDR (DEBUG_BASE_ADDR + 0x00003000)
+#define CTI0_BASE_ADDR (DEBUG_BASE_ADDR + 0x00004000)
+#define CTI1_BASE_ADDR (DEBUG_BASE_ADDR + 0x00005000)
+#define CTI2_BASE_ADDR (DEBUG_BASE_ADDR + 0x00006000)
+#define CTI3_BASE_ADDR (DEBUG_BASE_ADDR + 0x00007000)
+#define CORTEX_DBG_BASE_ADDR (DEBUG_BASE_ADDR + 0x00008000)
+
+/*
+ * SPBA global module enabled #0
+ */
+#define SPBA0_BASE_ADDR 0x70000000
+#define SPBA0_BASE_ADDR_VIRT 0xFB100000
+#define SPBA0_SIZE SZ_1M
+
+#define MMC_SDHC1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00004000)
+#define MMC_SDHC2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00008000)
+#define UART3_BASE_ADDR (SPBA0_BASE_ADDR + 0x0000C000)
+#define CSPI1_BASE_ADDR (SPBA0_BASE_ADDR + 0x00010000)
+#define SSI2_BASE_ADDR (SPBA0_BASE_ADDR + 0x00014000)
+#define MMC_SDHC3_BASE_ADDR (SPBA0_BASE_ADDR + 0x00020000)
+#define MMC_SDHC4_BASE_ADDR (SPBA0_BASE_ADDR + 0x00024000)
+#define SPDIF_BASE_ADDR (SPBA0_BASE_ADDR + 0x00028000)
+#define ATA_DMA_BASE_ADDR (SPBA0_BASE_ADDR + 0x00030000)
+#define SLIM_DMA_BASE_ADDR (SPBA0_BASE_ADDR + 0x00034000)
+#define HSI2C_DMA_BASE_ADDR (SPBA0_BASE_ADDR + 0x00038000)
+#define SPBA_CTRL_BASE_ADDR (SPBA0_BASE_ADDR + 0x0003C000)
+
+/*!
+ * defines for SPBA modules
+ */
+#define SPBA_SDHC1 0x04
+#define SPBA_SDHC2 0x08
+#define SPBA_UART3 0x0C
+#define SPBA_CSPI1 0x10
+#define SPBA_SSI2 0x14
+#define SPBA_SDHC3 0x20
+#define SPBA_SDHC4 0x24
+#define SPBA_SPDIF 0x28
+#define SPBA_ATA 0x30
+#define SPBA_SLIM 0x34
+#define SPBA_HSI2C 0x38
+#define SPBA_CTRL 0x3C
+
+/*
+ * AIPS 1
+ */
+#define AIPS1_BASE_ADDR 0x73F00000
+#define AIPS1_BASE_ADDR_VIRT 0xFB000000
+#define AIPS1_SIZE SZ_1M
+
+#define OTG_BASE_ADDR (AIPS1_BASE_ADDR + 0x00080000)
+#define GPIO1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00084000)
+#define GPIO2_BASE_ADDR (AIPS1_BASE_ADDR + 0x00088000)
+#define GPIO3_BASE_ADDR (AIPS1_BASE_ADDR + 0x0008C000)
+#define GPIO4_BASE_ADDR (AIPS1_BASE_ADDR + 0x00090000)
+#define KPP_BASE_ADDR (AIPS1_BASE_ADDR + 0x00094000)
+#define WDOG1_BASE_ADDR (AIPS1_BASE_ADDR + 0x00098000)
+#define WDOG2_BASE_ADDR (AIPS1_BASE_ADDR + 0x0009C000)
+#define GPT1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A0000)
+#define SRTC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A4000)
+#define IOMUXC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000A8000)
+#define EPIT1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000AC000)
+#define EPIT2_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B0000)
+#define PWM1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B4000)
+#define PWM2_BASE_ADDR (AIPS1_BASE_ADDR + 0x000B8000)
+#define UART1_BASE_ADDR (AIPS1_BASE_ADDR + 0x000BC000)
+#define UART2_BASE_ADDR (AIPS1_BASE_ADDR + 0x000C0000)
+#define SRC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000D0000)
+#define CCM_BASE_ADDR (AIPS1_BASE_ADDR + 0x000D4000)
+#define GPC_BASE_ADDR (AIPS1_BASE_ADDR + 0x000D8000)
+
+/*!
+ * Defines for modules using static and dynamic DMA channels
+ */
+#define MXC_DMA_CHANNEL_IRAM 30
+#define MXC_DMA_CHANNEL_SPDIF_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART2_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART2_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART3_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_UART3_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_MMC1 MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_MMC2 MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_SSI1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_SSI1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_SSI2_RX MXC_DMA_DYNAMIC_CHANNEL
+#ifdef CONFIG_SDMA_IRAM
+#define MXC_DMA_CHANNEL_SSI2_TX (MXC_DMA_CHANNEL_IRAM + 1)
+#else /*CONFIG_SDMA_IRAM */
+#define MXC_DMA_CHANNEL_SSI2_TX MXC_DMA_DYNAMIC_CHANNEL
+#endif /*CONFIG_SDMA_IRAM */
+#define MXC_DMA_CHANNEL_CSPI1_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI1_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI2_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI2_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI3_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_CSPI3_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_ATA_RX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_ATA_TX MXC_DMA_DYNAMIC_CHANNEL
+#define MXC_DMA_CHANNEL_MEMORY MXC_DMA_DYNAMIC_CHANNEL
+
+/*
+ * AIPS 2
+ */
+#define AIPS2_BASE_ADDR 0x83F00000
+#define AIPS2_BASE_ADDR_VIRT 0xFB200000
+#define AIPS2_SIZE SZ_1M
+
+#define PLL1_BASE_ADDR (AIPS2_BASE_ADDR + 0x00080000)
+#define PLL2_BASE_ADDR (AIPS2_BASE_ADDR + 0x00084000)
+#define PLL3_BASE_ADDR (AIPS2_BASE_ADDR + 0x00088000)
+#define AHBMAX_BASE_ADDR (AIPS2_BASE_ADDR + 0x00094000)
+#define IIM_BASE_ADDR (AIPS2_BASE_ADDR + 0x00098000)
+#define CSU_BASE_ADDR (AIPS2_BASE_ADDR + 0x0009C000)
+#define ARM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A0000)
+#define OWIRE_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A4000)
+#define FIRI_BASE_ADDR (AIPS2_BASE_ADDR + 0x000A8000)
+#define CSPI2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000AC000)
+#define SDMA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B0000)
+#define SCC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B4000)
+#define ROMCP_BASE_ADDR (AIPS2_BASE_ADDR + 0x000B8000)
+#define RTIC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000BC000)
+#define CSPI3_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C0000)
+#define I2C2_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C4000)
+#define I2C1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000C8000)
+#define SSI1_BASE_ADDR (AIPS2_BASE_ADDR + 0x000CC000)
+#define AUDMUX_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D0000)
+#define M4IF_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D8000)
+#define ESDCTL_BASE_ADDR (AIPS2_BASE_ADDR + 0x000D9000)
+#define WEIM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DA000)
+#define NFC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DB000)
+#define EMI_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DBF00)
+#define MIPI_HSC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000DC000)
+#define ATA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000E0000)
+#define SIM_BASE_ADDR (AIPS2_BASE_ADDR + 0x000E4000)
+#define SSI3BASE_ADDR (AIPS2_BASE_ADDR + 0x000E8000)
+#define FEC_BASE_ADDR (AIPS2_BASE_ADDR + 0x000EC000)
+#define TVE_BASE_ADDR (AIPS2_BASE_ADDR + 0x000F0000)
+#define VPU_BASE_ADDR (AIPS2_BASE_ADDR + 0x000F4000)
+#define SAHARA_BASE_ADDR (AIPS2_BASE_ADDR + 0x000F8000)
+
+/*
+ * Memory regions and CS
+ */
+#define GPU_CTRL_BASE_ADDR 0x30000000
+#define IPU_CTRL_BASE_ADDR 0x40000000
+#define CSD0_BASE_ADDR 0x90000000
+#define CSD1_BASE_ADDR 0xA0000000
+#define CS0_BASE_ADDR 0xB0000000
+#define CS1_BASE_ADDR 0xB8000000
+#define CS2_BASE_ADDR 0xC0000000
+#define CS3_BASE_ADDR 0xC8000000
+#define CS4_BASE_ADDR 0xCC000000
+#define CS5_BASE_ADDR 0xCE000000
+
+/*!
+ * This macro defines the physical to virtual address mapping for all the
+ * peripheral modules. It is used by passing in the physical address as x
+ * and returning the virtual address. If the physical address is not mapped,
+ * it returns 0xDEADBEEF
+ */
+#define IO_ADDRESS(x) \
+ ((((x) >= (unsigned long)IRAM_BASE_ADDR) && \
+ ((x) < (unsigned long)IRAM_BASE_ADDR + IRAM_SIZE)) ? \
+ IRAM_IO_ADDRESS(x):\
+ (((x) >= (unsigned long)TZIC_BASE_ADDR) && \
+ ((x) < (unsigned long)TZIC_BASE_ADDR + TZIC_SIZE)) ? \
+ TZIC_IO_ADDRESS(x):\
+ (((x) >= (unsigned long)DEBUG_BASE_ADDR) && \
+ ((x) < (unsigned long)DEBUG_BASE_ADDR + DEBUG_SIZE)) ? \
+ DEBUG_IO_ADDRESS(x):\
+ (((x) >= (unsigned long)SPBA0_BASE_ADDR) && \
+ ((x) < (unsigned long)SPBA0_BASE_ADDR + SPBA0_SIZE)) ? \
+ SPBA0_IO_ADDRESS(x):\
+ (((x) >= (unsigned long)AIPS1_BASE_ADDR) && \
+ ((x) < (unsigned long)AIPS1_BASE_ADDR + AIPS1_SIZE)) ? \
+ AIPS1_IO_ADDRESS(x):\
+ (((x) >= (unsigned long)AIPS2_BASE_ADDR) && \
+ ((x) < (unsigned long)AIPS2_BASE_ADDR + AIPS2_SIZE)) ? \
+ AIPS2_IO_ADDRESS(x):\
+ (((x) >= (unsigned long)NFC_BASE_ADDR_AXI) && \
+ ((x) < (unsigned long)NFC_BASE_ADDR_AXI + NFC_AXI_SIZE)) ? \
+ NFC_BASE_ADDR_AXI_IO_ADDRESS(x):\
+ 0xDEADBEEF)
+
+/*
+ * define the address mapping macros: in physical address order
+ */
+#define IRAM_IO_ADDRESS(x) \
+ (((x) - IRAM_BASE_ADDR) + IRAM_BASE_ADDR_VIRT)
+
+#define TZIC_IO_ADDRESS(x) \
+ (((x) - TZIC_BASE_ADDR) + TZIC_BASE_ADDR_VIRT)
+
+#define DEBUG_IO_ADDRESS(x) \
+ (((x) - DEBUG_BASE_ADDR) + DEBUG_BASE_ADDR_VIRT)
+
+#define SPBA0_IO_ADDRESS(x) \
+ (((x) - SPBA0_BASE_ADDR) + SPBA0_BASE_ADDR_VIRT)
+
+#define AIPS1_IO_ADDRESS(x) \
+ (((x) - AIPS1_BASE_ADDR) + AIPS1_BASE_ADDR_VIRT)
+
+#define AIPS2_IO_ADDRESS(x) \
+ (((x) - AIPS2_BASE_ADDR) + AIPS2_BASE_ADDR_VIRT)
+
+#define NFC_BASE_ADDR_AXI_IO_ADDRESS(x) \
+ (((x) - NFC_BASE_ADDR_AXI) + NFC_BASE_ADDR_AXI_VIRT)
+
+#define IS_MEM_DEVICE_NONSHARED(x) 0
+
+/*
+ * DMA request assignments
+ */
+#define DMA_REQ_SSI3_TX1 47
+#define DMA_REQ_SSI3_RX1 46
+#define DMA_REQ_SPDIF 45
+#define DMA_REQ_UART3_TX 44
+#define DMA_REQ_UART3_RX 43
+#define DMA_REQ_SLIM_B_TX 42
+#define DMA_REQ_SDHC4 41
+#define DMA_REQ_SDHC3 40
+#define DMA_REQ_CSPI_TX 39
+#define DMA_REQ_CSPI_RX 38
+#define DMA_REQ_SSI3_TX2 37
+#define DMA_REQ_IPU 36
+#define DMA_REQ_SSI3_RX2 35
+#define DMA_REQ_EPIT2 34
+#define DMA_REQ_CTI2_1 33
+#define DMA_REQ_EMI_WR 32
+#define DMA_REQ_CTI2_0 31
+#define DMA_REQ_EMI_RD 30
+#define DMA_REQ_SSI1_TX1 29
+#define DMA_REQ_SSI1_RX1 28
+#define DMA_REQ_SSI1_TX2 27
+#define DMA_REQ_SSI1_RX2 26
+#define DMA_REQ_SSI2_TX1 25
+#define DMA_REQ_SSI2_RX1 24
+#define DMA_REQ_SSI2_TX2 23
+#define DMA_REQ_SSI2_RX2 22
+#define DMA_REQ_SDHC2 21
+#define DMA_REQ_SDHC1 20
+#define DMA_REQ_UART1_TX 19
+#define DMA_REQ_UART1_RX 18
+#define DMA_REQ_UART2_TX 17
+#define DMA_REQ_UART2_RX 16
+#define DMA_REQ_GPU 15
+#define DMA_REQ_EXTREQ1 14
+#define DMA_REQ_FIRI_TX 13
+#define DMA_REQ_FIRI_RX 12
+#define DMA_REQ_HS_I2C_RX 11
+#define DMA_REQ_HS_I2C_TX 10
+#define DMA_REQ_CSPI2_TX 9
+#define DMA_REQ_CSPI2_RX 8
+#define DMA_REQ_CSPI1_TX 7
+#define DMA_REQ_CSPI1_RX 6
+#define DMA_REQ_SLIM_B 5
+#define DMA_REQ_ATA_TX_END 4
+#define DMA_REQ_ATA_TX 3
+#define DMA_REQ_ATA_RX 2
+#define DMA_REQ_GPC 1
+#define DMA_REQ_VPU 0
+
+/*
+ * Interrupt numbers
+ */
+#define MXC_INT_BASE 0
+#define MXC_INT_RESV0 0
+#define MXC_INT_MMC_SDHC1 1
+#define MXC_INT_MMC_SDHC2 2
+#define MXC_INT_MMC_SDHC3 3
+#define MXC_INT_MMC_SDHC4 4
+#define MXC_INT_RESV5 5
+#define MXC_INT_SDMA 6
+#define MXC_INT_IOMUX 7
+#define MXC_INT_NFC 8
+#define MXC_INT_VPU 9
+#define MXC_INT_IPU_ERR 10
+#define MXC_INT_IPU_SYN 11
+#define MXC_INT_GPU 12
+#define MXC_INT_RESV13 13
+#define MXC_INT_USB_H1 14
+#define MXC_INT_EMI 15
+#define MXC_INT_USB_H2 16
+#define MXC_INT_USB_H3 17
+#define MXC_INT_USB_OTG 18
+#define MXC_INT_SAHARA_H0 19
+#define MXC_INT_SAHARA_H1 20
+#define MXC_INT_SCC_SMN 21
+#define MXC_INT_SCC_STZ 22
+#define MXC_INT_SCC_SCM 23
+#define MXC_INT_SRTC_NTZ 24
+#define MXC_INT_SRTC_TZ 25
+#define MXC_INT_RTIC 26
+#define MXC_INT_CSU 27
+#define MXC_INT_SLIM_B 28
+#define MXC_INT_SSI1 29
+#define MXC_INT_SSI2 30
+#define MXC_INT_UART1 31
+#define MXC_INT_UART2 32
+#define MXC_INT_UART3 33
+#define MXC_INT_RESV34 34
+#define MXC_INT_RESV35 35
+#define MXC_INT_CSPI1 36
+#define MXC_INT_CSPI2 37
+#define MXC_INT_CSPI 38
+#define MXC_INT_GPT 39
+#define MXC_INT_EPIT1 40
+#define MXC_INT_EPIT2 41
+#define MXC_INT_GPIO1_INT7 42
+#define MXC_INT_GPIO1_INT6 43
+#define MXC_INT_GPIO1_INT5 44
+#define MXC_INT_GPIO1_INT4 45
+#define MXC_INT_GPIO1_INT3 46
+#define MXC_INT_GPIO1_INT2 47
+#define MXC_INT_GPIO1_INT1 48
+#define MXC_INT_GPIO1_INT0 49
+#define MXC_INT_GPIO1_LOW 50
+#define MXC_INT_GPIO1_HIGH 51
+#define MXC_INT_GPIO2_LOW 52
+#define MXC_INT_GPIO2_HIGH 53
+#define MXC_INT_GPIO3_LOW 54
+#define MXC_INT_GPIO3_HIGH 55
+#define MXC_INT_GPIO4_LOW 56
+#define MXC_INT_GPIO4_HIGH 57
+#define MXC_INT_WDOG1 58
+#define MXC_INT_WDOG2 59
+#define MXC_INT_KPP 60
+#define MXC_INT_PWM1 61
+#define MXC_INT_I2C1 62
+#define MXC_INT_I2C2 63
+#define MXC_INT_HS_I2C 64
+#define MXC_INT_RESV65 65
+#define MXC_INT_RESV66 66
+#define MXC_INT_SIM_IPB 67
+#define MXC_INT_SIM_DAT 68
+#define MXC_INT_IIM 69
+#define MXC_INT_ATA 70
+#define MXC_INT_CCM1 71
+#define MXC_INT_CCM2 72
+#define MXC_INT_GPC1 73
+#define MXC_INT_GPC2 74
+#define MXC_INT_SRC 75
+#define MXC_INT_NM 76
+#define MXC_INT_PMU 77
+#define MXC_INT_CTI_IRQ 78
+#define MXC_INT_CTI1_TG0 79
+#define MXC_INT_CTI1_TG1 80
+#define MXC_INT_MCG_ERR 81
+#define MXC_INT_MCG_TMR 82
+#define MXC_INT_MCG_FUNC 83
+#define MXC_INT_GPU2_IRQ 84
+#define MXC_INT_GPU2_BUSY 85
+#define MXC_INT_RESV86 86
+#define MXC_INT_FEC 87
+#define MXC_INT_OWIRE 88
+#define MXC_INT_CTI1_TG2 89
+#define MXC_INT_SJC 90
+#define MXC_INT_SPDIF 91
+#define MXC_INT_TVE 92
+#define MXC_INT_FIRI 93
+#define MXC_INT_PWM2 94
+#define MXC_INT_SLIM_EXP 95
+#define MXC_INT_SSI3 96
+#define MXC_INT_EMI_BOOT 97
+#define MXC_INT_CTI1_TG3 98
+#define MXC_INT_SMC_RX 99
+#define MXC_INT_VPU_IDLE 100
+#define MXC_INT_EMI_NFC 101
+#define MXC_INT_GPU_IDLE 102
+
+#define MXC_MAX_INT_LINES 128
+
+#define MXC_GPIO_INT_BASE (MXC_MAX_INT_LINES)
+
+/*!
+ * Number of GPIO port as defined in the IC Spec
+ */
+#define GPIO_PORT_NUM 4
+/*!
+ * Number of GPIO pins per port
+ */
+#define GPIO_NUM_PIN 32
+
+#define MXC_GPIO_SPLIT_IRQ_2
+
+#endif /* __ASM_ARCH_MXC_MX51_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc.h b/arch/arm/plat-mxc/include/mach/mxc.h
index f6caab062131..fb5c4f00f082 100644
--- 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 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright (C) 2008 Juergen Beisert (kernel@pengutronix.de)
*
* This program is free software; you can redistribute it and/or
@@ -24,19 +24,355 @@
#error "Do not include directly."
#endif
-/* clean up all things that are not used */
-#ifndef CONFIG_ARCH_MX3
-# define cpu_is_mx31() (0)
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
+/*!
+ * @ingroup MSL_MX27 MSL_MX31 MSL_MXC91321 MSL_MX37
+ */
+/*!
+ * gpio port structure
+ */
+struct mxc_gpio_port {
+ u32 num; /*!< gpio port number */
+ u32 base; /*!< gpio port base VA */
+#ifdef MXC_GPIO_SPLIT_IRQ_2
+ u16 irq_0_15, irq_16_31;
+#else
+ u16 irq; /*!< irq number to the core */
#endif
+ u16 virtual_irq_start; /*!< virtual irq start number */
+};
+/*!
+ * This structure is used to define the One wire platform data.
+ * It includes search rom accelerator.
+ */
+
+struct mxc_w1_config {
+ int search_rom_accelerator;
+};
+/*!
+ * This structure is used to define the SPI master controller's platform
+ * data. It includes the SPI bus number and the maximum number of
+ * slaves/chips it supports.
+ */
+struct mxc_spi_master {
+ /*!
+ * SPI Master's bus number.
+ */
+ unsigned int bus_num;
+ /*!
+ * SPI Master's maximum number of chip selects.
+ */
+ unsigned int maxchipselect;
+ /*!
+ * CSPI Hardware Version.
+ */
+ unsigned int spi_version;
+};
+
+struct mxc_ipu_config {
+ int rev;
+ struct clk *di_clk[2];
+};
+
+struct mxc_ir_platform_data {
+ int uart_ir_mux;
+ int ir_rx_invert;
+ int ir_tx_invert;
+ struct clk *uart_clk;
+};
+
+struct mxc_i2c_platform_data {
+ u32 i2c_clk;
+};
+/*This struct is to define the number of SSIs on a platform,
+DAM source port config, DAM external port config, and Regulator names*/
+struct mxc_audio_platform_data {
+ int ssi_num;
+ int src_port;
+ int ext_port;
+ int intr_id_hp;
+ int ext_ram;
+ struct clk *ssi_clk[2];
+ char *regulator1;
+ char *regulator2;
+};
+
+struct mxc_spdif_platform_data {
+ int spdif_tx;
+ int spdif_rx;
+ int spdif_clk_44100;
+ int spdif_clk_48000;
+ int spdif_clkid;
+ struct clk *spdif_clk;
+ struct clk *spdif_core_clk;
+};
+
+struct mxc_asrc_platform_data {
+ struct clk *asrc_core_clk;
+ struct clk *asrc_audio_clk;
+ unsigned int channel_bits;
+};
+
+struct mxc_bt_platform_data {
+ char *bt_vdd;
+ char *bt_vdd_parent;
+ char *bt_vusb;
+ char *bt_vusb_parent;
+ void (*bt_reset) (void);
+};
+
+struct mxc_lightsensor_platform_data {
+ char *vdd_reg;
+ int rext;
+};
+
+struct mxc_lcd_platform_data {
+ char *io_reg;
+ char *core_reg;
+ void (*reset) (void);
+};
+
+struct mxc_dvfs_platform_data {
+ /** Supply voltage regulator name string */
+ char *reg_id;
+ /* CPU clock name string */
+ char *clk1_id;
+ /* DVFS clock name string */
+ char *clk2_id;
+ /* GPC control reg address */
+ unsigned int gpc_cntr_reg_addr;
+ /* GPC voltage counter reg address */
+ unsigned int gpc_vcr_reg_addr;
+ /* DVFS threshold reg address */
+ unsigned int dvfs_thrs_reg_addr;
+ /* DVFS counters reg address */
+ unsigned int dvfs_coun_reg_addr;
+ /* DVFS EMAC reg address */
+ unsigned int dvfs_emac_reg_addr;
+ /* DVFS control reg address */
+ unsigned int dvfs_cntr_reg_addr;
+ /* DIV3CK mask */
+ u32 div3ck_mask;
+ /* DIV3CK offset */
+ int div3ck_offset;
+ /* DIV3CK value */
+ int div3ck_val;
+ /* EMAC value */
+ int emac_val;
+ /* Frequency increase threshold. Increase frequency change request
+ will be sent if DVFS counter value will be more than this value */
+ int upthr_val;
+ /* Frequency decrease threshold. Decrease frequency change request
+ will be sent if DVFS counter value will be less than this value */
+ int dnthr_val;
+ /* Panic threshold. Panic frequency change request
+ will be sent if DVFS counter value will be more than this value */
+ int pncthr_val;
+ /* The amount of times the up threshold should be exceeded
+ before DVFS will trigger frequency increase request */
+ int upcnt_val;
+ /* The amount of times the down threshold should be exceeded
+ before DVFS will trigger frequency decrease request */
+ int dncnt_val;
+ /* Delay time in us */
+ int delay_time;
+ /* Number of woking points supported */
+ int num_wp;
+};
+
+struct mxc_tsc_platform_data {
+ char *vdd_reg;
+ int penup_threshold;
+ void (*active) (void);
+ void (*inactive) (void);
+};
+
+struct mxc_tvout_platform_data {
+ char *io_reg;
+ char *core_reg;
+ char *analog_reg;
+ u32 detect_line;
+};
+
+struct mxc_tvin_platform_data {
+ char *dvddio_reg;
+ char *dvdd_reg;
+ char *avdd_reg;
+ char *pvdd_reg;
+ void (*pwdn) (int pwdn);
+ void (*reset) (void);
+};
+
+/*! Platform data for the IDE drive structure. */
+struct mxc_ide_platform_data {
+ char *power_drive; /*!< The power pointer */
+ char *power_io; /*!< The power pointer */
+};
+
+struct mxc_camera_platform_data {
+ char *core_regulator;
+ char *io_regulator;
+ char *analog_regulator;
+ char *gpo_regulator;
+ u32 mclk;
+ u32 csi;
+};
+
+/*gpo1-3 is in fixed state by hardware design,
+ * only deal with reset pin and clock_enable pin
+ * only poll mode can be used to control the chip,
+ * interrupt mode is not supported by 3ds*/
+struct mxc_fm_platform_data {
+ char *reg_vio;
+ char *reg_vdd;
+ void (*gpio_get) (void);
+ void (*gpio_put) (void);
+ void (*reset) (void);
+ void (*clock_ctl) (int flag);
+};
+
+struct mxc_mma7450_platform_data {
+ char *reg_dvdd_io;
+ char *reg_avdd;
+ void (*gpio_pin_get) (void);
+ void (*gpio_pin_put) (void);
+ int int1;
+ int int2;
+};
+
+struct mxc_keyp_platform_data {
+ u16 *matrix;
+ void (*active) (void);
+ void (*inactive) (void);
+ char *vdd_reg;
+};
-#ifndef CONFIG_MACH_MX27
-# define cpu_is_mx27() (0)
+struct mxc_unifi_platform_data {
+ void (*hardreset) (void);
+ void (*enable) (int en);
+ /* power parameters */
+ char *reg_gpo1;
+ char *reg_gpo2;
+ char *reg_1v5_ana_bb;
+ char *reg_vdd_vpa;
+ char *reg_1v5_dd;
+
+ int host_id;
+
+ void *priv;
+};
+
+struct mxc_gps_platform_data {
+ char *core_reg;
+ char *analog_reg;
+};
+
+struct mxc_mlb_platform_data {
+ u32 buf_address;
+ u32 phy_address;
+ char *reg_nvcc;
+ char *mlb_clk;
+};
+
+struct flexcan_platform_data {
+ char *core_reg;
+ char *io_reg;
+ void (*xcvr_enable) (int id, int en);
+ void (*active) (int id);
+ void (*inactive) (int id);
+};
+
+struct mxc_srtc_platform_data {
+ u32 srtc_sec_mode_addr;
+};
+
+struct tve_platform_data {
+ char *dac_reg;
+ char *dig_reg;
+};
+
+struct mxc_sgtl5000_platform_data {
+ int ssi_num;
+ int src_port;
+ int ext_port;
+ int hp_irq;
+ int (*hp_status)(void);
+
+ char *vddio_reg;
+ char *vdda_reg;
+ char *amp_gpo;
+ int vddio; /* voltage of VDDIO (uv) */
+ int vdda; /* voltage of vdda (uv) */
+ int vddd; /* voldtage of vddd (uv), zero if not connected */
+ int sysclk;
+};
+
+extern void mxc_wd_reset(void);
+unsigned long board_get_ckih_rate(void);
+
+int mxc_snoop_set_config(u32 num, unsigned long base, int size);
+int mxc_snoop_get_status(u32 num, u32 * statl, u32 * stath);
+
+struct platform_device;
+void mxc_pg_enable(struct platform_device *pdev);
+void mxc_pg_disable(struct platform_device *pdev);
+
+struct mxc_unifi_platform_data *get_unifi_plat_data(void);
+
+#endif /* __ASSEMBLY__ */
+
+#define MUX_IO_P 29
+#define MUX_IO_I 24
+#define IOMUX_TO_GPIO(pin) ((((unsigned int)pin >> MUX_IO_P) * GPIO_NUM_PIN) + ((pin >> MUX_IO_I) & ((1 << (MUX_IO_P - MUX_IO_I)) -1)))
+#define IOMUX_TO_IRQ(pin) (MXC_GPIO_INT_BASE + IOMUX_TO_GPIO(pin))
+#define GPIO_TO_PORT(n) (n / GPIO_NUM_PIN)
+#define GPIO_TO_INDEX(n) (n % GPIO_NUM_PIN)
+
+/* DMA driver defines */
+#define MXC_IDE_DMA_WATERMARK 32 /* DMA watermark level in bytes */
+#define MXC_IDE_DMA_BD_NR (512/3/4) /* Number of BDs per channel */
+
+#ifndef IS_MEM_DEVICE_NONSHARED
+/* all peripherals on MXC so far are below 0x80000000 but leave L2CC alone */
+#define IS_MEM_DEVICE_NONSHARED(x) ((x) < 0x80000000 && (x) != L2CC_BASE_ADDR)
#endif
+/*!
+ * DPTC GP and LP ID
+ */
+#define DPTC_GP_ID 0
+#define DPTC_LP_ID 1
+
+#ifndef __ASSEMBLY__
+#include <linux/types.h>
+
+struct cpu_wp {
+ u32 pll_reg;
+ u32 pll_rate;
+ u32 cpu_rate;
+ u32 pdr0_reg;
+ u32 pdf;
+ u32 mfi;
+ u32 mfd;
+ u32 mfn;
+ u32 cpu_voltage;
+ u32 cpu_podf;
+};
+
+struct cpu_wp *get_cpu_wp(int *wp);
+
+enum mxc_cpu_pwr_mode {
+ WAIT_CLOCKED, /* wfi only */
+ WAIT_UNCLOCKED, /* WAIT */
+ WAIT_UNCLOCKED_POWER_OFF, /* WAIT + SRPG */
+ STOP_POWER_ON, /* just STOP */
+ STOP_POWER_OFF, /* STOP + SRPG */
+};
+
+void mxc_cpu_lp_set(enum mxc_cpu_pwr_mode mode);
+int tzic_enable_wake(int is_idle);
-#if defined(CONFIG_ARCH_MX3) || defined(CONFIG_ARCH_MX2)
-#define CSCR_U(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10)
-#define CSCR_L(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x4)
-#define CSCR_A(n) (IO_ADDRESS(WEIM_BASE_ADDR) + n * 0x10 + 0x8)
#endif
#endif /* __ASM_ARCH_MXC_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc_asrc.h b/arch/arm/plat-mxc/include/mach/mxc_asrc.h
new file mode 100644
index 000000000000..5a4769146e32
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_asrc.h
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file mx35_asrc.h
+ *
+ * @brief MX35 Asynchronous Sample Rate Converter
+ *
+ * @ingroup ??
+ */
+
+#ifndef __MXC_ASRC_H__
+#define __MXC_ASRC_H__
+
+#define ASRC_IOC_MAGIC 'C'
+
+#define ASRC_REQ_PAIR _IOWR(ASRC_IOC_MAGIC, 0, struct asrc_req)
+#define ASRC_CONIFG_PAIR _IOWR(ASRC_IOC_MAGIC, 1, struct asrc_config)
+#define ASRC_RELEASE_PAIR _IOW(ASRC_IOC_MAGIC, 2, enum asrc_pair_index)
+#define ASRC_QUERYBUF _IOWR(ASRC_IOC_MAGIC, 3, struct asrc_buffer)
+#define ASRC_Q_INBUF _IOW(ASRC_IOC_MAGIC, 4, struct asrc_buffer)
+#define ASRC_DQ_INBUF _IOW(ASRC_IOC_MAGIC, 5, struct asrc_buffer)
+#define ASRC_Q_OUTBUF _IOW(ASRC_IOC_MAGIC, 6, struct asrc_buffer)
+#define ASRC_DQ_OUTBUF _IOW(ASRC_IOC_MAGIC, 7, struct asrc_buffer)
+#define ASRC_START_CONV _IOW(ASRC_IOC_MAGIC, 8, enum asrc_pair_index)
+#define ASRC_STOP_CONV _IOW(ASRC_IOC_MAGIC, 9, enum asrc_pair_index)
+
+enum asrc_pair_index {
+ ASRC_PAIR_A,
+ ASRC_PAIR_B,
+ ASRC_PAIR_C
+};
+
+enum asrc_inclk {
+ INCLK_NONE = 0x03,
+ INCLK_ESAI_RX = 0x00,
+ INCLK_SSI1_RX = 0x01,
+ INCLK_SSI2_RX = 0x02,
+ INCLK_SPDIF_RX = 0x04,
+ INCLK_MLB_CLK = 0x05,
+ INCLK_ESAI_TX = 0x08,
+ INCLK_SSI1_TX = 0x09,
+ INCLK_SSI2_TX = 0x0a,
+ INCLK_SPDIF_TX = 0x0c,
+ INCLK_ASRCK1_CLK = 0x0f,
+};
+
+enum asrc_outclk {
+ OUTCLK_NONE = 0x03,
+ OUTCLK_ESAI_TX = 0x00,
+ OUTCLK_SSI1_TX = 0x01,
+ OUTCLK_SSI2_TX = 0x02,
+ OUTCLK_SPDIF_TX = 0x04,
+ OUTCLK_MLB_CLK = 0x05,
+ OUTCLK_ESAI_RX = 0x08,
+ OUTCLK_SSI1_RX = 0x09,
+ OUTCLK_SSI2_RX = 0x0a,
+ OUTCLK_SPDIF_RX = 0x0c,
+ OUTCLK_ASRCK1_CLK = 0x0f,
+};
+
+struct asrc_config {
+ enum asrc_pair_index pair;
+ unsigned int channel_num;
+ unsigned int buffer_num;
+ unsigned int dma_buffer_size;
+ unsigned int input_sample_rate;
+ unsigned int output_sample_rate;
+ enum asrc_inclk inclk;
+ enum asrc_outclk outclk;
+};
+
+struct asrc_pair {
+ unsigned int start_channel;
+ unsigned int chn_num;
+ unsigned int chn_max;
+ unsigned int active;
+};
+
+struct asrc_req {
+ unsigned int chn_num;
+ enum asrc_pair_index index;
+};
+
+struct asrc_querybuf {
+ unsigned int buffer_index;
+ unsigned int input_length;
+ unsigned int output_length;
+ unsigned long input_offset;
+ unsigned long output_offset;
+};
+
+struct asrc_buffer {
+ unsigned int index;
+ unsigned int length;
+};
+
+#ifdef __KERNEL__
+
+#define ASRC_DMA_BUFFER_NUM 8
+
+#define ASRC_ASRCTR_REG 0x00
+#define ASRC_ASRIER_REG 0x04
+#define ASRC_ASRCNCR_REG 0x0C
+#define ASRC_ASRCFG_REG 0x10
+#define ASRC_ASRCSR_REG 0x14
+#define ASRC_ASRCDR1_REG 0x18
+#define ASRC_ASRCDR2_REG 0x1C
+#define ASRC_ASRSTR_REG 0x20
+#define ASRC_ASRRA_REG 0x24
+#define ASRC_ASRRB_REG 0x28
+#define ASRC_ASRRC_REG 0x2C
+#define ASRC_ASRPM1_REG 0x40
+#define ASRC_ASRPM2_REG 0x44
+#define ASRC_ASRPM3_REG 0x48
+#define ASRC_ASRPM4_REG 0x4C
+#define ASRC_ASRPM5_REG 0x50
+#define ASRC_ASRTFR1 0x54
+#define ASRC_ASRCCR_REG 0x5C
+#define ASRC_ASRDIA_REG 0x60
+#define ASRC_ASRDOA_REG 0x64
+#define ASRC_ASRDIB_REG 0x68
+#define ASRC_ASRDOB_REG 0x6C
+#define ASRC_ASRDIC_REG 0x70
+#define ASRC_ASRDOC_REG 0x74
+#define ASRC_ASRIDRHA_REG 0x80
+#define ASRC_ASRIDRLA_REG 0x84
+#define ASRC_ASRIDRHB_REG 0x88
+#define ASRC_ASRIDRLB_REG 0x8C
+#define ASRC_ASRIDRHC_REG 0x90
+#define ASRC_ASRIDRLC_REG 0x94
+#define ASRC_ASR76K_REG 0x98
+#define ASRC_ASR56K_REG 0x9C
+
+struct dma_block {
+ unsigned int index;
+ unsigned int length;
+ unsigned char *dma_vaddr;
+ dma_addr_t dma_paddr;
+ struct list_head queue;
+};
+
+struct asrc_pair_params {
+ enum asrc_pair_index index;
+ struct list_head input_queue;
+ struct list_head input_done_queue;
+ struct list_head output_queue;
+ struct list_head output_done_queue;
+ wait_queue_head_t input_wait_queue;
+ wait_queue_head_t output_wait_queue;
+ unsigned int input_counter;
+ unsigned int output_counter;
+ unsigned int input_queue_empty;
+ unsigned int output_queue_empty;
+ unsigned int input_dma_channel;
+ unsigned int output_dma_channel;
+ unsigned int input_buffer_size;
+ unsigned int output_buffer_size;
+ unsigned int buffer_num;
+ unsigned int pair_hold;
+ unsigned int asrc_active;
+ struct dma_block input_dma[ASRC_DMA_BUFFER_NUM];
+ struct dma_block output_dma[ASRC_DMA_BUFFER_NUM];
+ struct semaphore busy_lock;
+};
+
+struct asrc_data {
+ struct asrc_pair asrc_pair[3];
+};
+
+char *asrc_pair_id[] = {
+ [0] = "ASRC RX PAIR A",
+ [1] = "ASRC TX PAIR A",
+ [2] = "ASRC RX PAIR B",
+ [3] = "ASRC TX PAIR B",
+ [4] = "ASRC RX PAIR C",
+ [5] = "ASRC TX PAIR C",
+};
+
+extern int asrc_req_pair(int chn_num, enum asrc_pair_index *index);
+extern void asrc_release_pair(enum asrc_pair_index index);
+extern int asrc_config_pair(struct asrc_config *config);
+extern void asrc_start_conv(enum asrc_pair_index index);
+extern void asrc_stop_conv(enum asrc_pair_index index);
+
+#endif /* __kERNEL__ */
+
+#endif /* __MXC_ASRC_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc_dptc.h b/arch/arm/plat-mxc/include/mach/mxc_dptc.h
new file mode 100644
index 000000000000..b42fc36af3e1
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_dptc.h
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup DPTC Dynamic Process and Temperatur Compensation (DPTC) Driver
+ */
+
+/*!
+ * @file arch-mxc/mxc_dptc.h
+ *
+ * @brief This file contains the DPTC configuration structure definition.
+ *
+ *
+ * @ingroup DPTC
+ */
+
+#ifndef __ASM_ARCH_MXC_DPTC_H__
+#define __ASM_ARCH_MXC_DPTC_H__
+
+#ifdef __KERNEL__
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/workqueue.h>
+#include <linux/device.h>
+
+#define DPTC_WP_SUPPORTED 17
+#define DPTC_GP_WP_SUPPORTED 7
+#define DPTC_LP_WP_SUPPORTED 9
+
+struct dptc_wp {
+ u32 dcvr0;
+ u32 dcvr1;
+ u32 dcvr2;
+ u32 dcvr3;
+ u32 voltage;
+};
+
+/*!
+ * This structure is used to define the dptc controller's platform
+ * data. It includes the regulator name string and DPTC clock name string.
+ */
+struct mxc_dptc_data {
+ /** Regulator name string */
+ char *reg_id;
+ /* DPTC clock name string */
+ char *clk_id;
+ /* Control reg address */
+ unsigned int dptccr_reg_addr;
+ /* Comparator value reg 0 address */
+ unsigned int dcvr0_reg_addr;
+ /* GPC control reg address */
+ unsigned int gpc_cntr_reg_addr;
+ /* DPTC interrupt status bit */
+ unsigned int dptccr;
+ /* The number of DPTC working points */
+ unsigned int dptc_wp_supported;
+ /* Maximum value of DPTC clock rate */
+ unsigned long clk_max_val;
+ /* DPTC working points */
+ struct dptc_wp *dptc_wp_allfreq;
+ /* DPTC enable bit */
+ u32 dptc_enable_bit;
+ /* DPTC ADU bit */
+ int gpc_adu;
+ /* VAI mask */
+ u32 vai_mask;
+ /* VAI offset */
+ int vai_offset;
+ /* Mask DPTC interrupt */
+ u32 irq_mask;
+ /* DPTC no voltage change request bit */
+ u32 dptc_nvcr_bit;
+ /* ARM interrrupt bit */
+ u32 gpc_irq_bit;
+ /* dptc init config */
+ u32 init_config;
+ /* dptc enable config */
+ u32 enable_config;
+ /* dptc counting range mask */
+ u32 dcr_mask;
+};
+
+/*!
+ * This function is called to put the DPTC in a low power state.
+ *
+ * @param id The DPTC device id. DPTC_GP_ID is for DPTC GP;
+ * DPTC_LP_ID is for DPTC LP
+ */
+void dptc_suspend(int id);
+/*!
+ * This function is called to resume the DPTC from a low power state.
+ *
+ * @param id The DPTC device id. DPTC_GP_ID is for DPTC GP;
+ * DPTC_LP_ID is for DPTC LP
+ */
+void dptc_resume(int id);
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_ARCH_MXC_DPTC_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc_gpc.h b/arch/arm/plat-mxc/include/mach/mxc_gpc.h
new file mode 100644
index 000000000000..d3b3ae2d1b13
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_gpc.h
@@ -0,0 +1,74 @@
+
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup LPMD Low-Level Power Management Driver
+ */
+
+/*!
+ * @file arch-mxc/mxc_gpc.h
+ *
+ * @brief This file contains the chip level configuration details and
+ * public API declarations for GPC module
+ *
+ * @ingroup LPMD
+ */
+
+#ifndef __ASM_ARCH_MXC_GPC_H__
+#define __ASM_ARCH_MXC_GPC_H__
+
+/* AP Power Gating modules */
+typedef enum {
+ POWER_GATING_MODULE_AP_EMBEDDED_MEM_DEEPSLEEP,
+ POWER_GATING_MODULE_DISPLAY_BUFFER,
+ POWER_GATING_MODULE_EMI_DEEPSLEEP,
+ POWER_GATING_MODULE_IPU_STOP,
+ POWER_GATING_MODULE_L2_MEM_STOP,
+ POWER_GATING_MODULE_ARM_PLATFORM_STOP,
+} mxc_pm_ap_power_gating_modules_t;
+
+/* AP Power Gating pull-down config of modules */
+typedef enum {
+ POWER_GATING_PULL_DOWN_DISPLAY_BUFFER,
+ POWER_GATING_PULL_DOWN_EMI,
+ POWER_GATING_PULL_DOWN_IPU,
+ POWER_GATING_PULL_DOWN_L2_MEM,
+ POWER_GATING_PULL_DOWN_ARMPLATFORM,
+} mxc_pm_ap_power_gating_pulldown_t;
+
+/*!
+ * This function enables/disables the AP power gating by writing the APPCR
+ * register of the GPC module.
+ *
+ * @param enable Enable/Disable module power down
+ * 0 - disable; 1 - enable
+ * @param modules The desired module to be power gated
+ *
+ */
+void mxc_gpc_powergate_module(int enable,
+ mxc_pm_ap_power_gating_modules_t module);
+
+/*!
+ * This function enables/disables the AP power gating pull down selection of a
+ * module by writing the APPCR register of the GPC module.
+ *
+ * @param enable Enable/Disable module pull down
+ * 0 - disable; 1 - enable
+ * @param modules The desired module to be pulled down
+ *
+ */
+void mxc_gpc_powergate_pulldown(int enable,
+ mxc_pm_ap_power_gating_pulldown_t pulldown);
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/mxc_mlb.h b/arch/arm/plat-mxc/include/mach/mxc_mlb.h
new file mode 100644
index 000000000000..b91294d85314
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_mlb.h
@@ -0,0 +1,51 @@
+/*
+ * mxc_mlb.h
+ *
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef _MXC_MLB_H
+#define _MXC_MLB_H
+
+/* define IOCTL command */
+#define MLB_SET_FPS _IOW('S', 0x10, unsigned int)
+#define MLB_GET_VER _IOR('S', 0x11, unsigned long)
+#define MLB_SET_DEVADDR _IOR('S', 0x12, unsigned char)
+/*!
+ * set channel address for each logical channel
+ * the MSB 16bits is for tx channel, the left LSB is for rx channel
+ */
+#define MLB_CHAN_SETADDR _IOW('S', 0x13, unsigned int)
+#define MLB_CHAN_STARTUP _IO('S', 0x14)
+#define MLB_CHAN_SHUTDOWN _IO('S', 0x15)
+#define MLB_CHAN_GETEVENT _IOR('S', 0x16, unsigned long)
+
+/*!
+ * MLB event define
+ */
+enum {
+ MLB_EVT_TX_PROTO_ERR_CUR = 1 << 0,
+ MLB_EVT_TX_BRK_DETECT_CUR = 1 << 1,
+ MLB_EVT_TX_PROTO_ERR_PREV = 1 << 8,
+ MLB_EVT_TX_BRK_DETECT_PREV = 1 << 9,
+ MLB_EVT_RX_PROTO_ERR_CUR = 1 << 16,
+ MLB_EVT_RX_BRK_DETECT_CUR = 1 << 17,
+ MLB_EVT_RX_PROTO_ERR_PREV = 1 << 24,
+ MLB_EVT_RX_BRK_DETECT_PREV = 1 << 25,
+};
+
+#ifdef __KERNEL__
+extern void gpio_mlb_active(void);
+extern void gpio_mlb_inactive(void);
+#endif
+
+#endif /* _MXC_MLB_H */
diff --git a/arch/arm/plat-mxc/include/mach/mxc_pf.h b/arch/arm/plat-mxc/include/mach/mxc_pf.h
new file mode 100644
index 000000000000..990b12d8bd33
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_pf.h
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2005-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+/*!
+ * @defgroup MXC_PF MPEG4/H.264 Post Filter Driver
+ */
+/*!
+ * @file arch-mxc/mxc_pf.h
+ *
+ * @brief MXC IPU MPEG4/H.264 Post-filtering driver
+ *
+ * User-level API for IPU Hardware MPEG4/H.264 Post-filtering.
+ *
+ * @ingroup MXC_PF
+ */
+#ifndef __INCLUDED_MXC_PF_H__
+#define __INCLUDED_MXC_PF_H__
+
+#define PF_MAX_BUFFER_CNT 17
+
+#define PF_WAIT_Y 0x0001
+#define PF_WAIT_U 0x0002
+#define PF_WAIT_V 0x0004
+#define PF_WAIT_ALL (PF_WAIT_Y|PF_WAIT_U|PF_WAIT_V)
+
+/*!
+ * Structure for Post Filter initialization parameters.
+ */
+typedef struct {
+ uint16_t pf_mode; /*!< Post filter operation mode */
+ uint16_t width; /*!< Width of frame in pixels */
+ uint16_t height; /*!< Height of frame in pixels */
+ uint16_t stride; /*!< Stride of Y plane in pixels. Stride for U and V planes is half Y stride */
+ uint32_t qp_size;
+ unsigned long qp_paddr;
+} pf_init_params;
+
+/*!
+ * Structure for Post Filter buffer request parameters.
+ */
+typedef struct {
+ int count; /*!< Number of buffers requested */
+ __u32 req_size;
+} pf_reqbufs_params;
+
+/*!
+ * Structure for Post Filter buffer request parameters.
+ */
+typedef struct {
+ int index;
+ int size; /*!< Size of buffer allocated */
+ __u32 offset; /*!< Buffer offset in driver memory. Set by QUERYBUF */
+ __u32 y_offset; /*!< Optional starting relative offset of Y data
+ from beginning of buffer. Set to 0 to use default
+ calculated based on height and stride */
+ __u32 u_offset; /*!< Optional starting relative offset of U data
+ from beginning of buffer. Set to 0 to use default
+ calculated based on height and stride */
+ __u32 v_offset; /*!< Optional starting relative offset of V data
+ from beginning of buffer. Set to 0 to use default
+ calculated based on height and stride */
+} pf_buf;
+
+/*!
+ * Structure for Post Filter start parameters.
+ */
+typedef struct {
+ pf_buf in; /*!< Input buffer address and offsets */
+ pf_buf out; /*!< Output buffer address and offsets */
+ int qp_buf;
+ int wait;
+ uint32_t h264_pause_row; /*!< Row to pause at for H.264 mode. 0 to disable pause */
+} pf_start_params;
+
+/*! @name User Client Ioctl Interface */
+/*! @{ */
+
+/*!
+ * IOCTL to Initialize the Post Filter.
+ */
+#define PF_IOCTL_INIT _IOW('F',0x0, pf_init_params)
+
+/*!
+ * IOCTL to Uninitialize the Post Filter.
+ */
+#define PF_IOCTL_UNINIT _IO('F',0x1)
+
+/*!
+ * IOCTL to set the buffer mode and allocate buffers if driver allocated.
+ */
+#define PF_IOCTL_REQBUFS _IOWR('F',0x2, pf_reqbufs_params)
+
+/*!
+ * IOCTL to set the buffer mode and allocate buffers if driver allocated.
+ */
+#define PF_IOCTL_QUERYBUF _IOR('F',0x2, pf_buf)
+
+/*!
+ * IOCTL to start post filtering on a frame of data. This ioctl may block until
+ * processing is done or return immediately.
+ */
+#define PF_IOCTL_START _IOWR('F',0x3, pf_start_params)
+
+/*!
+ * IOCTL to resume post-filtering after an intra frame pause in H.264 mode.
+ */
+#define PF_IOCTL_RESUME _IOW('F',0x4, int)
+
+/*!
+ * IOCTL to wait for post-filtering to complete.
+ */
+#define PF_IOCTL_WAIT _IOW('F',0x5, int)
+/*! @} */
+
+#endif /* __INCLUDED_MXC_PF_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc_pm.h b/arch/arm/plat-mxc/include/mach/mxc_pm.h
new file mode 100644
index 000000000000..0cd865f2777c
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_pm.h
@@ -0,0 +1,252 @@
+
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup LPMD Low-Level Power Management Driver
+ */
+
+/*!
+ * @file arch-mxc/mxc_pm.h
+ *
+ * @brief This file contains the chip level configuration details and
+ * public API declarations for CRM_AP module
+ *
+ * @ingroup LPMD
+ */
+
+#ifndef __ASM_ARCH_MXC_PM_H__
+#define __ASM_ARCH_MXC_PM_H__
+
+#define WAIT_MODE 111
+#define DOZE_MODE 112
+#define STOP_MODE 113
+#define DSM_MODE 114
+/*
+ * MXC91231 Break-Point Frequency below which is low frequency and
+ * above which is high frequency
+ */
+#define BREAKPT_FREQ ((long)(400000000))
+
+#define GATE_STOP_WAIT 9
+#define GATE_STOP 10
+
+/*
+ * Used for MHz conversion
+ */
+#define MEGA_HERTZ 1000000
+
+/*
+ * If invalid frequency value other than the following
+ * CORE_133 - ARM desired to run @133MHz, LoV (1.2V)
+ * CORE_266 - ARM desired to run @266MHz, LoV (1.2V)
+ * CORE_399 - ARM desired to run @399MHz, LoV (1.2V)
+ * CORE_532 - ARM desired to run @133MHz, HiV (1.6V)
+ * are passed then this error is returned,
+ */
+#define ERR_FREQ_INVALID 1
+
+/*
+ * For MXC91231 Pass1, Integer DVFS greater than 133MHz is not allowed
+ * due to the hardware issue
+ */
+#define INTEGER_DVFS_NOT_ALLOW 1
+
+/*
+ * If PLL freq is less than desired ARM frequency during Integer
+ * DVFS, then return this error
+ */
+#define PLL_LESS_ARM_ERR 2
+
+/*
+ * Frequency change within the same-lo voltage is not approved.
+ * Inorder to do Integer DFS, move to the high voltage range and
+ * then set LFDF and move to the low voltage range
+ */
+#define INT_DFS_LOW_NOT_ALLOW 3
+
+/*
+ * If the desired AHB or IPG exceeds 133MHz or 66.5MHz respectively,
+ * then return this error
+ */
+#define AHB_IPG_EXCEED_LIMIT 4
+
+/*
+ * If the desired ARM frequency is too low to get by PLL scaling
+ * and the mxc_pm_pllscale API is called, return this error:
+ */
+#define PLL_DVFS_FREQ_TOO_LOW 5
+
+/*
+ * Invalid frequencies requested
+ */
+#define MXC_PM_INVALID_PARAM 6
+
+/*
+ * If AHB and/or IPG frequencies are greater than maximum allowed
+ */
+#define FREQ_OUT_OF_RANGE 2
+
+/*
+ * If AHB and/or IPG frequencies are other than 100 or 50Mhz
+ */
+#define BUS_FREQ_INVALID 2
+
+/*
+ * If MAX_PDF is greater than max value (8) then return this error
+ */
+#define AHB_MAX_DIV_ERR 3
+
+/*
+ * If IPG_PDF is greater than max value (2) then return this error
+ */
+#define IPG_MAX_DIV_ERR 4
+
+/*
+ * If ARM freq is out of range i.e., less than 133 or greater than
+ * 399 then return this error
+ */
+#define INVALID_ARM_FREQ 5
+
+/*
+ * This file includes all platform APIs. Some of the APIs are not
+ * appicable to some platforms. So, this error is used to indicate
+ * that a particular API is not available
+ */
+#define MXC_PM_API_NOT_SUPPORTED 6
+
+/*
+ * Error when frequency scaling is attempted while switch between MPLL and
+ * TPLL is in progress on MXC91321
+ */
+#define ERR_DFSP_SWITCH 2
+
+/*!
+ * Additional define for stop mode
+ */
+#define PM_SUSPEND_STOP ((__force suspend_state_t) 2)
+
+/*!
+ * CKOH pins configuration
+ */
+#define CKOH_AP_SEL 1
+#define CKOH_AHB_SEL 2
+#define CKOH_IP_SEL 3
+
+/*!
+ * Defines for Stop and DSM mode acknowledgements
+ */
+#define MXC_PM_LOWPWR_ACK_SDMA 0x01
+#define MXC_PM_LOWPWR_ACK_IPU 0x02
+#define MXC_PM_LOWPWR_ACK_MAX 0x04
+#define MXC_PM_LOWPWR_ACK_MQSPI 0x08
+#define MXC_PM_LOWPWR_ACK_USB 0x10
+#define MXC_PM_LOWPWR_ACK_RTIC 0x20
+
+/*
+ * PMIC configuration
+ */
+#define MXC_PMIC_1_2_VOLT 0xC
+#define MXC_PMIC_1_6_VOLT 0x1C
+#define MXC_PMIC_1_0_VOLT 0x4
+#if defined(CONFIG_ARCH_MXC91321) || defined(CONFIG_ARCH_MXC91231)
+#define MXC_PMIC_DVS_SPEED 0x1
+#else
+#define MXC_PMIC_DVS_SPEED 0x3
+#endif
+
+/*!
+ * Implementing Level 1 CRM Gate Control. Level 2 gate control
+ * is provided at module level using LPMD registers
+ *
+ * @param group The desired clock gate control register bits.
+ * Possible values are 0 through 6
+ * @param opt The desired option requesting clock to run during stop
+ * and wait modes or just during the stop mode. Possible
+ * values are GATE_STOP_WAIT and GATE_STOP.
+ *
+ */
+void mxc_pm_clockgate(int group, int opt);
+
+/*!
+ * Implementing steps required to transition to low-power modes
+ *
+ * @param mode The desired low-power mode. Possible values are,
+ * WAIT_MODE, STOP_MODE or DSM_MODE
+ *
+ */
+void mxc_pm_lowpower(int mode);
+
+/*!
+ * Enables acknowledgement from module when entering stop or DSM mode.
+ *
+ * @param ack The desired module acknowledgement to enable.
+ *
+ */
+void mxc_pm_lp_ack_enable(int ack);
+
+/*!
+ * Disables acknowledgement from module when entering stop or DSM mode.
+ *
+ * @param ack The desired module acknowledgement to disable.
+ *
+ */
+void mxc_pm_lp_ack_disable(int ack);
+
+/*!
+ * Implementing steps required to set Integer Scaling
+ *
+ * @param armfreq The desired ARM frequency. AHB and IP
+ * frequency are changed depending on ARM
+ * frequency and the divider values.
+ * @param ahbfreq The desired AHB frequency
+ * @param ipfreq The desired IP frequency
+ *
+ * @return Returns 0 on success or
+ * Returns -PLL_LESS_ARM_ERR if pllfreq is less than
+ * desired core freq
+ */
+int mxc_pm_intscale(long armfreq, long ahbfreq, long ipfreq);
+
+/*!
+ * To calculate MFI, MFN, MFD values. Using this the output frequency
+ * whose value is calculated using,
+ * 2 * REF_FREQ * (MF / PDF), where
+ * REF_FREQ is 26 Mhz
+ * MF = MFI + (MFN + MFD)
+ * PDF is assumed to be 1
+ *
+ * @param armfreq The desired ARM frequency
+ * @param ahbfreq The desired AHB frequency
+ * @param ipfreq The desired IP frequency
+ *
+ * @return Returns 0 on success or
+ * Returns -1 on error
+ */
+int mxc_pm_pllscale(long armfreq, long ahbfreq, long ipfreq);
+
+/*!
+ * To change AP core frequency and/or voltage suitably
+ *
+ * @param armfreq The desired ARM frequency
+ * @param ahbfreq The desired AHB frequency
+ * @param ipfreq The desired IP frequency
+ *
+ * @return Returns -ERR_FREQ_INVALID on failure
+ * Returns 0 on success
+ */
+int mxc_pm_dvfs(unsigned long armfreq, long ahbfreq, long ipfreq);
+
+extern void mxc_pm_arch_entry(u32 entry, u32 size);
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/mxc_scc.h b/arch/arm/plat-mxc/include/mach/mxc_scc.h
new file mode 100644
index 000000000000..d23f6c3e9913
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_scc.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file arch-mxc/mxc_scc.h
+ *
+ * @brief This is intended to be the file which contains all of code or changes
+ * needed to port the driver.
+ *
+ * @ingroup MXCSCC
+ */
+
+#ifndef __ASM_ARCH_MXC_SCC_H__
+#define __ASM_ARCH_MXC_SCC_H__
+
+#include <mach/hardware.h>
+
+/*!
+ * Expected to come from platform header files.
+ * This symbol must be the address of the SCC
+ */
+#define SCC_BASE SCC_BASE_ADDR
+
+/*!
+ * This must be the interrupt line number of the SCM interrupt.
+ */
+#define INT_SCC_SCM MXC_INT_SCC_SCM
+
+/*!
+ * if #USE_SMN_INTERRUPT is defined, this must be the interrupt line number of
+ * the SMN interrupt.
+ */
+#define INT_SCC_SMN MXC_INT_SCC_SMN
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/mxc_scc2_driver.h b/arch/arm/plat-mxc/include/mach/mxc_scc2_driver.h
new file mode 100644
index 000000000000..f8a24f278b1c
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_scc2_driver.h
@@ -0,0 +1,973 @@
+
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef SCC_DRIVER_H
+#define SCC_DRIVER_H
+
+/*
+ * NAMING CONVENTIONS
+ * ==================
+ * (A note to maintainers and other interested parties)
+ *
+ * Use scc_ or SCC_ prefix for 'high-level' interface routines and the types
+ * passed to those routines. Try to avoid #defines in these interfaces.
+ *
+ * Use SMN_ or SCM_ prefix for the #defines used with scc_read_register() and
+ * scc_write_register, or values passed/retrieved from those routines.
+ */
+
+/*! @file mxc_scc2_driver.h
+ *
+ * @brief (Header file to use the SCC2 driver.)
+ *
+ * The SCC2 driver is available to other kernel modules directly. Secure
+ * Partition functionality is extended to users through the SHW API. Other
+ * functionality of the SCC2 is limited to kernel-space users.
+ *
+ * With the exception of #scc_monitor_security_failure(), all routines are
+ * 'synchronous', i.e. they will not return to their caller until the requested
+ * action is complete, or fails to complete. Some of these functions could
+ * take quite a while to perform, depending upon the request.
+ *
+ * Routines are provided to:
+ * @li trigger a security-violation alarm - #scc_set_sw_alarm()
+ * @li get configuration and version information - #scc_get_configuration()
+ * @li zeroize memory - #scc_zeroize_memories()
+ * @li Work with secure partitions: #scc_allocate_partition()
+ * #scc_engage_partition() #scc_diminish_permissions()
+ * #scc_release_partition()
+ * @li Encrypt or decrypt regions of data: #scc_encrypt_region()
+ * #scc_decrypt_region()
+ * @li monitor the Security Failure alarm - #scc_monitor_security_failure()
+ * @li stop monitoring Security Failure alarm -
+ * #scc_stop_monitoring_security_failure()
+ * @li write registers of the SCC - #scc_write_register()
+ * @li read registers of the SCC - #scc_read_register()
+ *
+ * The SCC2 encrypts and decrypts using Triple DES with an internally stored
+ * key. When the SCC2 is in Secure mode, it uses its secret, unique-per-chip
+ * key. When it is in Non-Secure mode, it uses a default key. This ensures
+ * that secrets stay secret if the SCC2 is not in Secure mode.
+ *
+ * Not all functions that could be provided in a 'high level' manner have been
+ * implemented. Among the missing are interfaces to the ASC/AIC components and
+ * the timer functions. These and other features must be accessed through
+ * #scc_read_register() and #scc_write_register(), using the @c \#define values
+ * provided.
+ *
+ * Here is a glossary of acronyms used in the SCC2 driver documentation:
+ * - CBC - Cipher Block Chaining. A method of performing a block cipher.
+ * Each block is encrypted using some part of the result of the previous
+ * block's encryption. It needs an 'initialization vector' to seed the
+ * operation.
+ * - ECB - Electronic Code Book. A method of performing a block cipher.
+ * With a given key, a given block will always encrypt to the same value.
+ * - DES - Data Encryption Standard. (8-byte) Block cipher algorithm which
+ * uses 56-bit keys. In SCC2, this key is constant and unique to the device.
+ * SCC uses the "triple DES" form of this algorithm.
+ * - AIC - Algorithm Integrity Checker.
+ * - ASC - Algorithm Sequence Checker.
+ * - SMN - Security Monitor. The part of the SCC2 responsible for monitoring
+ * for security problems and notifying the CPU and other PISA components.
+ * - SCM - Secure Memory. The part of the SCC2 which handles the cryptography.
+ * - SCC - Security Controller. Central security mechanism for PISA.
+ * - PISA - Platform-Independent Security Architecture.
+ */
+
+/* Temporarily define compile-time flags to make Doxygen happy. */
+#ifdef DOXYGEN_HACK
+/** @defgroup scccompileflags SCC Driver compile-time flags
+ *
+ * These preprocessor flags should be set, if desired, in a makefile so
+ * that they show up on the compiler command line.
+ */
+/** @addtogroup scccompileflags */
+
+/** @{ */
+/**
+ * Compile-time flag to change @ref smnregs and @ref scmregs
+ * offset values for the SCC's implementation on the MX.21 board.
+ *
+ * This must also be set properly for any code which calls the
+ * scc_read_register() or scc_write_register() functions or references the
+ * register offsets.
+ */
+#define TAHITI
+/** @} */
+#undef TAHITI
+
+#endif /* DOXYGEN_HACK */
+
+/*! Major Version of the driver. Used for
+ scc_configuration->driver_major_version */
+#define SCC_DRIVER_MAJOR_VERSION 2
+/*! Old Minor Version of the driver. */
+#define SCC_DRIVER_MINOR_VERSION_0 0
+/*! Minor Version of the driver. Used for
+ scc_configuration->driver_minor_version */
+#define SCC_DRIVER_MINOR_VERSION_2 2
+
+
+/*!
+ * Interrupt line number of SCM interrupt.
+ */
+#define INT_SCC_SCM MXC_INT_SCC_SCM
+
+/*!
+ * Interrupt line number of the SMN interrupt.
+ */
+#define INT_SCC_SMN MXC_INT_SCC_SMN
+
+/**
+ * @typedef scc_return_t
+ */
+/** Common status return values from SCC driver functions. */
+ typedef enum scc_return_t {
+ SCC_RET_OK = 0, /**< Function succeeded */
+ SCC_RET_FAIL, /**< Non-specific failure */
+ SCC_RET_VERIFICATION_FAILED,
+ /**< Decrypt validation failed */
+ SCC_RET_TOO_MANY_FUNCTIONS,
+ /**< At maximum registered functions */
+ SCC_RET_BUSY, /**< SCC is busy and cannot handle request */
+ /**< Encryption or decryption failed because@c count_out_bytes
+ says that @c data_out is too small to hold the value. */
+ SCC_RET_INSUFFICIENT_SPACE,
+ } scc_return_t;
+
+/**
+ * @typedef scc_partition_status_t
+ */
+/** Partition status information. */
+ typedef enum scc_partition_status_t {
+ SCC_PART_S_UNUSABLE,
+ /**< Partition not implemented */
+ SCC_PART_S_UNAVAILABLE,
+ /**< Partition owned by other host */
+ SCC_PART_S_AVAILABLE,
+ /**< Partition available */
+ SCC_PART_S_ALLOCATED,
+ /**< Partition owned by host but not engaged*/
+ SCC_PART_S_ENGAGED,
+ /**< Partition owned by host and engaged */
+ } scc_partition_status_t;
+
+/**
+ * Configuration information about SCC and the driver.
+ *
+ * This struct/typedef contains information from the SCC and the driver to
+ * allow the user of the driver to determine the size of the SCC's memories and
+ * the version of the SCC and the driver.
+ */
+ typedef struct scc_config_t {
+ int driver_major_version;
+ /**< Major version of the SCC driver code */
+ int driver_minor_version;
+ /**< Minor version of the SCC driver code */
+ int scm_version; /**< Version from SCM Configuration register */
+ int smn_version; /**< Version from SMN Status register */
+ /**< Number of bytes per block of RAM; also
+ block size of the crypto algorithm. */
+ int block_size_bytes;
+ int partition_size_bytes;
+ /**< Number of bytes in each partition */
+ int partition_count;
+ /**< Number of partitions on this platform */
+ } scc_config_t;
+
+/**
+ * @typedef scc_enc_dec_t
+ */
+/**
+ * Determine whether SCC will run its cryptographic
+ * function as an encryption or decryption.
+ */
+ typedef enum scc_enc_dec_t {
+ SCC_ENCRYPT, /**< Encrypt (from Red to Black) */
+ SCC_DECRYPT /**< Decrypt (from Black to Red) */
+ } scc_enc_dec_t;
+
+/**
+ * @typedef scc_verify_t
+ */
+/**
+ * Tell the driver whether it is responsible for verifying the integrity of a
+ * secret. During an encryption, using other than #SCC_VERIFY_MODE_NONE will
+ * cause a check value to be generated and appended to the plaintext before
+ * encryption. During decryption, the check value will be verified after
+ * decryption, and then stripped from the message.
+ */
+ typedef enum scc_verify_t {
+ /** No verification value added or checked. Input plaintext data must be
+ * be a multiple of the blocksize (#scc_get_configuration()). */
+ SCC_VERIFY_MODE_NONE,
+ /** Driver will generate/validate a 2-byte CCITT CRC. Input plaintext
+ will be padded to a multiple of the blocksize, adding 3-10 bytes
+ to the resulting output ciphertext. Upon decryption, this padding
+ will be stripped, and the CRC will be verified. */
+ SCC_VERIFY_MODE_CCITT_CRC
+ } scc_verify_t;
+
+/**
+ * @typedef scc_cypher_mode_t
+ */
+/**
+ * Select the cypher mode to use for partition cover/uncover operations.
+ */
+
+ typedef enum scc_cypher_mode_t {
+ SCC_CYPHER_MODE_ECB = 1,
+ /**< ECB mode */
+ SCC_CYPHER_MODE_CBC = 2,
+ /**< CBC mode */
+ } scc_cypher_mode_t;
+
+/**
+ * Allocate a partition of secure memory
+ *
+ * @param smid_value Value to use for the SMID register. Must be 0 for
+ * kernel mode ownership.
+ * @param[out] part_no (If successful) Assigned partition number.
+ * @param[out] part_base Kernel virtual address of the partition.
+ * @param[out] part_phys Physical address of the partition.
+ *
+ * @return SCC_RET_OK if successful.
+ */
+ extern scc_return_t
+ scc_allocate_partition(uint32_t smid_value,
+ int *part_no,
+ void **part_base, uint32_t *part_phys);
+
+/* Note: This function has to be run in the same context (userspace or kernel
+ * mode) as the process that will be using the partition. Because the SCC2 API
+ * is not accessible in user mode, this function is also provided as a macro in
+ * in fsl_shw.h. Kernel-mode users that include this file are able to use this
+ * version of the function without having to include the whole SHW API. If the
+ * macro definition was defined before we got here, un-define it so this
+ * version will be used instead.
+ */
+
+#ifdef scc_engage_partition
+#undef scc_engage_partition
+#endif
+
+/**
+ * Engage partition of secure memory
+ *
+ * @param part_base (kernel) Virtual
+ * @param UMID NULL, or 16-byte UMID for partition security
+ * @param permissions ORed values of the type SCM_PERM_* which will be used as
+ * initial partition permissions. SHW API users should use
+ * the FSL_PERM_* definitions instead.
+ *
+ * @return SCC_RET_OK if successful.
+ */
+ extern scc_return_t
+ scc_engage_partition(void *part_base,
+ const uint8_t *UMID, uint32_t permissions);
+
+/**
+ * Release a partition of secure memory
+ *
+ * @param part_base Kernel virtual address of the partition to be released.
+ *
+ * @return SCC_RET_OK if successful.
+ */
+ extern scc_return_t scc_release_partition(void *part_base);
+
+/**
+ * Diminish the permissions on a partition of secure memory
+ *
+ * @param part_base Kernel virtual address of the partition.
+ *
+ * @param permissions ORed values of the type SCM_PERM_* which will be used as
+ * initial partition permissions. SHW API users should use
+ * the FSL_PERM_* definitions instead.
+ *
+ * @return SCC_RET_OK if successful.
+ */
+ extern scc_return_t
+ scc_diminish_permissions(void *part_base, uint32_t permissions);
+
+/**
+ * Query the status of a partition of secure memory
+ *
+ * @param part_base Kernel virtual address of the partition.
+ *
+ * @return SCC_RET_OK if successful.
+ */
+ extern scc_partition_status_t scc_partition_status(void *part_base);
+
+/**
+ * Calculate the physical address from the kernel virtual address.
+ */
+ extern uint32_t scc_virt_to_phys(void *address);
+/*scc_return_t
+scc_verify_slot_access(uint64_t owner_id, uint32_t slot, uint32_t access_len);*/
+
+
+/**
+ * Encrypt a region of secure memory.
+ *
+ * @param part_base Kernel virtual address of the partition.
+ * @param offset_bytes Offset from the start of the partition to the plaintext
+ * data.
+ * @param byte_count Length of the region (octets).
+ * @param black_data Physical location to store the encrypted data.
+ * @param IV Value to use for the Initialization Vector.
+ * @param cypher_mode Cyphering mode to use, specified by type
+ * #scc_cypher_mode_t
+ *
+ * @return SCC_RET_OK if successful.
+ */
+ extern scc_return_t
+ scc_encrypt_region(uint32_t part_base, uint32_t offset_bytes,
+ uint32_t byte_count, uint8_t *black_data,
+ uint32_t *IV, scc_cypher_mode_t cypher_mode);
+
+/**
+ * Decrypt a region into secure memory
+ *
+ * @param part_base Kernel virtual address of the partition.
+ * @param offset_bytes Offset from the start of the partition to store the
+ * plaintext data.
+ * @param byte_count Length of the region (octets).
+ * @param black_data Physical location of the encrypted data.
+ * @param IV Value to use for the Initialization Vector.
+ * @param cypher_mode Cyphering mode to use, specified by type
+ * #scc_cypher_mode_t
+ *
+ * @return SCC_RET_OK if successful.
+ */
+ extern scc_return_t
+ scc_decrypt_region(uint32_t part_base, uint32_t offset_bytes,
+ uint32_t byte_count, uint8_t *black_data,
+ uint32_t *IV, scc_cypher_mode_t cypher_mode);
+
+/**
+ * Retrieve configuration information from the SCC.
+ *
+ * This function always succeeds.
+ *
+ * @return A pointer to the configuration information. This is a pointer to
+ * static memory and must not be freed. The values never change, and
+ * the return value will never be null.
+ */
+ extern scc_config_t *scc_get_configuration(void);
+
+/**
+ * Zeroize Red and Black memories of the SCC. This will start the Zeroizing
+ * process. The routine will return when the memories have zeroized or failed
+ * to do so. The driver will poll waiting for this to occur, so this
+ * routine must not be called from interrupt level. Some future version of
+ * driver may elect instead to sleep.
+ *
+ * @return 0 or error if initialization fails.
+ */
+ extern scc_return_t scc_zeroize_memories(void);
+
+/**
+ * Signal a software alarm to the SCC. This will take the SCC and other PISA
+ * parts out of Secure mode and into Security Failure mode. The SCC will stay
+ * in failed mode until a reboot.
+ *
+ * @internal
+ * If the SCC is not already in fail state, simply write the
+ * #SMN_COMMAND_SET_SOFTWARE_ALARM bit in #SMN_COMMAND_REG. Since there is no
+ * reason to wait for the interrupt to bounce back, simply act as though
+ * one did.
+ */
+ extern void scc_set_sw_alarm(void);
+
+/**
+ * This routine will register a function to be called should a Security Failure
+ * be signalled by the SCC (Security Monitor).
+ *
+ * The callback function may be called from interrupt level, it may be called
+ * from some process' task. It should therefore not take a long time to
+ * perform its operation, and it may not sleep.
+ *
+ * @param callback_func Function pointer to routine which will receive
+ * notification of the security failure.
+ * @return 0 if function was successfully registered, non-zero on
+ * failure. See #scc_return_t.
+ *
+ * @internal
+ * There is a fixed global static array which keeps track of the requests to
+ * monitor the failure.
+ *
+ * Add @c callback_func to the first empty slot in #scc_callbacks[]. If there
+ * is no room, return #SCC_RET_TOO_MANY_FUNCTIONS.
+ */
+ extern scc_return_t scc_monitor_security_failure(void
+ callback_func(void));
+
+/**
+ * This routine will deregister a function previously registered with
+ * #scc_monitor_security_failure().
+ *
+ * @param callback_func Function pointer to routine previously registered with
+ * #scc_stop_monitoring_security_failure().
+ */
+ extern void scc_stop_monitoring_security_failure(void
+ callback_func(void));
+
+/**
+ * Read value from an SCC register.
+ * The offset will be checked for validity (range) as well as whether it is
+ * accessible (e.g. not busy, not in failed state) at the time of the call.
+ *
+ * @param[in] register_offset The (byte) offset within the SCC block
+ * of the register to be queried. See
+ * @ref scmregs and @ref smnregs.
+ * @param[out] value Pointer to where value from the register
+ * should be placed.
+ * @return 0 if OK, non-zero on error. See #scc_return_t.
+ *
+ * @internal
+ * Verify that the register_offset is a) valid, b) refers to a readable
+ * register, and c) the SCC is in a state which would allow a read of this
+ * register.
+ */
+ extern scc_return_t scc_read_register(int register_offset,
+ uint32_t * value);
+
+/**
+ * Write a new value into an SCC register.
+ * The offset will be checked for validity (range) as well as whether it is
+ * accessible (e.g. not busy, not in failed state) at the time of the call.
+ *
+ * @param[in] register_offset The (byte) offset within the SCC block
+ * of the register to be modified. See
+ * @ref scmregs and @ref smnregs
+ * @param[in] value The value to store into the register.
+ * @return 0 if OK, non-zero on error. See #scc_return_t.
+ *
+ * @internal
+ * Verify that the register_offset is a) valid, b) refers to a writeable
+ * register, and c) the SCC is in a state which would allow a write to this
+ * register.
+ */
+ extern scc_return_t scc_write_register(int register_offset,
+ uint32_t value);
+
+/**
+ * @defgroup scmregs SCM Registers
+ *
+ * These values are offsets into the SCC for the Secure Memory
+ * (SCM) registers. They are used in the @c register_offset parameter of
+ * #scc_read_register() and #scc_write_register().
+ */
+/** @addtogroup scmregs */
+/** @{ */
+/** Offset of SCM Version ID Register */
+#define SCM_VERSION_REG 0x000
+/** Offset of SCM Interrupt Control Register */
+#define SCM_INT_CTL_REG 0x008
+/** Offset of SCM Status Register */
+#define SCM_STATUS_REG 0x00c
+/** Offset of SCM Error Status Register */
+#define SCM_ERR_STATUS_REG 0x010
+/** Offset of SCM Fault Address Register */
+#define SCM_FAULT_ADR_REG 0x014
+/** Offset of SCM Partition Owners Register */
+#define SCM_PART_OWNERS_REG 0x018
+/** Offset of SCM Partitions Engaged Register */
+#define SCM_PART_ENGAGED_REG 0x01c
+/** Offset of SCM Unique Number 0 Register */
+#define SCM_UNIQUE_ID0_REG 0x020
+/** Offset of SCM Unique Number 1 Register */
+#define SCM_UNIQUE_ID1_REG 0x024
+/** Offset of SCM Unique Number 2 Register */
+#define SCM_UNIQUE_ID2_REG 0x028
+/** Offset of SCM Unique Number 3 Register */
+#define SCM_UNIQUE_ID3_REG 0x02c
+/** Offset of SCM Zeroize Command Register */
+#define SCM_ZCMD_REG 0x050
+/** Offset of SCM Cipher Command Register */
+#define SCM_CCMD_REG 0x054
+/** Offset of SCM Cipher Black RAM Start Address Register */
+#define SCM_C_BLACK_ST_REG 0x058
+/** Offset of SCM Internal Debug Register */
+#define SCM_DBG_STATUS_REG 0x05c
+/** Offset of SCM Cipher IV 0 Register */
+#define SCM_AES_CBC_IV0_REG 0x060
+/** Offset of SCM Cipher IV 1 Register */
+#define SCM_AES_CBC_IV1_REG 0x064
+/** Offset of SCM Cipher IV 2 Register */
+#define SCM_AES_CBC_IV2_REG 0x068
+/** Offset of SCM Cipher IV 3 Register */
+#define SCM_AES_CBC_IV3_REG 0x06c
+/** Offset of SCM SMID Partition 0 Register */
+#define SCM_SMID0_REG 0x080
+/** Offset of SCM Partition 0 Access Permissions Register */
+#define SCM_ACC0_REG 0x084
+/** Offset of SCM SMID Partition 1 Register */
+#define SCM_SMID1_REG 0x088
+/** Offset of SCM Partition 1 Access Permissions Register */
+#define SCM_ACC1_REG 0x08c
+/** Offset of SCM SMID Partition 2 Register */
+#define SCM_SMID2_REG 0x090
+/** Offset of SCM Partition 2 Access Permissions Register */
+#define SCM_ACC2_REG 0x094
+/** Offset of SCM SMID Partition 3 Register */
+#define SCM_SMID3_REG 0x098
+/** Offset of SCM Partition 3 Access Permissions Register */
+#define SCM_ACC3_REG 0x09c
+/** Offset of SCM SMID Partition 4 Register */
+#define SCM_SMID4_REG 0x0a0
+/** Offset of SCM Partition 4 Access Permissions Register */
+#define SCM_ACC4_REG 0x0a4
+/** Offset of SCM SMID Partition 5 Register */
+#define SCM_SMID5_REG 0x0a8
+/** Offset of SCM Partition 5 Access Permissions Register */
+#define SCM_ACC5_REG 0x0ac
+/** Offset of SCM SMID Partition 6 Register */
+#define SCM_SMID6_REG 0x0b0
+/** Offset of SCM Partition 6 Access Permissions Register */
+#define SCM_ACC6_REG 0x0b4
+/** Offset of SCM SMID Partition 7 Register */
+#define SCM_SMID7_REG 0x0b8
+/** Offset of SCM Partition 7 Access Permissions Register */
+#define SCM_ACC7_REG 0x0bc
+/** Offset of SCM SMID Partition 8 Register */
+#define SCM_SMID8_REG 0x0c0
+/** Offset of SCM Partition 8 Access Permissions Register */
+#define SCM_ACC8_REG 0x0c4
+/** Offset of SCM SMID Partition 9 Register */
+#define SCM_SMID9_REG 0x0c8
+/** Offset of SCM Partition 9 Access Permissions Register */
+#define SCM_ACC9_REG 0x0cc
+/** Offset of SCM SMID Partition 10 Register */
+#define SCM_SMID10_REG 0x0d0
+/** Offset of SCM Partition 10 Access Permissions Register */
+#define SCM_ACC10_REG 0x0d4
+/** Offset of SCM SMID Partition 11 Register */
+#define SCM_SMID11_REG 0x0d8
+/** Offset of SCM Partition 11 Access Permissions Register */
+#define SCM_ACC11_REG 0x0dc
+/** Offset of SCM SMID Partition 12 Register */
+#define SCM_SMID12_REG 0x0e0
+/** Offset of SCM Partition 12 Access Permissions Register */
+#define SCM_ACC12_REG 0x0e4
+/** Offset of SCM SMID Partition 13 Register */
+#define SCM_SMID13_REG 0x0e8
+/** Offset of SCM Partition 13 Access Permissions Register */
+#define SCM_ACC13_REG 0x0ec
+/** Offset of SCM SMID Partition 14 Register */
+#define SCM_SMID14_REG 0x0f0
+/** Offset of SCM Partition 14 Access Permissions Register */
+#define SCM_ACC14_REG 0x0f4
+/** Offset of SCM SMID Partition 15 Register */
+#define SCM_SMID15_REG 0x0f8
+/** Offset of SCM Partition 15 Access Permissions Register */
+#define SCM_ACC15_REG 0x0fc
+/** @} */
+
+/** Number of bytes of register space for the SCM. */
+#define SCM_REG_BANK_SIZE 0x100
+
+/** Number of bytes of register space for the SCM. */
+#define SCM_REG_BANK_SIZE 0x100
+
+/** Offset of the SMN registers */
+#define SMN_ADDR_OFFSET 0x100
+
+/**
+ * @defgroup smnregs SMN Registers
+ *
+ * These values are offsets into the SCC for the Security Monitor
+ * (SMN) registers. They are used in the @c register_offset parameter of the
+ * #scc_read_register() and #scc_write_register().
+ */
+/** @addtogroup smnregs */
+/** @{ */
+/** Offset of SMN Status Register */
+#define SMN_STATUS_REG (SMN_ADDR_OFFSET+0x00000000)
+/** Offset of SMH Command Register */
+#define SMN_COMMAND_REG (SMN_ADDR_OFFSET+0x00000004)
+/** Offset of SMH Sequence Start Register */
+#define SMN_SEQ_START_REG (SMN_ADDR_OFFSET+0x00000008)
+/** Offset of SMH Sequence End Register */
+#define SMN_SEQ_END_REG (SMN_ADDR_OFFSET+0x0000000c)
+/** Offset of SMH Sequence Check Register */
+#define SMN_SEQ_CHECK_REG (SMN_ADDR_OFFSET+0x00000010)
+/** Offset of SMH BitBank Count Register */
+#define SMN_BB_CNT_REG (SMN_ADDR_OFFSET+0x00000014)
+/** Offset of SMH BitBank Increment Register */
+#define SMN_BB_INC_REG (SMN_ADDR_OFFSET+0x00000018)
+/** Offset of SMH BitBank Decrement Register */
+#define SMN_BB_DEC_REG (SMN_ADDR_OFFSET+0x0000001c)
+/** Offset of SMH Compare Register */
+#define SMN_COMPARE_REG (SMN_ADDR_OFFSET+0x00000020)
+/** Offset of SMH Plaintext Check Register */
+#define SMN_PT_CHK_REG (SMN_ADDR_OFFSET+0x00000024)
+/** Offset of SMH Ciphertext Check Register */
+#define SMN_CT_CHK_REG (SMN_ADDR_OFFSET+0x00000028)
+/** Offset of SMH Timer Initial Value Register */
+#define SMN_TIMER_IV_REG (SMN_ADDR_OFFSET+0x0000002c)
+/** Offset of SMH Timer Control Register */
+#define SMN_TIMER_CTL_REG (SMN_ADDR_OFFSET+0x00000030)
+/** Offset of SMH Security Violation Register */
+#define SMN_SEC_VIO_REG (SMN_ADDR_OFFSET+0x00000034)
+/** Offset of SMH Timer Register */
+#define SMN_TIMER_REG (SMN_ADDR_OFFSET+0x00000038)
+/** Offset of SMH High-Assurance Control Register */
+#define SMN_HAC_REG (SMN_ADDR_OFFSET+0x0000003c)
+/** Number of bytes allocated to the SMN registers */
+#define SMN_REG_BANK_SIZE 0x40
+/** @} */
+
+/** Number of bytes of total register space for the SCC. */
+#define SCC_ADDRESS_RANGE (SMN_ADDR_OFFSET + SMN_REG_BANK_SIZE)
+
+/**
+ * @defgroup smnstatusregdefs SMN Status Register definitions (SMN_STATUS)
+ */
+/** @addtogroup smnstatusregdefs */
+/** @{ */
+/** SMN version id. */
+#define SMN_STATUS_VERSION_ID_MASK 0xfc000000
+/** number of bits to shift #SMN_STATUS_VERSION_ID_MASK to get it to LSB */
+#define SMN_STATUS_VERSION_ID_SHIFT 28
+/** Illegal bus master access attempted. */
+#define SMN_STATUS_ILLEGAL_MASTER 0x01000000
+/** Scan mode entered/exited since last reset. */
+#define SMN_STATUS_SCAN_EXIT 0x00800000
+/** Some security peripheral is initializing */
+#define SMN_STATUS_PERIP_INIT 0x00010000
+/** Internal error detected in SMN. */
+#define SMN_STATUS_SMN_ERROR 0x00008000
+/** SMN has an outstanding interrupt. */
+#define SMN_STATUS_SMN_STATUS_IRQ 0x00004000
+/** Software Alarm was triggered. */
+#define SMN_STATUS_SOFTWARE_ALARM 0x00002000
+/** Timer has expired. */
+#define SMN_STATUS_TIMER_ERROR 0x00001000
+/** Plaintext/Ciphertext compare failed. */
+#define SMN_STATUS_PC_ERROR 0x00000800
+/** Bit Bank detected overflow or underflow */
+#define SMN_STATUS_BITBANK_ERROR 0x00000400
+/** Algorithm Sequence Check failed. */
+#define SMN_STATUS_ASC_ERROR 0x00000200
+/** Security Policy Block detected error. */
+#define SMN_STATUS_SECURITY_POLICY_ERROR 0x00000100
+/** Security Violation Active error. */
+#define SMN_STATUS_SEC_VIO_ACTIVE_ERROR 0x00000080
+/** Processor booted from internal ROM. */
+#define SMN_STATUS_INTERNAL_BOOT 0x00000020
+/** SMN's internal state. */
+#define SMN_STATUS_STATE_MASK 0x0000001F
+/** Number of bits to shift #SMN_STATUS_STATE_MASK to get it to LSB. */
+#define SMN_STATUS_STATE_SHIFT 0
+/** @} */
+
+/**
+ * @defgroup sccscmstates SMN Model Secure State Controller States (SMN_STATE_MASK)
+ */
+/** @addtogroup sccscmstates */
+/** @{ */
+/** This is the first state of the SMN after power-on reset */
+#define SMN_STATE_START 0x0
+/** The SMN is zeroizing its RAM during reset */
+#define SMN_STATE_ZEROIZE_RAM 0x5
+/** SMN has passed internal checks, and is waiting for Software check-in */
+#define SMN_STATE_HEALTH_CHECK 0x6
+/** Fatal Security Violation. SMN is locked, SCM is inoperative. */
+#define SMN_STATE_FAIL 0x9
+/** SCC is in secure state. SCM is using secret key. */
+#define SMN_STATE_SECURE 0xA
+/** Due to non-fatal error, device is not secure. SCM is using default key. */
+#define SMN_STATE_NON_SECURE 0xC
+/** @} */
+
+/** @{ */
+/** SCM Status bit: Key Status is Default Key in Use */
+#define SCM_STATUS_KST_DEFAULT_KEY 0x80000000
+/** SCM Status bit: Key Status is (reserved) */
+#define SCM_STATUS_KST_RESERVED1 0x40000000
+/** SCM Status bit: Key status is Wrong Key */
+#define SCM_STATUS_KST_WRONG_KEY 0x20000000
+/** SCM Status bit: Bad Key detected */
+#define SCM_STATUS_KST_BAD_KEY 0x10000000
+/** SCM Status bit: Error has occurred */
+#define SCM_STATUS_ERR 0x00008000
+/** SCM Status bit: Monitor State is Failed */
+#define SCM_STATUS_MSS_FAIL 0x00004000
+/** SCM Status bit: Monitor State is Secure */
+#define SCM_STATUS_MSS_SEC 0x00002000
+/** SCM Status bit: Secure Storage is Failed */
+#define SCM_STATUS_RSS_FAIL 0x00000400
+/** SCM Status bit: Secure Storage is Secure */
+#define SCM_STATUS_RSS_SEC 0x00000200
+/** SCM Status bit: Secure Storage is Initializing */
+#define SCM_STATUS_RSS_INIT 0x00000100
+/** SCM Status bit: Unique Number Valid */
+#define SCM_STATUS_UNV 0x00000080
+/** SCM Status bit: Big Endian mode */
+#define SCM_STATUS_BIG 0x00000040
+/** SCM Status bit: Using Secret Key */
+#define SCM_STATUS_USK 0x00000020
+/** SCM Status bit: Ram is being blocked */
+#define SCM_STATUS_BAR 0x00000010
+/** Bit mask of SRS */
+#define SCM_STATUS_SRS_MASK 0x0000000F
+/** Number of bits to shift SRS to/from MSb */
+#define SCM_STATUS_SRS_SHIFT 0
+/** @} */
+
+#define SCM_STATUS_SRS_RESET 0x0 /**< Reset, Zeroise All */
+#define SCM_STATUS_SRS_READY 0x1 /**< All Ready */
+#define SCM_STATUS_SRS_ZBUSY 0x2 /**< Zeroize Busy (Partition Only) */
+#define SCM_STATUS_SRS_CBUSY 0x3 /**< Cipher Busy */
+#define SCM_STATUS_SRS_ABUSY 0x4 /**< All Busy */
+#define SCM_STATUS_SRS_ZDONE 0x5 /**< Zeroize Done, Cipher Ready */
+#define SCM_STATUS_SRS_CDONE 0x6 /**< Cipher Done, Zeroize Ready */
+#define SCM_STATUS_SRS_ZDONE2 0x7 /**< Zeroize Done, Cipher Busy */
+#define SCM_STATUS_SRS_CDONE2 0x8 /**< Cipher Done, Zeroize Busy */
+#define SCM_STATUS_SRS_ADONE 0xD /**< All Done */
+
+/* Format of the SCM VERSION ID REGISTER */
+#define SCM_VER_BPP_MASK 0xFF000000 /**< Bytes Per Partition Mask */
+#define SCM_VER_BPP_SHIFT 24 /**< Bytes Per Partition Shift */
+#define SCM_VER_BPCB_MASK 0x001F0000 /**< Bytes Per Cipher Block Mask */
+#define SCM_VER_BPCB_SHIFT 16 /**< Bytes Per Cipher Block Shift */
+#define SCM_VER_NP_MASK 0x0000F000 /**< Number of Partitions Mask */
+#define SCM_VER_NP_SHIFT 12 /**< Number of Partitions Shift */
+#define SCM_VER_MAJ_MASK 0x00000F00 /**< Major Version Mask */
+#define SCM_VER_MAJ_SHIFT 8 /**< Major Version Shift */
+#define SCM_VER_MIN_MASK 0x000000FF /**< Minor Version Mask */
+#define SCM_VER_MIN_SHIFT 0 /**< Minor Version Shift */
+
+/**< SCC Hardware version supported by this driver */
+#define SCM_MAJOR_VERSION_2 2
+
+/* Format of the SCM ERROR STATUS REGISTER */
+#define SCM_ERRSTAT_MID_MASK 0x00F00000 /**< Master ID Mask */
+#define SCM_ERRSTAT_MID_SHIFT 20 /**< Master ID Shift */
+#define SCM_ERRSTAT_ILM 0x00080000 /**< Illegal Master */
+#define SCM_ERRSTAT_SUP 0x00008000 /**< Supervisor Access */
+#define SCM_ERRSTAT_ERC_MASK 0x00000F00 /**< Error Code Mask */
+#define SCM_ERRSTAT_ERC_SHIFT 8 /**< Error Code Shift */
+#define SCM_ERRSTAT_SMS_MASK 0x000000F0 /**< Secure Monitor State Mask */
+#define SCM_ERRSTAT_SMS_SHIFT 4 /**< Secure Monitor State Shift */
+#define SCM_ERRSTAT_SRS_MASK 0x0000000F /**< Secure Ram State Mask */
+#define SCM_ERRSTAT_SRS_SHIFT 0 /**< Secure Ram State Shift */
+
+/* SCM ERROR STATUS REGISTER ERROR CODES */
+#define SCM_ERCD_UNK_ADDR 0x1 /**< Unknown Address */
+#define SCM_ERCD_UNK_CMD 0x2 /**< Unknown Command */
+#define SCM_ERCD_READ_PERM 0x3 /**< Read Permission Error */
+#define SCM_ERCD_WRITE_PERM 0x4 /**< Write Permission Error */
+#define SCM_ERCD_DMA_ERROR 0x5 /**< DMA Error */
+#define SCM_ERCD_BLK_OVFL 0x6 /**< Encryption Block Length Overflow */
+#define SCM_ERCD_NO_KEY 0x7 /**< Key Not Engaged */
+#define SCM_ERCD_ZRZ_OVFL 0x8 /**< Zeroize Command Queue Overflow */
+#define SCM_ERCD_CPHR_OVFL 0x9 /**< Cipher Command Queue Overflow */
+#define SCM_ERCD_PROC_INTR 0xA /**< Process Interrupted */
+#define SCM_ERCD_WRNG_KEY 0xB /**< Wrong Key */
+#define SCM_ERCD_DEVICE_BUSY 0xC /**< Device Busy */
+#define SCM_ERCD_UNALGN_ADDR 0xD /**< DMA Unaligned Address */
+
+/* Format of the CIPHER COMMAND REGISTER */
+#define SCM_CCMD_LENGTH_MASK 0xFFF00000 /**< Cipher Length Mask */
+#define SCM_CCMD_LENGTH_SHIFT 20 /**< Cipher Length Shift */
+#define SCM_CCMD_OFFSET_MASK 0x000FFF00 /**< Block Offset Mask */
+#define SCM_CCMD_OFFSET_SHIFT 8 /**< Block Offset Shift */
+#define SCM_CCMD_PART_MASK 0x000000F0 /**< Partition Number Mask */
+#define SCM_CCMD_PART_SHIFT 4 /**< Partition Number Shift */
+#define SCM_CCMD_CCMD_MASK 0x0000000F /**< Cipher Command Mask */
+#define SCM_CCMD_CCMD_SHIFT 0 /**< Cipher Command Shift */
+
+/* Values for SCM_CCMD_CCMD field */
+#define SCM_CCMD_AES_DEC_ECB 1 /**< Decrypt without Chaining (ECB) */
+#define SCM_CCMD_AES_ENC_ECB 3 /**< Encrypt without Chaining (ECB) */
+#define SCM_CCMD_AES_DEC_CBC 5 /**< Decrypt with Chaining (CBC) */
+#define SCM_CCMD_AES_ENC_CBC 7 /**< Encrypt with Chaining (CBC) */
+
+#define SCM_CCMD_AES 1 /**< Use AES Mode */
+#define SCM_CCMD_DEC 0 /**< Decrypt */
+#define SCM_CCMD_ENC 2 /**< Encrypt */
+#define SCM_CCMD_ECB 0 /**< Perform operation without chaining (ECB) */
+#define SCM_CCMD_CBC 4 /**< Perform operation with chaining (CBC) */
+
+/* Format of the ZEROIZE COMMAND REGISTER */
+#define SCM_ZCMD_PART_MASK 0x000000F0 /**< Target Partition Mask */
+#define SCM_ZCMD_PART_SHIFT 4 /**< Target Partition Shift */
+#define SCM_ZCMD_CCMD_MASK 0x0000000F /**< Zeroize Command Mask */
+#define SCM_ZCMD_CCMD_SHIFT 0 /**< Zeroize Command Shift */
+
+/* MASTER ACCESS PERMISSIONS REGISTER */
+/* Note that API users should use the FSL_PERM_ defines instead of these */
+/** SCM Access Permission: Do not zeroize/deallocate partition
+ on SMN Fail state */
+#define SCM_PERM_NO_ZEROIZE 0x10000000
+/** SCM Access Permission: Ignore Supervisor/User mode
+ in permission determination */
+#define SCM_PERM_HD_SUP_DISABLE 0x00000800
+/** SCM Access Permission: Allow Read Access to Host Domain */
+#define SCM_PERM_HD_READ 0x00000400
+/** SCM Access Permission: Allow Write Access to Host Domain */
+#define SCM_PERM_HD_WRITE 0x00000200
+/** SCM Access Permission: Allow Execute Access to Host Domain */
+#define SCM_PERM_HD_EXECUTE 0x00000100
+/** SCM Access Permission: Allow Read Access to Trusted Host Domain */
+#define SCM_PERM_TH_READ 0x00000040
+/** SCM Access Permission: Allow Write Access to Trusted Host Domain */
+#define SCM_PERM_TH_WRITE 0x00000020
+/** SCM Access Permission: Allow Read Access to Other/World Domain */
+#define SCM_PERM_OT_READ 0x00000004
+/** SCM Access Permission: Allow Write Access to Other/World Domain */
+#define SCM_PERM_OT_WRITE 0x00000002
+/** SCM Access Permission: Allow Execute Access to Other/World Domain */
+#define SCM_PERM_OT_EXECUTE 0x00000001
+/**< Valid bits that can be set in the Permissions register */
+#define SCM_PERM_MASK 0xC0000F67
+
+/* Zeroize Command register definitions */
+#define ZCMD_DEALLOC_PART 3 /**< Deallocate Partition */
+#define Z_INT_EN 0x00000002 /**< Zero Interrupt Enable */
+
+/**
+ * @defgroup scmpartitionownersregdefs SCM Partition Owners Register
+ */
+/** @addtogroup scmpartitionownersregdefs */
+/** @{ */
+/** Number of bits to shift partition number to get to its field. */
+#define SCM_POWN_SHIFT 2
+/** Mask for a field once the register has been shifted. */
+#define SCM_POWN_MASK 3
+/** Partition is free */
+#define SCM_POWN_PART_FREE 0
+/** Partition is unable to be allocated */
+#define SCM_POWN_PART_UNUSABLE 1
+/** Partition is owned by another master */
+#define SCM_POWN_PART_OTHER 2
+/** Partition is owned by this master */
+#define SCM_POWN_PART_OWNED 3
+/** @} */
+
+/**
+ * @defgroup smnpartitionsengagedregdefs SCM Partitions Engaged Register
+ */
+/** @addtogroup smnpartitionsengagedregdefs */
+/** @{ */
+/** Number of bits to shift partition number to get to its field. */
+#define SCM_PENG_SHIFT 1
+/** Engaged value for a field once the register has been shifted. */
+#define SCM_PENG_ENGAGED 1
+/** @} */
+
+/** Number of bytes between each subsequent SMID register */
+#define SCM_SMID_WIDTH 8
+
+/**
+ * @defgroup smncommandregdefs SMN Command Register Definitions (SMN_COMMAND_REG)
+ */
+/** @addtogroup smncommandregdefs */
+/** @{ */
+
+/** These bits are unimplemented or reserved */
+#define SMN_COMMAND_ZEROS_MASK 0xfffffff0
+#define SMN_COMMAND_CLEAR_INTERRUPT 0x8 /**< Clear SMN Interrupt */
+#define SMN_COMMAND_CLEAR_BIT_BANK 0x4 /**< Clear SMN Bit Bank */
+#define SMN_COMMAND_ENABLE_INTERRUPT 0x2 /**< Enable SMN Interrupts */
+#define SMN_COMMAND_SET_SOFTWARE_ALARM 0x1 /**< Set Software Alarm */
+/** @} */
+
+/**
+ * @defgroup smntimercontroldefs SMN Timer Control Register definitions (SMN_TIMER_CONTROL)
+ */
+/** @addtogroup smntimercontroldefs */
+/** @{ */
+/** These bits are reserved or zero */
+#define SMN_TIMER_CTRL_ZEROS_MASK 0xfffffffc
+/** Load the timer from #SMN_TIMER_IV_REG */
+#define SMN_TIMER_LOAD_TIMER 0x2
+/** Setting to zero stops the Timer */
+#define SMN_TIMER_STOP_MASK 0x1
+/** Setting this value starts the timer */
+#define SMN_TIMER_START_TIMER 0x1
+/** @} */
+
+/**
+ * @defgroup scmchainmodedefs SCM_CHAINING_MODE_MASK - Bit definitions
+ */
+/** @addtogroup scmchainmodedefs */
+/** @{ */
+#define SCM_CBC_MODE 0x2 /**< Cipher block chaining */
+#define SCM_ECB_MODE 0x0 /**< Electronic codebook. */
+/** @} */
+
+/* Bit definitions in the SCM_CIPHER_MODE_MASK */
+/**
+ * @defgroup scmciphermodedefs SCM_CIPHER_MODE_MASK - Bit definitions
+ */
+/** @addtogroup scmciphermodedefs */
+/** @{ */
+#define SCM_DECRYPT_MODE 0x1 /**< decrypt from black to red memory */
+#define SCM_ENCRYPT_MODE 0x0 /**< encrypt from red to black memory */
+/** @} */
+
+/**
+ * @defgroup smndbgdetdefs SMN Debug Detector Status Register (SCM_DEBUG_DETECT_STAT)
+ */
+/** @addtogroup smndbgdetdefs */
+/** @{ */
+#define SMN_DBG_ZEROS_MASK 0xfffff000 /**< These bits are zero or reserved */
+#define SMN_DBG_D12 0x0800 /**< Error detected on Debug Port D12 */
+#define SMN_DBG_D11 0x0400 /**< Error detected on Debug Port D11 */
+#define SMN_DBG_D10 0x0200 /**< Error detected on Debug Port D10 */
+#define SMN_DBG_D9 0x0100 /**< Error detected on Debug Port D9 */
+#define SMN_DBG_D8 0x0080 /**< Error detected on Debug Port D8 */
+#define SMN_DBG_D7 0x0040 /**< Error detected on Debug Port D7 */
+#define SMN_DBG_D6 0x0020 /**< Error detected on Debug Port D6 */
+#define SMN_DBG_D5 0x0010 /**< Error detected on Debug Port D5 */
+#define SMN_DBG_D4 0x0008 /**< Error detected on Debug Port D4 */
+#define SMN_DBG_D3 0x0004 /**< Error detected on Debug Port D3 */
+#define SMN_DBG_D2 0x0002 /**< Error detected on Debug Port D2 */
+#define SMN_DBG_D1 0x0001 /**< Error detected on Debug Port D1 */
+/** @} */
+
+/** Mask for the usable bits of the Sequence Start Register
+ (#SMN_SEQ_START_REG) */
+#define SMN_SEQUENCE_START_MASK 0x0000ffff
+
+/** Mask for the usable bits of the Sequence End Register
+ (#SMN_SEQ_END_REG) */
+#define SMN_SEQUENCE_END_MASK 0x0000ffff
+
+/** Mask for the usable bits of the Sequence Check Register
+ (#SMN_SEQ_CHECK_REG) */
+#define SMN_SEQUENCE_CHECK_MASK 0x0000ffff
+
+/** Mask for the usable bits of the Bit Counter Register
+ (#SMN_BB_CNT_REG) */
+#define SMN_BIT_COUNT_MASK 0x000007ff
+
+/** Mask for the usable bits of the Bit Bank Increment Size Register
+ (#SMN_BB_INC_REG) */
+#define SMN_BITBANK_INC_SIZE_MASK 0x000007ff
+
+/** Mask for the usable bits of the Bit Bank Decrement Register
+ (#SMN_BB_DEC_REG) */
+#define SMN_BITBANK_DECREMENT_MASK 0x000007ff
+
+/** Mask for the usable bits of the Compare Size Register
+ (#SMN_COMPARE_REG) */
+#define SMN_COMPARE_SIZE_MASK 0x0000003f
+
+/*! @} */
+
+#endif /* SCC_DRIVER_H */
diff --git a/arch/arm/plat-mxc/include/mach/mxc_scc_driver.h b/arch/arm/plat-mxc/include/mach/mxc_scc_driver.h
new file mode 100644
index 000000000000..5f1e1bbe8117
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_scc_driver.h
@@ -0,0 +1,1031 @@
+
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_SCC_DRIVER_H__
+#define __ASM_ARCH_MXC_SCC_DRIVER_H__
+
+/* Start marker for C++ compilers */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * NAMING CONVENTIONS
+ * ==================
+ * (A note to maintainers and other interested parties)
+ *
+ * Use scc_ or SCC_ prefix for 'high-level' interface routines and the types
+ * passed to those routines. Try to avoid #defines in these interfaces.
+ *
+ * Use SMN_ or SCM_ prefix for the #defines used with scc_read_register() and
+ * scc_write_register, or values passed/retrieved from those routines.
+ */
+
+/*!
+ * @defgroup MXCSCC SCC Driver
+ *
+ * @ingroup MXCSECDRVRS
+ */
+
+/*!
+ * @file arch-mxc/mxc_scc_driver.h
+ *
+ * @brief (Header file to use the SCC driver.)
+ *
+ * The SCC driver will only be available to other kernel modules. That is,
+ * there will be no node file in /dev, no way for a user-mode program to access
+ * the driver, no way for a user program to access the device directly.
+ *
+ * With the exception of #scc_monitor_security_failure(), all routines are
+ * 'synchronous', i.e. they will not return to their caller until the requested
+ * action is complete, or fails to complete. Some of these functions could
+ * take quite a while to perform, depending upon the request.
+ *
+ * Routines are provided to:
+ * @li encrypt or decrypt secrets - #scc_crypt()
+ * @li trigger a security-violation alarm - #scc_set_sw_alarm()
+ * @li get configuration and version information - #scc_get_configuration()
+ * @li zeroize memory - #scc_zeroize_memories()
+ * @li Work on wrapped and stored secret values: #scc_alloc_slot(),
+ * #scc_dealloc_slot(), scc_load_slot(), #scc_decrypt_slot(),
+ * #scc_encrypt_slot(), #scc_get_slot_info()
+
+ * @li monitor the Security Failure alarm - #scc_monitor_security_failure()
+ * @li stop monitoring Security Failure alarm -
+ * #scc_stop_monitoring_security_failure()
+ * @li write registers of the SCC - #scc_write_register()
+ * @li read registers of the SCC - #scc_read_register()
+ *
+ * The driver does not allow "storage" of data in either the Red or Black
+ * memories. Any decrypted secret is returned to the user, and if the user
+ * wants to use it at a later point, the encrypted form must again be passed
+ * to the driver, and it must be decrypted again.
+ *
+ * The SCC encrypts and decrypts using Triple DES with an internally stored
+ * key. When the SCC is in Secure mode, it uses its secret, unique-per-chip
+ * key. When it is in Non-Secure mode, it uses a default key. This ensures
+ * that secrets stay secret if the SCC is not in Secure mode.
+ *
+ * Not all functions that could be provided in a 'high level' manner have been
+ * implemented. Among the missing are interfaces to the ASC/AIC components and
+ * the timer functions. These and other features must be accessed through
+ * #scc_read_register() and #scc_write_register(), using the @c \#define values
+ * provided.
+ *
+ * Here is a glossary of acronyms used in the SCC driver documentation:
+ * - CBC - Cipher Block Chaining. A method of performing a block cipher.
+ * Each block is encrypted using some part of the result of the previous
+ * block's encryption. It needs an 'initialization vector' to seed the
+ * operation.
+ * - ECB - Electronic Code Book. A method of performing a block cipher.
+ * With a given key, a given block will always encrypt to the same value.
+ * - DES - Data Encryption Standard. (8-byte) Block cipher algorithm which
+ * uses 56-bit keys. In SCC, this key is constant and unique to the device.
+ * SCC uses the "triple DES" form of this algorithm.
+ * - AIC - Algorithm Integrity Checker.
+ * - ASC - Algorithm Sequence Checker.
+ * - SMN - Security Monitor. The part of the SCC responsible for monitoring
+ * for security problems and notifying the CPU and other PISA components.
+ * - SCM - Secure Memory. The part of the SCC which handles the cryptography.
+ * - SCC - Security Controller. Central security mechanism for PISA.
+ * - PISA - Platform-Independent Security Architecture.
+ */
+
+/* Temporarily define compile-time flags to make Doxygen happy. */
+#ifdef DOXYGEN_HACK
+/*! @defgroup scccompileflags SCC Driver compile-time flags
+ *
+ * These preprocessor flags should be set, if desired, in a makefile so
+ * that they show up on the compiler command line.
+ */
+/*! @addtogroup scccompileflags */
+
+/*! @{ */
+/*!
+ * Compile-time flag to change @ref smnregs and @ref scmregs
+ * offset values for the SCC's implementation on the MX.21 board.
+ *
+ * This must also be set properly for any code which calls the
+ * scc_read_register() or scc_write_register() functions or references the
+ * register offsets.
+ */
+#define TAHITI
+/*! @} */
+#undef TAHITI
+
+#endif /* DOXYGEN_HACK */
+
+/*! Major Version of the driver. Used for
+ scc_configuration->driver_major_version */
+#define SCC_DRIVER_MAJOR_VERSION_1 1
+/*! Old Minor Version of the driver. */
+#define SCC_DRIVER_MINOR_VERSION_0 0
+/*! Old Minor Version of the driver. */
+#define SCC_DRIVER_MINOR_VERSION_4 4
+/*! Old Minor Version of the driver. */
+#define SCC_DRIVER_MINOR_VERSION_5 5
+/*! Old Minor Version of the driver. */
+#define SCC_DRIVER_MINOR_VERSION_6 6
+/*! Minor Version of the driver. Used for
+ scc_configuration->driver_minor_version */
+#define SCC_DRIVER_MINOR_VERSION_8 8
+
+
+/*!
+ * @typedef scc_return_t
+ */
+/*! Common status return values from SCC driver functions. */
+ typedef enum scc_return_t {
+ SCC_RET_OK = 0, /*!< Function succeeded */
+ SCC_RET_FAIL, /*!< Non-specific failure */
+ SCC_RET_VERIFICATION_FAILED, /*!< Decrypt validation failed */
+ SCC_RET_TOO_MANY_FUNCTIONS, /*!< At maximum registered functions */
+ SCC_RET_BUSY, /*!< SCC is busy and cannot handle request */
+ SCC_RET_INSUFFICIENT_SPACE, /*!< Encryption or decryption failed because
+ @c count_out_bytes says that @c data_out is
+ too small to hold the value. */
+ } scc_return_t;
+
+/*!
+ * Configuration information about SCC and the driver.
+ *
+ * This struct/typedef contains information from the SCC and the driver to
+ * allow the user of the driver to determine the size of the SCC's memories and
+ * the version of the SCC and the driver.
+ */
+ typedef struct scc_config_t {
+ int driver_major_version; /*!< Major version of the SCC driver code */
+ int driver_minor_version; /*!< Minor version of the SCC driver code */
+ int scm_version; /*!< Version from SCM Configuration register */
+ int smn_version; /*!< Version from SMN Status register */
+ int block_size_bytes; /*!< Number of bytes per block of RAM; also
+ block size of the crypto algorithm. */
+ int black_ram_size_blocks; /*!< Number of blocks of Black RAM */
+ int red_ram_size_blocks; /*!< Number of blocks of Red RAM */
+ } scc_config_t;
+
+/*!
+ * @typedef scc_enc_dec_t
+ */
+/*!
+ * Determine whether SCC will run its cryptographic
+ * function as an encryption or decryption. Used as an argument to
+ * #scc_crypt().
+ */
+ typedef enum scc_enc_dec_t {
+ SCC_ENCRYPT, /*!< Encrypt (from Red to Black) */
+ SCC_DECRYPT /*!< Decrypt (from Black to Red) */
+ } scc_enc_dec_t;
+
+/*
+ * @typedef scc_crypto_mode_t
+ */
+/*!
+ * Determine whether SCC will run its cryptographic function in ECB (electronic
+ * codebook) or CBC (cipher-block chaining) mode. Used as an argument to
+ * #scc_crypt().
+ */
+ typedef enum scc_crypto_mode_t {
+ SCC_ECB_MODE, /*!< Electronic Codebook Mode */
+ SCC_CBC_MODE /*!< Cipher Block Chaining Mode */
+ } scc_crypto_mode_t;
+
+/*!
+ * @typedef scc_verify_t
+ */
+/*!
+ * Tell the driver whether it is responsible for verifying the integrity of a
+ * secret. During an encryption, using other than #SCC_VERIFY_MODE_NONE will
+ * cause a check value to be generated and appended to the plaintext before
+ * encryption. During decryption, the check value will be verified after
+ * decryption, and then stripped from the message.
+ */
+ typedef enum scc_verify_t {
+ /*! No verification value added or checked. Input plaintext data must be
+ * be a multiple of the blocksize (#scc_get_configuration()). */
+ SCC_VERIFY_MODE_NONE,
+ /*! Driver will generate/validate a 2-byte CCITT CRC. Input plaintext will
+ be padded to a multiple of the blocksize, adding 3-10 bytes to the
+ resulting output ciphertext. Upon decryption, this padding will be
+ stripped, and the CRC will be verified. */
+ SCC_VERIFY_MODE_CCITT_CRC
+ } scc_verify_t;
+
+/*!
+ * Determine if the given credentials match that of the key slot.
+ *
+ * @param[in] owner_id A value which will control access to the slot.
+ * @param[in] slot Key Slot to query
+ * @param[in] access_len Length of the key
+ *
+ * @return 0 on success, non-zero on failure. See #scc_return_t.
+ */
+ scc_return_t
+ scc_verify_slot_access(uint64_t owner_id, uint32_t slot,
+ uint32_t access_len);
+
+/*!
+ * Retrieve configuration information from the SCC.
+ *
+ * This function always succeeds.
+ *
+ * @return A pointer to the configuration information. This is a pointer to
+ * static memory and must not be freed. The values never change, and
+ * the return value will never be null.
+ */
+ extern scc_config_t *scc_get_configuration(void);
+
+/*!
+ * Zeroize Red and Black memories of the SCC. This will start the Zeroizing
+ * process. The routine will return when the memories have zeroized or failed
+ * to do so. The driver will poll waiting for this to occur, so this
+ * routine must not be called from interrupt level. Some future version of
+ * driver may elect instead to sleep.
+ *
+ * @return 0 or error if initialization fails.
+ */
+ extern scc_return_t scc_zeroize_memories(void);
+
+/*!
+ * Perform a Triple DES encryption or decryption operation.
+ *
+ * This routine will cause the SCM to perform an encryption or decryption with
+ * its internal key. If the SCC's #SMN_STATUS register shows that the SCC is
+ * in #SMN_STATE_SECURE, then the Secret Key will be used. If it is
+ * #SMN_STATE_NON_SECURE (or health check), then the Default Key will be used.
+ *
+ * This function will perform in a variety of ways, depending upon the values
+ * of @c direction, @c crypto_mode, and @c check_mode. If
+ * #SCC_VERIFY_MODE_CCITT_CRC mode is requested, upon successful completion,
+ * the @c count_in_bytes will be different from the returned value of @c
+ * count_out_bytes. This is because the two-byte CRC and some amount of
+ * padding (at least one byte) will either be added or stripped.
+ *
+ * This function will not return until the SCC has performed the operation (or
+ * reported failure to do so). It must therefore not be called from interrupt
+ * level. In the current version, it will poll the SCC for completion. In
+ * future versions, it may sleep.
+ *
+ * @param[in] count_in_bytes The number of bytes to move through the crypto
+ * function. Must be greater than zero.
+ *
+ * @param[in] data_in Pointer to the array of bytes to be used as input
+ * to the crypto function.
+ *
+ * @param[in] init_vector Pointer to the block-sized (8 byte) array of
+ * bytes which form the initialization vector for
+ * this operation. A non-null value is required
+ * when @c crypto_mode has the value #SCC_CBC_MODE;
+ * the value is ignored in #SCC_ECB_MODE.
+ *
+ * @param[in] direction Direct the driver to perform encryption or
+ * decryption.
+ *
+ * @param[in] crypto_mode Run the crypto function in ECB or CBC mode.
+ *
+ * @param[in] check_mode During encryption, generate and append a check
+ * value to the plaintext and pad the resulting
+ * data. During decryption, validate the plaintext
+ * with that check value and remove the padding.
+ *
+ * @param[in,out] count_out_bytes On input, the number of bytes available for
+ * copying to @c data_out. On return, the number of
+ * bytes copied to @c data_out.
+ *
+ * @param[out] data_out Pointer to the array of bytes that are where the
+ * output of the crypto function are to be placed.
+ * For encryption, this must be able to hold a
+ * longer ciphertext than the plaintext message at
+ * @c data_in. The driver will append a 'pad' of
+ * 1-8 bytes to the message, and if @c check_mode is
+ * used, additional bytes may be added, the number
+ * depending upon the type of check being requested.
+ *
+ * @return 0 on success, non-zero on failure. See #scc_return_t.
+ *
+ * @internal
+ * This function will verify SCC state and the functions parameters. It will
+ * acquire the crypto lock, and set up some SCC registers and variables common
+ * to encryption and decryption. A rough check will be made to verify that
+ * enough space is available in @c count_out_bytes. Upon success, either the
+ * #scc_encrypt or #scc_decrypt routine will be called to do the actual work.
+ * The crypto lock will then be released.
+ */
+extern scc_return_t scc_crypt(unsigned long count_in_bytes,
+ const uint8_t * data_in,
+ const uint8_t * init_vector,
+ scc_enc_dec_t direction,
+ scc_crypto_mode_t crypto_mode,
+ scc_verify_t check_mode,
+ uint8_t * data_out,
+ unsigned long *count_out_bytes);
+
+
+/*!
+ * Allocate a key slot for a stored key (or other stored value).
+ *
+ * This feature is to allow decrypted secret values to be kept in RED RAM.
+ * This can all visibility of the data only by Sahara.
+ *
+ * @param value_size_bytes Size, in bytes, of RED key/value. Currently only
+ * a size up to 32 bytes is supported.
+ *
+ * @param owner_id A value which will control access to the slot.
+ * It must be passed into to any subsequent calls to
+ * use the assigned slot.
+ *
+ * @param[out] slot The slot number for the key.
+ *
+ * @return 0 on success, non-zero on failure. See #scc_return_t.
+ */
+ extern scc_return_t scc_alloc_slot(uint32_t value_size_bytes,
+ uint64_t owner_id, uint32_t * slot);
+
+/*!
+ * Deallocate the key slot of a stored key or secret value.
+ *
+ * @param owner_id The id which owns the @c slot.
+ *
+ * @param slot The slot number for the key.
+
+ * @return 0 on success, non-zero on failure. See #scc_return_t.
+ */
+ extern scc_return_t scc_dealloc_slot(uint64_t owner_id, uint32_t slot);
+
+/*!
+ * Load a value into a slot.
+ *
+ * @param owner_id Value of owner of slot
+ * @param slot Handle of slot
+ * @param key_data Data to load into the slot
+ * @param key_length Length, in bytes, of @c key_data to copy to SCC.
+ *
+ * @return SCC_RET_OK on success. SCC_RET_FAIL will be returned if slot
+ * specified cannot be accessed for any reason, or SCC_RET_INSUFFICIENT_SPACE
+ * if @c key_length exceeds the size of the slot.
+ */
+ extern scc_return_t scc_load_slot(uint64_t owner_id, uint32_t slot,
+ const uint8_t * key_data,
+ uint32_t key_length);
+/*!
+ * Read a value from a slot.
+ *
+ * @param owner_id Value of owner of slot
+ * @param slot Handle of slot
+ * @param key_length Length, in bytes, of @c key_data to copy from SCC.
+ * @param key_data Location to write the key
+ *
+ * @return SCC_RET_OK on success. SCC_RET_FAIL will be returned if slot
+ * specified cannot be accessed for any reason, or SCC_RET_INSUFFICIENT_SPACE
+ * if @c key_length exceeds the size of the slot.
+ */
+ extern scc_return_t scc_read_slot(uint64_t owner_id, uint32_t slot,
+ uint32_t key_length,
+ uint8_t * key_data);
+
+/*!
+ * Allocate a key slot to fit the requested size.
+ *
+ * @param owner_id Value of owner of slot
+ * @param slot Handle of slot
+ * @param length Length, in bytes, of @c black_data
+ * @param black_data Location to store result of encrypting RED data in slot
+ *
+ * @return SCC_RET_OK on success, SCC_RET_FAIL if slot specified cannot be
+ * accessed for any reason.
+ */
+ extern scc_return_t scc_encrypt_slot(uint64_t owner_id, uint32_t slot,
+ uint32_t length,
+ uint8_t * black_data);
+
+/*!
+ * Decrypt some black data and leave result in the slot.
+ *
+ * @param owner_id Value of owner of slot
+ * @param slot Handle of slot
+ * @param length Length, in bytes, of @c black_data
+ * @param black_data Location of data to dencrypt and store in slot
+ *
+ * @return SCC_RET_OK on success, SCC_RET_FAIL if slot specified cannot be
+ * accessed for any reason.
+ */
+ extern scc_return_t scc_decrypt_slot(uint64_t owner_id, uint32_t slot,
+ uint32_t length,
+ const uint8_t * black_data);
+
+/*!
+ * Get attributes of data in RED slot.
+ *
+ * @param owner_id The id which owns the @c slot.
+ *
+ * @param slot The slot number for the key.
+ *
+ * @param[out] address Physical address of RED value.
+ *
+ * @param[out] value_size_bytes Length, in bytes, of RED value,
+ * or NULL if unneeded..
+ *
+ * @param[out] slot_size_bytes Length, in bytes, of slot size,
+ * or NULL if unneeded..
+ *
+ * @return 0 on success, non-zero on failure. See #scc_return_t.
+ */
+ extern scc_return_t scc_get_slot_info(uint64_t owner_id, uint32_t slot,
+ uint32_t *address,
+ uint32_t *value_size_bytes,
+ uint32_t *slot_size_bytes);
+
+/*!
+ * Signal a software alarm to the SCC. This will take the SCC and other PISA
+ * parts out of Secure mode and into Security Failure mode. The SCC will stay
+ * in failed mode until a reboot.
+ *
+ * @internal
+ * If the SCC is not already in fail state, simply write the
+ * #SMN_COMMAND_SET_SOFTWARE_ALARM bit in #SMN_COMMAND. Since there is no
+ * reason to wait for the interrupt to bounce back, simply act as though
+ * one did.
+ */
+ extern void scc_set_sw_alarm(void);
+
+/*!
+ * This routine will register a function to be called should a Security Failure
+ * be signalled by the SCC (Security Monitor).
+ *
+ * The callback function may be called from interrupt level, it may be called
+ * from some process' task. It should therefore not take a long time to
+ * perform its operation, and it may not sleep.
+ *
+ * @param callback_func Function pointer to routine which will receive
+ * notification of the security failure.
+ * @return 0 if function was successfully registered, non-zero on
+ * failure. See #scc_return_t.
+ *
+ * @internal
+ * There is a fixed global static array which keeps track of the requests to
+ * monitor the failure.
+ *
+ * Add @c callback_func to the first empty slot in #scc_callbacks[]. If there
+ * is no room, return #SCC_RET_TOO_MANY_FUNCTIONS.
+ */
+ extern scc_return_t scc_monitor_security_failure(void
+ callback_func(void));
+
+/*!
+ * This routine will deregister a function previously registered with
+ * #scc_monitor_security_failure().
+ *
+ * @param callback_func Function pointer to routine previously registered with
+ * #scc_stop_monitoring_security_failure().
+ */
+ extern void scc_stop_monitoring_security_failure(void
+ callback_func(void));
+
+/*!
+ * Read value from an SCC register.
+ * The offset will be checked for validity (range) as well as whether it is
+ * accessible (e.g. not busy, not in failed state) at the time of the call.
+ *
+ * @param[in] register_offset The (byte) offset within the SCC block
+ * of the register to be queried. See
+ * @ref scmregs and @ref smnregs.
+ * @param[out] value Pointer to where value from the register
+ * should be placed.
+ * @return 0 if OK, non-zero on error. See #scc_return_t.
+ *
+ * @internal
+ * Verify that the register_offset is a) valid, b) refers to a readable
+ * register, and c) the SCC is in a state which would allow a read of this
+ * register.
+ */
+ extern scc_return_t scc_read_register(int register_offset,
+ uint32_t * value);
+
+/*!
+ * Write a new value into an SCC register.
+ * The offset will be checked for validity (range) as well as whether it is
+ * accessible (e.g. not busy, not in failed state) at the time of the call.
+ *
+ * @param[in] register_offset The (byte) offset within the SCC block
+ * of the register to be modified. See
+ * @ref scmregs and @ref smnregs.
+ * @param[in] value The value to store into the register.
+ * @return 0 if OK, non-zero on error. See #scc_return_t.
+ *
+ * @internal
+ * Verify that the register_offset is a) valid, b) refers to a writeable
+ * register, and c) the SCC is in a state which would allow a write to this
+ * register.
+ */
+ extern scc_return_t scc_write_register(int register_offset,
+ uint32_t value);
+
+/*
+ * NOTE TO MAINTAINERS
+ *
+ * All of the doxygen comments for the register offset values are in this the
+ * following comment section. Any changes to register names or definitions
+ * must be reflected in this section and in both the TAHITI and non-TAHITI
+ *version of the memory map.
+ */
+
+/*!
+ * @defgroup scmregs SCM Registers
+ *
+ * These values are offsets into the SCC for the Secure Memory
+ * (SCM) registers. They are used in the @c register_offset parameter of
+ * #scc_read_register() and #scc_write_register().
+ */
+/*! @addtogroup scmregs */
+/*! @{ */
+/*! @def SCM_RED_START
+ * Starting block offset in red memory for cipher function. */
+
+/*! @def SCM_BLACK_START
+ * Starting block offset in black memory for cipher function. */
+
+/*! @def SCM_LENGTH
+ * Number of blocks to process during cipher function */
+
+/*! @def SCM_CONTROL
+ * SCM Control register.
+ * See @ref scmcontrolregdefs "SCM Control Register definitions" for details.
+ */
+
+/*! @def SCM_STATUS
+ * SCM Status register.
+ * See @ref scmstatusregdefs "SCM Status Register Definitions" for details.
+ */
+
+/*! @def SCM_ERROR_STATUS
+ * SCM Error Status Register.
+ * See @ref scmerrstatdefs "SCM Error Status Register definitions" for
+ * details. */
+
+/*! @def SCM_INTERRUPT_CTRL
+ * SCM Interrupt Control Register.
+ * See @ref scminterruptcontroldefs "SCM Interrupt Control Register definitions"
+ * for details.
+ */
+
+/*! @def SCM_CONFIGURATION
+ * SCM Configuration Register.
+ * See @ref scmconfigdefs "SCM Configuration Register Definitions" for
+ * details.
+ */
+
+/*! @def SCM_INIT_VECTOR_0
+ * Upper Half of the Initialization Vector */
+
+/*! @def SCM_INIT_VECTOR_1
+ * Lower Half of the Initialization Vector */
+
+/*! @def SCM_RED_MEMORY
+ * Starting location of first block of Red memory */
+
+/*! @def SCM_BLACK_MEMORY
+ * Starting location of first block of Black memory */
+
+ /*! @} *//* end of SCM group */
+
+/*!
+ * @defgroup smnregs SMN Registers
+ *
+ * These values are offsets into the SCC for the Security Monitor
+ * (SMN) registers. They are used in the @c register_offset parameter of the
+ * #scc_read_register() and #scc_write_register().
+ */
+/*! @addtogroup smnregs */
+/*! @{ */
+/*! @def SMN_STATUS
+ * Status register for SMN.
+ * See @ref smnstatusregdefs "SMN Status Register definitions" for further
+ * information.
+ */
+
+/*! @def SMN_COMMAND
+ * Command register for SMN. See
+ * @ref smncommandregdefs "Command Register Definitions" for further
+ * information.
+ */
+
+/*! @def SMN_SEQUENCE_START
+ * Sequence Start register for ASC. See #SMN_SEQUENCE_START_MASK
+ */
+
+/*! @def SMN_SEQUENCE_END
+ * Sequence End register for ASC. See #SMN_SEQUENCE_CHECK_MASK
+ */
+
+/*! @def SMN_SEQUENCE_CHECK
+ * Sequence Check register for ASC. See #SMN_SEQUENCE_END_MASK
+ */
+
+/*! @def SMN_BIT_COUNT
+ * Bit Bank Repository for AIC. See #SMN_BIT_COUNT_MASK
+ */
+
+/*! @def SMN_BITBANK_INC_SIZE
+ * Bit Bank Increment Size for AIC. See #SMN_BITBANK_INC_SIZE_MASK
+ */
+
+/*! @def SMN_BITBANK_DECREMENT
+ * Bit Bank Decrement for AIC. See #SMN_BITBANK_DECREMENT_MASK
+ */
+
+/*! @def SMN_COMPARE_SIZE
+ * Compare Size register for Plaintext/Ciphertext checker. See
+ * #SMN_COMPARE_SIZE_MASK */
+
+/*! @def SMN_PLAINTEXT_CHECK
+ * Plaintext Check register for Plaintext/Ciphertext checker.
+ */
+
+/*! @def SMN_CIPHERTEXT_CHECK
+ * Ciphertext Check register for Plaintext/Ciphertext checker.
+ */
+
+/*! @def SMN_TIMER_IV
+ * Timer Initial Value register
+ */
+
+/*! @def SMN_TIMER_CONTROL
+ * Timer Control register.
+ * See @ref smntimercontroldefs "SMN Timer Control Register definitions".
+ */
+
+/*! @def SMN_DEBUG_DETECT_STAT
+ * Debug Detector Status Register
+ * See @ref smndbgdetdefs "SMN Debug Detector Status Register"for definitions.
+ */
+
+/*! @def SMN_TIMER
+ * Current value of the Timer Register
+ */
+
+ /*! @} *//* end of SMN group */
+
+/*
+ * SCC MEMORY MAP
+ *
+ */
+
+/* SCM registers */
+#define SCM_RED_START 0x00000000 /* read/write */
+#define SCM_BLACK_START 0x00000004 /* read/write */
+#define SCM_LENGTH 0x00000008 /* read/write */
+#define SCM_CONTROL 0x0000000C /* read/write */
+#define SCM_STATUS 0x00000010 /* read only */
+#define SCM_ERROR_STATUS 0x00000014 /* read/write */
+#define SCM_INTERRUPT_CTRL 0x00000018 /* read/write */
+#define SCM_CONFIGURATION 0x0000001C /* read only */
+#define SCM_INIT_VECTOR_0 0x00000020 /* read/write */
+#define SCM_INIT_VECTOR_1 0x00000024 /* read/write */
+#define SCM_RED_MEMORY 0x00000400 /* read/write */
+#define SCM_BLACK_MEMORY 0x00000800 /* read/write */
+
+/* SMN Registers */
+#define SMN_STATUS 0x00001000 /* read/write */
+#define SMN_COMMAND 0x00001004 /* read/write */
+#define SMN_SEQUENCE_START 0x00001008 /* read/write */
+#define SMN_SEQUENCE_END 0x0000100C /* read/write */
+#define SMN_SEQUENCE_CHECK 0x00001010 /* read/write */
+#define SMN_BIT_COUNT 0x00001014 /* read only */
+#define SMN_BITBANK_INC_SIZE 0x00001018 /* read/write */
+#define SMN_BITBANK_DECREMENT 0x0000101C /* write only */
+#define SMN_COMPARE_SIZE 0x00001020 /* read/write */
+#define SMN_PLAINTEXT_CHECK 0x00001024 /* read/write */
+#define SMN_CIPHERTEXT_CHECK 0x00001028 /* read/write */
+#define SMN_TIMER_IV 0x0000102C /* read/write */
+#define SMN_TIMER_CONTROL 0x00001030 /* read/write */
+#define SMN_DEBUG_DETECT_STAT 0x00001034 /* read/write */
+#define SMN_TIMER 0x00001038 /* read only */
+
+/*! Total address space of the SCC, in bytes */
+#define SCC_ADDRESS_RANGE 0x103c
+
+/*!
+ * @defgroup smnstatusregdefs SMN Status Register definitions (SMN_STATUS)
+ */
+/*! @addtogroup smnstatusregdefs */
+/*! @{ */
+/*! SMN version id. */
+#define SMN_STATUS_VERSION_ID_MASK 0xfc000000
+/*! number of bits to shift #SMN_STATUS_VERSION_ID_MASK to get it to LSB */
+#define SMN_STATUS_VERSION_ID_SHIFT 26
+/*! Cacheable access to SMN attempted. */
+#define SMN_STATUS_CACHEABLE_ACCESS 0x02000000
+/*! Illegal bus master access attempted. */
+#define SMN_STATUS_ILLEGAL_MASTER 0x01000000
+/*! Scan mode entered/exited since last reset. */
+#define SMN_STATUS_SCAN_EXIT 0x00800000
+/*! Unaligned access attempted. */
+#define SMN_STATUS_UNALIGNED_ACCESS 0x00400000
+/*! Bad byte offset access attempted. */
+#define SMN_STATUS_BYTE_ACCESS 0x00200000
+/*! Illegal address access attempted. */
+#define SMN_STATUS_ILLEGAL_ADDRESS 0x00100000
+/*! User access attempted. */
+#define SMN_STATUS_USER_ACCESS 0x00080000
+/*! SCM is using DEFAULT key. */
+#define SMN_STATUS_DEFAULT_KEY 0x00040000
+/*! SCM detects weak or bad key. */
+#define SMN_STATUS_BAD_KEY 0x00020000
+/*! Illegal access to SCM detected. */
+#define SMN_STATUS_ILLEGAL_ACCESS 0x00010000
+/*! Internal error detected in SCM. */
+#define SMN_STATUS_SCM_ERROR 0x00008000
+/*! SMN has an outstanding interrupt. */
+#define SMN_STATUS_SMN_STATUS_IRQ 0x00004000
+/*! Software Alarm was triggered. */
+#define SMN_STATUS_SOFTWARE_ALARM 0x00002000
+/*! Timer has expired. */
+#define SMN_STATUS_TIMER_ERROR 0x00001000
+/*! Plaintext/Ciphertext compare failed. */
+#define SMN_STATUS_PC_ERROR 0x00000800
+/*! Bit Bank detected overflow or underflow */
+#define SMN_STATUS_BITBANK_ERROR 0x00000400
+/*! Algorithm Sequence Check failed. */
+#define SMN_STATUS_ASC_ERROR 0x00000200
+/*! Security Policy Block detected error. */
+#define SMN_STATUS_SECURITY_POLICY_ERROR 0x00000100
+/*! At least one Debug signal is active. */
+#define SMN_STATUS_DEBUG_ACTIVE 0x00000080
+/*! SCM failed to zeroize its memory. */
+#define SMN_STATUS_ZEROIZE_FAIL 0x00000040
+/*! Processor booted from internal ROM. */
+#define SMN_STATUS_INTERNAL_BOOT 0x00000020
+/*! SMN's internal state. */
+#define SMN_STATUS_STATE_MASK 0x0000001F
+/*! Number of bits to shift #SMN_STATUS_STATE_MASK to get it to LSB. */
+#define SMN_STATUS_STATE_SHIFT 0
+/*! @} */
+
+/*!
+ * @defgroup sccscmstates SMN Model Secure State Controller States (SMN_STATE_MASK)
+ */
+/*! @addtogroup sccscmstates */
+/*! @{ */
+/*! This is the first state of the SMN after power-on reset */
+#define SMN_STATE_START 0x0
+/*! The SMN is zeroizing its RAM during reset */
+#define SMN_STATE_ZEROIZE_RAM 0x5
+/*! SMN has passed internal checks, and is waiting for Software check-in */
+#define SMN_STATE_HEALTH_CHECK 0x6
+/*! Fatal Security Violation. SMN is locked, SCM is inoperative. */
+#define SMN_STATE_FAIL 0x9
+/*! SCC is in secure state. SCM is using secret key. */
+#define SMN_STATE_SECURE 0xA
+/*! Due to non-fatal error, device is not secure. SCM is using default key. */
+#define SMN_STATE_NON_SECURE 0xC
+/*! @} */
+
+/*!
+ * @defgroup scmconfigdefs SCM Configuration Register definitions (SCM_CONFIGURATION)
+ **/
+/*! @addtogroup scmconfigdefs */
+/*! @{ */
+/*! Version number of the Secure Memory. */
+#define SCM_CFG_VERSION_ID_MASK 0xf8000000
+/*! Number of bits to shift #SCM_CFG_VERSION_ID_MASK to get it to LSB. */
+#define SCM_CFG_VERSION_ID_SHIFT 27
+/*! Version one value for SCC configuration */
+#define SCM_VERSION_1 1
+/*! Size, in blocks, of Red memory. */
+#define SCM_CFG_BLACK_SIZE_MASK 0x07fe0000
+/*! Number of bits to shift #SCM_CFG_BLACK_SIZE_MASK to get it to LSB. */
+#define SCM_CFG_BLACK_SIZE_SHIFT 17
+/*! Size, in blocks, of Black memory. */
+#define SCM_CFG_RED_SIZE_MASK 0x0001ff80
+/*! Number of bits to shift #SCM_CFG_RED_SIZE_MASK to get it to LSB. */
+#define SCM_CFG_RED_SIZE_SHIFT 7
+/*! Number of bytes per block. */
+#define SCM_CFG_BLOCK_SIZE_MASK 0x0000007f
+/*! Number of bits to shift #SCM_CFG_BLOCK_SIZE_MASK to get it to LSB. */
+#define SCM_CFG_BLOCK_SIZE_SHIFT 0
+/*! @} */
+
+/*!
+ * @defgroup smncommandregdefs SMN Command Register Definitions (SMN_COMMAND)
+ */
+/*! @addtogroup smncommandregdefs */
+/*! @{ */
+#define SMN_COMMAND_ZEROS_MASK 0xffffff70 /*!< These bits are unimplemented
+ or reserved */
+#define SMN_COMMAND_TAMPER_LOCK 0x10 /*!< Lock Tamper Detect Bit */
+#define SMN_COMMAND_CLEAR_INTERRUPT 0x8 /*!< Clear SMN Interrupt */
+#define SMN_COMMAND_CLEAR_BIT_BANK 0x4 /*!< Clear SMN Bit Bank */
+#define SMN_COMMAND_ENABLE_INTERRUPT 0x2 /*!< Enable SMN Interrupts */
+#define SMN_COMMAND_SET_SOFTWARE_ALARM 0x1 /*!< Set Software Alarm */
+/*! @} */
+
+/*!
+ * @defgroup smntimercontroldefs SMN Timer Control Register definitions (SMN_TIMER_CONTROL)
+ */
+/*! @addtogroup smntimercontroldefs */
+/*! @{ */
+/*! These bits are reserved or zero */
+#define SMN_TIMER_CTRL_ZEROS_MASK 0xfffffffc
+/*! Load the timer from #SMN_TIMER_IV */
+#define SMN_TIMER_LOAD_TIMER 0x2
+/*! Setting to zero stops the Timer */
+#define SMN_TIMER_STOP_MASK 0x1
+/*! Setting this value starts the timer */
+#define SMN_TIMER_START_TIMER 0x1
+/*! @} */
+
+/*!
+ * @defgroup scminterruptcontroldefs SCM Interrupt Control Register definitions (SCM_INTERRUPT_CTRL)
+ *
+ * These are the bit definitions for the #SCM_INTERRUPT_CTRL register.
+ */
+/*! @addtogroup scminterruptcontroldefs */
+/*! @{ */
+/*! Clear SCM memory */
+#define SCM_INTERRUPT_CTRL_ZEROIZE_MEMORY 0x4
+/*! Clear outstanding SCM interrupt */
+#define SCM_INTERRUPT_CTRL_CLEAR_INTERRUPT 0x2
+/*! Inhibit SCM interrupts */
+#define SCM_INTERRUPT_CTRL_MASK_INTERRUPTS 0x1
+/*! @} */
+
+/*!
+ * @defgroup scmcontrolregdefs SCM Control Register definitions (SCM_CONTROL).
+ * These values are used with the #SCM_CONTROL register.
+ */
+/*! @addtogroup scmcontrolregdefs */
+/*! @{ */
+/*! These bits are zero or reserved */
+#define SCM_CONTROL_ZEROS_MASK 0xfffffff8
+/*! Setting this will start encrypt/decrypt */
+#define SCM_CONTROL_START_CIPHER 0x04
+/*! CBC/ECB flag.
+ * See @ref scmchainmodedefs "Chaining Mode bit definitions."
+ */
+#define SCM_CONTROL_CHAINING_MODE_MASK 0x02
+/*! Encrypt/decrypt choice.
+ * See @ref scmciphermodedefs "Cipher Mode bit definitions." */
+#define SCM_CONTROL_CIPHER_MODE_MASK 0x01
+/*! @} */
+
+/*!
+ * @defgroup scmchainmodedefs SCM_CHAINING_MODE_MASK - Bit definitions
+ */
+/*! @addtogroup scmchainmodedefs */
+/*! @{ */
+#define SCM_CBC_MODE 0x2 /*!< Cipher block chaining */
+#define SCM_ECB_MODE 0x0 /*!< Electronic codebook. */
+/*! @} */
+
+/* Bit definitions in the SCM_CIPHER_MODE_MASK */
+/*!
+ * @defgroup scmciphermodedefs SCM_CIPHER_MODE_MASK - Bit definitions
+ */
+/*! @{ */
+#define SCM_DECRYPT_MODE 0x1 /*!< decrypt from black to red memory */
+#define SCM_ENCRYPT_MODE 0x0 /*!< encrypt from red to black memory */
+/*! @} */
+
+/*!
+ * @defgroup scmstatusregdefs SCM Status Register (SCM_STATUS).
+ * Bit and field definitions of the SCM_STATUS register.
+ */
+/*! @addtogroup scmstatusregdefs */
+/*! @{ */
+/*! These bits are zero or reserved */
+#define SCM_STATUS_ZEROS_MASK 0xffffe000
+/*! Ciphering failed due to length error. */
+#define SCM_STATUS_LENGTH_ERROR 0x1000
+/*! SMN has stopped blocking access to the SCM */
+#define SCM_STATUS_BLOCK_ACCESS_REMOVED 0x0800
+/*! Ciphering done. */
+#define SCM_STATUS_CIPHERING_DONE 0x0400
+/*! Zeroizing done. */
+#define SCM_STATUS_ZEROIZING_DONE 0x0200
+/*! SCM wants attention. Interrupt status is available. */
+#define SCM_STATUS_INTERRUPT_STATUS 0x0100
+/*! Secret Key is in use. */
+#define SCM_STATUS_SECRET_KEY 0x0080
+/*! Secret Key is in use. Deprecated. Use #SCM_STATUS_SECRET_KEY. */
+#define SCM_STATUS_DEFAULT_KEY 0x0080
+/*! Internal error to SCM. */
+#define SCM_STATUS_INTERNAL_ERROR 0x0040
+/*! Secret key is not valid. */
+#define SCM_STATUS_BAD_SECRET_KEY 0x0020
+/*! Failed to zeroize memory. */
+#define SCM_STATUS_ZEROIZE_FAILED 0x0010
+/*! SMN is blocking access to Secure Memory. */
+#define SCM_STATUS_SMN_BLOCKING_ACCESS 0x0008
+/*! SCM is current encrypting or decrypting data. */
+#define SCM_STATUS_CIPHERING 0x0004
+/*! SCM is currently zeroizing data. */
+#define SCM_STATUS_ZEROIZING 0x0002
+/*! SCM is busy and access to memory is blocked. */
+#define SCM_STATUS_BUSY 0x0001
+/*! @} */
+
+/*!
+ * @defgroup scmerrstatdefs SCM Error Status Register (SCM_ERROR_STATUS)
+ *
+ * These definitions are associated with the SCM Error Status Register
+ * (SCM_ERROR_STATUS).
+ */
+/*! @addtogroup scmerrstatdefs */
+/*! @{ */
+/*! These bits are zero or reserved */
+#define SCM_ERR_ZEROS_MASK 0xffffc000
+/*! Cacheable access to SCM was attempted */
+#define SCM_ERR_CACHEABLE_ACCESS 0x2000
+/*! Access attempted by illegal bus master */
+#define SCM_ERR_ILLEGAL_MASTER 0x1000
+/*! Unaligned access attempted */
+#define SCM_ERR_UNALIGNED_ACCESS 0x0800
+/*! Byte or half-word access attempted */
+#define SCM_ERR_BYTE_ACCESS 0x0400
+/*! Illegal address attempted */
+#define SCM_ERR_ILLEGAL_ADDRESS 0x0200
+/*! User access attempted */
+#define SCM_ERR_USER_ACCESS 0x0100
+/*! Access attempted while SCM was using default key */
+#define SCM_ERR_SECRET_KEY_IN_USE 0x0080
+/*! Access attempted while SCM had internal error */
+#define SCM_ERR_INTERNAL_ERROR 0x0040
+/*! Access attempted while SCM was detecting Bad Key */
+#define SCM_ERR_BAD_SECRET_KEY 0x0020
+/*! The SCM failed to Zeroize memory */
+#define SCM_ERR_ZEROIZE_FAILED 0x0010
+/*! Access attempted while SMN was Blocking Access */
+#define SCM_ERR_SMN_BLOCKING_ACCESS 0x0008
+/*! Access attempted while SCM was CIPHERING */
+#define SCM_ERR_CIPHERING 0x0004
+/*! Access attempted while SCM was ZEROIZING */
+#define SCM_ERR_ZEROIZING 0x0002
+/*! Access attempted while SCM was BUSY */
+#define SCM_ERR_BUSY 0x0001
+/*! @} */
+
+/*!
+ * @defgroup smndbgdetdefs SMN Debug Detector Status Register
+ * (SCM_DEBUG_DETECT_STAT)
+ */
+/*! @addtogroup smndbgdetdefs */
+/*! @{ */
+#define SMN_DBG_ZEROS_MASK 0xfffff000 /*!< These bits are zero or reserved */
+#define SMN_DBG_D12 0x0800 /*!< Error detected on Debug Port D12 */
+#define SMN_DBG_D11 0x0400 /*!< Error detected on Debug Port D11 */
+#define SMN_DBG_D10 0x0200 /*!< Error detected on Debug Port D10 */
+#define SMN_DBG_D9 0x0100 /*!< Error detected on Debug Port D9 */
+#define SMN_DBG_D8 0x0080 /*!< Error detected on Debug Port D8 */
+#define SMN_DBG_D7 0x0040 /*!< Error detected on Debug Port D7 */
+#define SMN_DBG_D6 0x0020 /*!< Error detected on Debug Port D6 */
+#define SMN_DBG_D5 0x0010 /*!< Error detected on Debug Port D5 */
+#define SMN_DBG_D4 0x0008 /*!< Error detected on Debug Port D4 */
+#define SMN_DBG_D3 0x0004 /*!< Error detected on Debug Port D3 */
+#define SMN_DBG_D2 0x0002 /*!< Error detected on Debug Port D2 */
+#define SMN_DBG_D1 0x0001 /*!< Error detected on Debug Port D1 */
+/*! @} */
+
+/*! Mask for the usable bits of the Sequence Start Register
+ (#SMN_SEQUENCE_START) */
+#define SMN_SEQUENCE_START_MASK 0x0000ffff
+
+/*! Mask for the usable bits of the Sequence End Register
+ (#SMN_SEQUENCE_END) */
+#define SMN_SEQUENCE_END_MASK 0x0000ffff
+
+/*! Mask for the usable bits of the Sequence Check Register
+ (#SMN_SEQUENCE_CHECK) */
+#define SMN_SEQUENCE_CHECK_MASK 0x0000ffff
+
+/*! Mask for the usable bits of the Bit Counter Register
+ (#SMN_BIT_COUNT) */
+#define SMN_BIT_COUNT_MASK 0x000007ff
+
+/*! Mask for the usable bits of the Bit Bank Increment Size Register
+ (#SMN_BITBANK_INC_SIZE) */
+#define SMN_BITBANK_INC_SIZE_MASK 0x000007ff
+
+/*! Mask for the usable bits of the Bit Bank Decrement Register
+ (#SMN_BITBANK_DECREMENT) */
+#define SMN_BITBANK_DECREMENT_MASK 0x000007ff
+
+/*! Mask for the usable bits of the Compare Size Register
+ (#SMN_COMPARE_SIZE) */
+#define SMN_COMPARE_SIZE_MASK 0x0000003f
+
+/* Close out marker for C++ compilers */
+#ifdef __cplusplus
+}
+#endif
+#endif /* __ASM_ARCH_MXC_SCC_DRIVER_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc_timer.h b/arch/arm/plat-mxc/include/mach/mxc_timer.h
index 130aebfbe168..59fe2dceeb07 100644
--- a/arch/arm/plat-mxc/include/mach/mxc_timer.h
+++ b/arch/arm/plat-mxc/include/mach/mxc_timer.h
@@ -65,9 +65,8 @@ static void gpt_irq_acknowledge(void)
{
__raw_writel(0, TIMER_BASE + MXC_TSTAT);
}
-#endif /* CONFIG_ARCH_IMX */
-#ifdef CONFIG_ARCH_MX2
+#elif defined(CONFIG_ARCH_MX2)
#define TIMER_BASE IO_ADDRESS(GPT1_BASE_ADDR)
#define TIMER_INTERRUPT MXC_INT_GPT1
@@ -103,15 +102,15 @@ static void gpt_irq_acknowledge(void)
{
__raw_writel(TSTAT_CAPT | TSTAT_COMP, TIMER_BASE + MXC_TSTAT);
}
-#endif /* CONFIG_ARCH_MX2 */
-#ifdef CONFIG_ARCH_MX3
+#else
#define TIMER_BASE IO_ADDRESS(GPT1_BASE_ADDR)
#define TIMER_INTERRUPT MXC_INT_GPT
#define MXC_TCTL 0x00
-#define TCTL_VAL (TCTL_CLK_IPG | TCTL_WAITEN)
+#define TCTL_VAL (TCTL_CLK_HIGH_FREQ | TCTL_WAITEN)
#define TCTL_CLK_IPG (1<<6)
+#define TCTL_CLK_HIGH_FREQ (2<<6)
#define TCTL_FRR (1<<9)
#define TCTL_WAITEN (1<<3)
diff --git a/arch/arm/plat-mxc/include/mach/mxc_uart.h b/arch/arm/plat-mxc/include/mach/mxc_uart.h
new file mode 100644
index 000000000000..d1db8023d724
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_uart.h
@@ -0,0 +1,275 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup UART Universal Asynchronous Receiver Transmitter (UART) Driver
+ */
+
+/*!
+ * @file arch-mxc/mxc_uart.h
+ *
+ * @brief This file contains the UART configuration structure definition.
+ *
+ *
+ * @ingroup UART
+ */
+
+#ifndef __ASM_ARCH_MXC_UART_H__
+#define __ASM_ARCH_MXC_UART_H__
+
+#ifdef __KERNEL__
+
+#include <linux/serial_core.h>
+#include <mach/dma.h>
+
+/*
+ * The modes of the UART ports
+ */
+#define MODE_DTE 0
+#define MODE_DCE 1
+/*
+ * Is the UART configured to be a IR port
+ */
+#define IRDA 0
+#define NO_IRDA 1
+
+/*!
+ * This structure is used to store the the physical and virtual
+ * addresses of the UART DMA receive buffer.
+ */
+typedef struct {
+ /*!
+ * DMA Receive buffer virtual address
+ */
+ char *rx_buf;
+ /*!
+ * DMA Receive buffer physical address
+ */
+ dma_addr_t rx_handle;
+} mxc_uart_rxdmamap;
+
+/*!
+ * This structure is a way for the low level driver to define their own
+ * \b uart_port structure. This structure includes the core \b uart_port
+ * structure that is provided by Linux as an element and has other
+ * elements that are specifically required by this low-level driver.
+ */
+typedef struct {
+ /*!
+ * The port structure holds all the information about the UART
+ * port like base address, and so on.
+ */
+ struct uart_port port;
+ /*!
+ * Flag to determine if the interrupts are muxed.
+ */
+ int ints_muxed;
+ /*!
+ * Array that holds the receive and master interrupt numbers
+ * when the interrupts are not muxed.
+ */
+ int irqs[2];
+ /*!
+ * Flag to determine the DTE/DCE mode.
+ */
+ int mode;
+ /*!
+ * Flag to hold the IR mode of the port.
+ */
+ int ir_mode;
+ /*!
+ * Flag to enable/disable the UART port.
+ */
+ int enabled;
+ /*!
+ * Flag to indicate if we wish to use hardware-driven hardware
+ * flow control.
+ */
+ int hardware_flow;
+ /*!
+ * Holds the threshold value at which the CTS line is deasserted in
+ * case we use hardware-driven hardware flow control.
+ */
+ unsigned int cts_threshold;
+ /*!
+ * Flag to enable/disable DMA data transfer.
+ */
+ int dma_enabled;
+ /*!
+ * Holds the DMA receive buffer size.
+ */
+ int dma_rxbuf_size;
+ /*!
+ * DMA Receive buffers information
+ */
+ mxc_uart_rxdmamap *rx_dmamap;
+ /*!
+ * DMA RX buffer id
+ */
+ int dma_rxbuf_id;
+ /*!
+ * DMA Transmit buffer virtual address
+ */
+ char *tx_buf;
+ /*!
+ * DMA Transmit buffer physical address
+ */
+ dma_addr_t tx_handle;
+ /*!
+ * Holds the RxFIFO threshold value.
+ */
+ unsigned int rx_threshold;
+ /*!
+ * Holds the TxFIFO threshold value.
+ */
+ unsigned int tx_threshold;
+ /*!
+ * Information whether this is a shared UART
+ */
+ unsigned int shared;
+ /*!
+ * Clock id for UART clock
+ */
+ struct clk *clk;
+ /*!
+ * Information whether RXDMUXSEL must be set or not for IR port
+ */
+ int rxd_mux;
+ int ir_tx_inv;
+ int ir_rx_inv;
+ /*!
+ * DMA ID for transmit
+ */
+ mxc_dma_device_t dma_tx_id;
+ /*!
+ * DMA ID for receive
+ */
+ mxc_dma_device_t dma_rx_id;
+} uart_mxc_port;
+
+/* Address offsets of the UART registers */
+#define MXC_UARTURXD 0x000 /* Receive reg */
+#define MXC_UARTUTXD 0x040 /* Transmitter reg */
+#define MXC_UARTUCR1 0x080 /* Control reg 1 */
+#define MXC_UARTUCR2 0x084 /* Control reg 2 */
+#define MXC_UARTUCR3 0x088 /* Control reg 3 */
+#define MXC_UARTUCR4 0x08C /* Control reg 4 */
+#define MXC_UARTUFCR 0x090 /* FIFO control reg */
+#define MXC_UARTUSR1 0x094 /* Status reg 1 */
+#define MXC_UARTUSR2 0x098 /* Status reg 2 */
+#define MXC_UARTUESC 0x09C /* Escape character reg */
+#define MXC_UARTUTIM 0x0A0 /* Escape timer reg */
+#define MXC_UARTUBIR 0x0A4 /* BRM incremental reg */
+#define MXC_UARTUBMR 0x0A8 /* BRM modulator reg */
+#define MXC_UARTUBRC 0x0AC /* Baud rate count reg */
+#define MXC_UARTONEMS 0x0B0 /* One millisecond reg */
+#define MXC_UARTUTS 0x0B4 /* Test reg */
+
+/* Bit definations of UCR1 */
+#define MXC_UARTUCR1_ADEN 0x8000
+#define MXC_UARTUCR1_ADBR 0x4000
+#define MXC_UARTUCR1_TRDYEN 0x2000
+#define MXC_UARTUCR1_IDEN 0x1000
+#define MXC_UARTUCR1_RRDYEN 0x0200
+#define MXC_UARTUCR1_RXDMAEN 0x0100
+#define MXC_UARTUCR1_IREN 0x0080
+#define MXC_UARTUCR1_TXMPTYEN 0x0040
+#define MXC_UARTUCR1_RTSDEN 0x0020
+#define MXC_UARTUCR1_SNDBRK 0x0010
+#define MXC_UARTUCR1_TXDMAEN 0x0008
+#define MXC_UARTUCR1_ATDMAEN 0x0004
+#define MXC_UARTUCR1_DOZE 0x0002
+#define MXC_UARTUCR1_UARTEN 0x0001
+
+/* Bit definations of UCR2 */
+#define MXC_UARTUCR2_ESCI 0x8000
+#define MXC_UARTUCR2_IRTS 0x4000
+#define MXC_UARTUCR2_CTSC 0x2000
+#define MXC_UARTUCR2_CTS 0x1000
+#define MXC_UARTUCR2_PREN 0x0100
+#define MXC_UARTUCR2_PROE 0x0080
+#define MXC_UARTUCR2_STPB 0x0040
+#define MXC_UARTUCR2_WS 0x0020
+#define MXC_UARTUCR2_RTSEN 0x0010
+#define MXC_UARTUCR2_ATEN 0x0008
+#define MXC_UARTUCR2_TXEN 0x0004
+#define MXC_UARTUCR2_RXEN 0x0002
+#define MXC_UARTUCR2_SRST 0x0001
+
+/* Bit definations of UCR3 */
+#define MXC_UARTUCR3_DTREN 0x2000
+#define MXC_UARTUCR3_PARERREN 0x1000
+#define MXC_UARTUCR3_FRAERREN 0x0800
+#define MXC_UARTUCR3_DSR 0x0400
+#define MXC_UARTUCR3_DCD 0x0200
+#define MXC_UARTUCR3_RI 0x0100
+#define MXC_UARTUCR3_RXDSEN 0x0040
+#define MXC_UARTUCR3_AWAKEN 0x0010
+#define MXC_UARTUCR3_DTRDEN 0x0008
+#define MXC_UARTUCR3_RXDMUXSEL 0x0004
+#define MXC_UARTUCR3_INVT 0x0002
+
+/* Bit definations of UCR4 */
+#define MXC_UARTUCR4_CTSTL_OFFSET 10
+#define MXC_UARTUCR4_CTSTL_MASK (0x3F << 10)
+#define MXC_UARTUCR4_INVR 0x0200
+#define MXC_UARTUCR4_ENIRI 0x0100
+#define MXC_UARTUCR4_REF16 0x0040
+#define MXC_UARTUCR4_IRSC 0x0020
+#define MXC_UARTUCR4_TCEN 0x0008
+#define MXC_UARTUCR4_OREN 0x0002
+#define MXC_UARTUCR4_DREN 0x0001
+
+/* Bit definations of UFCR */
+#define MXC_UARTUFCR_RFDIV 0x0200 /* Ref freq div is set to 2 */
+#define MXC_UARTUFCR_RFDIV_OFFSET 7
+#define MXC_UARTUFCR_RFDIV_MASK (0x7 << 7)
+#define MXC_UARTUFCR_TXTL_OFFSET 10
+#define MXC_UARTUFCR_DCEDTE 0x0040
+
+/* Bit definations of URXD */
+#define MXC_UARTURXD_ERR 0x4000
+#define MXC_UARTURXD_OVRRUN 0x2000
+#define MXC_UARTURXD_FRMERR 0x1000
+#define MXC_UARTURXD_BRK 0x0800
+#define MXC_UARTURXD_PRERR 0x0400
+
+/* Bit definations of USR1 */
+#define MXC_UARTUSR1_PARITYERR 0x8000
+#define MXC_UARTUSR1_RTSS 0x4000
+#define MXC_UARTUSR1_TRDY 0x2000
+#define MXC_UARTUSR1_RTSD 0x1000
+#define MXC_UARTUSR1_FRAMERR 0x0400
+#define MXC_UARTUSR1_RRDY 0x0200
+#define MXC_UARTUSR1_AGTIM 0x0100
+#define MXC_UARTUSR1_DTRD 0x0080
+#define MXC_UARTUSR1_AWAKE 0x0010
+
+/* Bit definations of USR2 */
+#define MXC_UARTUSR2_TXFE 0x4000
+#define MXC_UARTUSR2_IDLE 0x1000
+#define MXC_UARTUSR2_RIDELT 0x0400
+#define MXC_UARTUSR2_RIIN 0x0200
+#define MXC_UARTUSR2_DCDDELT 0x0040
+#define MXC_UARTUSR2_DCDIN 0x0020
+#define MXC_UARTUSR2_TXDC 0x0008
+#define MXC_UARTUSR2_ORE 0x0002
+#define MXC_UARTUSR2_RDR 0x0001
+#define MXC_UARTUSR2_BRCD 0x0004
+
+/* Bit definations of UTS */
+#define MXC_UARTUTS_LOOP 0x1000
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_ARCH_MXC_UART_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/mxc_v4l2.h b/arch/arm/plat-mxc/include/mach/mxc_v4l2.h
new file mode 100644
index 000000000000..ade1e18104e9
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_v4l2.h
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+/*!
+ * @file arch-mxc/mxc_v4l2.h
+ *
+ * @brief mxc V4L2 private structures
+ *
+ * @ingroup MXC_V4L2_CAPTURE
+ */
+
+#ifndef __ASM_ARCH_MXC_V4L2_H__
+#define __ASM_ARCH_MXC_V4L2_H__
+
+#define V4L2_CID_MXC_ROT (V4L2_CID_PRIVATE_BASE + 0)
+#define V4L2_CID_MXC_FLASH (V4L2_CID_PRIVATE_BASE + 1)
+
+#define V4L2_MXC_ROTATE_NONE 0
+#define V4L2_MXC_ROTATE_VERT_FLIP 1
+#define V4L2_MXC_ROTATE_HORIZ_FLIP 2
+#define V4L2_MXC_ROTATE_180 3
+#define V4L2_MXC_ROTATE_90_RIGHT 4
+#define V4L2_MXC_ROTATE_90_RIGHT_VFLIP 5
+#define V4L2_MXC_ROTATE_90_RIGHT_HFLIP 6
+#define V4L2_MXC_ROTATE_90_LEFT 7
+
+struct v4l2_mxc_offset {
+ uint32_t u_offset;
+ uint32_t v_offset;
+};
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/mxc_vpu.h b/arch/arm/plat-mxc/include/mach/mxc_vpu.h
new file mode 100644
index 000000000000..51f19799ff4c
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxc_vpu.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+/*!
+ * @defgroup VPU Video Processor Unit Driver
+ */
+
+/*!
+ * @file arch-mxc/mxc_vpu.h
+ *
+ * @brief VPU system initialization and file operation definition
+ *
+ * @ingroup VPU
+ */
+
+#ifndef __ASM_ARCH_MXC_VPU_H__
+#define __ASM_ARCH_MXC_VPU_H__
+
+#include <linux/fs.h>
+
+struct vpu_mem_desc {
+ u32 size;
+ dma_addr_t phy_addr;
+ u32 cpu_addr; /* cpu address to free the dma mem */
+ u32 virt_uaddr; /* virtual user space address */
+};
+
+#define VPU_IOC_MAGIC 'V'
+
+#define VPU_IOC_PHYMEM_ALLOC _IO(VPU_IOC_MAGIC, 0)
+#define VPU_IOC_PHYMEM_FREE _IO(VPU_IOC_MAGIC, 1)
+#define VPU_IOC_WAIT4INT _IO(VPU_IOC_MAGIC, 2)
+#define VPU_IOC_PHYMEM_DUMP _IO(VPU_IOC_MAGIC, 3)
+#define VPU_IOC_REG_DUMP _IO(VPU_IOC_MAGIC, 4)
+#define VPU_IOC_VL2CC_FLUSH _IO(VPU_IOC_MAGIC, 5)
+#define VPU_IOC_IRAM_SETTING _IO(VPU_IOC_MAGIC, 6)
+#define VPU_IOC_CLKGATE_SETTING _IO(VPU_IOC_MAGIC, 7)
+#define VPU_IOC_GET_WORK_ADDR _IO(VPU_IOC_MAGIC, 8)
+#define VPU_IOC_GET_PIC_PARA_ADDR _IO(VPU_IOC_MAGIC, 9)
+#define VPU_IOC_GET_USER_DATA_ADDR _IO(VPU_IOC_MAGIC, 10)
+
+#define BIT_CODE_RUN 0x000
+#define BIT_CODE_DOWN 0x004
+#define BIT_INT_CLEAR 0x00C
+#define BIT_INT_STATUS 0x010
+
+#define BIT_WORK_CTRL_BUF_BASE 0x100
+#define BIT_WORK_CTRL_BUF_REG(i) (BIT_WORK_CTRL_BUF_BASE + i * 4)
+#define BIT_CODE_BUF_ADDR BIT_WORK_CTRL_BUF_REG(0)
+#define BIT_WORK_BUF_ADDR BIT_WORK_CTRL_BUF_REG(1)
+#define BIT_PARA_BUF_ADDR BIT_WORK_CTRL_BUF_REG(2)
+#define BIT_BIT_STREAM_CTRL BIT_WORK_CTRL_BUF_REG(3)
+#define BIT_FRAME_MEM_CTRL BIT_WORK_CTRL_BUF_REG(4)
+#define BIT_BIT_STREAM_PARAM BIT_WORK_CTRL_BUF_REG(5)
+
+#define BIT_RESET_CTRL 0x11C
+
+/* i could be 0, 1, 2, 3 */
+#define BIT_RD_PTR_BASE 0x120
+#define BIT_RD_PTR_REG(i) (BIT_RD_PTR_BASE + i * 8)
+#define BIT_WR_PTR_REG(i) (BIT_RD_PTR_BASE + i * 8 + 4)
+
+/* i could be 0, 1, 2, 3 */
+#define BIT_FRM_DIS_FLG_BASE (cpu_is_mx51() ? 0x150 : 0x140)
+#define BIT_FRM_DIS_FLG_REG(i) (BIT_FRM_DIS_FLG_BASE + i * 4)
+
+#define BIT_BUSY_FLAG 0x160
+#define BIT_RUN_COMMAND 0x164
+#define BIT_INT_ENABLE 0x170
+
+#define BITVAL_PIC_RUN 8
+
+#define VPU_SLEEP_REG_VALUE 10
+#define VPU_WAKE_REG_VALUE 11
+
+int vl2cc_init(u32 vl2cc_hw_base);
+void vl2cc_enable(void);
+void vl2cc_flush(void);
+void vl2cc_disable(void);
+void vl2cc_cleanup(void);
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/mxcfb.h b/arch/arm/plat-mxc/include/mach/mxcfb.h
new file mode 100644
index 000000000000..4bff1a6aefc6
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/mxcfb.h
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+/*
+ * @file arch-mxc/ mxcfb.h
+ *
+ * @brief Global header file for the MXC Frame buffer
+ *
+ * @ingroup Framebuffer
+ */
+#ifndef __ASM_ARCH_MXCFB_H__
+#define __ASM_ARCH_MXCFB_H__
+
+#include <linux/fb.h>
+
+#define FB_SYNC_OE_ACT_HIGH 0x80000000
+#define FB_SYNC_CLK_INVERT 0x40000000
+#define FB_SYNC_DATA_INVERT 0x20000000
+#define FB_SYNC_CLK_IDLE_EN 0x10000000
+#define FB_SYNC_SHARP_MODE 0x08000000
+#define FB_SYNC_SWAP_RGB 0x04000000
+
+struct mxcfb_gbl_alpha {
+ int enable;
+ int alpha;
+};
+
+struct mxcfb_color_key {
+ int enable;
+ __u32 color_key;
+};
+
+struct mxcfb_pos {
+ __u16 x;
+ __u16 y;
+};
+
+#define MXCFB_WAIT_FOR_VSYNC _IOW('F', 0x20, u_int32_t)
+#define MXCFB_SET_GBL_ALPHA _IOW('F', 0x21, struct mxcfb_gbl_alpha)
+#define MXCFB_SET_CLR_KEY _IOW('F', 0x22, struct mxcfb_color_key)
+#define MXCFB_SET_OVERLAY_POS _IOW('F', 0x24, struct mxcfb_pos)
+
+#ifdef __KERNEL__
+
+extern struct fb_videomode mxcfb_modedb[];
+extern int mxcfb_modedb_sz;
+
+enum {
+ MXCFB_REFRESH_OFF,
+ MXCFB_REFRESH_AUTO,
+ MXCFB_REFRESH_PARTIAL,
+};
+
+struct mxcfb_rect {
+ u32 top;
+ u32 left;
+ u32 width;
+ u32 height;
+};
+
+int mxcfb_set_refresh_mode(struct fb_info *fbi, int mode,
+ struct mxcfb_rect *update_region);
+
+#endif /* __KERNEL__ */
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/pcmcia.h b/arch/arm/plat-mxc/include/mach/pcmcia.h
new file mode 100644
index 000000000000..c50302bbbac5
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/pcmcia.h
@@ -0,0 +1,218 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_MXC_PCMCIA_H__
+#define __ASM_ARCH_MXC_PCMCIA_H__
+
+#include <mach/hardware.h>
+
+#define WINDOW_SIZE 0x1000000 /* The size of a window: 16M */
+#define PCMCIA_WINDOWS 5 /* How many windows / socket */
+#define SOCKET_NO 1 /* How many sockets */
+
+#define ATTRIBUTE_MEMORY_WINDOW 0
+#define IO_WINDOW 1
+#define COMMON_MEMORY_WINDOW 2
+
+/*
+ * PCMCIA socket
+ */
+#define PCMCIAPrtSp WINDOW_SIZE /* PCMCIA window size */
+#define PCMCIASp (4*PCMCIAPrtSp) /* PCMCIA Space [byte] */
+#define PCMCIAIOSp PCMCIAPrtSp /* PCMCIA I/O Space [byte] */
+#define PCMCIAAttrSp PCMCIAPrtSp /* PCMCIA Attribute Space [byte] */
+#define PCMCIAMemSp PCMCIAPrtSp /* PCMCIA Memory Space [byte] */
+
+#define PCMCIA0Sp PCMCIASp /* PCMCIA 0 Space [byte] */
+#define PCMCIA0IOSp PCMCIAIOSp /* PCMCIA 0 I/O Space [byte] */
+#define PCMCIA0AttrSp PCMCIAAttrSp /* PCMCIA 0 Attribute Space [byte] */
+#define PCMCIA0MemSp PCMCIAMemSp /* PCMCIA 0 Memory Space [byte] */
+
+#define _PCMCIA(Nb) /* PCMCIA [0..1] */ \
+ (PCMCIA_MEM_BASE_ADDR + (Nb) * PCMCIASp)
+
+#define _PCMCIAAttr(Nb) _PCMCIA (Nb) /* PCMCIA I/O [0..1] */
+
+#define _PCMCIAIO(Nb) /* PCMCIA Attribute [0..1] */ \
+ (_PCMCIA (Nb) + (IO_WINDOW) * PCMCIAPrtSp)
+#define _PCMCIAMem(Nb) /* PCMCIA Memory [0..1] */ \
+ (_PCMCIA (Nb) + (COMMON_MEMORY_WINDOW) * PCMCIAPrtSp)
+
+#define _PCMCIA0 _PCMCIA (0) /* PCMCIA 0 */
+#define _PCMCIA0IO _PCMCIAIO (0) /* PCMCIA 0 I/O */
+#define _PCMCIA0Attr _PCMCIAAttr (0) /* PCMCIA 0 Attribute */
+#define _PCMCIA0Mem _PCMCIAMem (0) /* PCMCIA 0 Memory */
+
+/*
+ * Module: PCMCIA, Addr Range: 0xB8004000 - 0xB8004FFF, Size: 4 Kbyte
+ */
+#define PCMCIA_BASE_ADDR (PCMCIA_CTL_BASE_ADDR) /* PCMCIA Base Address */
+#define PCMCIA_IO_ADDR(x) (* (volatile u32 *)PCMCIA_IO_ADDRESS(x))
+
+#define _reg_PCMCIA_PIPR PCMCIA_IO_ADDR(PCMCIA_BASE_ADDR + 0x00) /* PCMCIA input pins register */
+#define _reg_PCMCIA_PSCR PCMCIA_IO_ADDR(PCMCIA_BASE_ADDR + 0x04) /* PCMCIA Status Changed Register */
+#define _reg_PCMCIA_PER PCMCIA_IO_ADDR(PCMCIA_BASE_ADDR + 0x08) /* PCMCIA Enable Register */
+
+/* win: 0-4 */
+#define _reg_PCMCIA_PBR(win) PCMCIA_IO_ADDR(PCMCIA_BASE_ADDR + 0x0C + 4 * (win)) /* PCMCIA Base Register x */
+#define _reg_PCMCIA_POR(win) PCMCIA_IO_ADDR(PCMCIA_BASE_ADDR + 0x28 + 4 * (win)) /* PCMCIA Option Register x */
+#define _reg_PCMCIA_POFR(win) PCMCIA_IO_ADDR(PCMCIA_BASE_ADDR + 0x44 + 4 * (win)) /* PCMCIA Offset Register x */
+
+#define _reg_PCMCIA_PGCR PCMCIA_IO_ADDR(PCMCIA_BASE_ADDR + 0x60) /* PCMCIA General Control Register */
+#define _reg_PCMCIA_PGSR PCMCIA_IO_ADDR(PCMCIA_BASE_ADDR + 0x64) /* PCMCIA General Status Register */
+
+/* PCMCIA_PIPR - PCMCIA Input Pins Register - fields */
+#define PCMCIA_PIPR_POWERON (1 << 8) /* card indicates "power on" */
+#define PCMCIA_PIPR_RDY (1 << 7) /* card is ready */
+#define PCMCIA_PIPR_BVD2 (1 << 6) /* battery voltage 2/SPKR in */
+#define PCMCIA_PIPR_BVD1 (1 << 5) /* battery voltage 1/STSCHG */
+#define PCMCIA_PIPR_CD (3 << 3) /* card detect 1 and 2 */
+#define PCMCIA_PIPR_WP (1 << 2) /* write protect switch enabled */
+#define PCMCIA_PIPR_VS (3 << 0) /* voltage sense bits */
+#define PCMCIA_PIPR_VS_5V (1 << 0) /* 5v */
+
+/* PCMCIA_PSCR - PCMCIA Status Change Register - fields */
+#define PCMCIA_PSCR_POWC (1 << 11) /* */
+#define PCMCIA_PSCR_RDYR (1 << 10) /* */
+#define PCMCIA_PSCR_RDYF (1 << 9) /* */
+#define PCMCIA_PSCR_RDYH (1 << 8) /* */
+#define PCMCIA_PSCR_RDYL (1 << 7) /* */
+#define PCMCIA_PSCR_BVDC2 (1 << 6) /* */
+#define PCMCIA_PSCR_BVDC1 (1 << 5) /* */
+#define PCMCIA_PSCR_CDC2 (1 << 4) /* */
+#define PCMCIA_PSCR_CDC1 (1 << 3) /* */
+#define PCMCIA_PSCR_WPC (1 << 2) /* */
+#define PCMCIA_PSCR_VSC2 (1 << 1) /* */
+#define PCMCIA_PSCR_VSC1 (1 << 0) /* */
+
+/* PCMCIA_PER - PCMCIA Enable Register - fields */
+#define PCMCIA_PER_ERRINTEN (1 << 12) /* error interrupt enable */
+#define PCMCIA_PER_POWERONEN (1 << 11) /* power on interrupt enable */
+#define PCMCIA_PER_RDYRE (1 << 10) /* RDY/nIREQ pin rising edge */
+#define PCMCIA_PER_RDYFE (1 << 9) /* RDY/nIREQ pin falling edge */
+#define PCMCIA_PER_RDYHE (1 << 8) /* RDY/nIREQ pin high */
+#define PCMCIA_PER_RDYLE (1 << 7) /* RDY/nIREQ pin low */
+#define PCMCIA_PER_BVDE2 (1 << 6) /* battery voltage 2/SPKR in */
+#define PCMCIA_PER_BVDE1 (1 << 5) /* battery voltage 1/STSCHG */
+#define PCMCIA_PER_CDE2 (1 << 4) /* card detect 2 */
+#define PCMCIA_PER_CDE1 (1 << 3) /* card detect 1 */
+#define PCMCIA_PER_WPE (1 << 2) /* write protect */
+#define PCMCIA_PER_VSE2 (1 << 1) /* voltage sense 2 */
+#define PCMCIA_PER_VSE1 (1 << 0) /* voltage sense 1 */
+
+/* PCMCIA_POR[0-4] - PCMCIA Option Registers 0-4 - fields */
+#define PCMCIA_POR_PV (1 << 29) /* set iff bank is valid */
+#define PCMCIA_POR_WPEN (1 << 28) /* write protect (WP) input signal is enabled */
+#define PCMCIA_POR_WP (1 << 27) /* write protected */
+
+#define PCMCIA_POR_PRS_SHIFT (25)
+#define PCMCIA_POR_PRS(x) (((x) & 0x3) << PCMCIA_POR_PRS_SHIFT )
+#define PCMCIA_POR_PRS_MASK PCMCIA_POR_PRS(3) /* PCMCIA region select */
+#define PCMCIA_POR_PRS_COMMON (0) /* values of POR_PRS field */
+#define PCMCIA_POR_PRS_TRUE_IDE (1)
+#define PCMCIA_POR_PRS_ATTRIBUTE (2)
+#define PCMCIA_POR_PRS_IO (3)
+
+#define PCMCIA_POR_PPS_8 (1 << 24) /* PCMCIA Port size = 8bits */
+#define PCMCIA_POR_PPS_16 (0 << 24) /* PCMCIA Port size = 16bits */
+
+#define PCMCIA_POR_PSL_SHIFT (17) /* strobe length */
+#define PCMCIA_POR_PSL(x) (((x) & 0x7F) << PCMCIA_POR_PSL_SHIFT)
+#define PCMCIA_POR_PSL_MASK PCMCIA_POR_PSL(0x7f)
+
+#define PCMCIA_POR_PSST_SHIFT (11) /* strobe setup time */
+#define PCMCIA_POR_PSST(x) (((x) & 0x3F) << PCMCIA_POR_PSST_SHIFT)
+#define PCMCIA_POR_PSST_MASK PCMCIA_POR_PSST(0x3f)
+
+#define PCMCIA_POR_PSHT_SHIFT (5) /* strobe hold time */
+#define PCMCIA_POR_PSHT(x) (((x) & 0x3F) << PCMCIA_POR_PSHT_SHIFT)
+#define PCMCIA_POR_PSHT_MASK PCMCIA_POR_PSHT(0x3f)
+
+#define PCMCIA_POR_BSIZE_SHIFT (0) /* bank size */
+#define PCMCIA_POR_BSIZE(x) (((x) & 0x1F) << PCMCIA_POR_BSIZE_SHIFT)
+#define PCMCIA_POR_BSIZE_MASK PCMCIA_POR_BSIZE(0x1F)
+
+/* some handy BSIZE values */
+#define POR_BSIZE_1 PCMCIA_POR_BSIZE(0x00)
+#define POR_BSIZE_2 PCMCIA_POR_BSIZE(0x01)
+#define POR_BSIZE_4 PCMCIA_POR_BSIZE(0x03)
+#define POR_BSIZE_8 PCMCIA_POR_BSIZE(0x02)
+#define POR_BSIZE_16 PCMCIA_POR_BSIZE(0x06)
+#define POR_BSIZE_32 PCMCIA_POR_BSIZE(0x07)
+#define POR_BSIZE_64 PCMCIA_POR_BSIZE(0x05)
+#define POR_BSIZE_128 PCMCIA_POR_BSIZE(0x04)
+#define POR_BSIZE_256 PCMCIA_POR_BSIZE(0x0C)
+#define POR_BSIZE_512 PCMCIA_POR_BSIZE(0x0D)
+#define POR_BSIZE_1K PCMCIA_POR_BSIZE(0x0F)
+#define POR_BSIZE_2K PCMCIA_POR_BSIZE(0x0E)
+
+#define POR_BSIZE_4K PCMCIA_POR_BSIZE(0x0A)
+#define POR_BSIZE_8K PCMCIA_POR_BSIZE(0x0B)
+#define POR_BSIZE_16K PCMCIA_POR_BSIZE(0x09)
+#define POR_BSIZE_32K PCMCIA_POR_BSIZE(0x08)
+#define POR_BSIZE_64K PCMCIA_POR_BSIZE(0x18)
+#define POR_BSIZE_128K PCMCIA_POR_BSIZE(0x19)
+#define POR_BSIZE_256K PCMCIA_POR_BSIZE(0x1B)
+#define POR_BSIZE_512K PCMCIA_POR_BSIZE(0x1A)
+#define POR_BSIZE_1M PCMCIA_POR_BSIZE(0x1E)
+#define POR_BSIZE_2M PCMCIA_POR_BSIZE(0x1F)
+#define POR_BSIZE_4M PCMCIA_POR_BSIZE(0x1D)
+#define POR_BSIZE_8M PCMCIA_POR_BSIZE(0x1C)
+#define POR_BSIZE_16M PCMCIA_POR_BSIZE(0x14)
+#define POR_BSIZE_32M PCMCIA_POR_BSIZE(0x15)
+#define POR_BSIZE_64M PCMCIA_POR_BSIZE(0x17)
+
+/* Window size */
+#define POR_1 0x1
+#define POR_2 0x2
+#define POR_4 0x4
+#define POR_8 0x8
+#define POR_16 0x10
+#define POR_32 0x20
+#define POR_64 0x40
+#define POR_128 0x80
+#define POR_256 0x100
+#define POR_512 0x200
+
+#define POR_1K 0x400
+#define POR_2K 0x800
+#define POR_4K 0x1000
+#define POR_8K 0x2000
+#define POR_16K 0x4000
+#define POR_32K 0x8000
+#define POR_64K 0x10000
+#define POR_128K 0x20000
+#define POR_256K 0x40000
+#define POR_512K 0x80000
+
+#define POR_1M 0x100000
+#define POR_2M 0x200000
+#define POR_4M 0x400000
+#define POR_8M 0x800000
+#define POR_16M 0x1000000
+#define POR_32M 0x2000000
+#define POR_64M 0x4000000
+
+/* PCMCIA_PGCR - PCMCIA General Control Register - fields */
+#define PCMCIA_PGCR_LPMEN (1 << 3) /* Low power Mode Enable */
+#define PCMCIA_PGCR_SPKREN (1 << 2) /* SPKROUT routing enable */
+#define PCMCIA_PGCR_POE (1 << 1) /* Controller out enable */
+#define PCMCIA_PGCR_RESET (1 << 0) /* Card reset */
+
+/* PCMCIA_PGSR - PCMCIA General Status Register - fields */
+#define PCMCIA_PGSR_NWINE (1 << 4) /* No Window error */
+#define PCMCIA_PGSR_LPE (1 << 3) /* Low Power error */
+#define PCMCIA_PGSR_SE (1 << 2) /* Size error */
+#define PCMCIA_PGSR_CDE (1 << 1) /* Card Detect error */
+#define PCMCIA_PGSR_WPE (1 << 0) /* Write Protect error */
+
+#endif /* __ASM_ARCH_MXC_PCMCIA_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/pmic_adc.h b/arch/arm/plat-mxc/include/mach/pmic_adc.h
new file mode 100644
index 000000000000..90b24a407a81
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/pmic_adc.h
@@ -0,0 +1,455 @@
+/*
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_PMIC_ADC_H__
+#define __ASM_ARCH_MXC_PMIC_ADC_H__
+
+/*!
+ * @defgroup PMIC_ADC PMIC Digitizer Driver
+ * @ingroup PMIC_DRVRS
+ */
+
+/*!
+ * @file arch-mxc/pmic_adc.h
+ * @brief This is the header of PMIC ADC driver.
+ *
+ * @ingroup PMIC_ADC
+ */
+
+#include <asm/ioctl.h>
+#include <mach/pmic_status.h>
+#include <mach/pmic_external.h>
+
+/*!
+ * @name IOCTL user space interface
+ */
+
+/*! @{ */
+/*!
+ * Initialize ADC.
+ * Argument type: none.
+ */
+#define PMIC_ADC_INIT _IO('p', 0xb0)
+/*!
+ * De-initialize ADC.
+ * Argument type: none.
+ */
+#define PMIC_ADC_DEINIT _IO('p', 0xb1)
+/*!
+ * Convert one channel.
+ * Argument type: pointer to t_adc_convert_param.
+ */
+#define PMIC_ADC_CONVERT _IOWR('p', 0xb2, int)
+/*!
+ * Convert one channel eight samples.
+ * Argument type: pointer to t_adc_convert_param.
+ */
+#define PMIC_ADC_CONVERT_8X _IOWR('p', 0xb3, int)
+/*!
+ * Convert multiple channels.
+ * Argument type: pointer to t_adc_convert_param.
+ */
+#define PMIC_ADC_CONVERT_MULTICHANNEL _IOWR('p', 0xb4, int)
+/*!
+ * Set touch screen operation mode.
+ * Argument type: t_touch_mode.
+ */
+#define PMIC_ADC_SET_TOUCH_MODE _IOW('p', 0xb5, int)
+/*!
+ * Get touch screen operation mode.
+ * Argument type: pointer to t_touch_mode.
+ */
+#define PMIC_ADC_GET_TOUCH_MODE _IOR('p', 0xb6, int)
+/*!
+ * Get touch screen sample.
+ * Argument type: pointer to t_touch_sample.
+ */
+#define PMIC_ADC_GET_TOUCH_SAMPLE _IOWR('p', 0xb7, int)
+/*!
+ * Get battery current.
+ * Argument type: pointer to unsigned short.
+ */
+#define PMIC_ADC_GET_BATTERY_CURRENT _IOR('p', 0xb8, int)
+/*!
+ * Activate comparator.
+ * Argument type: pointer to t_adc_comp_param.
+ */
+#define PMIC_ADC_ACTIVATE_COMPARATOR _IOW('p', 0xb9, int)
+/*!
+ * De-active comparator.
+ * Argument type: none.
+ */
+#define PMIC_ADC_DEACTIVE_COMPARATOR _IOW('p', 0xba, int)
+
+/*!
+ * Install touch screen read interface.
+ */
+#define TOUCH_SCREEN_READ_INSTALL _IOWR('D',4, int)
+/*!
+ * Remove touch screen read interface.
+ */
+#define TOUCH_SCREEN_READ_UNINSTALL _IOWR('D',5, int)
+
+/*! @{ */
+/*!
+ * @name Touch Screen minimum and maximum values
+ */
+#define TS_X_MIN 80 /*! < Minimum X */
+#define TS_Y_MIN 80 /*! < Minimum Y */
+
+#define TS_X_MAX 1000 /*! < Maximum X */
+#define TS_Y_MAX 1000 /*! < Maximum Y */
+/*! @} */
+/*!
+ * This enumeration defines input channels for PMIC ADC
+ */
+
+typedef enum {
+ BATTERY_VOLTAGE,
+ BATTERY_CURRENT,
+ CHARGE_VOLTAGE,
+ CHARGE_CURRENT,
+ APPLICATION_SUPPLY,
+ TS_X_POS1,
+ TS_X_POS2,
+ TS_Y_POS1,
+ TS_Y_POS2,
+ GEN_PURPOSE_AD4,
+ GEN_PURPOSE_AD5,
+ GEN_PURPOSE_AD6,
+ GEN_PURPOSE_AD7,
+ GEN_PURPOSE_AD8,
+ GEN_PURPOSE_AD9,
+ GEN_PURPOSE_AD10,
+ GEN_PURPOSE_AD11,
+ USB_ID,
+ LICELL,
+ RAWEXTBPLUSSENSE,
+ MPBSENSE,
+ BATSENSE,
+ GND,
+ THERMISTOR,
+ DIE_TEMP
+} t_channel;
+
+/*!
+ * This enumeration defines reason of ADC Comparator interrupt.
+ */
+typedef enum {
+ /*!
+ * Greater than WHIGH
+ */
+ GTWHIGH,
+ /*!
+ * Less than WLOW
+ */
+ LTWLOW,
+} t_comp_exception;
+
+/*!
+ * ADC comparator callback function type
+ */
+typedef void (*t_comparator_cb) (t_comp_exception reason);
+
+/*!
+ * This enumeration defines the touch screen operation modes.
+ */
+typedef enum {
+ /*!
+ * Touch Screen X position
+ */
+ TS_X_POSITION = 0,
+ /*!
+ * Touch Screen Y position
+ */
+ TS_Y_POSITION = 1,
+ /*!
+ * Pressure
+ */
+ TS_PRESSURE = 2,
+ /*!
+ * Plate X
+ */
+ TS_PLATE_X = 3,
+ /*!
+ * Plate Y
+ */
+ TS_PLATE_Y = 4,
+ /*!
+ * Standby
+ */
+ TS_STANDBY = 5,
+ /*!
+ * No touch screen, TSX1, TSX2, TSY1 and TSY2 are used as general
+ * purpose A/D inputs.
+ */
+ TS_NONE = 6,
+} t_touch_mode;
+/*!
+ * This structure is used to report touch screen value.
+ */
+typedef struct {
+/*!
+ * Touch Screen X position
+ */
+ unsigned int x_position;
+ /*!
+ * Touch Screen X position1
+ */
+ unsigned int x_position1;
+ /*!
+ * Touch Screen X position2
+ */
+ unsigned int x_position2;
+ /*!
+ * Touch Screen X position3
+ */
+ unsigned int x_position3;
+ /*!
+ * Touch Screen Y position
+ */
+ unsigned int y_position;
+ /*!
+ * Touch Screen Y position1
+ */
+ unsigned int y_position1;
+ /*!
+ * Touch Screen Y position2
+ */
+ unsigned int y_position2;
+ /*!
+ * Touch Screen Y position3
+ */
+ unsigned int y_position3;
+ /*!
+ * Touch Screen contact value
+ */
+ unsigned int contact_resistance;
+} t_touch_screen;
+
+/*!
+ * This enumeration defines ADC conversion modes.
+ */
+typedef enum {
+ /*!
+ * Sample 8 channels, 1 sample per channel
+ */
+ ADC_8CHAN_1X = 0,
+ /*!
+ * Sample 1 channel 8 times
+ */
+ ADC_1CHAN_8X,
+} t_conversion_mode;
+
+/*!
+ * This structure is used with IOCTL code \a PMIC_ADC_CONVERT,
+ * \a PMIC_ADC_CONVERT_8X and \a PMIC_ADC_CONVERT_MULTICHANNEL.
+ */
+
+typedef struct {
+ /*!
+ * channel or channels to be sampled.
+ */
+ t_channel channel;
+ /*!
+ * holds up to 16 sampling results
+ */
+ unsigned short result[16];
+} t_adc_convert_param;
+
+/*!
+ * This structure is used to activate/deactivate ADC comparator.
+ */
+typedef struct {
+ /*!
+ * wlow.
+ */
+ unsigned char wlow;
+ /*!
+ * whigh.
+ */
+ unsigned char whigh;
+ /*!
+ * channel to monitor
+ */
+ t_channel channel;
+ /*!
+ * callback function.
+ */
+ t_comparator_cb callback;
+} t_adc_comp_param;
+
+/* EXPORTED FUNCTIONS */
+
+#ifdef __KERNEL__
+/*!
+ * This function initializes all ADC registers with default values. This
+ * function also registers the interrupt events.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_adc_init(void);
+
+/*!
+ * This function disables the ADC, de-registers the interrupt events.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_adc_deinit(void);
+
+/*!
+ * This function triggers a conversion and returns one sampling result of one
+ * channel.
+ *
+ * @param channel The channel to be sampled
+ * @param result The pointer to the conversion result. The memory
+ * should be allocated by the caller of this function.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+
+PMIC_STATUS pmic_adc_convert(t_channel channel, unsigned short *result);
+
+/*!
+ * This function triggers a conversion and returns eight sampling results of
+ * one channel.
+ *
+ * @param channel The channel to be sampled
+ * @param result The pointer to array to store eight sampling results.
+ * The memory should be allocated by the caller of this
+ * function.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+
+PMIC_STATUS pmic_adc_convert_8x(t_channel channel, unsigned short *result);
+
+/*!
+ * This function triggers a conversion and returns sampling results of each
+ * specified channel.
+ *
+ * @param channels This input parameter is bitmap to specify channels
+ * to be sampled.
+ * @param result The pointer to array to store sampling result.
+ * The order of the result in the array is from lowest
+ * channel number to highest channel number of the
+ * sampled channels.
+ * The memory should be allocated by the caller of this
+ * function.
+ * Note that the behavior of this function might differ
+ * from one platform to another regarding especially
+ * channels order.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+
+PMIC_STATUS pmic_adc_convert_multichnnel(t_channel channels,
+ unsigned short *result);
+
+/*!
+ * This function sets touch screen operation mode.
+ *
+ * @param touch_mode Touch screen operation mode.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_adc_set_touch_mode(t_touch_mode touch_mode);
+
+/*!
+ * This function retrieves the current touch screen operation mode.
+ *
+ * @param touch_mode Pointer to the retrieved touch screen operation
+ * mode.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_adc_get_touch_mode(t_touch_mode * touch_mode);
+
+/*!
+ * This function retrieves the current touch screen operation mode.
+ *
+ * @param touch_sample Pointer to touch sample.
+ * @param wait Indicates if this function needs to block or not.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_adc_get_touch_sample(t_touch_screen * ts_value, int wait);
+
+/*!
+ * This function starts a Battery Current mode conversion.
+ *
+ * @param mode Conversion mode.
+ * @param result Battery Current measurement result.
+ * if \a mode = ADC_8CHAN_1X, the result is \n
+ * result[0] = (BATTP - BATT_I) \n
+ * if \a mode = ADC_1CHAN_8X, the result is \n
+ * result[0] = BATTP \n
+ * result[1] = BATT_I \n
+ * result[2] = BATTP \n
+ * result[3] = BATT_I \n
+ * result[4] = BATTP \n
+ * result[5] = BATT_I \n
+ * result[6] = BATTP \n
+ * result[7] = BATT_I
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_adc_get_battery_current(t_conversion_mode mode,
+ unsigned short *result);
+
+/*!
+ * This function actives the comparator. When comparator is activated and ADC
+ * is enabled, the 8th converted value will be digitally compared against the
+ * window defined by WLOW and WHIGH registers.
+ *
+ * @param low Comparison window low threshold (WLOW).
+ * @param high Comparison window high threshold (WHIGH).
+ * @param callback Callback function to be called when the converted
+ * value is beyond the comparison window. The callback
+ * function will pass a parameter of type
+ * \b t_comp_expection to indicate the reason of
+ * comparator exception.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+
+PMIC_STATUS pmic_adc_active_comparator(unsigned char low,
+ unsigned char high,
+ t_channel channel,
+ t_comparator_cb callback);
+
+/*!
+ * This function de-actives the comparator.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_adc_deactive_comparator(void);
+
+/*!
+ * This function enables the touch screen read interface.
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_adc_install_ts(void);
+
+/*!
+ * This function disables the touch screen read interface.
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_adc_remove_ts(void);
+
+int is_pmic_adc_ready(void);
+
+#endif /* _KERNEL */
+#endif /* __ASM_ARCH_MXC_PMIC_ADC_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/pmic_audio.h b/arch/arm/plat-mxc/include/mach/pmic_audio.h
new file mode 100644
index 000000000000..cab2e6353ce8
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/pmic_audio.h
@@ -0,0 +1,2315 @@
+/*
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_MXC_PMIC_AUDIO_H__
+#define __ASM_ARCH_MXC_PMIC_AUDIO_H__
+
+/*!
+ * @defgroup PMIC_AUDIO PMIC Audio Driver
+ * @ingroup PMIC_DRVRS
+ */
+
+/*!
+ * @file arch-mxc/pmic_audio.h
+ * @brief External definitions for the PMIC Audio Client driver.
+ *
+ * The PMIC Audio driver and this API were developed to support the
+ * audio playback, recording, and mixing capabilities of the power
+ * management ICs that are available from Freescale Semiconductor, Inc.
+ *
+ * The following table shows which audio-related capabilities are supported
+ * by each power management IC:
+ *
+ * @ingroup PMIC_AUDIO
+ */
+
+#include <mach/pmic_status.h>
+#include <mach/pmic_external.h>
+
+/***************************************************************************
+ * TYPEDEFS AND ENUMERATIONS *
+ ***************************************************************************/
+
+/*!
+ * @name General Setup and Audio Device Access Typedefs and Enumerations
+ * Typedefs and enumerations that are used for initial access to the
+ * PMIC Audio hardware.
+ */
+/*@{*/
+
+/*!
+ * @typedef PMIC_AUDIO_HANDLE
+ * @brief Define typedef for a handle to the PMIC Audio hardware.
+ *
+ * Define a "handle" that is returned when the PMIC Audio hardware
+ * is opened. This handle grants exclusive access to the PMIC Audio
+ * hardware and must be used in all subsequent function calls. When access
+ * to the PMIC Audio hardware is no longer required, then a close
+ * operation must be done with this handle. The handle is no longer valid
+ * if the close operation was successful.
+ */
+typedef long *PMIC_AUDIO_HANDLE;
+
+/*!
+ * @enum PMIC_AUDIO_EVENTS
+ * @brief Identify the audio events that have been detected and should be
+ * handled.
+ *
+ * This enumeration defines all of the possible PMIC Audio events. Multiple
+ * events may be selected when defining a mask and multiple events may be
+ * signalled together.
+ *
+ * Note that the MICROPHONE_DETECT and MICROPHONE_REMOVED events may also be
+ * used to signal the operation of a serial or parallel microphone switch
+ * when used with a combined headset+microphone device. In that case the
+ * HEADSET_DETECT state must also be checked to determine if it's only the
+ * microphone switch being operated or whether the microphone has truly been
+ * inserted/removed (along with the headset).
+ */
+typedef enum {
+ HEADSET_DETECTED = 1, /*!< Detected headset insertion. */
+ HEADSET_STEREO = 2, /*!< Detected stereo headset device. */
+ HEADSET_MONO = 4, /*!< Detected mono headset device. */
+ HEADSET_THERMAL_SHUTDOWN = 8, /*!< Detected output amplifier
+ shutdown due to thermal
+ limits . */
+ HEADSET_SHORT_CIRCUIT = 16, /*!< Detected output amplifier
+ short circuit condition
+ . */
+ HEADSET_REMOVED = 32, /*!< Detected headset removal. */
+ MICROPHONE_DETECTED = 64, /*!< Detected microphone insertion. */
+ MICROPHONE_REMOVED = 128, /*!< Detected microphone removal. */
+ PTT_BUTTON_PRESS = 256, /*!< Detected PTT button down
+ . */
+ PTT_BUTTON_RANGE = 512, /*!< Detected PTT button within
+ voltage range
+ . */
+ PTT_SHORT_OR_INVALID = 1024 /*!< Detected PTT button outside
+ of voltage range or invalid
+ device . */
+} PMIC_AUDIO_EVENTS;
+
+/*!
+ * @typedef PMIC_AUDIO_CALLBACK
+ * @brief Typedef for PMIC Audio event notification callback function.
+ *
+ * Define a typedef for the PMIC Audio event notification callback
+ * function. The signalled events are passed to the function as the first
+ * argument. The callback function should then process whatever events it
+ * can and then return the set of unhandled events (if any).
+ */
+typedef PMIC_AUDIO_EVENTS(*PMIC_AUDIO_CALLBACK) (const PMIC_AUDIO_EVENTS event);
+
+typedef struct {
+ int hs_state;
+ int event_type;
+} PMIC_HS_STATE;
+
+/*!
+ * @enum PMIC_AUDIO_SOURCE
+ * @brief Select an audio signal processing component.
+ *
+ * This enumeration defines all of the possible PMIC audio signal handling
+ * components which can be acquired by calling pmic_audio_open().
+ *
+ * Note that the EXTERNAL_STEREO_IN selection is used to simply gain access
+ * to the stereo input pins. The stereo input signal can then be routed
+ * directly to the output amplifiers. In this case, no signal processing is
+ * done by either the Voice CODEC or the Stereo DAC.
+ */
+typedef enum {
+ STEREO_DAC, /*!< Open connection to Stereo DAC. */
+ VOICE_CODEC, /*!< Open connection to Voice CODEC. */
+ EXTERNAL_STEREO_IN /*!< Open connection to external stereo inputs. */
+} PMIC_AUDIO_SOURCE;
+
+/*@}*/
+
+/*!
+ * @name Data Bus Setup and Configuration Typedefs and Enumerations
+ * Typedefs and enumerations that are used to define and configure
+ * the data bus protocol in order to communicate with the Stereo DAC
+ * or the Voice CODEC.
+ */
+/*@{*/
+
+/*!
+ * @enum PMIC_AUDIO_DATA_BUS
+ * @brief Select the data bus used to transfer data between the host and
+ * Voice CODEC and/or the Stereo DAC.
+ *
+ * This enumeration defines all of the possible PMIC audio data buses that
+ * can be used to transfer data between the host and the Voice CODEC and/or
+ * the Stereo DAC on the PMIC.
+ *
+ * Note that the same data bus may be used to transfer audio data to/from
+ * the Voice CODEC and the Stereo DAC. However, in this case, the data bus
+ * must be configured for network mode with different timeslots assigned to
+ * the Voice CODEC and the Stereo DAC. Also, the sampling rates must be
+ * identical for both the Voice CODEC and the Stereo DAC in order to avoid
+ * a data bus timing conflict and audio signal distortion.
+ */
+typedef enum {
+ AUDIO_DATA_BUS_1, /*!< Use data bus 1 for audio data. */
+ AUDIO_DATA_BUS_2 /*!< Use data bus 2 for audio data. */
+} PMIC_AUDIO_DATA_BUS;
+
+/*!
+ * @enum PMIC_AUDIO_BUS_PROTOCOL
+ * @brief Select the data bus protocol to be used.
+ *
+ * This enumeration defines all of the possible PMIC audio data bus protocols
+ * that may be selected.
+ */
+typedef enum {
+ NORMAL_MSB_JUSTIFIED_MODE, /*!< Transmit and receive audio data
+ in normal MSB-justified mode. */
+ NETWORK_MODE, /*!< Transmit and receive audio data
+ in network mode. */
+ I2S_MODE, /*!< Transmit and receive audio data
+ in I2S mode. */
+ SPD_IF_MODE /*!< Transmit and receive audio data
+ in SPD/IF mode . */
+} PMIC_AUDIO_BUS_PROTOCOL;
+
+/*!
+ * @enum PMIC_AUDIO_BUS_MODE
+ * @brief Select the data bus mode to be used.
+ *
+ * This enumeration defines all of the possible PMIC audio data bus modes
+ * that may be selected. When configured in BUS_MASTER_MODE, the PMIC is
+ * responsible for supplying the data bus clock signals. Alternatively,
+ * when configured in BUS_SLAVE_MODE, the PMIC will use the data bus clock
+ * signals that are supplied by the bus master.
+ */
+typedef enum {
+ BUS_MASTER_MODE = 0, /*!< Operate as bus master. */
+ BUS_SLAVE_MODE = 1 /*!< Operate as bus slave. */
+} PMIC_AUDIO_BUS_MODE;
+
+/*!
+ * @enum PMIC_AUDIO_CLOCK_IN_SOURCE
+ * @brief Select the clock signal source when in bus master mode.
+ *
+ * This enumeration defines all of the possible PMIC audio clock signal
+ * sources that may be selected. One of these clock signal sources must
+ * be selected in order to use either the Voice CODEC or the Stereo DAC.
+ *
+ * When configured in BUS_MASTER_MODE, the PMIC's onboard PLL circuits
+ * will also be driven by the selected clock input signal.
+ */
+typedef enum {
+ CLOCK_IN_DEFAULT, /*!< Just use default (power-up) clock input. */
+ CLOCK_IN_CLIA, /*!< Use the CLIA clock source (Stereo DAC
+ default) . */
+ CLOCK_IN_CLIB, /*!< Use the CLIB clock source (Voice CODEC
+ default) . */
+ CLOCK_IN_CLKIN, /*!< Use the CLKIN clock source
+ . */
+ CLOCK_IN_MCLK, /*!< Disable the internal PLL and use the MCLK
+ clock source (Stereo DAC only)
+ . */
+ CLOCK_IN_FSYNC, /*!< Internal PLL input from external framesync
+ (Stereo DAC only) . */
+ CLOCK_IN_BITCLK /*!< Internal PLL input from external bitclock
+ (Stereo DAC only) */
+} PMIC_AUDIO_CLOCK_IN_SOURCE;
+
+/*!
+ * @enum PMIC_AUDIO_CLOCK_INVERT
+ * @brief Select whether to invert the frame sync or bit clock signals.
+ *
+ * This enumeration enables or disables the inversion of the incoming
+ * frame sync or bit clock signals.
+ */
+typedef enum {
+ NO_INVERT = 0, /*!< Do not invert the clock signals. */
+ INVERT_BITCLOCK = 1, /*!< Invert the BCLK input signal. */
+ INVERT_FRAMESYNC = 2 /*!< Invert the FSYNC input signal. */
+} PMIC_AUDIO_CLOCK_INVERT;
+
+/*!
+ * @enum PMIC_AUDIO_NUMSLOTS
+ * @brief Select whether to invert the frame sync or bit clock signals.
+ *
+ * This enumeration defines all of the possible number of timeslots that may
+ * be selected when the PMIC is configured as the data bus master. One of these
+ * options must be selected if the Stereo DAC is to provide the data bus
+ * clock signals.
+ *
+ * Note that the Voice CODEC currently only allows USE_4_TIMESLOTS when
+ * operating in data bus master mode.
+ */
+typedef enum {
+ USE_2_TIMESLOTS, /*!< Configure for 2 timeslots. */
+ USE_4_TIMESLOTS, /*!< Configure for 4 timeslots. */
+ USE_8_STAR_TIMESLOTS, /*!< Configure for 8 (Left, Right, 6 other) timeslots. */
+ USE_8_TIMESLOTS /*!< Configure for 8 timeslots. */
+} PMIC_AUDIO_NUMSLOTS;
+
+/*!
+ * @enum PMIC_AUDIO_STDAC_SAMPLING_RATE
+ * @brief Select the audio data sampling rate for the Stereo DAC.
+ *
+ * This enumeration defines all of the possible sampling rates currently
+ * supported by the Stereo DAC. One of these sampling rates must be selected
+ * and it must match that of the audio stream or else signal distortion will
+ * occur.
+ */
+typedef enum {
+ STDAC_RATE_8_KHZ, /*!< Use 8 kHz sampling rate. */
+ STDAC_RATE_11_025_KHZ, /*!< Use 11.025 kHz sampling rate. */
+ STDAC_RATE_12_KHZ, /*!< Use 12 kHz sampling rate. */
+ STDAC_RATE_16_KHZ, /*!< Use 16 kHz sampling rate. */
+ STDAC_RATE_22_050_KHZ, /*!< Use 22.050 kHz sampling rate. */
+ STDAC_RATE_24_KHZ, /*!< Use 24 kHz sampling rate. */
+ STDAC_RATE_32_KHZ, /*!< Use 32 kHz sampling rate. */
+ STDAC_RATE_44_1_KHZ, /*!< Use 44.1 kHz sampling rate. */
+ STDAC_RATE_48_KHZ, /*!< Use 48 kHz sampling rate. */
+ STDAC_RATE_64_KHZ, /*!< Use 64 kHz sampling rate
+ . */
+ STDAC_RATE_96_KHZ /*!< Use 96 kHz sampling rate.
+ . */
+} PMIC_AUDIO_STDAC_SAMPLING_RATE;
+
+/*!
+ * @enum PMIC_AUDIO_VCODEC_SAMPLING_RATE
+ * @brief Select the audio data sampling rate for the Voice CODEC.
+ *
+ * This enumeration defines all of the possible sampling rates currently
+ * supported by the Voice CODEC. One of these sampling rates must be selected
+ * and it must match that of the audio stream or else signal distortion will
+ * occur.
+ */
+typedef enum {
+ VCODEC_RATE_8_KHZ, /*!< Use 8 kHz sampling rate. */
+ VCODEC_RATE_16_KHZ, /*!< Use 16 kHz sampling rate. */
+} PMIC_AUDIO_VCODEC_SAMPLING_RATE;
+
+/*!
+ * @enum PMIC_AUDIO_ANTI_POP_RAMP_SPEED
+ * @brief Select the anti-pop circuitry's ramp up speed.
+ *
+ * This enumeration defines all of the possible ramp up speeds for the
+ * anti-pop circuitry. A slow ramp up speed may be required in order to
+ * avoid the popping noise that is typically generated during the insertion
+ * or removal of a headset or microphone.
+ */
+typedef enum {
+ ANTI_POP_RAMP_FAST, /*!< Select fast ramp up. */
+ ANTI_POP_RAMP_SLOW /*!< Select slow ramp up. */
+} PMIC_AUDIO_ANTI_POP_RAMP_SPEED;
+
+/*@}*/
+
+/*!
+ * @name General Voice CODEC Configuration Typedefs and Enumerations
+ * Typedefs and enumerations that are used to define and configure
+ * the basic operating options for the Voice CODEC.
+ */
+/*@{*/
+
+/*!
+ * @enum PMIC_AUDIO_VCODEC_CLOCK_IN_FREQ
+ * @brief Select the Voice CODEC input clock frequency.
+ *
+ * This enumeration defines all of the supported Voice CODEC input clock
+ * frequencies. One of these frequencies must be selected in order to
+ * properly configure the Voice CODEC to operate at the required sampling
+ * rate.
+ */
+typedef enum {
+ VCODEC_CLI_13MHZ, /*!< Clock frequency is 13MHz. */
+ VCODEC_CLI_15_36MHZ, /*!< Clock frequency is 15.36MHz. */
+ VCODEC_CLI_16_8MHZ, /*!< Clock frequency is 16.8MHz
+ . */
+ VCODEC_CLI_26MHZ, /*!< Clock frequency is 26MHz. */
+ VCODEC_CLI_33_6MHZ, /*!< Clock frequency is 33.6MHz. */
+} PMIC_AUDIO_VCODEC_CLOCK_IN_FREQ;
+
+/*!
+ * @enum PMIC_AUDIO_VCODEC_CONFIG
+ * @brief Select the Voice CODEC configuration options.
+ *
+ * This enumeration is used to enable/disable each of the Voice CODEC options.
+ * This includes the use of highpass digital filters and audio signal
+ * loopback modes.
+ *
+ * Note that resetting the digital filters is now handled by the
+ * pmic_audio_digital_filter_reset() API.
+ */
+typedef enum {
+ DITHERING = 1, /*!< Enable/disable dithering. */
+ INPUT_HIGHPASS_FILTER = 2, /*!< Enable/disable the input high
+ pass digital filter. */
+ OUTPUT_HIGHPASS_FILTER = 4, /*!< Enable/disable the output high
+ pass digital filter. */
+ ANALOG_LOOPBACK = 8, /*!< Enable/disable the analog
+ loopback path
+ . */
+ DIGITAL_LOOPBACK = 16, /*!< Enable/disable the digital
+ loopback path. */
+ VCODEC_MASTER_CLOCK_OUTPUTS = 32, /*!< Enable/disable the bus master
+ clock outputs. */
+ TRISTATE_TS = 64 /*!< Enable/disable FSYNC, BITCLK,
+ and TX tristate. */
+} PMIC_AUDIO_VCODEC_CONFIG;
+
+/*@}*/
+
+/*!
+ * @name General Stereo DAC Configuration Typedefs and Enumerations
+ * Typedefs and enumerations that are used to define and configure
+ * the basic operating options for the Stereo DAC.
+ */
+/*@{*/
+
+/*!
+ * @enum PMIC_AUDIO_STDAC_CLOCK_IN_FREQ
+ * @brief Select the Stereo DAC input clock frequency.
+ *
+ * This enumeration defines all of the supported Stereo DAC input clock
+ * frequencies. One of these frequencies must be selected in order to
+ * properly configure the Stereo DAC to operate at the required sampling
+ * rate.
+ */
+typedef enum {
+ STDAC_CLI_3_36864MHZ, /*!< Clock frequency is 3.36864MHz
+ . */
+ STDAC_CLI_12MHZ, /*!< Clock frequency is 12MHz.
+ . */
+ STDAC_CLI_13MHZ, /*!< Clock frequency is 13MHz. */
+ STDAC_CLI_15_36MHZ, /*!< Clock frequency is 15.36MHz. */
+ STDAC_CLI_16_8MHZ, /*!< Clock frequency is 16.8MHz
+ . */
+ STDAC_CLI_26MHZ, /*!< Clock frequency is 26MHz. */
+ STDAC_CLI_33_6MHZ, /*!< Clock frequency is 33.6MHz. */
+ STDAC_MCLK_PLL_DISABLED, /*!< Use MCLK and disable internal PLL. */
+ STDAC_FSYNC_IN_PLL, /*!< Use FSYNC as internal PLL input. */
+ STDAC_BCLK_IN_PLL /*!< Use BCLK as internal PLL input. */
+} PMIC_AUDIO_STDAC_CLOCK_IN_FREQ;
+
+/*!
+ * @enum PMIC_AUDIO_STDAC_CONFIG
+ * @brief Select the Stereo DAC configuration options.
+ *
+ * This enumeration is used to enable/disable each of the Stereo DAC options.
+ */
+typedef enum {
+ STDAC_MASTER_CLOCK_OUTPUTS = 1 /*!< Enable/disable the bus master clock
+ outputs. */
+} PMIC_AUDIO_STDAC_CONFIG;
+
+/*@}*/
+
+/*!
+ * @name Voice CODEC Audio Port Mixing Typedefs and Enumerations
+ * Typedefs and enumerations that are used for setting up the audio mixer
+ * within the Voice CODEC.
+ */
+/*@{*/
+
+/*!
+ * @enum PMIC_AUDIO_VCODEC_TIMESLOT
+ * @brief Select the Stereo DAC configuration options.
+ *
+ * This enumeration is used to select the timeslot for both the primary and
+ * secondary (for mc13783-only) audio channels to the Voice CODEC.
+ */
+typedef enum {
+ USE_TS0, /*!< Use timeslot 0 for audio signal source
+ . */
+ USE_TS1, /*!< Use timeslot 1 for audio signal source
+ . */
+ USE_TS2, /*!< Use timeslot 2 for audio signal source
+ . */
+ USE_TS3 /*!< Use timeslot 3 for audio signal source
+ . */
+} PMIC_AUDIO_VCODEC_TIMESLOT;
+
+/*!
+ * @enum PMIC_AUDIO_VCODEC_MIX_IN_GAIN
+ * @brief Select the secondary channel input gain for the Voice CODEC mixer.
+ *
+ * This enumeration selects the secondary channel input gain for the Voice
+ * CODEC mixer.
+ */
+typedef enum {
+ VCODEC_NO_MIX, /*!< No audio mixing . */
+ VCODEC_MIX_IN_0DB, /*!< Mix with 0dB secondary channel gain
+ . */
+ VCODEC_MIX_IN_MINUS_6DB, /*!< Mix with -6dB secondary channel gain
+ . */
+ VCODEC_MIX_IN_MINUS_12DB, /*!< Mix with -12dB secondary channel gain
+ . */
+} PMIC_AUDIO_VCODEC_MIX_IN_GAIN;
+
+/*!
+ * @enum PMIC_AUDIO_VCODEC_MIX_OUT_GAIN
+ * @brief Select the output gain for the Voice CODEC mixer.
+ *
+ * This enumeration selects the output gain for the Voice CODEC mixer.
+ */
+typedef enum {
+ VCODEC_MIX_OUT_0DB, /*!< Select 0dB mixer output gain
+ . */
+ VCODEC_MIX_OUT_MINUS_6DB, /*!< Select -6dB mixer output gain
+ . */
+} PMIC_AUDIO_VCODEC_MIX_OUT_GAIN;
+
+/*@}*/
+
+/*!
+ * @name Stereo DAC Audio Port Mixing Typedefs and Enumerations
+ * Typedefs and enumerations that are used for setting up the audio mixer
+ * within the Stereo DAC.
+ */
+/*@{*/
+
+/*!
+ * @enum PMIC_AUDIO_STDAC_TIMESLOTS
+ * @brief Select the timeslots used to transmit the left and right audio
+ * channels to the Stereo DAC.
+ *
+ * This enumeration is used to select the timeslots used to transmit the
+ * data corresponding to the left and right audio channels to the Stereo
+ * DAC.
+ */
+typedef enum {
+ USE_TS0_TS1, /*!< Use timeslots 0 and 1 for left and
+ right channels, respectively. */
+ USE_TS2_TS3, /*!< Use timeslots 2 and 3 for left and
+ right channels, respectively
+ . */
+ USE_TS4_TS5, /*!< Use timeslots 4 and 5 for left and
+ right channels, respectively
+ . */
+ USE_TS6_TS7 /*!< Use timeslots 6 and 7 for left and
+ right channels, respectively
+ . */
+} PMIC_AUDIO_STDAC_TIMESLOTS;
+
+/*!
+ * @enum PMIC_AUDIO_STDAC_MIX_IN_GAIN
+ * @brief Select the secondary channel input gain for the Stereo DAC mixer.
+ *
+ * This enumeration is used to select the secondary channel input gain for
+ * the Stereo DAC mixer.
+ */
+typedef enum {
+ STDAC_NO_MIX, /*!< No mixing, keep separate left
+ and right audio channels. */
+ STDAC_MIX_IN_0DB, /*!< Mix left and right audio channels
+ together with 0dB secondary
+ channel gain. */
+ STDAC_MIX_IN_MINUS_6DB, /*!< Mix left and right audio channels
+ together with -6dB secondary
+ channel gain. */
+ STDAC_MIX_IN_MINUS_12DB /*!< Mix left and right audio channels
+ together with -12dB secondary
+ channel gain . */
+} PMIC_AUDIO_STDAC_MIX_IN_GAIN;
+
+/*!
+ * @enum PMIC_AUDIO_STDAC_MIX_OUT_GAIN
+ * @brief Select the output gain for the Stereo DAC mixer.
+ *
+ * This enumeration is used to select the output gain for the Stereo DAC
+ * mixer.
+ */
+typedef enum {
+ STDAC_MIX_OUT_0DB, /*!< Select 0dB mixer output gain. */
+ STDAC_MIX_OUT_MINUS_6DB, /*!< Select -6dB mixer output gain
+ . */
+} PMIC_AUDIO_STDAC_MIX_OUT_GAIN;
+
+/*@}*/
+
+/*!
+ * @name Microphone Input Typedefs and Enumerations
+ * Typedefs and enumerations that are used for selecting and setting up
+ * one or more or microphone inputs for recording.
+ */
+/*@{*/
+
+/*!
+ * @enum PMIC_AUDIO_MIC_BIAS
+ * @brief Select the microphone bias circuit to be enabled/disabled.
+ *
+ * This enumeration lists all of the available microphone bias circuits that
+ * may be enabled or disabled.
+ */
+typedef enum {
+ NO_BIAS = 0, /*!< No microphone bias circuit selected. */
+ MIC_BIAS1 = 1, /*!< Enable/disable microphone bias 1 circuit. */
+ MIC_BIAS2 = 2, /*!< Enable/disable microphone bias 2 circuit. */
+} PMIC_AUDIO_MIC_BIAS;
+
+/*!
+ * @enum PMIC_AUDIO_INPUT_PORT
+ * @brief Select an audio input port for recording.
+ *
+ * This enumeration lists all of the available audio input ports that may
+ * be selected for a recording operation.
+ */
+typedef enum {
+ NO_MIC, /*!< No microphone input selected. */
+ MIC1_LEFT, /*!< Enable left/mono channel microphone input
+ . */
+ MIC1_RIGHT_MIC_MONO, /*!< Enable right channel microphone input. */
+ MIC2_AUX, /*!< Enable auxiliary microphone input. */
+ TXIN_EXT /*!< Enable external mono input. */
+} PMIC_AUDIO_INPUT_PORT;
+
+/*!
+ * @enum PMIC_AUDIO_INPUT_MIC_STATE
+ * @brief Control whether the input microphone is on/off.
+ *
+ * This enumeration allows the currently selected input microphone amplifier
+ * to be turned on/off.
+ */
+typedef enum {
+ MICROPHONE_ON, /*!< Turn microphone input on for recording. */
+ MICROPHONE_OFF /*!< Turn microphone input off (mute). */
+} PMIC_AUDIO_INPUT_MIC_STATE;
+
+/*!
+ * @enum PMIC_AUDIO_INPUT_CONFIG
+ * @brief Enable/disable the audio input options.
+ *
+ * This enumeration allows for enabling/disabling any of the audio input
+ * section options.
+ */
+typedef enum {
+ MIC_AMP_AUTO_DISABLE = 1 /*!< Enable/disable automatic disabling of
+ microphone input amplifiers following
+ headset insertion/removal */
+} PMIC_AUDIO_INPUT_CONFIG;
+
+/*!
+ * @enum PMIC_AUDIO_MIC_AMP_MODE
+ * @brief Select the operating mode for the microphone amplifiers.
+ *
+ * This enumeration is used to select the operating mode for the microphone
+ * amplifier.
+ */
+typedef enum {
+ AMP_OFF, /*!< Disable input amplifier. */
+ VOLTAGE_TO_VOLTAGE, /*!< Operate input amplifier in
+ voltage-to-voltage mode
+ . */
+ CURRENT_TO_VOLTAGE /*!< Operate input amplifier in
+ current-to-voltage mode */
+} PMIC_AUDIO_MIC_AMP_MODE;
+
+/*!
+ * @enum PMIC_AUDIO_MIC_GAIN
+ * @brief Select the microphone amplifier gain level.
+ *
+ * This enumeration lists all of the available microphone amplifier gain
+ * levels.
+ */
+typedef enum {
+ MIC_GAIN_MINUS_8DB, /*!< Select -8dB microphone amplifier gain
+ . */
+ MIC_GAIN_MINUS_7DB, /*!< Select -7dB microphone amplifier gain
+ . */
+ MIC_GAIN_MINUS_6DB, /*!< Select -6dB microphone amplifier gain
+ . */
+ MIC_GAIN_MINUS_5DB, /*!< Select -5dB microphone amplifier gain
+ . */
+ MIC_GAIN_MINUS_4DB, /*!< Select -4dB microphone amplifier gain
+ . */
+ MIC_GAIN_MINUS_3DB, /*!< Select -3dB microphone amplifier gain
+ . */
+ MIC_GAIN_MINUS_2DB, /*!< Select -2dB microphone amplifier gain
+ . */
+ MIC_GAIN_MINUS_1DB, /*!< Select -1dB microphone amplifier gain
+ . */
+ MIC_GAIN_0DB, /*!< Select 0dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_1DB, /*!< Select 1dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_2DB, /*!< Select 2dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_3DB, /*!< Select 3dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_4DB, /*!< Select 4dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_5DB, /*!< Select 5dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_6DB, /*!< Select 6dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_7DB, /*!< Select 7dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_8DB, /*!< Select 8dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_9DB, /*!< Select 9dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_10DB, /*!< Select 10dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_11DB, /*!< Select 11dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_12DB, /*!< Select 12dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_13DB, /*!< Select 13dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_14DB, /*!< Select 14dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_15DB, /*!< Select 15dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_16DB, /*!< Select 16dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_17DB, /*!< Select 17dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_18DB, /*!< Select 18dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_19DB, /*!< Select 19dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_20DB, /*!< Select 20dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_21DB, /*!< Select 21dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_22DB, /*!< Select 22dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_23DB, /*!< Select 23dB microphone amplifier gain. */
+ MIC_GAIN_PLUS_24DB, /*!< Select 24dB microphone amplifier gain
+ . */
+ MIC_GAIN_PLUS_25DB, /*!< Select 25dB microphone amplifier gain
+ . */
+ MIC_GAIN_PLUS_26DB, /*!< Select 26dB microphone amplifier gain
+ . */
+ MIC_GAIN_PLUS_27DB, /*!< Select 27dB microphone amplifier gain
+ . */
+ MIC_GAIN_PLUS_28DB, /*!< Select 28dB microphone amplifier gain
+ . */
+ MIC_GAIN_PLUS_29DB, /*!< Select 29dB microphone amplifier gain
+ . */
+ MIC_GAIN_PLUS_30DB, /*!< Select 30dB microphone amplifier gain
+ . */
+ MIC_GAIN_PLUS_31DB /*!< Select 31dB microphone amplifier gain
+ . */
+} PMIC_AUDIO_MIC_GAIN;
+
+/*@}*/
+
+/*!
+ * @name Audio Output Section Typedefs and Enumerations
+ * Typedefs and enumerations that are used for selecting and setting up
+ * one or more or audio output ports for playback.
+ */
+/*@{*/
+
+/*!
+ * @enum PMIC_AUDIO_OUTPUT_PORT
+ * @brief Select the audio output port.
+ *
+ * This enumeration lists all of the available audio output ports. One or
+ * more may be selected as desired to handle the output audio stream from
+ * either the Voice CODEC or the Stereo DAC.
+ */
+typedef enum {
+ MONO_SPEAKER = 1, /*!< Select mono output speaker. */
+ MONO_LOUDSPEAKER = 2, /*!< Select mono loudspeaker
+ . */
+ MONO_ALERT = 4, /*!< Select mono alert output */
+ MONO_EXTOUT = 8, /*!< Select mono external output */
+ MONO_CDCOUT = 16, /*!< Select dedicated Voice CODEC output
+ . */
+ STEREO_LEFT_LOW_POWER = 32, /*!< Select stereo left channel low power
+ output . */
+ STEREO_HEADSET_LEFT = 64, /*!< Select stereo headset left channel. */
+ STEREO_HEADSET_RIGHT = 128, /*!< Select stereo headset right channel. */
+ STEREO_OUT_LEFT = 256, /*!< Select stereo external left channel
+ output . */
+ STEREO_OUT_RIGHT = 512 /*!< Select stereo external right channel
+ output . */
+} PMIC_AUDIO_OUTPUT_PORT;
+
+/*!
+ * @enum PMIC_AUDIO_OUTPUT_CONFIG
+ * @brief Enable/disable the audio output section options.
+ *
+ * This enumeration is used to enable/disable any of the audio output section
+ * options.
+ */
+typedef enum {
+ MONO_SPEAKER_INVERT_OUT_ONLY = 1, /*!< Enable/disable the non-inverted
+ mono speaker output */
+ MONO_LOUDSPEAKER_COMMON_BIAS = 2, /*!< Enable/disable the loudspeaker
+ output amplifier common bias
+ . */
+ HEADSET_DETECT_ENABLE = 4, /*!< Enable/disable headset
+ insertion/removal detection
+ . */
+ STEREO_HEADSET_AMP_AUTO_DISABLE = 8 /*!< Enable/disable automatic
+ disabling of the stereo headset
+ output amplifiers following
+ headset insertion/removal. */
+} PMIC_AUDIO_OUTPUT_CONFIG;
+
+/*!
+ * @enum PMIC_AUDIO_STEREO_IN_GAIN
+ * @brief Select the amplifier gain for the external stereo inputs.
+ *
+ * This enumeration is used to select the amplifier gain level to be used for
+ * the external stereo inputs.
+ */
+typedef enum {
+ STEREO_IN_GAIN_0DB, /*!< Select 0dB external stereo signal
+ input gain. */
+ STEREO_IN_GAIN_PLUS_18DB /*!< Select 18dB external stereo signal
+ input gain . */
+} PMIC_AUDIO_STEREO_IN_GAIN;
+
+/*!
+ * @enum PMIC_AUDIO_OUTPUT_PGA_GAIN
+ * @brief Select the output PGA amplifier gain level.
+ *
+ * This enumeration is used to select the output PGA amplifier gain level.
+ */
+typedef enum {
+ OUTPGA_GAIN_MINUS_33DB, /*!< Select -33dB output PGA gain
+ . */
+ OUTPGA_GAIN_MINUS_30DB, /*!< Select -30dB output PGA gain
+ . */
+ OUTPGA_GAIN_MINUS_27DB, /*!< Select -27dB output PGA gain
+ . */
+ OUTPGA_GAIN_MINUS_24DB, /*!< Select -24dB output PGA gain. */
+ OUTPGA_GAIN_MINUS_21DB, /*!< Select -21dB output PGA gain. */
+ OUTPGA_GAIN_MINUS_18DB, /*!< Select -18dB output PGA gain. */
+ OUTPGA_GAIN_MINUS_15DB, /*!< Select -15dB output PGA gain. */
+ OUTPGA_GAIN_MINUS_12DB, /*!< Select -12dB output PGA gain. */
+ OUTPGA_GAIN_MINUS_9DB, /*!< Select -9dB output PGA gain. */
+ OUTPGA_GAIN_MINUS_6DB, /*!< Select -6dB output PGA gain. */
+ OUTPGA_GAIN_MINUS_3DB, /*!< Select -3dB output PGA gain. */
+ OUTPGA_GAIN_0DB, /*!< Select 0dB output PGA gain. */
+ OUTPGA_GAIN_PLUS_3DB, /*!< Select 3dB output PGA gain. */
+ OUTPGA_GAIN_PLUS_6DB, /*!< Select 6dB output PGA gain. */
+ OUTPGA_GAIN_PLUS_9DB, /*!< Select 9dB output PGA gain.
+ . */
+ OUTPGA_GAIN_PLUS_12DB, /*!< Select 12dB output PGA gain
+ . */
+ OUTPGA_GAIN_PLUS_15DB, /*!< Select 15dB output PGA gain
+ . */
+ OUTPGA_GAIN_PLUS_18DB, /*!< Select 18dB output PGA gain
+ . */
+ OUTPGA_GAIN_PLUS_21DB /*!< Select 21dB output PGA gain
+ . */
+} PMIC_AUDIO_OUTPUT_PGA_GAIN;
+
+/*!
+ * @enum PMIC_AUDIO_OUTPUT_BALANCE_GAIN
+ * @brief Select the left/right channel balance gain level.
+ *
+ * This enumeration is used to select the balance gain level that is to be
+ * separately applied to the left and right audio channels.
+ */
+typedef enum {
+ BAL_GAIN_MINUS_21DB, /*!< Select -21dB channel balance
+ gain . */
+ BAL_GAIN_MINUS_18DB, /*!< Select -18dB channel balance
+ gain . */
+ BAL_GAIN_MINUS_15DB, /*!< Select -15dB channel balance
+ gain . */
+ BAL_GAIN_MINUS_12DB, /*!< Select -12dB channel balance
+ gain . */
+ BAL_GAIN_MINUS_9DB, /*!< Select -9dB channel balance
+ gain . */
+ BAL_GAIN_MINUS_6DB, /*!< Select -6dB channel balance
+ gain . */
+ BAL_GAIN_MINUS_3DB, /*!< Select -3dB channel balance
+ gain . */
+ BAL_GAIN_0DB /*!< Select 0dB channel balance gain. */
+} PMIC_AUDIO_OUTPUT_BALANCE_GAIN;
+
+/*!
+ * @enum PMIC_AUDIO_MONO_ADDER_MODE
+ * @brief Select the output mono adder operating mode.
+ *
+ * This enumeration is used to select the operating mode for the mono adder
+ * in the audio output section.
+ */
+typedef enum {
+ MONO_ADDER_OFF, /*!< Disable mono adder (keep separate
+ left and right channels). */
+ MONO_ADD_LEFT_RIGHT, /*!< Add left and right channels. */
+ MONO_ADD_OPPOSITE_PHASE, /*!< Add left and right channels but
+ with outputs in opposite phase
+ . */
+ STEREO_OPPOSITE_PHASE /*!< Keep separate left and right
+ channels but invert phase of
+ left channel . */
+} PMIC_AUDIO_MONO_ADDER_MODE;
+
+/*!
+ * @enum PMIC_AUDIO_MONO_ADDER_OUTPUT_GAIN
+ * @brief Select the mono adder output amplifier gain level.
+ *
+ * This enumeration is used to select the output amplifier gain level for
+ * the mono adder.
+ */
+typedef enum {
+ MONOADD_GAIN_MINUS_6DB, /*!< Select -6dB mono adder output gain
+ . */
+ MONOADD_GAIN_MINUS_3DB, /*!< Select -3dB mono adder output gain
+ . */
+ MONOADD_GAIN_0DB /*!< Select 0dB mono adder output gain. */
+} PMIC_AUDIO_MONO_ADDER_OUTPUT_GAIN;
+
+/*@}*/
+
+/***************************************************************************
+ * PMIC-SPECIFIC DEFINITIONS *
+ ***************************************************************************/
+
+/*!
+ * @name Definition of PMIC-specific Capabilities
+ * Constants that are used to define PMIC-specific capabilities.
+ */
+/*@{*/
+
+/*!
+ * Define the minimum Stereo DAC sampling rate (Hz).
+ */
+extern const unsigned MIN_STDAC_SAMPLING_RATE_HZ;
+/*!
+ * Define the maximum Stereo DAC sampling rate (Hz).
+ */
+extern const unsigned MAX_STDAC_SAMPLING_RATE_HZ;
+
+/*@}*/
+
+#define DEBUG_AUDIO
+
+#ifdef __KERNEL__
+
+/***************************************************************************
+ * PMIC API DEFINITIONS *
+ ***************************************************************************/
+
+/*!
+ * @name General Setup and Configuration APIs
+ * Functions for general setup and configuration of the PMIC Audio
+ * hardware.
+ */
+/*@{*/
+
+/*!
+ * This function enables the Headset detection mechanism in hardware
+ */
+PMIC_STATUS pmic_audio_set_autodetect(int val);
+
+/*!
+ * @brief Request exclusive access to the PMIC Audio hardware.
+ *
+ * Attempt to open and gain exclusive access to a key PMIC audio hardware
+ * component (e.g., the Stereo DAC or the Voice CODEC). Depending upon the
+ * type of audio operation that is desired and the nature of the audio data
+ * stream, the Stereo DAC and/or the Voice CODEC will be a required hardware
+ * component and needs to be acquired by calling this function.
+ *
+ * If the open request is successful, then a numeric handle is returned
+ * and this handle must be used in all subsequent function calls to complete
+ * the configuration of either the Stereo DAC or the Voice CODEC and along
+ * with any other associated audio hardware components that will be needed.
+ *
+ * The same handle must also be used in the close call when use of the PMIC
+ * audio hardware is no longer required.
+ *
+ * The open request will fail if the requested audio hardware component has
+ * already been acquired by a previous open call but not yet closed.
+ *
+ * @param[out] handle Device handle to be used for subsequent PMIC
+ * Connectivity API calls.
+ * @param[in] device The required PMIC audio hardware component.
+ *
+ * @retval PMIC_SUCCESS If the open request was successful
+ * @retval PMIC_PARAMETER_ERROR If the handle argument is NULL.
+ * @retval PMIC_ERROR If the audio hardware component is
+ * unavailable.
+ */
+PMIC_STATUS pmic_audio_open(PMIC_AUDIO_HANDLE * const handle,
+ const PMIC_AUDIO_SOURCE device);
+
+/*!
+ * @brief Terminate further access to the PMIC audio hardware.
+ *
+ * Terminate further access to the PMIC audio hardware that was previously
+ * acquired by calling pmic_audio_open(). This now allows another thread to
+ * successfully call pmic_audio_open() to gain access.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ *
+ * @retval PMIC_SUCCESS If the close request was successful.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ */
+PMIC_STATUS pmic_audio_close(const PMIC_AUDIO_HANDLE handle);
+
+/*!
+ * @brief Configure the data bus protocol to be used.
+ *
+ * Provide the parameters needed to properly configure the audio data bus
+ * protocol so that data can be read/written to either the Stereo DAC or
+ * the Voice CODEC.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] busID Select data bus to be used.
+ * @param[in] protocol Select the data bus protocol.
+ * @param[in] masterSlave Select the data bus timing mode.
+ * @param[in] numSlots Define the number of timeslots (only if in
+ * master mode).
+ *
+ * @retval PMIC_SUCCESS If the protocol was successful configured.
+ * @retval PMIC_PARAMETER_ERROR If the handle or the protocol parameters
+ * are invalid.
+ */
+PMIC_STATUS pmic_audio_set_protocol(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_DATA_BUS busID,
+ const PMIC_AUDIO_BUS_PROTOCOL protocol,
+ const PMIC_AUDIO_BUS_MODE masterSlave,
+ const PMIC_AUDIO_NUMSLOTS numSlots);
+
+/*!
+ * @brief Retrieve the current data bus protocol configuration.
+ *
+ * Retrieve the parameters that define the current audio data bus protocol.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] busID The data bus being used.
+ * @param[out] protocol The data bus protocol being used.
+ * @param[out] masterSlave The data bus timing mode being used.
+ * @param[out] numSlots The number of timeslots being used (if in
+ * master mode).
+ *
+ * @retval PMIC_SUCCESS If the protocol was successful retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ */
+PMIC_STATUS pmic_audio_get_protocol(const PMIC_AUDIO_HANDLE handle,
+ PMIC_AUDIO_DATA_BUS * const busID,
+ PMIC_AUDIO_BUS_PROTOCOL * const protocol,
+ PMIC_AUDIO_BUS_MODE * const masterSlave,
+ PMIC_AUDIO_NUMSLOTS * const numSlots);
+
+/*!
+ * @brief Enable the Stereo DAC or the Voice CODEC.
+ *
+ * Explicitly enable the Stereo DAC or the Voice CODEC to begin audio
+ * playback or recording as required. This should only be done after
+ * successfully configuring all of the associated audio components (e.g.,
+ * microphones, amplifiers, etc.).
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ *
+ * @retval PMIC_SUCCESS If the device was successful enabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ * @retval PMIC_ERROR If the device could not be enabled.
+ */
+PMIC_STATUS pmic_audio_enable(const PMIC_AUDIO_HANDLE handle);
+
+/*!
+ * @brief Disable the Stereo DAC or the Voice CODEC.
+ *
+ * Explicitly disable the Stereo DAC or the Voice CODEC to end audio
+ * playback or recording as required.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ *
+ * @retval PMIC_SUCCESS If the device was successful disabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ * @retval PMIC_ERROR If the device could not be disabled.
+ */
+PMIC_STATUS pmic_audio_disable(const PMIC_AUDIO_HANDLE handle);
+
+/*!
+ * @brief Reset the selected audio hardware control registers to their
+ * power on state.
+ *
+ * This resets all of the audio hardware control registers currently
+ * associated with the device handle back to their power on states. For
+ * example, if the handle is associated with the Stereo DAC and a
+ * specific output port and output amplifiers, then this function will
+ * reset all of those components to their power on state.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ *
+ * @retval PMIC_SUCCESS If the reset operation was successful.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ * @retval PMIC_ERROR If the reset was unsuccessful.
+ */
+PMIC_STATUS pmic_audio_reset(const PMIC_AUDIO_HANDLE handle);
+
+/*!
+ * @brief Reset all audio hardware control registers to their power on state.
+ *
+ * This resets all of the audio hardware control registers back to their
+ * power on states. Use this function with care since it also invalidates
+ * (i.e., automatically closes) all currently opened device handles.
+ *
+ * @retval PMIC_SUCCESS If the reset operation was successful.
+ * @retval PMIC_ERROR If the reset was unsuccessful.
+ */
+PMIC_STATUS pmic_audio_reset_all(void);
+
+/*!
+ * @brief Set the Audio callback function.
+ *
+ * Register a callback function that will be used to signal PMIC audio
+ * events. For example, the OSS audio driver should register a callback
+ * function in order to be notified of headset connect/disconnect events.
+ *
+ * @param[in] func A pointer to the callback function.
+ * @param[in] eventMask A mask selecting events to be notified.
+ * @param[in] hs_state To know the headset state.
+ *
+ * @retval PMIC_SUCCESS If the callback was successfully
+ * registered.
+ * @retval PMIC_PARAMETER_ERROR If the handle or the eventMask is invalid.
+ */
+PMIC_STATUS pmic_audio_set_callback(void *func,
+ const PMIC_AUDIO_EVENTS eventMask,
+ PMIC_HS_STATE * hs_state);
+
+/*!
+ * @brief Deregisters the existing audio callback function.
+ *
+ * Deregister the callback function that was previously registered by calling
+ * pmic_audio_set_callback().
+ *
+ *
+ * @retval PMIC_SUCCESS If the callback was successfully
+ * deregistered.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ */
+PMIC_STATUS pmic_audio_clear_callback(void);
+
+/*!
+ * @brief Get the current audio callback function settings.
+ *
+ * Get the current callback function and event mask.
+ *
+ * @param[out] func The current callback function.
+ * @param[out] eventMask The current event selection mask.
+ *
+ * @retval PMIC_SUCCESS If the callback information was
+ * successfully retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ */
+PMIC_STATUS pmic_audio_get_callback(PMIC_AUDIO_CALLBACK * const func,
+ PMIC_AUDIO_EVENTS * const eventMask);
+
+/*!
+ * @brief Enable the anti-pop circuitry to avoid extra noise when inserting
+ * or removing a external device (e.g., a headset).
+ *
+ * Enable the use of the built-in anti-pop circuitry to prevent noise from
+ * being generated when an external audio device is inserted or removed
+ * from an audio plug. A slow ramp speed may be needed to avoid extra noise.
+ *
+ * @param[in] rampSpeed The desired anti-pop circuitry ramp speed.
+ *
+ * @retval PMIC_SUCCESS If the anti-pop circuitry was successfully
+ * enabled.
+ * @retval PMIC_ERROR If the anti-pop circuitry could not be
+ * enabled.
+ */
+PMIC_STATUS pmic_audio_antipop_enable(const PMIC_AUDIO_ANTI_POP_RAMP_SPEED
+ rampSpeed);
+
+/*!
+ * @brief Disable the anti-pop circuitry.
+ *
+ * Disable the use of the built-in anti-pop circuitry to prevent noise from
+ * being generated when an external audio device is inserted or removed
+ * from an audio plug.
+ *
+ * @retval PMIC_SUCCESS If the anti-pop circuitry was successfully
+ * disabled.
+ * @retval PMIC_ERROR If the anti-pop circuitry could not be
+ * disabled.
+ */
+PMIC_STATUS pmic_audio_antipop_disable(void);
+
+/*!
+ * @brief Performs a reset of the Voice CODEC/Stereo DAC digital filter.
+ *
+ * This function performs a reset of the digital filter using the back-to-back
+ * SPI write procedure.
+ *
+ * @retval PMIC_SUCCESS If the digital filter was successfully
+ * reset.
+ * @retval PMIC_ERROR If the digital filter could not be reset.
+ */
+PMIC_STATUS pmic_audio_digital_filter_reset(const PMIC_AUDIO_HANDLE handle);
+
+/*!
+ * @brief Get the most recent PTT button voltage reading.
+ *
+ * This function returns the most recent reading for the PTT button voltage.
+ * The value may be used during the processing of the PTT_BUTTON_RANGE event
+ * as part of the headset ID detection process.
+ *
+ * @retval PMIC_SUCCESS If the most recent PTT button voltage was
+ * returned.
+ * @retval PMIC_PARAMETER_ERROR If a NULL pointer argument was given.
+ */
+PMIC_STATUS pmic_audio_get_ptt_button_level(unsigned int *const level);
+
+#ifdef DEBUG_AUDIO
+
+/*!
+ * @brief Provide a hexadecimal dump of all PMIC audio registers (DEBUG only).
+ *
+ * This function is intended strictly for debugging purposes only (i.e.,
+ * the DEBUG macro must be defined) and will print the current values of the
+ * following PMIC registers:
+ *
+ * - AUD_CODEC (Voice CODEC state)
+ * - ST_DAC (Stereo DAC state)
+ * - RX_AUD_AMPS (audio input section state)
+ * - TX_AUD_AMPS (audio output section state)
+ *
+ * The register fields will also be decoded.
+ */
+void pmic_audio_dump_registers(void);
+
+#endif /* DEBUG */
+
+/*@}*/
+
+/*!
+ * @name General Voice CODEC Setup and Configuration APIs
+ * Functions for general setup and configuration of the PMIC Voice
+ * CODEC hardware.
+ */
+/*@{*/
+
+/*!
+ * @brief Set the Voice CODEC clock source and operating characteristics.
+ *
+ * Define the Voice CODEC clock source and operating characteristics. This
+ * must be done before the Voice CODEC is enabled.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] clockIn Select the clock signal source.
+ * @param[in] clockFreq Select the clock signal frequency.
+ * @param[in] samplingRate Select the audio data sampling rate.
+ * @param[in] invert Enable inversion of the frame sync and/or
+ * bit clock inputs.
+ *
+ * @retval PMIC_SUCCESS If the Voice CODEC clock settings were
+ * successfully configured.
+ * @retval PMIC_PARAMETER_ERROR If the handle or clock configuration was
+ * invalid.
+ * @retval PMIC_ERROR If the Voice CODEC clock configuration
+ * could not be set.
+ */
+PMIC_STATUS pmic_audio_vcodec_set_clock(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_CLOCK_IN_SOURCE
+ clockIn,
+ const PMIC_AUDIO_VCODEC_CLOCK_IN_FREQ
+ clockFreq,
+ const PMIC_AUDIO_VCODEC_SAMPLING_RATE
+ samplingRate,
+ const PMIC_AUDIO_CLOCK_INVERT invert);
+
+/*!
+ * @brief Get the Voice CODEC clock source and operating characteristics.
+ *
+ * Get the current Voice CODEC clock source and operating characteristics.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] clockIn The clock signal source.
+ * @param[out] clockFreq The clock signal frequency.
+ * @param[out] samplingRate The audio data sampling rate.
+ * @param[out] invert Inversion of the frame sync and/or
+ * bit clock inputs is enabled/disabled.
+ *
+ * @retval PMIC_SUCCESS If the Voice CODEC clock settings were
+ * successfully retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle invalid.
+ * @retval PMIC_ERROR If the Voice CODEC clock configuration
+ * could not be retrieved.
+ */
+PMIC_STATUS pmic_audio_vcodec_get_clock(const PMIC_AUDIO_HANDLE handle,
+ PMIC_AUDIO_CLOCK_IN_SOURCE *
+ const clockIn,
+ PMIC_AUDIO_VCODEC_CLOCK_IN_FREQ *
+ const clockFreq,
+ PMIC_AUDIO_VCODEC_SAMPLING_RATE *
+ const samplingRate,
+ PMIC_AUDIO_CLOCK_INVERT * const invert);
+
+/*!
+ * @brief Set the Voice CODEC primary audio channel timeslot.
+ *
+ * Set the Voice CODEC primary audio channel timeslot. This function must be
+ * used if the default timeslot for the primary audio channel is to be changed.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] timeslot Select the primary audio channel timeslot.
+ *
+ * @retval PMIC_SUCCESS If the Voice CODEC primary audio channel
+ * timeslot was successfully configured.
+ * @retval PMIC_PARAMETER_ERROR If the handle or audio channel timeslot
+ * was invalid.
+ * @retval PMIC_ERROR If the Voice CODEC primary audio channel
+ * timeslot could not be set.
+ */
+PMIC_STATUS pmic_audio_vcodec_set_rxtx_timeslot(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_VCODEC_TIMESLOT
+ timeslot);
+
+/*!
+ * @brief Get the current Voice CODEC primary audio channel timeslot.
+ *
+ * Get the current Voice CODEC primary audio channel timeslot.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] timeslot The primary audio channel timeslot.
+ *
+ * @retval PMIC_SUCCESS If the Voice CODEC primary audio channel
+ * timeslot was successfully retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the Voice CODEC primary audio channel
+ * timeslot could not be retrieved.
+ */
+PMIC_STATUS pmic_audio_vcodec_get_rxtx_timeslot(const PMIC_AUDIO_HANDLE handle,
+ PMIC_AUDIO_VCODEC_TIMESLOT *
+ const timeslot);
+
+/*!
+ * @brief Set the Voice CODEC secondary recording audio channel timeslot.
+ *
+ * Set the Voice CODEC secondary audio channel timeslot. This function must be
+ * used if the default timeslot for the secondary audio channel is to be
+ * changed. The secondary audio channel timeslot is used to transmit the audio
+ * data that was recorded by the Voice CODEC from the secondary audio input
+ * channel.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] timeslot Select the secondary audio channel timeslot.
+ *
+ * @retval PMIC_SUCCESS If the Voice CODEC secondary audio channel
+ * timeslot was successfully configured.
+ * @retval PMIC_PARAMETER_ERROR If the handle or audio channel timeslot
+ * was invalid.
+ * @retval PMIC_ERROR If the Voice CODEC secondary audio channel
+ * timeslot could not be set.
+ */
+PMIC_STATUS pmic_audio_vcodec_set_secondary_txslot(const PMIC_AUDIO_HANDLE
+ handle,
+ const
+ PMIC_AUDIO_VCODEC_TIMESLOT
+ timeslot);
+
+/*!
+ * @brief Get the Voice CODEC secondary recording audio channel timeslot.
+ *
+ * Get the Voice CODEC secondary audio channel timeslot.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] timeslot The secondary audio channel timeslot.
+ *
+ * @retval PMIC_SUCCESS If the Voice CODEC secondary audio channel
+ * timeslot was successfully retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the Voice CODEC secondary audio channel
+ * timeslot could not be retrieved.
+ */
+PMIC_STATUS pmic_audio_vcodec_get_secondary_txslot(const PMIC_AUDIO_HANDLE
+ handle,
+ PMIC_AUDIO_VCODEC_TIMESLOT *
+ const timeslot);
+
+/*!
+ * @brief Set/Enable the Voice CODEC options.
+ *
+ * Set or enable various Voice CODEC options. The available options include
+ * the use of dithering, highpass digital filters, and loopback modes.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] config The Voice CODEC options to enable.
+ *
+ * @retval PMIC_SUCCESS If the Voice CODEC options were
+ * successfully configured.
+ * @retval PMIC_PARAMETER_ERROR If the handle or Voice CODEC options
+ * were invalid.
+ * @retval PMIC_ERROR If the Voice CODEC options could not be
+ * successfully set/enabled.
+ */
+PMIC_STATUS pmic_audio_vcodec_set_config(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_VCODEC_CONFIG config);
+
+/*!
+ * @brief Clear/Disable the Voice CODEC options.
+ *
+ * Clear or disable various Voice CODEC options.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] config The Voice CODEC options to be cleared/disabled.
+ *
+ * @retval PMIC_SUCCESS If the Voice CODEC options were
+ * successfully cleared/disabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle or the Voice CODEC options
+ * were invalid.
+ * @retval PMIC_ERROR If the Voice CODEC options could not be
+ * cleared/disabled.
+ */
+PMIC_STATUS pmic_audio_vcodec_clear_config(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_VCODEC_CONFIG
+ config);
+
+/*!
+ * @brief Get the current Voice CODEC options.
+ *
+ * Get the current Voice CODEC options.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] config The current set of Voice CODEC options.
+ *
+ * @retval PMIC_SUCCESS If the Voice CODEC options were
+ * successfully retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the Voice CODEC options could not be
+ * retrieved.
+ */
+PMIC_STATUS pmic_audio_vcodec_get_config(const PMIC_AUDIO_HANDLE handle,
+ PMIC_AUDIO_VCODEC_CONFIG *
+ const config);
+
+/*!
+ * @brief Enable the Voice CODEC bypass audio pathway.
+ *
+ * Enables the Voice CODEC bypass pathway for audio data. This allows direct
+ * output of the voltages on the TX data bus line to the output amplifiers
+ * (bypassing the digital-to-analog converters within the Voice CODEC).
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ *
+ * @retval PMIC_SUCCESS If the Voice CODEC bypass was successfully
+ * enabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the Voice CODEC bypass could not be
+ * enabled.
+ */
+PMIC_STATUS pmic_audio_vcodec_enable_bypass(const PMIC_AUDIO_HANDLE handle);
+
+/*!
+ * @brief Disable the Voice CODEC bypass audio pathway.
+ *
+ * Disables the Voice CODEC bypass pathway for audio data. This means that
+ * the TX data bus line will deliver digital data to the digital-to-analog
+ * converters within the Voice CODEC.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ *
+ * @retval PMIC_SUCCESS If the Voice CODEC bypass was successfully
+ * disabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the Voice CODEC bypass could not be
+ * disabled.
+ */
+PMIC_STATUS pmic_audio_vcodec_disable_bypass(const PMIC_AUDIO_HANDLE handle);
+
+/*@}*/
+
+/*!
+ * @name General Stereo DAC Setup and Configuration APIs
+ * Functions for general setup and configuration of the PMIC Stereo
+ * DAC hardware.
+ */
+/*@{*/
+
+/*!
+ * @brief Set the Stereo DAC clock source and operating characteristics.
+ *
+ * Define the Stereo DAC clock source and operating characteristics. This
+ * must be done before the Stereo DAC is enabled.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] clockIn Select the clock signal source.
+ * @param[in] clockFreq Select the clock signal frequency.
+ * @param[in] samplingRate Select the audio data sampling rate.
+ * @param[in] invert Enable inversion of the frame sync and/or
+ * bit clock inputs.
+ *
+ * @retval PMIC_SUCCESS If the Stereo DAC clock settings were
+ * successfully configured.
+ * @retval PMIC_PARAMETER_ERROR If the handle or clock configuration was
+ * invalid.
+ * @retval PMIC_ERROR If the Stereo DAC clock configuration
+ * could not be set.
+ */
+PMIC_STATUS pmic_audio_stdac_set_clock(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_CLOCK_IN_SOURCE clockIn,
+ const PMIC_AUDIO_STDAC_CLOCK_IN_FREQ
+ clockFreq,
+ const PMIC_AUDIO_STDAC_SAMPLING_RATE
+ samplingRate,
+ const PMIC_AUDIO_CLOCK_INVERT invert);
+
+/*!
+ * @brief Get the Stereo DAC clock source and operating characteristics.
+ *
+ * Get the current Stereo DAC clock source and operating characteristics.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] clockIn The clock signal source.
+ * @param[out] clockFreq The clock signal frequency.
+ * @param[out] samplingRate The audio data sampling rate.
+ * @param[out] invert Inversion of the frame sync and/or
+ * bit clock inputs is enabled/disabled.
+ *
+ * @retval PMIC_SUCCESS If the Stereo DAC clock settings were
+ * successfully retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle invalid.
+ * @retval PMIC_ERROR If the Stereo DAC clock configuration
+ * could not be retrieved.
+ */
+PMIC_STATUS pmic_audio_stdac_get_clock(const PMIC_AUDIO_HANDLE handle,
+ PMIC_AUDIO_CLOCK_IN_SOURCE *
+ const clockIn,
+ PMIC_AUDIO_STDAC_SAMPLING_RATE *
+ const samplingRate,
+ PMIC_AUDIO_STDAC_CLOCK_IN_FREQ *
+ const clockFreq,
+ PMIC_AUDIO_CLOCK_INVERT * const invert);
+
+/*!
+ * @brief Set the Stereo DAC primary audio channel timeslot.
+ *
+ * Set the Stereo DAC primary audio channel timeslot. This function must be
+ * used if the default timeslot for the primary audio channel is to be changed.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] timeslot Select the primary audio channel timeslot.
+ *
+ * @retval PMIC_SUCCESS If the Stereo DAC primary audio channel
+ * timeslot was successfully configured.
+ * @retval PMIC_PARAMETER_ERROR If the handle or audio channel timeslot
+ * was invalid.
+ * @retval PMIC_ERROR If the Stereo DAC primary audio channel
+ * timeslot could not be set.
+ */
+PMIC_STATUS pmic_audio_stdac_set_rxtx_timeslot(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_STDAC_TIMESLOTS
+ timeslot);
+
+/*!
+ * @brief Get the current Stereo DAC primary audio channel timeslot.
+ *
+ * Get the current Stereo DAC primary audio channel timeslot.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] timeslot The primary audio channel timeslot.
+ *
+ * @retval PMIC_SUCCESS If the Stereo DAC primary audio channel
+ * timeslot was successfully retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the Stereo DAC primary audio channel
+ * timeslot could not be retrieved.
+ */
+PMIC_STATUS pmic_audio_stdac_get_rxtx_timeslot(const PMIC_AUDIO_HANDLE handle,
+ PMIC_AUDIO_STDAC_TIMESLOTS *
+ const timeslot);
+
+/*!
+ * @brief Set/Enable the Stereo DAC options.
+ *
+ * Set or enable various Stereo DAC options. The available options include
+ * enabling/disabling the bus master clock outputs.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] config The Stereo DAC options to enable.
+ *
+ * @retval PMIC_SUCCESS If the Stereo DAC options were
+ * successfully configured.
+ * @retval PMIC_PARAMETER_ERROR If the handle or Stereo DAC options
+ * were invalid.
+ * @retval PMIC_ERROR If the Stereo DAC options could not be
+ * successfully set/enabled.
+ */
+PMIC_STATUS pmic_audio_stdac_set_config(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_STDAC_CONFIG config);
+
+/*!
+ * @brief Clear/Disable the Stereo DAC options.
+ *
+ * Clear or disable various Stereo DAC options.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] config The Stereo DAC options to be cleared/disabled.
+ *
+ * @retval PMIC_SUCCESS If the Stereo DAC options were
+ * successfully cleared/disabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle or the Stereo DAC options
+ * were invalid.
+ * @retval PMIC_ERROR If the Stereo DAC options could not be
+ * cleared/disabled.
+ */
+PMIC_STATUS pmic_audio_stdac_clear_config(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_STDAC_CONFIG config);
+
+/*!
+ * @brief Get the current Stereo DAC options.
+ *
+ * Get the current Stereo DAC options.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] config The current set of Stereo DAC options.
+ *
+ * @retval PMIC_SUCCESS If the Stereo DAC options were
+ * successfully retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the Stereo DAC options could not be
+ * retrieved.
+ */
+PMIC_STATUS pmic_audio_stdac_get_config(const PMIC_AUDIO_HANDLE handle,
+ PMIC_AUDIO_STDAC_CONFIG * const config);
+
+/*@}*/
+
+/*!
+ * @name Audio Input Setup and Configuration APIs
+ * Functions for general setup and configuration of the PMIC audio
+ * input hardware.
+ */
+/*@{*/
+
+/*!
+ * @brief Set/Enable the audio input section options.
+ *
+ * Set or enable various audio input section options. The only available
+ * option right now is to enable the automatic disabling of the microphone
+ * input amplifiers when a microphone/headset is inserted or removed.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] config The audio input section options to enable.
+ *
+ * @retval PMIC_SUCCESS If the audio input section options were
+ * successfully configured.
+ * @retval PMIC_PARAMETER_ERROR If the handle or audio input section
+ * options were invalid.
+ * @retval PMIC_ERROR If the audio input section options could
+ * not be successfully set/enabled.
+ */
+PMIC_STATUS pmic_audio_input_set_config(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_INPUT_CONFIG config);
+
+/*!
+ * @brief Clear/Disable the audio input section options.
+ *
+ * Clear or disable various audio input section options.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] config The audio input section options to be
+ * cleared/disabled.
+ *
+ * @retval PMIC_SUCCESS If the audio input section options were
+ * successfully cleared/disabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle or the audio input section
+ * options were invalid.
+ * @retval PMIC_ERROR If the audio input section options could
+ * not be cleared/disabled.
+ */
+PMIC_STATUS pmic_audio_input_clear_config(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_INPUT_CONFIG config);
+
+/*!
+ * @brief Get the current audio input section options.
+ *
+ * Get the current audio input section options.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] config The current set of audio input section options.
+ *
+ * @retval PMIC_SUCCESS If the audio input section options were
+ * successfully retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the audio input section options could
+ * not be retrieved.
+ */
+PMIC_STATUS pmic_audio_input_get_config(const PMIC_AUDIO_HANDLE handle,
+ PMIC_AUDIO_INPUT_CONFIG * const config);
+
+/*@}*/
+
+/*!
+ * @name Audio Recording Using the Voice CODEC Setup and Configuration APIs
+ * Functions for general setup and configuration of the PMIC Voice CODEC
+ * to perform audio recording.
+ */
+/*@{*/
+
+/*!
+ * @brief Select the microphone inputs to be used for Voice CODEC recording.
+ *
+ * Select left and right microphone inputs for Voice CODEC
+ * recording. It is possible to disable or not use a particular microphone
+ * input channel by specifying NO_MIC as a parameter.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] leftChannel Select the left microphone input channel.
+ * @param[in] rightChannel Select the right microphone input channel.
+ *
+ * @retval PMIC_SUCCESS If the microphone input channels were
+ * successfully enabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle or microphone input ports
+ * were invalid.
+ * @retval PMIC_ERROR If the microphone input channels could
+ * not be successfully enabled.
+ */
+PMIC_STATUS pmic_audio_vcodec_set_mic(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_INPUT_PORT leftChannel,
+ const PMIC_AUDIO_INPUT_PORT rightChannel);
+
+/*!
+ * @brief Get the current microphone inputs being used for Voice CODEC
+ * recording.
+ *
+ * Get the left and right microphone inputs currently being
+ * used for Voice CODEC recording.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] leftChannel The left microphone input channel.
+ * @param[out] rightChannel The right microphone input channel.
+ *
+ * @retval PMIC_SUCCESS If the microphone input channels were
+ * successfully retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the microphone input channels could
+ * not be retrieved.
+ */
+PMIC_STATUS pmic_audio_vcodec_get_mic(const PMIC_AUDIO_HANDLE handle,
+ PMIC_AUDIO_INPUT_PORT * const leftChannel,
+ PMIC_AUDIO_INPUT_PORT *
+ const rightChannel);
+
+/*!
+ * @brief Enable/disable the microphone input.
+ *
+ * This function enables/disables the current microphone input channel. The
+ * input amplifier is automatically turned off when the microphone input is
+ * disabled.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] leftChannel The left microphone input channel state.
+ * @param[in] rightChannel the right microphone input channel state.
+ *
+ * @retval PMIC_SUCCESS If the microphone input channels were
+ * successfully reconfigured.
+ * @retval PMIC_PARAMETER_ERROR If the handle or microphone input states
+ * were invalid.
+ * @retval PMIC_ERROR If the microphone input channels could
+ * not be reconfigured.
+ */
+PMIC_STATUS pmic_audio_vcodec_set_mic_on_off(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_INPUT_MIC_STATE
+ leftChannel,
+ const PMIC_AUDIO_INPUT_MIC_STATE
+ rightChannel);
+
+/*!
+ * @brief Return the current state of the microphone inputs.
+ *
+ * This function returns the current state (on/off) of the microphone
+ * input channels.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] leftChannel The current left microphone input channel
+ * state.
+ * @param[out] rightChannel the current right microphone input channel
+ * state.
+ *
+ * @retval PMIC_SUCCESS If the microphone input channel states
+ * were successfully retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the microphone input channel states
+ * could not be retrieved.
+ */
+PMIC_STATUS pmic_audio_vcodec_get_mic_on_off(const PMIC_AUDIO_HANDLE handle,
+ PMIC_AUDIO_INPUT_MIC_STATE *
+ const leftChannel,
+ PMIC_AUDIO_INPUT_MIC_STATE *
+ const rightChannel);
+
+/*!
+ * @brief Set the microphone input amplifier mode and gain level.
+ *
+ * This function sets the current microphone input amplifier operating mode
+ * and gain level.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] leftChannelMode The left microphone input amplifier mode.
+ * @param[in] leftChannelGain The left microphone input amplifier gain level.
+ * @param[in] rightChannelMode The right microphone input amplifier mode.
+ * @param[in] rightChannelGain The right microphone input amplifier gain
+ * level.
+ *
+ * @retval PMIC_SUCCESS If the microphone input amplifiers were
+ * successfully reconfigured.
+ * @retval PMIC_PARAMETER_ERROR If the handle or microphone input amplifier
+ * modes or gain levels were invalid.
+ * @retval PMIC_ERROR If the microphone input amplifiers could
+ * not be reconfigured.
+ */
+PMIC_STATUS pmic_audio_vcodec_set_record_gain(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_MIC_AMP_MODE
+ leftChannelMode,
+ const PMIC_AUDIO_MIC_GAIN
+ leftChannelGain,
+ const PMIC_AUDIO_MIC_AMP_MODE
+ rightChannelMode,
+ const PMIC_AUDIO_MIC_GAIN
+ rightChannelGain);
+
+/*!
+ * @brief Get the current microphone input amplifier mode and gain level.
+ *
+ * This function gets the current microphone input amplifier operating mode
+ * and gain level.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] leftChannelMode The left microphone input amplifier mode.
+ * @param[out] leftChannelGain The left microphone input amplifier gain level.
+ * @param[out] rightChannelMode The right microphone input amplifier mode.
+ * @param[out] rightChannelGain The right microphone input amplifier gain
+ * level.
+ *
+ * @retval PMIC_SUCCESS If the microphone input amplifier modes
+ * and gain levels were successfully
+ * retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the microphone input amplifier modes
+ * and gain levels could not be retrieved.
+ */
+PMIC_STATUS pmic_audio_vcodec_get_record_gain(const PMIC_AUDIO_HANDLE handle,
+ PMIC_AUDIO_MIC_AMP_MODE *
+ const leftChannelMode,
+ PMIC_AUDIO_MIC_GAIN *
+ const leftChannelGain,
+ PMIC_AUDIO_MIC_AMP_MODE *
+ const rightChannelMode,
+ PMIC_AUDIO_MIC_GAIN *
+ const rightChannelGain);
+
+/*!
+ * @brief Enable a microphone bias circuit.
+ *
+ * This function enables one of the available microphone bias circuits.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] biasCircuit The microphone bias circuit to be enabled.
+ *
+ * @retval PMIC_SUCCESS If the microphone bias circuit was
+ * successfully enabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle or selected microphone bias
+ * circuit was invalid.
+ * @retval PMIC_ERROR If the microphone bias circuit could not
+ * be enabled.
+ */
+PMIC_STATUS pmic_audio_vcodec_enable_micbias(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_MIC_BIAS
+ biasCircuit);
+
+/*!
+ * @brief Disable a microphone bias circuit.
+ *
+ * This function disables one of the available microphone bias circuits.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] biasCircuit The microphone bias circuit to be disabled.
+ *
+ * @retval PMIC_SUCCESS If the microphone bias circuit was
+ * successfully disabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle or selected microphone bias
+ * circuit was invalid.
+ * @retval PMIC_ERROR If the microphone bias circuit could not
+ * be disabled.
+ */
+PMIC_STATUS pmic_audio_vcodec_disable_micbias(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_MIC_BIAS
+ biasCircuit);
+
+/*@}*/
+
+/*!
+ * @name Audio Playback Using the Voice CODEC Setup and Configuration APIs
+ * Functions for general setup and configuration of the PMIC Voice CODEC
+ * to perform audio playback.
+ */
+/*@{*/
+
+/*!
+ * @brief Configure and enable the Voice CODEC mixer.
+ *
+ * This function configures and enables the Voice CODEC mixer.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] rxSecondaryTimeslot The timeslot used for the secondary audio
+ * channel.
+ * @param[in] gainIn The secondary audio channel gain level.
+ * @param[in] gainOut The mixer output gain level.
+ *
+ * @retval PMIC_SUCCESS If the Voice CODEC mixer was successfully
+ * configured and enabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle or mixer configuration
+ * was invalid.
+ * @retval PMIC_ERROR If the Voice CODEC mixer could not be
+ * reconfigured or enabled.
+ */
+PMIC_STATUS pmic_audio_vcodec_enable_mixer(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_VCODEC_TIMESLOT
+ rxSecondaryTimeslot,
+ const PMIC_AUDIO_VCODEC_MIX_IN_GAIN
+ gainIn,
+ const PMIC_AUDIO_VCODEC_MIX_OUT_GAIN
+ gainOut);
+
+/*!
+ * @brief Disable the Voice CODEC mixer.
+ *
+ * This function disables the Voice CODEC mixer.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ *
+ * @retval PMIC_SUCCESS If the Voice CODEC mixer was successfully
+ * disabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the Voice CODEC mixer could not be
+ * disabled.
+ */
+PMIC_STATUS pmic_audio_vcodec_disable_mixer(const PMIC_AUDIO_HANDLE handle);
+
+/*@}*/
+
+/*!
+ * @name Audio Playback Using the Stereo DAC Setup and Configuration APIs
+ * Functions for general setup and configuration of the PMIC Stereo DAC
+ * to perform audio playback.
+ */
+/*@{*/
+
+/*!
+ * @brief Configure and enable the Stereo DAC mixer.
+ *
+ * This function configures and enables the Stereo DAC mixer.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] rxSecondaryTimeslot The timeslot used for the secondary audio
+ * channel.
+ * @param[in] gainIn The secondary audio channel gain level.
+ * @param[in] gainOut The mixer output gain level.
+ *
+ * @retval PMIC_SUCCESS If the Stereo DAC mixer was successfully
+ * configured and enabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle or mixer configuration
+ * was invalid.
+ * @retval PMIC_ERROR If the Stereo DAC mixer could not be
+ * reconfigured or enabled.
+ */
+PMIC_STATUS pmic_audio_stdac_enable_mixer(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_STDAC_TIMESLOTS
+ rxSecondaryTimeslot,
+ const PMIC_AUDIO_STDAC_MIX_IN_GAIN
+ gainIn,
+ const PMIC_AUDIO_STDAC_MIX_OUT_GAIN
+ gainOut);
+
+/*!
+ * @brief Disable the Stereo DAC mixer.
+ *
+ * This function disables the Stereo DAC mixer.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ *
+ * @retval PMIC_SUCCESS If the Stereo DAC mixer was successfully
+ * disabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the Stereo DAC mixer could not be
+ * disabled.
+ */
+PMIC_STATUS pmic_audio_stdac_disable_mixer(const PMIC_AUDIO_HANDLE handle);
+
+/*@}*/
+
+/*!
+ * @name Audio Output Section Setup and Configuration APIs
+ * Functions for general setup and configuration of the PMIC audio output
+ * section to support playback.
+ */
+/*@{*/
+
+/*!
+ * @brief Select the audio output ports.
+ *
+ * This function selects the audio output ports to be used. This also enables
+ * the appropriate output amplifiers.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] port The audio output ports to be used.
+ *
+ * @retval PMIC_SUCCESS If the audio output ports were successfully
+ * acquired.
+ * @retval PMIC_PARAMETER_ERROR If the handle or output ports were
+ * invalid.
+ * @retval PMIC_ERROR If the audio output ports could not be
+ * acquired.
+ */
+PMIC_STATUS pmic_audio_output_set_port(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_OUTPUT_PORT port);
+
+/*!
+ * @brief Deselect/disable the audio output ports.
+ *
+ * This function disables the audio output ports that were previously enabled
+ * by calling pmic_audio_output_set_port().
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] port The audio output ports to be disabled.
+ *
+ * @retval PMIC_SUCCESS If the audio output ports were successfully
+ * disabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle or output ports were
+ * invalid.
+ * @retval PMIC_ERROR If the audio output ports could not be
+ * disabled.
+ */
+PMIC_STATUS pmic_audio_output_clear_port(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_OUTPUT_PORT port);
+
+/*!
+ * @brief Get the current audio output ports.
+ *
+ * This function retrieves the audio output ports that are currently being
+ * used.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] port The audio output ports currently being used.
+ *
+ * @retval PMIC_SUCCESS If the audio output ports were successfully
+ * retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the audio output ports could not be
+ * retrieved.
+ */
+PMIC_STATUS pmic_audio_output_get_port(const PMIC_AUDIO_HANDLE handle,
+ PMIC_AUDIO_OUTPUT_PORT * const port);
+
+/*!
+ * @brief Set the gain level for the external stereo inputs.
+ *
+ * This function sets the gain levels for the external stereo inputs.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] gain The external stereo input gain level.
+ *
+ * @retval PMIC_SUCCESS If the gain level was successfully set.
+ * @retval PMIC_PARAMETER_ERROR If the handle or gain level was invalid.
+ * @retval PMIC_ERROR If the gain level could not be set.
+ */
+PMIC_STATUS pmic_audio_output_set_stereo_in_gain(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_STEREO_IN_GAIN
+ gain);
+
+/*!
+ * @brief Get the current gain level for the external stereo inputs.
+ *
+ * This function retrieves the current gain levels for the external stereo
+ * inputs.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] gain The current external stereo input gain
+ * level.
+ *
+ * @retval PMIC_SUCCESS If the gain level was successfully
+ * retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the gain level could not be retrieved.
+ */
+PMIC_STATUS pmic_audio_output_get_stereo_in_gain(const PMIC_AUDIO_HANDLE handle,
+ PMIC_AUDIO_STEREO_IN_GAIN *
+ const gain);
+
+/*!
+ * @brief Set the output PGA gain level.
+ *
+ * This function sets the audio output PGA gain level.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] gain The output PGA gain level.
+ *
+ * @retval PMIC_SUCCESS If the gain level was successfully set.
+ * @retval PMIC_PARAMETER_ERROR If the handle or gain level was invalid.
+ * @retval PMIC_ERROR If the gain level could not be set.
+ */
+PMIC_STATUS pmic_audio_output_set_pgaGain(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_OUTPUT_PGA_GAIN
+ gain);
+
+/*!
+ * @brief Get the output PGA gain level.
+ *
+ * This function retrieves the current audio output PGA gain level.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] gain The current output PGA gain level.
+ *
+ * @retval PMIC_SUCCESS If the gain level was successfully
+ * retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the gain level could not be retrieved.
+ */
+PMIC_STATUS pmic_audio_output_get_pgaGain(const PMIC_AUDIO_HANDLE handle,
+ PMIC_AUDIO_OUTPUT_PGA_GAIN *
+ const gain);
+
+/*!
+ * @brief Enable the output mixer.
+ *
+ * This function enables the output mixer for the audio stream that
+ * corresponds to the current handle (i.e., the Voice CODEC, Stereo DAC, or
+ * the external stereo inputs).
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ *
+ * @retval PMIC_SUCCESS If the mixer was successfully enabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the mixer could not be enabled.
+ */
+PMIC_STATUS pmic_audio_output_enable_mixer(const PMIC_AUDIO_HANDLE handle);
+
+/*!
+ * @brief Disable the output mixer.
+ *
+ * This function disables the output mixer for the audio stream that
+ * corresponds to the current handle (i.e., the Voice CODEC, Stereo DAC, or
+ * the external stereo inputs).
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ *
+ * @retval PMIC_SUCCESS If the mixer was successfully disabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the mixer could not be disabled.
+ */
+PMIC_STATUS pmic_audio_output_disable_mixer(const PMIC_AUDIO_HANDLE handle);
+
+/*!
+ * @brief Configure and enable the output balance amplifiers.
+ *
+ * This function configures and enables the output balance amplifiers.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] leftGain The desired left channel gain level.
+ * @param[in] rightGain The desired right channel gain level.
+ *
+ * @retval PMIC_SUCCESS If the output balance amplifiers were
+ * successfully configured and enabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle or gain levels were invalid.
+ * @retval PMIC_ERROR If the output balance amplifiers could not
+ * be reconfigured or enabled.
+ */
+PMIC_STATUS pmic_audio_output_set_balance(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_OUTPUT_BALANCE_GAIN
+ leftGain,
+ const PMIC_AUDIO_OUTPUT_BALANCE_GAIN
+ rightGain);
+
+/*!
+ * @brief Get the current output balance amplifier gain levels.
+ *
+ * This function retrieves the current output balance amplifier gain levels.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] leftGain The current left channel gain level.
+ * @param[out] rightGain The current right channel gain level.
+ *
+ * @retval PMIC_SUCCESS If the output balance amplifier gain levels
+ * were successfully retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the output balance amplifier gain levels
+ * could be retrieved.
+ */
+PMIC_STATUS pmic_audio_output_get_balance(const PMIC_AUDIO_HANDLE handle,
+ PMIC_AUDIO_OUTPUT_BALANCE_GAIN *
+ const leftGain,
+ PMIC_AUDIO_OUTPUT_BALANCE_GAIN *
+ const rightGain);
+
+/*!
+ * @brief Configure and enable the output mono adder.
+ *
+ * This function configures and enables the output mono adder.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] mode The desired mono adder operating mode.
+ *
+ * @retval PMIC_SUCCESS If the mono adder was successfully
+ * configured and enabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle or mono adder mode was
+ * invalid.
+ * @retval PMIC_ERROR If the mono adder could not be reconfigured
+ * or enabled.
+ */
+PMIC_STATUS pmic_audio_output_enable_mono_adder(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_MONO_ADDER_MODE
+ mode);
+
+/*!
+ * @brief Disable the output mono adder.
+ *
+ * This function disables the output mono adder.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ *
+ * @retval PMIC_SUCCESS If the mono adder was successfully
+ * disabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the mono adder could not be disabled.
+ */
+PMIC_STATUS pmic_audio_output_disable_mono_adder(const PMIC_AUDIO_HANDLE
+ handle);
+
+/*!
+ * @brief Configure the mono adder output gain level.
+ *
+ * This function configures the mono adder output amplifier gain level.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] gain The desired output gain level.
+ *
+ * @retval PMIC_SUCCESS If the mono adder output amplifier gain
+ * level was successfully set.
+ * @retval PMIC_PARAMETER_ERROR If the handle or gain level was invalid.
+ * @retval PMIC_ERROR If the mono adder output amplifier gain
+ * level could not be reconfigured.
+ */
+PMIC_STATUS pmic_audio_output_set_mono_adder_gain(const PMIC_AUDIO_HANDLE
+ handle,
+ const
+ PMIC_AUDIO_MONO_ADDER_OUTPUT_GAIN
+ gain);
+
+/*!
+ * @brief Get the current mono adder output gain level.
+ *
+ * This function retrieves the current mono adder output amplifier gain level.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] gain The current output gain level.
+ *
+ * @retval PMIC_SUCCESS If the mono adder output amplifier gain
+ * level was successfully retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the mono adder output amplifier gain
+ * level could not be retrieved.
+ */
+PMIC_STATUS pmic_audio_output_get_mono_adder_gain(const PMIC_AUDIO_HANDLE
+ handle,
+ PMIC_AUDIO_MONO_ADDER_OUTPUT_GAIN
+ * const gain);
+
+/*!
+ * @brief Set various audio output section options.
+ *
+ * This function sets one or more audio output section configuration
+ * options. The currently supported options include whether to disable
+ * the non-inverting mono speaker output, enabling the loudspeaker common
+ * bias circuit, enabling detection of headset insertion/removal, and
+ * whether to automatically disable the headset amplifiers when a headset
+ * insertion/removal has been detected.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] config The desired audio output section
+ * configuration options to be set.
+ *
+ * @retval PMIC_SUCCESS If the desired configuration options were
+ * all successfully set.
+ * @retval PMIC_PARAMETER_ERROR If the handle or configuration options
+ * were invalid.
+ * @retval PMIC_ERROR If the desired configuration options
+ * could not be set.
+ */
+PMIC_STATUS pmic_audio_output_set_config(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_OUTPUT_CONFIG config);
+
+/*!
+ * @brief Clear various audio output section options.
+ *
+ * This function clears one or more audio output section configuration
+ * options.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[in] config The desired audio output section
+ * configuration options to be cleared.
+ *
+ * @retval PMIC_SUCCESS If the desired configuration options were
+ * all successfully cleared.
+ * @retval PMIC_PARAMETER_ERROR If the handle or configuration options
+ * were invalid.
+ * @retval PMIC_ERROR If the desired configuration options
+ * could not be cleared.
+ */
+PMIC_STATUS pmic_audio_output_clear_config(const PMIC_AUDIO_HANDLE handle,
+ const PMIC_AUDIO_OUTPUT_CONFIG
+ config);
+
+/*!
+ * @brief Get the current audio output section options.
+ *
+ * This function retrieves the current audio output section configuration
+ * option settings.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ * @param[out] config The current audio output section
+ * configuration option settings.
+ *
+ * @retval PMIC_SUCCESS If the current configuration options were
+ * successfully retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the current configuration options
+ * could not be retrieved.
+ */
+PMIC_STATUS pmic_audio_output_get_config(const PMIC_AUDIO_HANDLE handle,
+ PMIC_AUDIO_OUTPUT_CONFIG *
+ const config);
+
+/*!
+ * @brief Enable the phantom ground circuit that is used to help identify
+ * the type of headset that has been inserted.
+ *
+ * This function enables the phantom ground circuit that is used to help
+ * identify the type of headset (e.g., stereo or mono) that has been inserted.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ *
+ * @retval PMIC_SUCCESS If the phantom ground circuit was
+ * successfully enabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the phantom ground circuit could not
+ * be enabled.
+ */
+PMIC_STATUS pmic_audio_output_enable_phantom_ground(void);
+
+/*!
+ * @brief Disable the phantom ground circuit that is used to help identify
+ * the type of headset that has been inserted.
+ *
+ * This function disables the phantom ground circuit that is used to help
+ * identify the type of headset (e.g., stereo or mono) that has been inserted.
+ *
+ * @param[in] handle Device handle from pmic_audio_open() call.
+ *
+ * @retval PMIC_SUCCESS If the phantom ground circuit was
+ * successfully disabled.
+ * @retval PMIC_PARAMETER_ERROR If the handle was invalid.
+ * @retval PMIC_ERROR If the phantom ground circuit could not
+ * be disabled.
+ */
+PMIC_STATUS pmic_audio_output_disable_phantom_ground(void);
+
+/*!
+ * @brief Enable/Disable fm output
+ *
+ * This function enables/disables the fm output.
+ *
+ * @param[in] enable True to enable and false to disable
+ *
+ * @retval PMIC_SUCCESS If the fm output was
+ * successfully enable or disabled
+ * @retval PMIC_ERROR If the operation fails
+ */
+PMIC_STATUS pmic_audio_fm_output_enable(bool enable);
+
+/*@}*/
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_ARCH_MXC_PMIC_AUDIO_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/pmic_battery.h b/arch/arm/plat-mxc/include/mach/pmic_battery.h
new file mode 100644
index 000000000000..04eb986bdc6f
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/pmic_battery.h
@@ -0,0 +1,419 @@
+/*
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+#ifndef __ASM_ARCH_MXC_PMIC_BATTERY_H__
+#define __ASM_ARCH_MXC_PMIC_BATTERY_H__
+
+/*!
+ * @defgroup PMIC_BATTERY PMIC Battery Driver
+ * @ingroup PMIC_DRVRS
+ */
+
+/*!
+ * @file arch-mxc/pmic_battery.h
+ * @brief This is the header of PMIC Battery driver.
+ *
+ * @ingroup PMIC_BATTERY
+ */
+
+#include <asm/ioctl.h>
+#include <mach/pmic_status.h>
+#include <mach/pmic_external.h>
+
+/*!
+ * @name IOCTL user space interface
+ */
+
+/*! @{ */
+/*!
+ * Enable and disable charger.
+ * Argument type: pointer to t_charger_setting
+ */
+#define PMIC_BATT_CHARGER_CONTROL _IOW('p', 0xc0, int)
+/*!
+ * Set charger configuration.
+ * Argument type: pointer to t_charger_setting
+ */
+#define PMIC_BATT_SET_CHARGER _IOW('p', 0xc1, int)
+/*!
+ * Get charger configuration.
+ * Argument type: pointer to t_charger_setting
+ */
+#define PMIC_BATT_GET_CHARGER _IOR('p', 0xc2, int)
+/*!
+ * Get charger current.
+ * Argument type: pointer to t_charger_setting
+ */
+#define PMIC_BATT_GET_CHARGER_CURRENT _IOR('p', 0xc3, int)
+/*!
+ * Set EOL control
+ * Argument type: pointer to t_eol_setting
+ */
+#define PMIC_BATT_EOL_CONTROL _IOW('p', 0xc4, int)
+/*!
+ * Enable and disable charging LED.
+ * Argument type: bool
+ */
+#define PMIC_BATT_LED_CONTROL _IOW('p', 0xc5, int)
+/*!
+ * Enable and disable reverse supply.
+ * Argument type: bool
+ */
+#define PMIC_BATT_REV_SUPP_CONTROL _IOW('p', 0xc6, int)
+/*!
+ * Enable and disable unregulated charging mode.
+ * Argument type: bool
+ */
+#define PMIC_BATT_UNREG_CONTROL _IOW('p', 0xc7, int)
+
+/*!
+ * Set the output controls.
+ * Argument type: t_control
+ */
+#define PMIC_BATT_SET_OUT_CONTROL _IOW('p', 0xc8, int)
+/*!
+ * Set the over voltage threshold.
+ * Argument type: int
+ */
+#define PMIC_BATT_SET_THRESHOLD _IOW('p', 0xc9, int)
+
+/*!
+ * Get the charger voltage.
+ * Argument type: int
+ */
+#define PMIC_BATT_GET_CHARGER_VOLTAGE _IOR('p', 0xca, int)
+/*!
+ * Get the battery voltage.
+ * Argument type: int
+ */
+#define PMIC_BATT_GET_BATTERY_VOLTAGE _IOR('p', 0xcb, int)
+/*!
+ * Get the battery current.
+ * Argument type: int
+ */
+#define PMIC_BATT_GET_BATTERY_CURRENT _IOR('p', 0xcc, int)
+/*!
+ * Get the charger sensor.
+ * Argument type: int
+ */
+#define PMIC_BATT_GET_CHARGER_SENSOR _IOR('p', 0xcd, int)
+/*!
+ * Get the battery temperature.
+ * Argument type: int
+ */
+#define PMIC_BATT_GET_BATTERY_TEMPERATURE _IOR('p', 0xce, int)
+/*! @} */
+
+/*!
+ * This enumeration defines battery chargers.
+ */
+typedef enum {
+ BATT_MAIN_CHGR = 0, /*!< Main battery charger */
+ BATT_CELL_CHGR, /*!< Cell battery charger */
+ BATT_TRCKLE_CHGR /*!< Trickle charger (only available on mc13783) */
+} t_batt_charger;
+
+/*!
+ * This enumeration defines the bp threshold.
+ */
+typedef enum {
+ BATT_BP_0 = 0, /*!< LOBATL UVDET + 0.2 */
+ BATT_BP_1, /*!< LOBATL UVDET + 0.3 */
+ BATT_BP_2, /*!< LOBATL UVDET + 0.4 */
+ BATT_BP_3 /*!< LOBATL UVDET + 0.5 */
+} t_bp_threshold;
+
+/*!
+ * This enumeration of all types of output controls
+ */
+typedef enum {
+ /*!
+ * controlled hardware
+ */
+ CONTROL_HARDWARE = 0,
+ /*!
+ * BPFET is driven low, BATTFET is driven high
+ */
+ CONTROL_BPFET_LOW,
+ /*!
+ * BPFET is driven high, BATTFET is driven low
+ */
+ CONTROL_BPFET_HIGH,
+} t_control;
+
+/*!
+ * This enumeration define all battery interrupt
+ */
+typedef enum {
+ /*!
+ * Charge detection interrupt
+ */
+ BAT_IT_CHG_DET,
+ /*!
+ * Charge over voltage detection it
+ */
+ BAT_IT_CHG_OVERVOLT,
+ /*!
+ * Charge path reverse current it
+ */
+ BAT_IT_CHG_REVERSE,
+ /*!
+ * Charge path short circuitin revers supply mode it
+ */
+ BAT_IT_CHG_SHORT_CIRCUIT,
+ /*!
+ * Charger has switched its mode (CC to CV or CV to CC)
+ */
+ BAT_IT_CCCV,
+ /*!
+ * Charge current has dropped below its threshold
+ */
+ BAT_IT_BELOW_THRESHOLD,
+} t_batt_event;
+
+/*!
+ * This structure is used for the following battery changer control
+ * IOCTLs:
+ * - PMIC_BATT_CHARGER_CONTROL
+ * - PMIC_BATT_SET_CHARGER
+ * - PMIC_BATT_GET_CHARGER
+ */
+typedef struct {
+ /*!
+ * Charger
+ */
+ t_batt_charger chgr;
+ /*!
+ * Turn on charger
+ */
+ bool on;
+ /*!
+ * Charging voltage
+ */
+ unsigned char c_voltage;
+ /*!
+ * Charging current
+ */
+ unsigned char c_current;
+} t_charger_setting;
+
+/*!
+ * This structure is used for EOL setting IOCTL PMIC_BATT_EOL_CONTROL
+ */
+typedef struct {
+ /*!
+ * Enable EOL comparator
+ */
+ bool enable;
+ /*!
+ * c_voltage threshold - Used on SC55112
+ */
+ unsigned char threshold;
+ /*!
+ * bp threshold - Used on mc13783
+ */
+ t_bp_threshold typical;
+} t_eol_setting;
+
+/* EXPORTED FUNCTIONS */
+
+#ifdef __KERNEL__
+
+/*START: for 3ds hw event*/
+/*!
+ * Battery event type enum
+ */
+enum {
+ BAT_EVENT_CHARGER_PLUG = 0x01,
+ BAT_EVENT_CHARGER_UNPLUG = 0x02,
+ BAT_EVENT_CHARGER_OVERVOLTAGE = 0x04,
+ BAT_EVENT_BATTERY_LOW = 0x08,
+ BAT_EVENT_POWER_FAILED = 0x10,
+ BAT_EVENT_CHARGER_FULL = 0x20,
+} t_bat_event;
+/*END: for 3ds hw event*/
+
+/*!
+ * This function is used to start charging a battery. For different charger,
+ * different c_voltage and current range are supported. \n
+ *
+ *
+ * @param chgr Charger as defined in \b t_batt_charger.
+ * @param c_voltage Charging voltage.
+ * @param c_current Charging current.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_batt_enable_charger(t_batt_charger chgr,
+ unsigned char c_voltage,
+ unsigned char c_current);
+
+/*!
+ * This function turns off a charger.
+ *
+ * @param chgr Charger as defined in \b t_batt_charger.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_batt_disable_charger(t_batt_charger chgr);
+
+/*!
+ * This function is used to change the charger setting.
+ *
+ * @param chgr Charger as defined in \b t_batt_charger.
+ * @param c_voltage Charging voltage.
+ * @param c_current Charging current.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_batt_set_charger(t_batt_charger chgr,
+ unsigned char c_voltage,
+ unsigned char c_current);
+
+/*!
+ * This function is used to retrieve the charger setting.
+ *
+ * @param chgr Charger as defined in \b t_batt_charger.
+ * @param c_voltage Output parameter for charging c_voltage setting.
+ * @param c_current Output parameter for charging current setting.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_batt_get_charger_setting(t_batt_charger chgr,
+ unsigned char *c_voltage,
+ unsigned char *c_current);
+
+/*!
+ * This function is retrieves the main battery charging current.
+ *
+ * @param c_current Output parameter for charging current setting.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+
+PMIC_STATUS pmic_batt_get_charge_current(unsigned short *c_current);
+
+/*!
+ * This function enables End-of-Life comparator.
+ *
+ * @param threshold End-of-Life threshold.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_batt_enable_eol(unsigned char threshold);
+
+/*!
+ * This function enables End-of-Life comparator.
+ *
+ * @param typical Falling Edge Threshold threshold.
+ * @verbatim
+ BPDET UVDET LOBATL
+ ____ _____ ___________
+ 0 2.6 UVDET + 0.2
+ 1 2.6 UVDET + 0.3
+ 2 2.6 UVDET + 0.4
+ 3 2.6 UVDET + 0.5
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_batt_bp_enable_eol(t_bp_threshold typical);
+
+/*!
+ * This function disables End-of-Life comparator.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_batt_disable_eol(void);
+
+/*!
+ * This function sets the output controls.
+ * It sets the FETOVRD and FETCTRL bits of mc13783
+ *
+ * @param control type of control.
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_batt_set_out_control(t_control control);
+
+/*!
+ * This function sets over voltage threshold.
+ *
+ * @param threshold value of over voltage threshold.
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_batt_set_threshold(int threshold);
+
+/*!
+ * This function controls charge LED.
+ *
+ * @param on If on is true, LED will be turned on,
+ * or otherwise, LED will be turned off.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_batt_led_control(bool on);
+
+/*!
+ * This function sets reverse supply mode.
+ *
+ * @param enable If enable is true, reverse supply mode is enable,
+ * or otherwise, reverse supply mode is disabled.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_batt_set_reverse_supply(bool enable);
+
+/*!
+ * This function sets unregulated charging mode on main battery.
+ *
+ * @param enable If enable is true, unregulated charging mode is
+ * enable, or otherwise, disabled.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_batt_set_unregulated(bool enable);
+
+/*!
+ * This function sets a 5K pull down at CHRGRAW.
+ * To be used in the dual path charging configuration.
+ *
+ * @param enable If enable is true, 5k pull down is
+ * enable, or otherwise, disabled.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_batt_set_5k_pull(bool enable);
+
+/*!
+ * This function is used to subscribe on battery event IT.
+ *
+ * @param event type of event.
+ * @param callback event callback function.
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_batt_event_subscribe(t_batt_event event, void *callback);
+
+/*!
+ * This function is used to un subscribe on battery event IT.
+ *
+ * @param event type of event.
+ * @param callback event callback function.
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_batt_event_unsubscribe(t_batt_event event, void *callback);
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_ARCH_MXC_PMIC_BATTERY_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/pmic_convity.h b/arch/arm/plat-mxc/include/mach/pmic_convity.h
new file mode 100644
index 000000000000..5b51ab8288cd
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/pmic_convity.h
@@ -0,0 +1,873 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_MXC_PMIC_CONVITY_H__
+#define __ASM_ARCH_MXC_PMIC_CONVITY_H__
+
+/*!
+ * @defgroup PMIC_CONNECTIVITY PMIC Connectivity Driver
+ * @ingroup PMIC_DRVRS
+ */
+
+/*!
+ * @file arch-mxc/pmic_convity.h
+ * @brief External definitions for the PMIC Connectivity Client driver.
+ *
+ * The PMIC Connectivity driver and this API were developed to support the
+ * external connectivity capabilities of several power management ICs that
+ * are available from Freescale Semiconductor, Inc.
+ *
+ * The following operating modes, in terms of external connectivity, are
+ * supported:
+ *
+ *
+ *
+ * @ingroup PMIC_CONNECTIVITY
+ */
+
+#include <mach/pmic_status.h>
+#include <mach/pmic_external.h>
+
+/***************************************************************************
+ * TYPEDEFS AND ENUMERATIONS *
+ ***************************************************************************/
+
+/*!
+ * @name General Setup and Configuration Typedefs and Enumerations
+ * Typedefs and enumerations that are used for initial access to and
+ * configuration of the PMIC Connectivity hardware.
+ */
+/*@{*/
+
+#define DEBUG_CONVITY
+
+/*!
+ * @typedef PMIC_CONVITY_HANDLE
+ * @brief Define typedef for a handle to the PMIC Connectivity hardware.
+ *
+ * Define a "handle" that is returned when the PMIC Connectivity hardware
+ * is opened. This handle grants exclusive access to the PMIC Connectivity
+ * hardware and must be used in all subsequent function calls. When access
+ * to the PMIC Connectivity hardware is no longer required, then a close
+ * operation must be done with this handle. The handle is no longer valid
+ * if the close operation was successful.
+ */
+typedef long PMIC_CONVITY_HANDLE;
+
+/*!
+ * @enum PMIC_CONVITY_MODE
+ * @brief Select the main Connectivity operating mode.
+ *
+ * Defines all possible PMIC Connectivity main operating modes. Only one of
+ * these modes can be active at a time.
+ */
+typedef enum {
+ USB, /*!< Select USB mode (this is also the Reset/Default
+ mode). */
+ RS232, /*!< Select RS-232 mode. for SC55112 */
+ RS232_1, /*!< Select RS-232_1 mode. */
+ RS232_2, /*!< Select RS-232_2 mode. */
+ CEA936_MONO, /*!< Select CE-936 Mono mode . */
+ CEA936_STEREO, /*!< Select CE-936 Stereo mode . */
+ CEA936_TEST_RIGHT, /*!< Select CE-936 Right Channel Test mode
+ . */
+ CEA936_TEST_LEFT /*!< Select CE-936 Left Channel Test mode
+ . */
+} PMIC_CONVITY_MODE;
+
+/*!
+ * @enum PMIC_CONVITY_EVENTS
+ * @brief Identify the connectivity events that have been detected and should
+ * be handled.
+ *
+ * Defines all possible PMIC Connectivity events. Multiple events may be
+ * selected when defining a mask.
+ */
+typedef enum {
+ USB_DETECT_4V4_RISE = 1, /*!< Detected 4.4V rising edge. */
+ USB_DETECT_4V4_FALL = 2, /*!< Detected 4.4V falling edge. */
+ USB_DETECT_2V0_RISE = 4, /*!< Detected 2.0V rising edge. */
+ USB_DETECT_2V0_FALL = 8, /*!< Detected 2.0V falling edge. */
+ USB_DETECT_0V8_RISE = 16, /*!< Detected 0.8V rising edge. */
+ USB_DETECT_0V8_FALL = 32, /*!< Detected 0.8V falling edge. */
+ USB_DETECT_MINI_A = 64, /*!< Detected USB mini A plug. */
+ USB_DETECT_MINI_B = 128, /*!< Detected USB mini B plug. */
+ USB_DETECT_NON_USB_ACCESSORY = 256, /*!< Detected a non-USB connection
+ . */
+ USB_DETECT_FACTORY_MODE = 512, /*!< Detected a factory-mode
+ connection . */
+ USB_DP_HI = 1024,
+
+ USB_DM_HI = 2048
+} PMIC_CONVITY_EVENTS;
+
+/*!
+ * @typedef PMIC_CONVITY_CALLBACK
+ * @brief Typedef for PMIC Connectivity event notification callback function.
+ *
+ * Define a typedef for the PMIC Connectivity event notification callback
+ * function. The signalled events are passed to the function as the first
+ * argument. The callback function should then process whatever events it
+ * can and then return the set of unhandled events (if any).
+ */
+typedef void (*PMIC_CONVITY_CALLBACK) (const PMIC_CONVITY_EVENTS event);
+
+/*@}*/
+
+/*!
+ * @name USB and USB On-The-Go Mode-specific Typedefs and Enumerations
+ * Typedefs and enumerations that are used only for setting up and controlling
+ * the USB and USB On-The-Go modes of operation.
+ */
+/*@{*/
+
+/*!
+ * @enum PMIC_CONVITY_USB_DEVICE_TYPE
+ * @brief Select the USB device type (either A or B).
+ *
+ * Defines all possible USB device types. This must match the physical
+ * connector being used.
+ */
+typedef enum {
+ USB_A_DEVICE,
+ USB_B_DEVICE
+} PMIC_CONVITY_USB_DEVICE_TYPE;
+
+/*!
+ * @enum PMIC_CONVITY_USB_SPEED
+ * @brief Select the USB transceiver operating speed.
+ *
+ * Defines all possible USB transceiver operating speeds. Only one
+ * speed setting may be used at a time.
+ */
+typedef enum {
+ USB_LOW_SPEED, /*!< Select 1.5 Mbps. */
+ USB_FULL_SPEED, /*!< Select 12 Mbps. */
+ USB_HIGH_SPEED /*!< Select 480 Mbps <b>(currently
+ not supported)</b>. */
+} PMIC_CONVITY_USB_SPEED;
+
+/*!
+ * @enum PMIC_CONVITY_USB_MODE
+ * @brief Select the USB transceiver operating mode.
+ *
+ * Defines all possible USB transceiver operating modes. Only one
+ * mode may be used at a time. The selected mode, in combination with
+ * the USB bus speed, determines the selection of pull-up and pull-down
+ * resistors.
+ */
+typedef enum {
+ USB_HOST,
+ USB_PERIPHERAL
+} PMIC_CONVITY_USB_MODE;
+
+/*!
+ * @enum PMIC_CONVITY_USB_POWER_IN
+ * @brief Select the USB transceiver's power regulator input source.
+ *
+ * Defines all possible input power sources for the USB transceiver power
+ * regulator. Only one power supply source may be selected at a time.
+ */
+typedef enum {
+
+ USB_POWER_INTERNAL_BOOST, /*!< Select internal power source
+ with boost. */
+
+ USB_POWER_VBUS, /*!< Select VBUS power source. */
+
+ USB_POWER_INTERNAL /*!< Select internal power source
+ . */
+} PMIC_CONVITY_USB_POWER_IN;
+
+/*!
+ * @enum PMIC_CONVITY_USB_POWER_OUT
+ * @brief Select the USB transceiver power regulator output voltage.
+ *
+ * Defines all possible output voltages for the USB transceiver power
+ * regulator. Only one power output voltage level may be selected at
+ * a time.
+ */
+typedef enum {
+ USB_POWER_2V775, /*!< Select 2.775V output voltage
+ . */
+ USB_POWER_3V3 /*!< Select 3.3V output voltage. */
+} PMIC_CONVITY_USB_POWER_OUT;
+
+/*!
+ * @enum PMIC_CONVITY_USB_TRANSCEIVER_MODE
+ * @brief Select the USB transceiver operating mode.
+ *
+ * Defines all valid USB transceiver operating modes. Only one of the
+ * following USB transceiver modes may be selected at a time.
+ */
+typedef enum {
+ USB_TRANSCEIVER_OFF, /*!< USB transceiver currently off
+ . */
+ USB_SINGLE_ENDED_UNIDIR, /*!< Select Single-ended
+ unidirectional transmit mode. */
+ USB_SINGLE_ENDED_UNIDIR_TX, /*!< Select Single-ended
+ unidirectional transmit mode. */
+ USB_SINGLE_ENDED_UNIDIR_RX, /*!< Select Single-ended
+ unidirectional receive mode. */
+ USB_SINGLE_ENDED_BIDIR, /*!< Select Single-ended
+ bidirectional transmit mode. */
+ USB_SINGLE_ENDED_LOW, /*!< Select USB SE0 mode. */
+ USB_DIFFERENTIAL_UNIDIR_TX, /*!< Select Differential
+ unidirectional transmit mode
+ . */
+ USB_DIFFERENTIAL_UNIDIR, /*!< Select Differential
+ unidirectional transmit mode
+ . */
+
+ USB_DIFFERENTIAL_UNIDIR_RX, /*!< Select Differential
+ unidirectional receive mode. */
+ USB_DIFFERENTIAL_BIDIR, /*!< Select Differential
+ bidirectional transmit mode
+ */
+ USB_SUSPEND_ON, /*!< Select Suspend mode. */
+ USB_SUSPEND_OFF, /*!< Terminate Suspend mode. */
+ USB_OTG_SRP_DLP_START, /*!< Start USB On-The-Go Session
+ Request Protocol using Data
+ Line Pulsing. */
+ USB_OTG_SRP_DLP_STOP /*!< Terminate USB On-The-Go Session
+ Request Protocol using Data
+ Line Pulsing. */
+} PMIC_CONVITY_USB_TRANSCEIVER_MODE;
+
+/*!
+ * @enum PMIC_CONVITY_USB_OTG_CONFIG
+ * @brief Select the USB On-The-Go configuration options.
+ *
+ * Defines all possible USB On-The-Go configuration options. Multiple
+ * configuration options may be selected at the same time. However, only one
+ * VBUS current limit may be selected at a time. Selecting more than one
+ * VBUS current limit will result in undefined and implementation-dependent
+ * behavior.
+ */
+typedef enum {
+ USB_OTG_SE0CONN = 0x00001, /*!< Enable automatic
+ connection of a pull-up
+ resistor to VUSB when the
+ SE0 condition is detected. */
+ USB_OTG_DLP_SRP = 0x00002, /*!< Enable use of the hardware
+ timer to control the
+ duration of the data line
+ pulse during the session
+ request protocol. */
+ USB_PULL_OVERRIDE = 0x00004, /*!< Enable automatic disconnect
+ of pull-up and pull-down
+ resistors when transmitter
+ is enabled. */
+
+ USB_DP150K_PU = 0x00008,
+
+ USB_VBUS_CURRENT_LIMIT_HIGH = 0x00010, /*!< Select current limit to 200mA
+ for VBUS regulator. */
+ USB_VBUS_CURRENT_LIMIT_LOW = 0x00020, /*!< Select low current limit
+ for VBUS regulator. */
+ USB_VBUS_CURRENT_LIMIT_LOW_10MS = 0x00040, /*!< Select low current limit
+ for VBUS regulator for
+ 10 ms . */
+ USB_VBUS_CURRENT_LIMIT_LOW_20MS = 0x00080, /*!< Select low current limit
+ for VBUS regulator for
+ 20 ms . */
+ USB_VBUS_CURRENT_LIMIT_LOW_30MS = 0x00100, /*!< Select low current limit
+ for VBUS regulator for
+ 30 ms . */
+ USB_VBUS_CURRENT_LIMIT_LOW_40MS = 0x00200, /*!< Select low current limit
+ for VBUS regulator for
+ 40 ms . */
+ USB_VBUS_CURRENT_LIMIT_LOW_50MS = 0x00400, /*!< Select low current limit
+ for VBUS regulator for
+ 50 ms . */
+ USB_VBUS_CURRENT_LIMIT_LOW_60MS = 0x00800, /*!< Select low current limit
+ for VBUS regulator for
+ 60 ms . */
+
+ USB_VBUS_PULLDOWN = 0x01000, /*!< Enable VBUS pull-down. */
+
+ USB_USBCNTRL = 0x02000,
+
+ USB_UDP_PD = 0x04000,
+
+ USB_UDM_PD = 0x08000,
+
+ USB_PU = 0x10000,
+
+ USBXCVREN = 0x20000
+} PMIC_CONVITY_USB_OTG_CONFIG;
+/*@}*/
+
+/*!
+ * @name RS-232 Mode-specific Typedefs and Enumerations
+ * Typedefs and enumerations that are used only for setting up and controlling
+ * the RS-232 mode of operation.
+ */
+/*@{*/
+
+/*!
+ * @enum PMIC_CONVITY_RS232_EXTERNAL
+ * @brief Select the RS-232 transceiver external connections.
+ *
+ * Defines all valid RS-232 transceiver external RX/TX connection options.
+ * Only one connection mode may be selected at a time.
+ */
+typedef enum {
+ RS232_TX_UDM_RX_UDP, /*!< Select RS-232 TX on UDM */
+ RS232_TX_UDP_RX_UDM, /*!< Select RS-232 TX on UDP
+ . */
+ RS232_TX_RX_EXTERNAL_DEFAULT /*!< Use power on default. */
+} PMIC_CONVITY_RS232_EXTERNAL;
+
+/*!
+ * @enum PMIC_CONVITY_RS232_INTERNAL
+ * @brief Select the RS-232 transceiver internal connections.
+ *
+ * Defines all valid RS-232 transceiver internal RX/TX connection options.
+ * Only one connection mode can be selected at a time.
+ */
+typedef enum {
+ RS232_TX_USE0VM_RX_UDATVP, /*!< Select RS-232 TX from USE0VM
+ . */
+ RS232_TX_UDATVP_RX_URXVM, /*!< Select RS-232 TX from UDATVP
+ . */
+ RS232_TX_UTXDI_RX_URXDO, /*!< Select RS-232 TX from UTXDI
+ . */
+ RS232_TX_RX_INTERNAL_DEFAULT /*!< Use power on default. */
+} PMIC_CONVITY_RS232_INTERNAL;
+
+/*@}*/
+
+/*!
+ * @name CEA-936 Mode-specific Typedefs and Enumerations
+ * Typedefs and enumerations that are used only for setting up and controlling
+ * the CEA-936 mode of operation.
+ */
+/*@{*/
+
+/*!
+ * @enum PMIC_CONVITY_CEA936_EXIT_SIGNAL
+ * @brief Select the CEA-936 mode exit signal.
+ *
+ * Defines all valid CEA-936 connection termination signals. Only one
+ * termination signal can be selected at a time.
+ */
+typedef enum {
+ CEA936_UID_NO_PULLDOWN, /*!< No UID pull-down . */
+ CEA936_UID_PULLDOWN_6MS, /*!< UID pull-down for 6 ms (+/-2 ms)
+ . */
+ CEA936_UID_PULLDOWN, /*!< UID pulled down . */
+ CEA936_UDMPULSE /*!< UDM pulsed . */
+} PMIC_CONVITY_CEA936_EXIT_SIGNAL;
+
+/*@}*/
+
+/***************************************************************************
+ * PMIC API DEFINITIONS *
+ ***************************************************************************/
+
+/*!
+ * @name General Setup and Configuration APIs
+ * Functions for general setup and configuration of the PMIC Connectivity
+ * hardware.
+ */
+/*@{*/
+
+/*!
+ * @brief Request exclusive access to the PMIC Connectivity hardware.
+ *
+ * Attempt to open and gain exclusive access to the PMIC Connectivity
+ * hardware. An initial operating mode (e.g., USB or RS-232) must also
+ * be specified.
+ *
+ * If the open request is successful, then a numeric handle is returned
+ * and this handle must be used in all subsequent function calls. The
+ * same handle must also be used in the close call when use of the PMIC
+ * connectivity hardware is no longer required.
+ *
+ * The open request will fail if another thread has already obtained the
+ * device handle and has not yet called pmic_convity_close() with it.
+ *
+ * @param handle Device handle to be used for subsequent PMIC
+ * Connectivity API calls.
+ * @param mode Initial connectivity operating mode.
+ *
+ * @retval PMIC_SUCCESS If the open request was successful
+ * @retval PMIC_ERROR If the connectivity hardware cannot be opened.
+ */
+PMIC_STATUS pmic_convity_open(PMIC_CONVITY_HANDLE * const handle,
+ const PMIC_CONVITY_MODE mode);
+
+/*!
+ * @brief Terminate further access to the PMIC Connectivity hardware.
+ *
+ * Terminate further access to the PMIC Connectivity hardware. This also
+ * allows another thread to successfully call pmic_convity_open() to gain
+ * access.
+ *
+ * @param handle Device handle from open() call.
+ *
+ * @retval PMIC_SUCCESS If the close request was successful.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ */
+PMIC_STATUS pmic_convity_close(const PMIC_CONVITY_HANDLE handle);
+
+/*!
+ * @brief Set the PMIC Connectivity main operating mode.
+ *
+ * Change the current operating mode of the PMIC Connectivity hardware.
+ * The available connectivity operating modes are hardware-dependent and
+ * consists of one or more of the following: USB (including USB On-the-Go),
+ * RS-232, and CEA-936. Requesting an operating mode that is not supported
+ * by the PMIC hardware will return PMIC_NOT_SUPPORTED.
+ *
+ * @param handle Device handle from open() call.
+ * @param mode Desired operating mode.
+ *
+ * @retval PMIC_SUCCESS If the requested mode was successfully set.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ * @retval PMIC_NOT_SUPPORTED If the PMIC hardware does not support
+ * the desired operating mode.
+ */
+PMIC_STATUS pmic_convity_set_mode(const PMIC_CONVITY_HANDLE handle,
+ const PMIC_CONVITY_MODE mode);
+
+/*!
+ * @brief Get the current PMIC Connectivity main operating mode.
+ *
+ * Get the current operating mode for the PMIC Connectivity hardware.
+ *
+ * @param handle Device handle from open() call.
+ * @param mode The current PMIC Connectivity operating mode.
+ *
+ * @retval PMIC_SUCCESS If the requested mode was successfully set.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ */
+PMIC_STATUS pmic_convity_get_mode(const PMIC_CONVITY_HANDLE handle,
+ PMIC_CONVITY_MODE * const mode);
+
+/*!
+ * @brief Reset the Connectivity hardware to it's power on state.
+ *
+ * Restore all registers to the initial power-on/reset state.
+ *
+ * @param handle Device handle from open() call.
+ *
+ * @retval PMIC_SUCCESS If the reset was successful.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ */
+PMIC_STATUS pmic_convity_reset(const PMIC_CONVITY_HANDLE handle);
+
+/*!
+ * @brief Set the Connectivity callback function.
+ *
+ * Register a callback function that will be used to signal PMIC Connectivity
+ * events. For example, the USB subsystem should register a callback function
+ * in order to be notified of device connect/disconnect events. Note, however,
+ * that non-USB events may also be signalled depending upon the PMIC hardware
+ * capabilities. Therefore, the callback function must be able to properly
+ * handle all of the possible events if support for non-USB peripherals is
+ * also to be included.
+ *
+ * @param handle Device handle from open() call.
+ * @param func A pointer to the callback function.
+ * @param eventMask A mask selecting events to be notified.
+ *
+ * @retval PMIC_SUCCESS If the callback was successfully registered.
+ * @retval PMIC_PARAMETER_ERROR If the handle or the eventMask is invalid.
+ */
+PMIC_STATUS pmic_convity_set_callback(const PMIC_CONVITY_HANDLE handle,
+ const PMIC_CONVITY_CALLBACK func,
+ const PMIC_CONVITY_EVENTS eventMask);
+
+/*!
+ * @brief Deregisters the existing Connectivity callback function.
+ *
+ * Deregister the callback function that was previously registered by calling
+ * pmic_convity_set_callback().
+ *
+ * @param handle Device handle from open() call.
+ *
+ * @retval PMIC_SUCCESS If the callback was successfully deregistered.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ */
+PMIC_STATUS pmic_convity_clear_callback(const PMIC_CONVITY_HANDLE handle);
+
+/*!
+ * @brief Get the current Connectivity callback function settings.
+ *
+ * Get the current callback function and event mask.
+ *
+ * @param handle Device handle from open() call.
+ * @param func The current callback function.
+ * @param eventMask The current event selection mask.
+ *
+ * @retval PMIC_SUCCESS If the callback information was successfully
+ * retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ */
+PMIC_STATUS pmic_convity_get_callback(const PMIC_CONVITY_HANDLE handle,
+ PMIC_CONVITY_CALLBACK * const func,
+ PMIC_CONVITY_EVENTS * const eventMask);
+
+/*@}*/
+
+/***************************************************************************/
+
+/*!
+ * @name USB and USB On-The-Go APIs
+ * USB Connectivity mode-specific configuration and setup functions.
+ */
+/*@{*/
+
+/*!
+ * @brief Set the USB transceiver's operating speed.
+ *
+ * Set the USB transceiver speed.
+ *
+ * @param handle Device handle from open() call.
+ * @param speed The desired USB transceiver speed.
+ *
+ * @retval PMIC_SUCCESS If the transceiver speed was successfully
+ * set.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ * @retval PMIC_NOT_SUPPORTED If the high speed (480 Mbps) mode is
+ * requested.
+ */
+PMIC_STATUS pmic_convity_usb_set_speed(const PMIC_CONVITY_HANDLE handle,
+ const PMIC_CONVITY_USB_SPEED speed);
+
+/*!
+ * This function enables/disables VUSB and VBUS output.
+ * This API configures the VUSBEN and VBUSEN bits of USB register
+ *
+ * @param handle Device handle from open() call.
+ * @param out_type true, for VUSB
+ * false, for VBUS
+ * @param out if true, output is enabled
+ * if false, output is disabled
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+
+PMIC_STATUS pmic_convity_set_output(const PMIC_CONVITY_HANDLE handle,
+ bool out_type, bool out);
+
+/*!
+ * @brief Get the USB transceiver's operating speed.
+ *
+ * Get the USB transceiver speed.
+ *
+ * @param handle Device handle from open() call.
+ * @param speed The current USB transceiver speed.
+ * @param mode The current USB transceiver mode.
+ *
+ * @retval PMIC_SUCCESS If the transceiver speed was successfully
+ * set.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ * obtained
+ */
+PMIC_STATUS pmic_convity_usb_get_speed(const PMIC_CONVITY_HANDLE handle,
+ PMIC_CONVITY_USB_SPEED * const speed,
+ PMIC_CONVITY_USB_MODE * const mode);
+
+/*!
+ * @brief Set the USB transceiver's power supply configuration.
+ *
+ * Set the USB transceiver's power supply configuration.
+ *
+ * @param handle Device handle from open() call.
+ * @param pwrin USB transceiver regulator input power source.
+ * @param pwrout USB transceiver regulator output power level.
+ *
+ * @retval PMIC_SUCCESS If the USB transceiver's power supply
+ * configuration was successfully set.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ * @retval PMIC_NOT_SUPPORTED If the PMIC hardware does not support
+ * the desired configuration.
+ */
+PMIC_STATUS pmic_convity_usb_set_power_source(const PMIC_CONVITY_HANDLE handle,
+ const PMIC_CONVITY_USB_POWER_IN
+ pwrin,
+ const PMIC_CONVITY_USB_POWER_OUT
+ pwrout);
+
+/*!
+ * @brief Get the USB transceiver's power supply configuration.
+ *
+ * Get the USB transceiver's current power supply configuration.
+ *
+ * @param handle Device handle from open() call.
+ * @param pwrin USB transceiver regulator input power source
+ * @param pwrout USB transceiver regulator output power level
+ *
+ * @retval PMIC_SUCCESS If the USB transceiver's power supply
+ * configuration was successfully retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ */
+PMIC_STATUS pmic_convity_usb_get_power_source(const PMIC_CONVITY_HANDLE handle,
+ PMIC_CONVITY_USB_POWER_IN *
+ const pwrin,
+ PMIC_CONVITY_USB_POWER_OUT *
+ const pwrout);
+
+/*!
+ * @brief Set the current USB transceiver operating mode.
+ *
+ * Set the USB transceiver's operating mode.
+ *
+ * @param handle Device handle from open() call.
+ * @param mode Desired operating mode.
+ *
+ * @retval PMIC_SUCCESS If the USB transceiver's operating mode
+ * was successfully configured.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ * @retval PMIC_NOT_SUPPORTED If the desired USB transceiver mode is
+ * not supported by the PMIC hardware.
+ */
+PMIC_STATUS pmic_convity_usb_set_xcvr(const PMIC_CONVITY_HANDLE handle,
+ const PMIC_CONVITY_USB_TRANSCEIVER_MODE
+ mode);
+
+/*!
+ * @brief Get the current USB transceiver operating mode.
+ *
+ * Get the USB transceiver's current operating mode.
+ *
+ * @param handle Device handle from open() call.
+ * @param mode Current operating mode.
+ *
+ * @retval PMIC_SUCCESS If the USB transceiver's operating mode
+ * was successfully retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ */
+PMIC_STATUS pmic_convity_usb_get_xcvr(const PMIC_CONVITY_HANDLE handle,
+ PMIC_CONVITY_USB_TRANSCEIVER_MODE *
+ const mode);
+
+/*!
+ * @brief Set the current USB On-The-Go data line pulse duration (ms).
+ *
+ * Set the Data Line Pulse duration (in milliseconds) for the USB OTG
+ * Session Request Protocol.
+ *
+ * Note that for mc13783 the duration is fixed at 7.5 ms and calling this
+ * function will simply return PMIC_NOT_SUPPORTED.
+ *
+ * @param handle Device handle from open() call.
+ * @param duration The data line pulse duration (ms).
+ *
+ * @retval PMIC_SUCCESS If the pulse duration was successfully set.
+ * @retval PMIC_PARAMETER_ERROR If the handle or the data line pulse
+ * duration is invalid.
+ * @retval PMIC_NOT_SUPPORTED If the desired data line pulse duration
+ * is not supported by the PMIC hardware.
+ */
+PMIC_STATUS pmic_convity_usb_otg_set_dlp_duration(const PMIC_CONVITY_HANDLE
+ handle,
+ const unsigned int duration);
+
+/*!
+ * @brief Get the current USB On-The-Go data line pulse duration (ms).
+ *
+ * Get the current Data Line Pulse duration (in milliseconds) for the USB
+ * OTG Session Request Protocol.
+ *
+ * Note that the Data Line Pulse duration is fixed at 7.5 ms for the mc13783
+ * PMIC. Therefore, calling this function while using the mc13783 PMIC will
+ * simply return PMIC_NOT_SUPPORTED.
+ *
+ * @param handle Device handle from open() call.
+ * @param duration The data line pulse duration (ms).
+ *
+ * @retval PMIC_SUCCESS If the pulse duration was successfully
+ * obtained.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ * @retval PMIC_NOT_SUPPORTED If called using the mc13783 PMIC.
+ */
+PMIC_STATUS pmic_convity_usb_otg_get_dlp_duration(const PMIC_CONVITY_HANDLE
+ handle,
+ unsigned int *const duration);
+
+/*!
+ * @brief Start the USB OTG Host Negotiation Protocol (HNP) process.
+ *
+ * This function must be called during the start of the HNP process to
+ * properly reconfigure the pull-up resistor on the D+ line for both
+ * the USB A and B devices.
+ *
+ * @param handle device handle from open() call
+ * @param deviceType the USB device type (either A or B)
+ *
+ * @return PMIC_SUCCESS if the HNP was successfully started
+ */
+PMIC_STATUS pmic_convity_usb_otg_begin_hnp(const PMIC_CONVITY_HANDLE handle,
+ const PMIC_CONVITY_USB_DEVICE_TYPE
+ deviceType);
+
+/*!
+ * @brief Complete the USB OTG Host Negotiation Protocol (HNP) process.
+ *
+ * This function must be called during the end of the HNP process to
+ * properly reconfigure the pull-up resistor on the D+ line for both
+ * the USB A and B devices.
+ *
+ * @param handle device handle from open() call
+ * @param deviceType the USB device type (either A or B)
+ *
+ * @return PMIC_SUCCESS if the HNP was successfully ended
+ */
+PMIC_STATUS pmic_convity_usb_otg_end_hnp(const PMIC_CONVITY_HANDLE handle,
+ const PMIC_CONVITY_USB_DEVICE_TYPE
+ deviceType);
+
+/*!
+ * @brief Set the current USB On-The-Go configuration.
+ *
+ * Set the USB On-The-Go (OTG) configuration. Multiple configuration settings
+ * may be OR'd together in a single call. However, selecting conflicting
+ * settings (e.g., multiple VBUS current limits) will result in undefined
+ * behavior.
+ *
+ * @param handle Device handle from open() call.
+ * @param cfg Desired USB OTG configuration.
+ *
+ * @retval PMIC_SUCCESS If the OTG configuration was successfully
+ * set.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ * @retval PMIC_NOT_SUPPORTED If the desired USB OTG configuration is
+ * not supported by the PMIC hardware.
+ */
+PMIC_STATUS pmic_convity_usb_otg_set_config(const PMIC_CONVITY_HANDLE handle,
+ const PMIC_CONVITY_USB_OTG_CONFIG
+ cfg);
+
+/*!
+ * @brief Clear the current USB On-The-Go configuration.
+ *
+ * Clears the USB On-The-Go (OTG) configuration. Multiple configuration settings
+ * may be OR'd together in a single call. However, selecting conflicting
+ * settings (e.g., multiple VBUS current limits) will result in undefined
+ * behavior.
+ *
+ * @param handle Device handle from open() call.
+ * @param cfg USB OTG configuration settings to be cleared.
+ *
+ * @retval PMIC_SUCCESS If the OTG configuration was successfully
+ * cleared.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ * @retval PMIC_NOT_SUPPORTED If the desired USB OTG configuration is
+ * not supported by the PMIC hardware.
+ */
+PMIC_STATUS pmic_convity_usb_otg_clear_config(const PMIC_CONVITY_HANDLE handle,
+ const PMIC_CONVITY_USB_OTG_CONFIG
+ cfg);
+
+/*!
+ * @brief Get the current USB On-The-Go configuration.
+ *
+ * Get the current USB On-The-Go (OTG) configuration.
+ *
+ * @param handle Device handle from open() call.
+ * @param cfg The current USB OTG configuration.
+ *
+ * @retval PMIC_SUCCESS If the OTG configuration was successfully
+ * retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ */
+PMIC_STATUS pmic_convity_usb_otg_get_config(const PMIC_CONVITY_HANDLE handle,
+ PMIC_CONVITY_USB_OTG_CONFIG *
+ const cfg);
+
+/*@}*/
+
+/***************************************************************************/
+
+/*!
+ * @name RS-232 APIs
+ * RS-232 Connectivity mode-specific configuration and setup functions.
+ */
+/*@{*/
+
+/*!
+ * @brief Set the current RS-232 operating configuration.
+ *
+ * Set the connectivity interface to the selected RS-232 operating mode.
+ * Note that the RS-232 operating mode will be automatically overridden
+ * if the USB_EN is asserted at any time (e.g., when a USB device is
+ * attached).
+ *
+ * @param handle Device handle from open() call.
+ * @param cfgInternal RS-232 transceiver internal connections.
+ * @param cfgExternal RS-232 transceiver external connections.
+ *
+ * @retval PMIC_SUCCESS If the requested RS-232 mode was set.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ * @retval PMIC_NOT_SUPPORTED If the desired RS-232 configuration is
+ * not supported by the PMIC hardware.
+ */
+PMIC_STATUS pmic_convity_rs232_set_config(const PMIC_CONVITY_HANDLE handle,
+ const PMIC_CONVITY_RS232_INTERNAL
+ cfgInternal,
+ const PMIC_CONVITY_RS232_EXTERNAL
+ cfgExternal);
+
+/*!
+ * @brief Get the current RS-232 operating configuration.
+ *
+ * Get the connectivity interface's current RS-232 operating mode.
+ *
+ * @param handle Device handle from open() call.
+ * @param cfgInternal RS-232 transceiver internal connections.
+ * @param cfgExternal RS-232 transceiver external connections.
+ *
+ * @retval PMIC_SUCCESS If the requested RS-232 mode was retrieved.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ */
+PMIC_STATUS pmic_convity_rs232_get_config(const PMIC_CONVITY_HANDLE handle,
+ PMIC_CONVITY_RS232_INTERNAL *
+ const cfgInternal,
+ PMIC_CONVITY_RS232_EXTERNAL *
+ const cfgExternal);
+
+/***************************************************************************/
+
+/*@}*/
+
+/*!
+ * @name CE-936 APIs
+ * CE-936 Connectivity mode-specific configuration and setup functions.
+ */
+/*@{*/
+
+/*!
+ * @brief Send a signal to exit CEA-936 mode.
+ *
+ * Signal the attached device to exit the current CEA-936 operating mode.
+ * Returns an error if the current operating mode is not CEA-936.
+ *
+ * @param handle Device handle from open() call.
+ * @param signal Type of exit signal to be sent.
+ *
+ * @retval PMIC_SUCCESS If the CEA-936 exit mode signal was sent.
+ * @retval PMIC_PARAMETER_ERROR If the handle is invalid.
+ * @retval PMIC_NOT_SUPPORTED If the desired CEA-936 exit mode signal
+ * is not supported by the PMIC hardware.
+ */
+PMIC_STATUS pmic_convity_cea936_exit_signal(const PMIC_CONVITY_HANDLE handle,
+ const
+ PMIC_CONVITY_CEA936_EXIT_SIGNAL
+ signal);
+
+/*@}*/
+
+#endif /* __ASM_ARCH_MXC_PMIC_CONVITY_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/pmic_external.h b/arch/arm/plat-mxc/include/mach/pmic_external.h
new file mode 100644
index 000000000000..1375b266a15e
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/pmic_external.h
@@ -0,0 +1,1135 @@
+/*
+ * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+#ifndef __ASM_ARCH_MXC_PMIC_EXTERNAL_H__
+#define __ASM_ARCH_MXC_PMIC_EXTERNAL_H__
+
+#ifdef __KERNEL__
+#include <linux/list.h>
+#endif
+
+/*!
+ * @defgroup PMIC_DRVRS PMIC Drivers
+ */
+
+/*!
+ * @defgroup PMIC_CORE PMIC Protocol Drivers
+ * @ingroup PMIC_DRVRS
+ */
+
+/*!
+ * @file arch-mxc/pmic_external.h
+ * @brief This file contains interface of PMIC protocol driver.
+ *
+ * @ingroup PMIC_CORE
+ */
+
+#include <asm/ioctl.h>
+#include <mach/pmic_status.h>
+
+/*!
+ * This is the enumeration of versions of PMIC
+ */
+typedef enum {
+ PMIC_MC13783 = 1, /*!< MC13783 */
+ PMIC_SC55112 = 2, /*!< SC55112 */
+ PMIC_MC13892 = 3,
+ PMIC_MC34704 = 4
+} pmic_id_t;
+
+/*!
+ * @struct pmic_version_t
+ * @brief PMIC version and revision
+ */
+typedef struct {
+ /*!
+ * PMIC version identifier.
+ */
+ pmic_id_t id;
+ /*!
+ * Revision of the PMIC.
+ */
+ int revision;
+} pmic_version_t;
+
+/*!
+ * struct pmic_event_callback_t
+ * @brief This structure contains callback function pointer and its
+ * parameter to be used when un/registering and launching a callback
+ * for an event.
+ */
+typedef struct {
+ /*!
+ * call back function
+ */
+ void (*func) (void *);
+
+ /*!
+ * call back function parameter
+ */
+ void *param;
+} pmic_event_callback_t;
+
+/*!
+ * This structure is used with IOCTL.
+ * It defines register, register value, register mask and event number
+ */
+typedef struct {
+ /*!
+ * register number
+ */
+ int reg;
+ /*!
+ * value of register
+ */
+ unsigned int reg_value;
+ /*!
+ * mask of bits, only used with PMIC_WRITE_REG
+ */
+ unsigned int reg_mask;
+} register_info;
+
+/*!
+ * @name IOCTL definitions for sc55112 core driver
+ */
+/*! @{ */
+/*! Read a PMIC register */
+#define PMIC_READ_REG _IOWR('P', 0xa0, register_info*)
+/*! Write a PMIC register */
+#define PMIC_WRITE_REG _IOWR('P', 0xa1, register_info*)
+/*! Subscribe a PMIC interrupt event */
+#define PMIC_SUBSCRIBE _IOR('P', 0xa2, int)
+/*! Unsubscribe a PMIC interrupt event */
+#define PMIC_UNSUBSCRIBE _IOR('P', 0xa3, int)
+/*! Subscribe a PMIC event for user notification*/
+#define PMIC_NOTIFY_USER _IOR('P', 0xa4, int)
+/*! Get the PMIC event occured for which user recieved notification */
+#define PMIC_GET_NOTIFY _IOW('P', 0xa5, int)
+/*! @} */
+
+/*!
+ * This is PMIC registers valid bits
+ */
+#define PMIC_ALL_BITS 0xFFFFFF
+#define PMIC_MAX_EVENTS 48
+
+#define PMIC_ARBITRATION "NULL"
+
+#ifdef CONFIG_MXC_PMIC_MC13783
+/*!
+ * This is the enumeration of register names of MC13783
+ */
+typedef enum {
+ /*!
+ * REG_INTERRUPT_STATUS_0
+ */
+ REG_INTERRUPT_STATUS_0 = 0,
+ /*!
+ * REG_INTERRUPT_MASK_0
+ */
+ REG_INTERRUPT_MASK_0,
+ /*!
+ * REG_INTERRUPT_SENSE_0
+ */
+ REG_INTERRUPT_SENSE_0,
+ /*!
+ * REG_INTERRUPT_STATUS_1
+ */
+ REG_INTERRUPT_STATUS_1,
+ /*!
+ * REG_INTERRUPT_MASK_1
+ */
+ REG_INTERRUPT_MASK_1,
+ /*!
+ * REG_INTERRUPT_SENSE_1
+ */
+ REG_INTERRUPT_SENSE_1,
+ /*!
+ * REG_POWER_UP_MODE_SENSE
+ */
+ REG_POWER_UP_MODE_SENSE,
+ /*!
+ * REG_REVISION
+ */
+ REG_REVISION,
+ /*!
+ * REG_SEMAPHORE
+ */
+ REG_SEMAPHORE,
+ /*!
+ * REG_ARBITRATION_PERIPHERAL_AUDIO
+ */
+ REG_ARBITRATION_PERIPHERAL_AUDIO,
+ /*!
+ * REG_ARBITRATION_SWITCHERS
+ */
+ REG_ARBITRATION_SWITCHERS,
+ /*!
+ * REG_ARBITRATION_REGULATORS_0
+ */
+ REG_ARBITRATION_REGULATORS_0,
+ /*!
+ * REG_ARBITRATION_REGULATORS_1
+ */
+ REG_ARBITRATION_REGULATORS_1,
+ /*!
+ * REG_POWER_CONTROL_0
+ */
+ REG_POWER_CONTROL_0,
+ /*!
+ * REG_POWER_CONTROL_1
+ */
+ REG_POWER_CONTROL_1,
+ /*!
+ * REG_POWER_CONTROL_2
+ */
+ REG_POWER_CONTROL_2,
+ /*!
+ * REG_REGEN_ASSIGNMENT
+ */
+ REG_REGEN_ASSIGNMENT,
+ /*!
+ * REG_CONTROL_SPARE
+ */
+ REG_CONTROL_SPARE,
+ /*!
+ * REG_MEMORY_A
+ */
+ REG_MEMORY_A,
+ /*!
+ * REG_MEMORY_B
+ */
+ REG_MEMORY_B,
+ /*!
+ * REG_RTC_TIME
+ */
+ REG_RTC_TIME,
+ /*!
+ * REG_RTC_ALARM
+ */
+ REG_RTC_ALARM,
+ /*!
+ * REG_RTC_DAY
+ */
+ REG_RTC_DAY,
+ /*!
+ * REG_RTC_DAY_ALARM
+ */
+ REG_RTC_DAY_ALARM,
+ /*!
+ * REG_SWITCHERS_0
+ */
+ REG_SWITCHERS_0,
+ /*!
+ * REG_SWITCHERS_1
+ */
+ REG_SWITCHERS_1,
+ /*!
+ * REG_SWITCHERS_2
+ */
+ REG_SWITCHERS_2,
+ /*!
+ * REG_SWITCHERS_3
+ */
+ REG_SWITCHERS_3,
+ /*!
+ * REG_SWITCHERS_4
+ */
+ REG_SWITCHERS_4,
+ /*!
+ * REG_SWITCHERS_5
+ */
+ REG_SWITCHERS_5,
+ /*!
+ * REG_REGULATOR_SETTING_0
+ */
+ REG_REGULATOR_SETTING_0,
+ /*!
+ * REG_REGULATOR_SETTING_1
+ */
+ REG_REGULATOR_SETTING_1,
+ /*!
+ * REG_REGULATOR_MODE_0
+ */
+ REG_REGULATOR_MODE_0,
+ /*!
+ * REG_REGULATOR_MODE_1
+ */
+ REG_REGULATOR_MODE_1,
+ /*!
+ * REG_POWER_MISCELLANEOUS
+ */
+ REG_POWER_MISCELLANEOUS,
+ /*!
+ * REG_POWER_SPARE
+ */
+ REG_POWER_SPARE,
+ /*!
+ * REG_AUDIO_RX_0
+ */
+ REG_AUDIO_RX_0,
+ /*!
+ * REG_AUDIO_RX_1
+ */
+ REG_AUDIO_RX_1,
+ /*!
+ * REG_AUDIO_TX
+ */
+ REG_AUDIO_TX,
+ /*!
+ * REG_AUDIO_SSI_NETWORK
+ */
+ REG_AUDIO_SSI_NETWORK,
+ /*!
+ * REG_AUDIO_CODEC
+ */
+ REG_AUDIO_CODEC,
+ /*!
+ * REG_AUDIO_STEREO_DAC
+ */
+ REG_AUDIO_STEREO_DAC,
+ /*!
+ * REG_AUDIO_SPARE
+ */
+ REG_AUDIO_SPARE,
+ /*!
+ * REG_ADC_0
+ */
+ REG_ADC_0,
+ /*!
+ * REG_ADC_1
+ */
+ REG_ADC_1,
+ /*!
+ * REG_ADC_2
+ */
+ REG_ADC_2,
+ /*!
+ * REG_ADC_3
+ */
+ REG_ADC_3,
+ /*!
+ * REG_ADC_4
+ */
+ REG_ADC_4,
+ /*!
+ * REG_CHARGER
+ */
+ REG_CHARGER,
+ /*!
+ * REG_USB
+ */
+ REG_USB,
+ /*!
+ * REG_CHARGE_USB_SPARE
+ */
+ REG_CHARGE_USB_SPARE,
+ /*!
+ * REG_LED_CONTROL_0
+ */
+ REG_LED_CONTROL_0,
+ /*!
+ * REG_LED_CONTROL_1
+ */
+ REG_LED_CONTROL_1,
+ /*!
+ * REG_LED_CONTROL_2
+ */
+ REG_LED_CONTROL_2,
+ /*!
+ * REG_LED_CONTROL_3
+ */
+ REG_LED_CONTROL_3,
+ /*!
+ * REG_LED_CONTROL_4
+ */
+ REG_LED_CONTROL_4,
+ /*!
+ * REG_LED_CONTROL_5
+ */
+ REG_LED_CONTROL_5,
+ /*!
+ * REG_SPARE
+ */
+ REG_SPARE,
+ /*!
+ * REG_TRIM_0
+ */
+ REG_TRIM_0,
+ /*!
+ * REG_TRIM_1
+ */
+ REG_TRIM_1,
+ /*!
+ * REG_TEST_0
+ */
+ REG_TEST_0,
+ /*!
+ * REG_TEST_1
+ */
+ REG_TEST_1,
+ /*!
+ * REG_TEST_2
+ */
+ REG_TEST_2,
+ /*!
+ * REG_TEST_3
+ */
+ REG_TEST_3,
+ /*!
+ * REG_NB
+ */
+ REG_NB,
+} pmic_reg;
+
+/*!
+ * This is event list of mc13783 interrupt
+ */
+
+typedef enum {
+ /*!
+ * ADC has finished requested conversions
+ */
+ EVENT_ADCDONEI = 0,
+ /*!
+ * ADCBIS has finished requested conversions
+ */
+ EVENT_ADCBISDONEI = 1,
+ /*!
+ * Touchscreen wakeup
+ */
+ EVENT_TSI = 2,
+ /*!
+ * ADC reading above high limit
+ */
+ EVENT_WHIGHI = 3,
+ /*!
+ * ADC reading below low limit
+ */
+ EVENT_WLOWI = 4,
+ /*!
+ * Charger attach and removal
+ */
+ EVENT_CHGDETI = 6,
+ /*!
+ * Charger over-voltage detection
+ */
+ EVENT_CHGOVI = 7,
+ /*!
+ * Charger path reverse current
+ */
+ EVENT_CHGREVI = 8,
+ /*!
+ * Charger path short circuit
+ */
+ EVENT_CHGSHORTI = 9,
+ /*!
+ * BP regulator current or voltage regulation
+ */
+ EVENT_CCCVI = 10,
+ /*!
+ * Charge current below threshold
+ */
+ EVENT_CHRGCURRI = 11,
+ /*!
+ * BP turn on threshold detection
+ */
+ EVENT_BPONI = 12,
+ /*!
+ * End of life / low battery detect
+ */
+ EVENT_LOBATLI = 13,
+ /*!
+ * Low battery warning
+ */
+ EVENT_LOBATHI = 14,
+ /*!
+ * USB detect
+ */
+ EVENT_USBI = 16,
+ /*!
+ * USB ID Line detect
+ */
+ EVENT_IDI = 19,
+ /*!
+ * Single ended 1 detect
+ */
+ EVENT_SE1I = 21,
+ /*!
+ * Car-kit detect
+ */
+ EVENT_CKDETI = 22,
+ /*!
+ * 1 Hz time-tick
+ */
+ EVENT_E1HZI = 24,
+ /*!
+ * Time of day alarm
+ */
+ EVENT_TODAI = 25,
+ /*!
+ * ON1B event
+ */
+ EVENT_ONOFD1I = 27,
+ /*!
+ * ON2B event
+ */
+ EVENT_ONOFD2I = 28,
+ /*!
+ * ON3B event
+ */
+ EVENT_ONOFD3I = 29,
+ /*!
+ * System reset
+ */
+ EVENT_SYSRSTI = 30,
+ /*!
+ * RTC reset occurred
+ */
+ EVENT_RTCRSTI = 31,
+ /*!
+ * Power cut event
+ */
+ EVENT_PCI = 32,
+ /*!
+ * Warm start event
+ */
+ EVENT_WARMI = 33,
+ /*!
+ * Memory hold event
+ */
+ EVENT_MEMHLDI = 34,
+ /*!
+ * Power ready
+ */
+ EVENT_PWRRDYI = 35,
+ /*!
+ * Thermal warning lower threshold
+ */
+ EVENT_THWARNLI = 36,
+ /*!
+ * Thermal warning higher threshold
+ */
+ EVENT_THWARNHI = 37,
+ /*!
+ * Clock source change
+ */
+ EVENT_CLKI = 38,
+ /*!
+ * Semaphore
+ */
+ EVENT_SEMAFI = 39,
+ /*!
+ * Microphone bias 2 detect
+ */
+ EVENT_MC2BI = 41,
+ /*!
+ * Headset attach
+ */
+ EVENT_HSDETI = 42,
+ /*!
+ * Stereo headset detect
+ */
+ EVENT_HSLI = 43,
+ /*!
+ * Thermal shutdown ALSP
+ */
+ EVENT_ALSPTHI = 44,
+ /*!
+ * Short circuit on AHS outputs
+ */
+ EVENT_AHSSHORTI = 45,
+ /*!
+ * number of event
+ */
+ EVENT_NB,
+} type_event;
+
+/*!
+ * This enumeration all senses of MC13783.
+ */
+typedef enum {
+ /*!
+ * Charger attach sense
+ */
+ SENSE_CHGDETS = 6,
+ /*!
+ * Charger over-voltage sense
+ */
+ SENSE_CHGOVS,
+ /*!
+ * Charger reverse current
+ * If 1 current flows into phone
+ */
+ SENSE_CHGREVS,
+ /*!
+ * Charger short circuit
+ */
+ SENSE_CHGSHORTS,
+ /*!
+ * Charger regulator operating mode
+ */
+ SENSE_CCCVS,
+ /*!
+ * Charger current below threshold
+ */
+ SENSE_CHGCURRS,
+ /*!
+ * BP turn on
+ */
+ SENSE_BPONS,
+ /*!
+ * Low bat detect
+ */
+ SENSE_LOBATLS,
+ /*!
+ * Low bat warning
+ */
+ SENSE_LOBATHS,
+ /*!
+ * UDPS
+ */
+ SENSE_UDPS,
+ /*!
+ * USB 4V4
+ */
+ SENSE_USB4V4S,
+ /*!
+ * USB 2V0
+ */
+ SENSE_USB2V0S,
+ /*!
+ * USB 0V8
+ */
+ SENSE_USB0V8S,
+ /*!
+ * ID Floats
+ */
+ SENSE_ID_FLOATS,
+ /*!
+ * ID Gnds
+ */
+ SENSE_ID_GNDS,
+ /*!
+ * Single ended
+ */
+ SENSE_SE1S,
+ /*!
+ * Car-kit detect
+ */
+ SENSE_CKDETS,
+ /*!
+ * UDMS
+ */
+ SENSE_UDMS,
+ /*!
+ * mic bias detect
+ */
+ SENSE_MC2BS,
+ /*!
+ * headset attached
+ */
+ SENSE_HSDETS,
+ /*!
+ * ST headset attached
+ */
+ SENSE_HSLS,
+ /*!
+ * Thermal shutdown ALSP
+ */
+ SENSE_ALSPTHS,
+ /*!
+ * short circuit on AHS
+ */
+ SENSE_AHSSHORTS,
+ /*!
+ * ON1B pin is hight
+ */
+ SENSE_ONOFD1S,
+ /*!
+ * ON2B pin is hight
+ */
+ SENSE_ONOFD2S,
+ /*!
+ * ON3B pin is hight
+ */
+ SENSE_ONOFD3S,
+ /*!
+ * System reset power ready
+ */
+ SENSE_PWRRDYS,
+ /*!
+ * Thermal warning higher threshold
+ */
+ SENSE_THWARNHS,
+ /*!
+ * Thermal warning lower threshold
+ */
+ SENSE_THWARNLS,
+ /*!
+ * Clock source is XTAL
+ */
+ SENSE_CLKS,
+} t_sensor;
+
+/*!
+ * This structure is used to read all sense bits of MC13783.
+ */
+typedef struct {
+ /*!
+ * Charger attach sense
+ */
+ bool sense_chgdets;
+ /*!
+ * Charger over-voltage sense
+ */
+ bool sense_chgovs;
+ /*!
+ * Charger reverse current
+ * If 1 current flows into phone
+ */
+ bool sense_chgrevs;
+ /*!
+ * Charger short circuit
+ */
+ bool sense_chgshorts;
+ /*!
+ * Charger regulator operating mode
+ */
+ bool sense_cccvs;
+ /*!
+ * Charger current below threshold
+ */
+ bool sense_chgcurrs;
+ /*!
+ * BP turn on
+ */
+ bool sense_bpons;
+ /*!
+ * Low bat detect
+ */
+ bool sense_lobatls;
+ /*!
+ * Low bat warning
+ */
+ bool sense_lobaths;
+ /*!
+ * USB 4V4
+ */
+ bool sense_usb4v4s;
+ /*!
+ * USB 2V0
+ */
+ bool sense_usb2v0s;
+ /*!
+ * USB 0V8
+ */
+ bool sense_usb0v8s;
+ /*!
+ * ID Floats
+ */
+ bool sense_id_floats;
+ /*!
+ * ID Gnds
+ */
+ bool sense_id_gnds;
+ /*!
+ * Single ended
+ */
+ bool sense_se1s;
+ /*!
+ * Car-kit detect
+ */
+ bool sense_ckdets;
+ /*!
+ * mic bias detect
+ */
+ bool sense_mc2bs;
+ /*!
+ * headset attached
+ */
+ bool sense_hsdets;
+ /*!
+ * ST headset attached
+ */
+ bool sense_hsls;
+ /*!
+ * Thermal shutdown ALSP
+ */
+ bool sense_alspths;
+ /*!
+ * short circuit on AHS
+ */
+ bool sense_ahsshorts;
+ /*!
+ * ON1B pin is hight
+ */
+ bool sense_onofd1s;
+ /*!
+ * ON2B pin is hight
+ */
+ bool sense_onofd2s;
+ /*!
+ * ON3B pin is hight
+ */
+ bool sense_onofd3s;
+ /*!
+ * System reset power ready
+ */
+ bool sense_pwrrdys;
+ /*!
+ * Thermal warning higher threshold
+ */
+ bool sense_thwarnhs;
+ /*!
+ * Thermal warning lower threshold
+ */
+ bool sense_thwarnls;
+ /*!
+ * Clock source is XTAL
+ */
+ bool sense_clks;
+} t_sensor_bits;
+
+#endif /*CONFIG_MXC_PMIC_MC13783 */
+
+#if defined(CONFIG_MXC_PMIC_MC13892_MODULE) || defined(CONFIG_MXC_PMIC_MC13892)
+enum {
+ REG_INT_STATUS0 = 0,
+ REG_INT_MASK0,
+ REG_INT_SENSE0,
+ REG_INT_STATUS1,
+ REG_INT_MASK1,
+ REG_INT_SENSE1,
+ REG_PU_MODE_S,
+ REG_IDENTIFICATION,
+ REG_UNUSED0,
+ REG_ACC0,
+ REG_ACC1, /*10 */
+ REG_UNUSED1,
+ REG_UNUSED2,
+ REG_POWER_CTL0,
+ REG_POWER_CTL1,
+ REG_POWER_CTL2,
+ REG_REGEN_ASSIGN,
+ REG_UNUSED3,
+ REG_MEM_A,
+ REG_MEM_B,
+ REG_RTC_TIME, /*20 */
+ REG_RTC_ALARM,
+ REG_RTC_DAY,
+ REG_RTC_DAY_ALARM,
+ REG_SW_0,
+ REG_SW_1,
+ REG_SW_2,
+ REG_SW_3,
+ REG_SW_4,
+ REG_SW_5,
+ REG_SETTING_0, /*30 */
+ REG_SETTING_1,
+ REG_MODE_0,
+ REG_MODE_1,
+ REG_POWER_MISC,
+ REG_UNUSED4,
+ REG_UNUSED5,
+ REG_UNUSED6,
+ REG_UNUSED7,
+ REG_UNUSED8,
+ REG_UNUSED9, /*40 */
+ REG_UNUSED10,
+ REG_UNUSED11,
+ REG_ADC0,
+ REG_ADC1,
+ REG_ADC2,
+ REG_ADC3,
+ REG_ADC4,
+ REG_CHARGE,
+ REG_USB0,
+ REG_USB1, /*50 */
+ REG_LED_CTL0,
+ REG_LED_CTL1,
+ REG_LED_CTL2,
+ REG_LED_CTL3,
+ REG_UNUSED12,
+ REG_UNUSED13,
+ REG_TRIM0,
+ REG_TRIM1,
+ REG_TEST0,
+ REG_TEST1, /*60 */
+ REG_TEST2,
+ REG_TEST3,
+ REG_TEST4,
+};
+
+typedef enum {
+ EVENT_ADCDONEI = 0,
+ EVENT_ADCBISDONEI = 1,
+ EVENT_TSI = 2,
+ EVENT_VBUSVI = 3,
+ EVENT_IDFACI = 4,
+ EVENT_USBOVI = 5,
+ EVENT_CHGDETI = 6,
+ EVENT_CHGFAULTI = 7,
+ EVENT_CHGREVI = 8,
+ EVENT_CHGRSHORTI = 9,
+ EVENT_CCCVI = 10,
+ EVENT_CHGCURRI = 11,
+ EVENT_BPONI = 12,
+ EVENT_LOBATLI = 13,
+ EVENT_LOBATHI = 14,
+ EVENT_IDFLOATI = 19,
+ EVENT_IDGNDI = 20,
+ EVENT_SE1I = 21,
+ EVENT_CKDETI = 22,
+ EVENT_1HZI = 24,
+ EVENT_TODAI = 25,
+ EVENT_PWRONI = 27,
+ EVENT_WDIRESETI = 29,
+ EVENT_SYSRSTI = 30,
+ EVENT_RTCRSTI = 31,
+ EVENT_PCI = 32,
+ EVENT_WARMI = 33,
+ EVENT_MEMHLDI = 34,
+ EVENT_THWARNLI = 36,
+ EVENT_THWARNHI = 37,
+ EVENT_CLKI = 38,
+ EVENT_SCPI = 40,
+ EVENT_LBPI = 44,
+ EVENT_NB,
+} type_event;
+
+typedef enum {
+ SENSE_VBUSVS = 3,
+ SENSE_IDFACS = 4,
+ SENSE_USBOVS = 5,
+ SENSE_CHGDETS = 6,
+ SENSE_CHGREVS = 8,
+ SENSE_CHGRSHORTS = 9,
+ SENSE_CCCVS = 10,
+ SENSE_CHGCURRS = 11,
+ SENSE_BPONS = 12,
+ SENSE_LOBATLS = 13,
+ SENSE_LOBATHS = 14,
+ SENSE_IDFLOATS = 19,
+ SENSE_IDGNDS = 20,
+ SENSE_SE1S = 21,
+ SENSE_PWRONS = 27,
+ SENSE_THWARNLS = 36,
+ SENSE_THWARNHS = 37,
+ SENSE_CLKS = 38,
+ SENSE_LBPS = 44,
+ SENSE_NB,
+} t_sensor;
+
+typedef struct {
+ bool sense_vbusvs;
+ bool sense_idfacs;
+ bool sense_usbovs;
+ bool sense_chgdets;
+ bool sense_chgrevs;
+ bool sense_chgrshorts;
+ bool sense_cccvs;
+ bool sense_chgcurrs;
+ bool sense_bpons;
+ bool sense_lobatls;
+ bool sense_lobaths;
+ bool sense_idfloats;
+ bool sense_idgnds;
+ bool sense_se1s;
+ bool sense_pwrons;
+ bool sense_thwarnls;
+ bool sense_thwarnhs;
+ bool sense_clks;
+ bool sense_lbps;
+} t_sensor_bits;
+
+extern struct i2c_client *mc13892_client;
+int pmic_i2c_24bit_read(struct i2c_client *client, unsigned int reg_num,
+ unsigned int *value);
+int pmic_read(int reg_num, unsigned int *reg_val);
+int pmic_write(int reg_num, const unsigned int reg_val);
+void gpio_pmic_active(void);
+void pmic_event_list_init(void);
+void mc13892_power_off(void);
+
+#endif
+
+#if defined(CONFIG_MXC_PMIC_MC34704_MODULE) || defined(CONFIG_MXC_PMIC_MC34704)
+
+typedef enum {
+ /* register names for mc34704 */
+ REG_MC34704_GENERAL1 = 0x01,
+ REG_MC34704_GENERAL2 = 0x02,
+ REG_MC34704_GENERAL3 = 0x03,
+ REG_MC34704_VGSET1 = 0x04,
+ REG_MC34704_VGSET2 = 0x05,
+ REG_MC34704_REG2SET1 = 0x06,
+ REG_MC34704_REG2SET2 = 0x07,
+ REG_MC34704_REG3SET1 = 0x08,
+ REG_MC34704_REG3SET2 = 0x09,
+ REG_MC34704_REG4SET1 = 0x0A,
+ REG_MC34704_REG4SET2 = 0x0B,
+ REG_MC34704_REG5SET1 = 0x0C,
+ REG_MC34704_REG5SET2 = 0x0D,
+ REG_MC34704_REG5SET3 = 0x0E,
+ REG_MC34704_REG6SET1 = 0x0F,
+ REG_MC34704_REG6SET2 = 0x10,
+ REG_MC34704_REG6SET3 = 0x11,
+ REG_MC34704_REG7SET1 = 0x12,
+ REG_MC34704_REG7SET2 = 0x13,
+ REG_MC34704_REG7SET3 = 0x14,
+ REG_MC34704_REG8SET1 = 0x15,
+ REG_MC34704_REG8SET2 = 0x16,
+ REG_MC34704_REG8SET3 = 0x17,
+ REG_MC34704_FAULTS = 0x18,
+ REG_MC34704_I2CSET1 = 0x19,
+ REG_MC34704_REG3DAC = 0x49,
+ REG_MC34704_REG7CR0 = 0x58,
+ REG_MC34704_REG7DAC = 0x59,
+ REG_NB = 0x60,
+} pmic_reg;
+
+typedef enum {
+ /* events for mc34704 */
+ EVENT_FLT1 = 0,
+ EVENT_FLT2,
+ EVENT_FLT3,
+ EVENT_FLT4,
+ EVENT_FLT5,
+ EVENT_FLT6,
+ EVENT_FLT7,
+ EVENT_FLT8,
+ EVENT_NB,
+} type_event;
+
+typedef enum {
+ MCU_SENSOR_NOT_SUPPORT
+} t_sensor;
+
+typedef enum {
+ MCU_SENSOR_BIT_NOT_SUPPORT
+} t_sensor_bits;
+
+#endif /* MXC_PMIC_MC34704 */
+
+/* EXPORTED FUNCTIONS */
+#ifdef __KERNEL__
+
+#if defined(CONFIG_MXC_PMIC)
+/*!
+ * This function is used to determine the PMIC type and its revision.
+ *
+ * @return Returns the PMIC type and its revision.
+ */
+pmic_version_t pmic_get_version(void);
+
+/*!
+ * This function is called by PMIC clients to read a register on PMIC.
+ *
+ * @param priority priority of access
+ * @param reg number of register
+ * @param reg_value return value of register
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_read_reg(int reg, unsigned int *reg_value,
+ unsigned int reg_mask);
+/*!
+ * This function is called by PMIC clients to write a register on MC13783.
+ *
+ * @param priority priority of access
+ * @param reg number of register
+ * @param reg_value New value of register
+ * @param reg_mask Bitmap mask indicating which bits to modify
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_write_reg(int reg, unsigned int reg_value,
+ unsigned int reg_mask);
+
+/*!
+ * This function is called by PMIC clients to subscribe on an event.
+ *
+ * @param event_sub structure of event, it contains type of event and callback
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_event_subscribe(type_event event,
+ pmic_event_callback_t callback);
+/*!
+* This function is called by PMIC clients to un-subscribe on an event.
+*
+* @param event_unsub structure of event, it contains type of event and callback
+*
+* @return This function returns PMIC_SUCCESS if successful.
+*/
+PMIC_STATUS pmic_event_unsubscribe(type_event event,
+ pmic_event_callback_t callback);
+/*!
+* This function is called to read all sensor bits of PMIC.
+*
+* @param sensor Sensor to be checked.
+*
+* @return This function returns true if the sensor bit is high;
+* or returns false if the sensor bit is low.
+*/
+bool pmic_check_sensor(t_sensor sensor);
+
+/*!
+* This function checks one sensor of PMIC.
+*
+* @param sensor_bits structure of all sensor bits.
+*
+* @return This function returns PMIC_SUCCESS if successful.
+*/
+PMIC_STATUS pmic_get_sensors(t_sensor_bits * sensor_bits);
+
+void pmic_event_callback(type_event event);
+void pmic_event_list_init(void);
+
+#ifdef CONFIG_REGULATOR_MC13783
+/*!
+ * This function is used to initialize the regulator for MC13783.
+ *
+ * @return Returns 0.
+ */
+int reg_mc13783_probe(void);
+#else
+static inline int reg_mc13783_probe(void)
+{
+ return 0;
+};
+#endif
+
+#ifdef CONFIG_REGULATOR_MC13892
+int reg_mc13892_probe(void);
+#else
+static inline int reg_mc13892_probe(void)
+{
+ return 0;
+};
+#endif
+
+#ifdef CONFIG_REGULATOR_MC34704
+int reg_mc34704_probe(void);
+#else
+static inline int reg_mc34704_probe(void)
+{
+ return 0;
+};
+#endif
+
+#endif /*CONFIG_MXC_PMIC*/
+#endif /* __KERNEL__ */
+/* CONFIG_MXC_PMIC_MC13783 || CONFIG_MXC_PMIC_MC9SDZ60 */
+
+#endif /* __ASM_ARCH_MXC_PMIC_EXTERNAL_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/pmic_light.h b/arch/arm/plat-mxc/include/mach/pmic_light.h
new file mode 100644
index 000000000000..73b9fec7b6c1
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/pmic_light.h
@@ -0,0 +1,1082 @@
+/*
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+#ifndef __ASM_ARCH_MXC_PMIC_LIGHT_H__
+#define __ASM_ARCH_MXC_PMIC_LIGHT_H__
+
+/*!
+ * @defgroup PMIC_LIGHT PMIC Light Driver
+ * @ingroup PMIC_DRVRS
+ */
+
+/*!
+ * @file arch-mxc/pmic_light.h
+ * @brief This is the header of PMIC Light driver.
+ *
+ * @ingroup PMIC_LIGHT
+ */
+
+#include <asm/ioctl.h>
+#include <mach/pmic_status.h>
+#include <mach/pmic_external.h>
+
+/*!
+ * @name IOCTL user space interface
+ */
+
+/*! @{ */
+/*!
+ * Enable Backlight.
+ * Argument type: none.
+ */
+#define PMIC_BKLIT_ENABLE _IO('p', 0xe0)
+/*!
+ * Disable Backlight.
+ * Argument type: none.
+ */
+#define PMIC_BKLIT_DISABLE _IO('p', 0xe1)
+/*!
+ * Set backlight configuration.
+ * Argument type: pointer to t_bklit_setting_param
+ */
+#define PMIC_SET_BKLIT _IOW('p', 0xe2, int)
+/*!
+ * Get backlight configuration.
+ * Argument type: pointer to t_bklit_setting_param
+ */
+#define PMIC_GET_BKLIT _IOWR('p', 0xe3, int)
+/*!
+ * Ramp up configuration.
+ * Argument type: t_bklit_channel
+ */
+#define PMIC_RAMPUP_BKLIT _IOW('p', 0xe4, int)
+/*!
+ * Ramp down configuration.
+ * Argument type: t_bklit_channel
+ */
+#define PMIC_RAMPDOWN_BKLIT _IOW('p', 0xe5, int)
+/*!
+ * Enable Tri-color LED.
+ * Argument type: t_tcled_enable_param
+ */
+#define PMIC_TCLED_ENABLE _IOW('p', 0xe6, int)
+/*!
+ * Disable Tri-color LED.
+ * Argument type: t_funlight_bank
+ */
+#define PMIC_TCLED_DISABLE _IOW('p', 0xe7, int)
+/*!
+ * Start Tri-color LED pattern.
+ * Argument type: t_fun_param
+ */
+#define PMIC_TCLED_PATTERN _IOW('p', 0xe8, int)
+/*!
+ * Enable Backlight & tcled.
+ * Argument type: none.
+ */
+#define PMIC_BKLIT_TCLED_ENABLE _IO('p', 0xe9)
+/*!
+ * Disable Backlight & tcled.
+ * Argument type: none.
+ */
+#define PMIC_BKLIT_TCLED_DISABLE _IO('p', 0xea)
+/*!
+ * Reset ramp up configuration.
+ * Argument type: t_bklit_channel
+ */
+#define PMIC_OFF_RAMPUP_BKLIT _IOW('p', 0xeb, int)
+/*!
+ * Reset ramp down configuration.
+ * Argument type: t_bklit_channel
+ */
+#define PMIC_OFF_RAMPDOWN_BKLIT _IOW('p', 0xec, int)
+/*!
+ * Set tcled ind configuration.
+ * Argument type: t_tcled_ind_param
+ */
+#define PMIC_SET_TCLED _IOW('p', 0xed, int)
+/*!
+ * Get tcled ind configuration.
+ * Argument type: t_tcled_ind_param
+ */
+#define PMIC_GET_TCLED _IOWR('p', 0xee, int)
+/*! @} */
+/*!
+ * @enum t_bklit_mode
+ * @brief Backlight modes.
+ */
+typedef enum {
+ BACKLIGHT_CURRENT_CTRL_MODE, /*! < Current control mode */
+ BACKLIGHT_TRIODE_MODE /*! < Triode mode */
+} t_bklit_mode;
+
+/*!
+ * @enum t_bklit_channel
+ * @brief Backlight channels.
+ */
+typedef enum {
+ BACKLIGHT_LED1, /*! < Backlight channel 1 */
+ BACKLIGHT_LED2, /*! < Backlight channel 2 */
+ BACKLIGHT_LED3 /*! < Backlight channel 3 */
+} t_bklit_channel;
+
+/*!
+ * @enum t_bklit_strobe_mode
+ * @brief Backlight Strobe Light Pulsing modes.
+ */
+typedef enum {
+ /*!
+ * No Strobe Light Pulsing
+ */
+ BACKLIGHT_STROBE_NONE,
+ /*!
+ * Strobe Light Pulsing at 3.3% duty cycle over 300msec (Driver goes
+ * into Triode Mode with pulses constrained to 10msec.)
+ */
+ BACKLIGHT_STROBE_FAST,
+ /*!
+ * Strobe Light Pulsing at 10% duty cycle over 100msec (Driver goes
+ * into Triode Mode with pulses constrained to 10msec.)
+ */
+ BACKLIGHT_STROBE_SLOW
+} t_bklit_strobe_mode;
+
+/*!
+ * @struct t_bklit_setting_param
+ * @brief Backlight setting.
+ */
+
+typedef struct {
+ t_bklit_channel channel; /*!< Channel */
+ t_bklit_mode mode; /*!< Mode */
+ t_bklit_strobe_mode strobe; /*!< Strobe mode */
+ unsigned char current_level; /*!< Current level */
+ unsigned char duty_cycle; /*!< Duty cycle */
+ unsigned char cycle_time; /*!< Cycle time */
+ bool edge_slow; /*!< Edge Slow */
+ bool en_dis; /*!< Enable disable boost mode */
+ unsigned int abms; /*!< Adaptive boost
+ * mode selection */
+ unsigned int abr; /*!< Adaptive
+ * boost reference */
+} t_bklit_setting_param;
+
+/*!
+ * @enum t_funlight_bank
+ * @brief Tri-color LED fun light banks.
+ */
+typedef enum {
+ TCLED_FUN_BANK1 = 0, /*! < Fun light bank 1 */
+ TCLED_FUN_BANK2, /*! < Fun light bank 2 */
+ TCLED_FUN_BANK3 /*! < Fun light bank 3 */
+} t_funlight_bank;
+
+/*!
+ * @enum t_tcled_mode
+ * @brief Tri-color LED operation modes.
+ *
+ * The Tri-Color LED Driver circuitry includes 2 modes of operation. In LED
+ * Indicator Mode, this circuitry operates as Red and Green LED Drivers with
+ * flasher timing to indicate GSM network status. In Fun Light Mode, this
+ * circuitry provides expanded capability for current control and distribution
+ * that supplements the three channels.
+ */
+typedef enum {
+ TCLED_IND_MODE = 0, /*! < LED Indicator Mode */
+ TCLED_FUN_MODE /*! < Fun Light Mode */
+} t_tcled_mode;
+
+/*!
+ * @struct t_tcled_enable_param
+ * @brief enable setting.
+ */
+typedef struct {
+ t_funlight_bank bank; /*!< Bank */
+ t_tcled_mode mode; /*!< Mode */
+} t_tcled_enable_param;
+
+/*!
+ * @enum t_ind_channel
+ * @brief Tri-color LED indicator mode channels.
+ *
+ */
+
+typedef enum {
+ TCLED_IND_RED = 0, /*! < Red LED */
+ TCLED_IND_GREEN, /*! < Green LED */
+ TCLED_IND_BLUE /*! < Blue LED */
+} t_ind_channel;
+
+/*!
+ * @enum t_funlight_channel
+ * @brief Tri-color LED fun light mode channels.
+ *
+ */
+typedef enum {
+ TCLED_FUN_CHANNEL1 = 0, /*! < Fun light channel 1 (Red) */
+ TCLED_FUN_CHANNEL2, /*! < Fun light channel 2 (Green) */
+ TCLED_FUN_CHANNEL3 /*! < Fun light channel 3 (Blue) */
+} t_funlight_channel;
+
+/*!
+ * @enum t_tcled_ind_blink_pattern
+ * @brief Tri-color LED Indicator Mode blinking mode.
+ */
+typedef enum {
+ TCLED_IND_OFF = 0, /*! < Continuous off */
+ TCLED_IND_BLINK_1, /*! < 1 / 31 */
+ TCLED_IND_BLINK_2, /*! < 2 / 31 */
+ TCLED_IND_BLINK_3, /*! < 3 / 31 */
+ TCLED_IND_BLINK_4, /*! < 4 / 31 */
+ TCLED_IND_BLINK_5, /*! < 5 / 31 */
+ TCLED_IND_BLINK_6, /*! < 6 / 31 */
+ TCLED_IND_BLINK_7, /*! < 7 / 31 */
+ TCLED_IND_BLINK_8, /*! < 8 / 31 */
+ TCLED_IND_BLINK_9, /*! < 9 / 31 */
+ TCLED_IND_BLINK_10, /*! < 10 / 31 */
+ TCLED_IND_BLINK_11, /*! < 11 / 31 */
+ TCLED_IND_BLINK_12, /*! < 12 / 31 */
+ TCLED_IND_BLINK_13, /*! < 13 / 31 */
+ TCLED_IND_BLINK_14, /*! < 14 / 31 */
+ TCLED_IND_BLINK_15, /*! < 15 / 31 */
+ TCLED_IND_BLINK_16, /*! < 16 / 31 */
+ TCLED_IND_BLINK_17, /*! < 17 / 31 */
+ TCLED_IND_BLINK_18, /*! < 18 / 31 */
+ TCLED_IND_BLINK_19, /*! < 19 / 31 */
+ TCLED_IND_BLINK_20, /*! < 20 / 31 */
+ TCLED_IND_BLINK_21, /*! < 21 / 31 */
+ TCLED_IND_BLINK_22, /*! < 22 / 31 */
+ TCLED_IND_BLINK_23, /*! < 23 / 31 */
+ TCLED_IND_BLINK_24, /*! < 24 / 31 */
+ TCLED_IND_BLINK_25, /*! < 25 / 31 */
+ TCLED_IND_BLINK_26, /*! < 26 / 31 */
+ TCLED_IND_BLINK_27, /*! < 27 / 31 */
+ TCLED_IND_BLINK_28, /*! < 28 / 31 */
+ TCLED_IND_BLINK_29, /*! < 29 / 31 */
+ TCLED_IND_BLINK_30, /*! < 30 / 31 */
+ TCLED_IND_ON /*! < Continuous on */
+} t_tcled_ind_blink_pattern;
+
+/*!
+ * @enum t_tcled_cur_level
+ * @brief Tri-color LED current levels.
+ */
+typedef enum {
+ TCLED_CUR_LEVEL_1 = 0, /*! < Tri-Color LED current level 1 */
+ TCLED_CUR_LEVEL_2, /*! < Tri-Color LED current level 2 */
+ TCLED_CUR_LEVEL_3, /*! < Tri-Color LED current level 3 */
+ TCLED_CUR_LEVEL_4 /*! < Tri-Color LED current level 4 */
+} t_tcled_cur_level;
+
+/*!
+ * @enum t_tcled_fun_cycle_time
+ * @brief Tri-color LED fun light mode cycle time.
+ */
+typedef enum {
+ TC_CYCLE_TIME_1 = 0, /*! < Tri-Color LED cycle time 1 */
+ TC_CYCLE_TIME_2, /*! < Tri-Color LED cycle time 2 */
+ TC_CYCLE_TIME_3, /*! < Tri-Color LED cycle time 3 */
+ TC_CYCLE_TIME_4 /*! < Tri-Color LED cycle time 4 */
+} t_tcled_fun_cycle_time;
+
+/*!
+ * @enum t_tcled_fun_speed
+ * @brief Tri-color LED fun light mode pattern speed.
+ */
+typedef enum {
+ TC_OFF = 0, /*! < Tri-Color pattern off */
+ TC_SLOW, /*! < Tri-Color slow pattern */
+ TC_FAST /*! < Tri-Color fast pattern */
+} t_tcled_fun_speed;
+
+/*!
+ * @enum t_tcled_fun_speed
+ * @brief Tri-color LED fun light mode pattern speed.
+ */
+typedef enum {
+ TC_STROBE_OFF = 0, /*! < No strobe */
+ TC_STROBE_SLOW, /*! < Slow strobe pattern */
+ TC_STROBE_FAST /*! < fast strobe pattern */
+} t_tcled_fun_strobe_speed;
+
+/*!
+ * @enum t_chaselight_pattern
+ * @brief Tri-color LED fun light mode chasing light patterns.
+ */
+typedef enum {
+ PMIC_RGB = 0, /*!< R -> G -> B */
+ BGR /*!< B -> G -> R */
+} t_chaselight_pattern;
+
+/*!
+ * This enumeration of Fun Light Pattern.
+ */
+typedef enum {
+ /*!
+ * Blended ramps slow
+ */
+ BLENDED_RAMPS_SLOW,
+ /*!
+ * Blended ramps fast
+ */
+ BLENDED_RAMPS_FAST,
+ /*!
+ * Saw ramps slow
+ */
+ SAW_RAMPS_SLOW,
+ /*!
+ * Saw ramps fast
+ */
+ SAW_RAMPS_FAST,
+ /*!
+ * Blended bowtie slow
+ */
+ BLENDED_BOWTIE_SLOW,
+ /*!
+ * Blended bowtie fast
+ */
+ BLENDED_BOWTIE_FAST,
+ /*!
+ * Strobe slow
+ */
+ STROBE_SLOW,
+ /*!
+ * Strobe fast
+ */
+ STROBE_FAST,
+ /*!
+ * Chasing Light RGB Slow
+ */
+ CHASING_LIGHT_RGB_SLOW,
+ /*!
+ * Chasing Light RGB fast
+ */
+ CHASING_LIGHT_RGB_FAST,
+ /*!
+ * Chasing Light BGR Slow
+ */
+ CHASING_LIGHT_BGR_SLOW,
+ /*!
+ * Chasing Light BGR fast
+ */
+ CHASING_LIGHT_BGR_FAST,
+} t_fun_pattern;
+
+/*!
+ * @struct t_fun_param
+ * @brief LED fun pattern IOCTL parameter
+ */
+typedef struct {
+ t_funlight_bank bank; /*!< TCLED bank */
+ t_funlight_channel channel; /*!< TCLED channel */
+ t_fun_pattern pattern; /*!< Fun pattern */
+} t_fun_param;
+
+/*!
+ * @enum t_led_channel
+ * @brief LED channels including backlight and tri-color LEDs.
+ */
+typedef enum {
+ AUDIO_LED1, /*! < Backlight channel 1 */
+ AUDIO_LED2, /*! < Backlight channel 2 */
+ AUDIO_LEDR, /*! < Fun light channel 1 (Red) */
+ AUDIO_LEDG, /*! < Fun light channel 2 (Green) */
+ AUDIO_LEDB /*! < Fun light channel 3 (Blue) */
+} t_led_channel;
+
+/*!
+ * @enum t_aud_path
+ * @brief LED audio modulation in-out audio channels
+ */
+typedef enum {
+ MIXED_RX = 0, /*!< Mixed L & R Channel RX audio */
+ TX /*!< TX path */
+} t_aud_path;
+
+/*!
+ * @enum t_aud_gain
+ * @brief LED audio modulation in-out audio channels
+ */
+typedef enum {
+ GAIN_MINUS6DB = 0, /*!< -6 dB */
+ GAIN_0DB, /*!< 0 dB */
+ GAIN_6DB, /*!< 6 dB */
+ GAIN_12DB /*!< 12 dB */
+} t_aud_gain;
+
+/*!
+ * @struct t_tcled_ind_param
+ * @brief LED parameter
+ */
+typedef struct {
+ t_funlight_bank bank; /*! < tcled bank */
+ t_ind_channel channel; /*! < tcled channel */
+ t_tcled_cur_level level; /*! < tcled current level */
+ t_tcled_ind_blink_pattern pattern; /*! < tcled dutty cycle */
+ bool skip; /*! < tcled skip */
+ bool rampup; /*! < tcled rampup */
+ bool rampdown; /*! < tcled rampdown */
+ bool half_current; /*! < tcled half current */
+} t_tcled_ind_param;
+
+#if defined(CONFIG_MXC_PMIC_MC13892)
+
+enum curr_level {
+ LIT_CURR_0 = 0,
+ LIT_CURR_3,
+ LIT_CURR_6,
+ LIT_CURR_9,
+ LIT_CURR_12,
+ LIT_CURR_15,
+ LIT_CURR_18,
+ LIT_CURR_21,
+ /* below setting only used for main/aux/keypad */
+ LIT_CURR_HI_0,
+ LIT_CURR_HI_6,
+ LIT_CURR_HI_12,
+ LIT_CURR_HI_18,
+ LIT_CURR_HI_24,
+ LIT_CURR_HI_30,
+ LIT_CURR_HI_36,
+ LIT_CURR_HI_42,
+};
+
+enum lit_channel {
+ LIT_MAIN = 0,
+ LIT_AUX,
+ LIT_KEY,
+ LIT_RED,
+ LIT_GREEN,
+ LIT_BLUE,
+};
+
+#endif
+
+/* EXPORTED FUNCTIONS */
+#ifdef __KERNEL__
+/*!
+ * This function enables backlight & tcled.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_tcled_master_enable(void);
+
+/*!
+ * This function disables backlight & tcled.
+ *
+ * @return This function returns PMIC_SUCCESS if successful
+ */
+PMIC_STATUS pmic_bklit_tcled_master_disable(void);
+
+/*!
+ * This function enables backlight.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_master_enable(void);
+
+/*!
+ * This function disables backlight.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_master_disable(void);
+
+/*!
+ * This function sets backlight current level.
+ *
+ * @param channel Backlight channel
+ * @param level Backlight current level, as the following table.
+ * @verbatim
+ level current
+ ------ -----------
+ 0 0 mA
+ 1 12 mA
+ 2 24 mA
+ 3 36 mA
+ 4 48 mA
+ 5 60 mA
+ 6 72 mA
+ 7 84 mA
+ @endverbatim
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_set_current(t_bklit_channel channel,
+ unsigned char level);
+
+/*!
+ * This function retrives backlight current level.
+ *
+ * @param channel Backlight channel
+ * @param level Pointer to store backlight current level result.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_get_current(t_bklit_channel channel,
+ unsigned char *level);
+
+/*!
+ * This function sets a backlight channel duty cycle.
+ * LED perceived brightness for each zone may be individually set by setting
+ * duty cycle. The default setting is for 0% duty cycle; this keeps all zone
+ * drivers turned off even after the master enable command. Each LED current
+ * sink can be turned on and adjusted for brightness with an independent 4 bit
+ * word for a duty cycle ranging from 0% to 100% in approximately 6.7% steps.
+ *
+ * @param channel Backlight channel.
+ * @param dc Backlight duty cycle, as the following table.
+ * @verbatim
+ dc Duty Cycle (% On-time over Cycle Time)
+ ------ ---------------------------------------
+ 0 0%
+ 1 6.7%
+ 2 13.3%
+ 3 20%
+ 4 26.7%
+ 5 33.3%
+ 6 40%
+ 7 46.7%
+ 8 53.3%
+ 9 60%
+ 10 66.7%
+ 11 73.3%
+ 12 80%
+ 13 86.7%
+ 14 93.3%
+ 15 100%
+ @endverbatim
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_set_dutycycle(t_bklit_channel channel, unsigned char dc);
+
+/*!
+ * This function retrives a backlight channel duty cycle.
+ *
+ * @param channel Backlight channel.
+ * @param cycle Pointer to backlight duty cycle.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_get_dutycycle(t_bklit_channel channel,
+ unsigned char *dc);
+
+/*!
+ * This function sets a backlight channel cycle time.
+ * Cycle Time is defined as the period of a complete cycle of
+ * Time_on + Time_off. The default Cycle Time is set to 0.01 seconds such that
+ * the 100 Hz on-off cycling is averaged out by the eye to eliminate
+ * flickering. Additionally, the Cycle Time can be programmed to intentionally
+ * extend the period of on-off cycles for a visual pulsating or blinking effect.
+ *
+ * @param period Backlight cycle time, as the following table.
+ * @verbatim
+ period Cycle Time
+ -------- ------------
+ 0 0.01 seconds
+ 1 0.1 seconds
+ 2 0.5 seconds
+ 3 2 seconds
+ @endverbatim
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_set_cycle_time(unsigned char period);
+
+/*!
+ * This function retrives a backlight channel cycle time setting.
+ *
+ * @param period Pointer to save backlight cycle time setting result.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_get_cycle_time(unsigned char *period);
+
+/*!
+ * This function sets backlight operation mode. There are two modes of
+ * operations: current control and triode mode.
+ * The Duty Cycle/Cycle Time control is retained in Triode Mode. Audio
+ * coupling is not available in Triode Mode.
+ *
+ * @param channel Backlight channel.
+ * @param mode Backlight operation mode.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_set_mode(t_bklit_channel channel, t_bklit_mode mode);
+/*!
+ * This function gets backlight operation mode. There are two modes of
+ * operations: current control and triode mode.
+ * The Duty Cycle/Cycle Time control is retained in Triode Mode. Audio
+ * coupling is not available in Triode Mode.
+ *
+ * @param channel Backlight channel.
+ * @param mode Backlight operation mode.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_get_mode(t_bklit_channel channel, t_bklit_mode * mode);
+/*!
+ * This function starts backlight brightness ramp up function; ramp time is
+ * fixed at 0.5 seconds.
+ *
+ * @param channel Backlight channel.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_rampup(t_bklit_channel channel);
+/*!
+ * This function stops backlight brightness ramp up function;
+ *
+ * @param channel Backlight channel.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_off_rampup(t_bklit_channel channel);
+/*!
+ * This function starts backlight brightness ramp down function; ramp time is
+ * fixed at 0.5 seconds.
+ *
+ * @param channel Backlight channel.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_rampdown(t_bklit_channel channel);
+/*!
+ * This function stops backlight brightness ramp down function.
+ *
+ * @param channel Backlight channel.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_off_rampdown(t_bklit_channel channel);
+/*!
+ * This function enables backlight analog edge slowing mode. Analog Edge
+ * Slowing slows down the transient edges to reduce the chance of coupling LED
+ * modulation activity into other circuits. Rise and fall times will be targeted
+ * for approximately 50usec.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_enable_edge_slow(void);
+
+/*!
+ * This function disables backlight analog edge slowing mode. The backlight
+ * drivers will default to an “Instant On” mode.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_disable_edge_slow(void);
+/*!
+ * This function gets backlight analog edge slowing mode. DThe backlight
+ *
+ * @param edge Edge slowing mode.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_get_edge_slow(bool * edge);
+/*!
+ * This function sets backlight Strobe Light Pulsing mode.
+ *
+ * @param channel Backlight channel.
+ * @param mode Strobe Light Pulsing mode.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_bklit_set_strobemode(t_bklit_channel channel,
+ t_bklit_strobe_mode mode);
+
+/*!
+ * This function enables tri-color LED.
+ *
+ * @param mode Tri-color LED operation mode.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_enable(t_tcled_mode mode, t_funlight_bank bank);
+/*!
+ * This function disables tri-color LED.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_disable(t_funlight_bank bank);
+/*!
+ * This function retrives tri-color LED operation mode.
+ *
+ * @param mode Pointer to Tri-color LED operation mode.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_get_mode(t_tcled_mode * mode, t_funlight_bank bank);
+/*!
+ * This function sets a tri-color LED channel current level in indicator mode.
+ *
+ * @param channel Tri-color LED channel.
+ * @param level Current level.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_ind_set_current(t_ind_channel channel,
+ t_tcled_cur_level level,
+ t_funlight_bank bank);
+/*!
+ * This function retrives a tri-color LED channel current level in indicator mode.
+ *
+ * @param channel Tri-color LED channel.
+ * @param level Pointer to current level.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_ind_get_current(t_ind_channel channel,
+ t_tcled_cur_level * level,
+ t_funlight_bank bank);
+/*!
+ * This function sets a tri-color LED channel blinking pattern in indication
+ * mode.
+ *
+ * @param channel Tri-color LED channel.
+ * @param pattern Blinking pattern.
+ * @param skip If true, skip a cycle after each cycle.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+
+PMIC_STATUS pmic_tcled_ind_set_blink_pattern(t_ind_channel channel,
+ t_tcled_ind_blink_pattern pattern,
+ bool skip, t_funlight_bank bank);
+/*!
+ * This function retrives a tri-color LED channel blinking pattern in
+ * indication mode.
+ *
+ * @param channel Tri-color LED channel.
+ * @param pattern Pointer to Blinking pattern.
+ * @param skip Pointer to a boolean variable indicating if skip
+ * a cycle after each cycle.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_ind_get_blink_pattern(t_ind_channel channel,
+ t_tcled_ind_blink_pattern *
+ pattern, bool * skip,
+ t_funlight_bank bank);
+/*!
+ * This function sets a tri-color LED channel current level in Fun Light mode.
+ *
+ * @param bank Tri-color LED bank
+ * @param channel Tri-color LED channel.
+ * @param level Current level.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_fun_set_current(t_funlight_bank bank,
+ t_funlight_channel channel,
+ t_tcled_cur_level level);
+
+/*!
+ * This function retrives a tri-color LED channel current level
+ * in Fun Light mode.
+ *
+ * @param bank Tri-color LED bank
+ * @param channel Tri-color LED channel.
+ * @param level Pointer to current level.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_fun_get_current(t_funlight_bank bank,
+ t_funlight_channel channel,
+ t_tcled_cur_level * level);
+
+/*!
+ * This function sets tri-color LED cycle time in Fun Light mode.
+ *
+ * @param bank Tri-color LED bank
+ * @param ct Cycle time.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_fun_set_cycletime(t_funlight_bank bank,
+ t_tcled_fun_cycle_time ct);
+
+/*!
+ * This function retrives tri-color LED cycle time in Fun Light mode.
+ *
+ * @param bank Tri-color LED bank
+ * @param ct Pointer to cycle time.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_fun_get_cycletime(t_funlight_bank bank,
+ t_tcled_fun_cycle_time * ct);
+
+/*!
+ * This function sets a tri-color LED channel duty cycle in Fun Light mode.
+ *
+ * @param bank Tri-color LED bank
+ * @param channel Tri-color LED channel.
+ * @param dc Duty cycle.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_fun_set_dutycycle(t_funlight_bank bank,
+ t_funlight_channel channel,
+ unsigned char dc);
+
+/*!
+ * This function retrives a tri-color LED channel duty cycle in Fun Light mode.
+ *
+ * @param bank Tri-color LED bank
+ * @param channel Tri-color LED channel.
+ * @param dc Pointer to duty cycle.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_fun_get_dutycycle(t_funlight_bank bank,
+ t_funlight_channel channel,
+ unsigned char *dc);
+
+/*!
+ * This function initiates Blended Ramp fun light pattern.
+ *
+ * @param bank Tri-color LED bank
+ * @param speed Speed of pattern.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_fun_blendedramps(t_funlight_bank bank,
+ t_tcled_fun_speed speed);
+
+/*!
+ * This function initiates Saw Ramp fun light pattern.
+ *
+ * @param bank Tri-color LED bank
+ * @param speed Speed of pattern.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_fun_sawramps(t_funlight_bank bank,
+ t_tcled_fun_speed speed);
+
+/*!
+ * This function initiates Blended Bowtie fun light pattern.
+ *
+ * @param bank Tri-color LED bank
+ * @param speed Speed of pattern.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_fun_blendedbowtie(t_funlight_bank bank,
+ t_tcled_fun_speed speed);
+
+/*!
+ * This function initiates Chasing Lights fun light pattern.
+ *
+ * @param bank Tri-color LED bank
+ * @param pattern Chasing light pattern mode.
+ * @param speed Speed of pattern.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_fun_chasinglightspattern(t_funlight_bank bank,
+ t_chaselight_pattern pattern,
+ t_tcled_fun_speed speed);
+
+/*!
+ * This function initiates Strobe Mode fun light pattern.
+ *
+ * @param bank Tri-color LED bank
+ * @param channel Tri-color LED channel.
+ * @param speed Speed of pattern.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_fun_strobe(t_funlight_bank bank,
+ t_funlight_channel channel,
+ t_tcled_fun_strobe_speed speed);
+
+/*!
+ * This function initiates Tri-color LED brightness Ramp Up function; Ramp time
+ * is fixed at 1 second.
+ *
+ * @param bank Tri-color LED bank
+ * @param channel Tri-color LED channel.
+ * @param rampup Ramp-up configuration.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_fun_rampup(t_funlight_bank bank,
+ t_funlight_channel channel, bool rampup);
+/*!
+ * This function gets Tri-color LED brightness Ramp Up function; Ramp time
+ * is fixed at 1 second.
+ *
+ * @param bank Tri-color LED bank
+ * @param channel Tri-color LED channel.
+ * @param rampup Ramp-up configuration.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_get_fun_rampup(t_funlight_bank bank,
+ t_funlight_channel channel,
+ bool * rampup);
+
+/*!
+ * This function initiates Tri-color LED brightness Ramp Down function; Ramp
+ * time is fixed at 1 second.
+ *
+ * @param bank Tri-color LED bank
+ * @param channel Tri-color LED channel.
+ * @param rampdown Ramp-down configuration.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_fun_rampdown(t_funlight_bank bank,
+ t_funlight_channel channel, bool rampdown);
+/*!
+ * This function initiates Tri-color LED brightness Ramp Down function; Ramp
+ * time is fixed at 1 second.
+ *
+ * @param bank Tri-color LED bank
+ * @param channel Tri-color LED channel.
+ * @param rampdown Ramp-down configuration.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_get_fun_rampdown(t_funlight_bank bank,
+ t_funlight_channel channel,
+ bool * rampdown);
+
+/*!
+ * This function enables a Tri-color channel triode mode.
+ *
+ * @param bank Tri-color LED bank
+ * @param channel Tri-color LED channel.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_fun_triode_on(t_funlight_bank bank,
+ t_funlight_channel channel);
+
+/*!
+ * This function disables a Tri-color LED channel triode mode.
+ *
+ * @param bank Tri-color LED bank
+ * @param channel Tri-color LED channel.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_tcled_fun_triode_off(t_funlight_bank bank,
+ t_funlight_channel channel);
+
+/*!
+ * This function enables Tri-color LED edge slowing.
+ *
+ * @return This function returns PMIC_NOT_SUPPORTED.
+ */
+PMIC_STATUS pmic_tcled_enable_edge_slow(void);
+
+/*!
+ * This function disables Tri-color LED edge slowing.
+ *
+ * @return This function returns PMIC_NOT_SUPPORTED.
+ */
+PMIC_STATUS pmic_tcled_disable_edge_slow(void);
+
+/*!
+ * This function enables Tri-color LED half current mode.
+ *
+ * @return This function returns PMIC_NOT_SUPPORTED.
+ */
+PMIC_STATUS pmic_tcled_enable_half_current(void);
+
+/*!
+ * This function disables Tri-color LED half current mode.
+ *
+ * @return This function returns PMIC_NOT_SUPPORTED.
+ */
+PMIC_STATUS pmic_tcled_disable_half_current(void);
+
+/*!
+ * This function enables backlight or Tri-color LED audio modulation.
+ *
+ * @return This function returns PMIC_NOT_SUPPORTED.
+ */
+PMIC_STATUS pmic_tcled_enable_audio_modulation(t_led_channel channel,
+ t_aud_path path,
+ t_aud_gain gain,
+ bool lpf_bypass);
+
+/*!
+ * This function disables backlight or Tri-color LED audio modulation.
+ *
+ * @return This function returns PMIC_NOT_SUPPORTED.
+ */
+PMIC_STATUS pmic_tcled_disable_audio_modulation(void);
+/*!
+ * This function enables the boost mode.
+ * Only on mc13783 2.0 or higher
+ *
+ * @param en_dis Enable or disable the boost mode
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_bklit_set_boost_mode(bool en_dis);
+
+/*!
+ * This function gets the boost mode.
+ * Only on mc13783 2.0 or higher
+ *
+ * @param en_dis Enable or disable the boost mode
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_bklit_get_boost_mode(bool * en_dis);
+
+/*!
+ * This function sets boost mode configuration
+ * Only on mc13783 2.0 or higher
+ *
+ * @param abms Define adaptive boost mode selection
+ * @param abr Define adaptive boost reference
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_bklit_config_boost_mode(unsigned int abms, unsigned int abr);
+
+/*!
+ * This function gets boost mode configuration
+ * Only on mc13783 2.0 or higher
+ *
+ * @param abms Define adaptive boost mode selection
+ * @param abr Define adaptive boost reference
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_bklit_gets_boost_mode(unsigned int *abms, unsigned int *abr);
+
+#if defined(CONFIG_MXC_PMIC_MC13892)
+
+PMIC_STATUS mc13892_bklit_set_current(enum lit_channel channel,
+ unsigned char level);
+PMIC_STATUS mc13892_bklit_get_current(enum lit_channel channel,
+ unsigned char *level);
+PMIC_STATUS mc13892_bklit_set_dutycycle(enum lit_channel channel,
+ unsigned char dc);
+PMIC_STATUS mc13892_bklit_get_dutycycle(enum lit_channel channel,
+ unsigned char *dc);
+PMIC_STATUS mc13892_bklit_set_ramp(enum lit_channel channel, int flag);
+PMIC_STATUS mc13892_bklit_get_ramp(enum lit_channel channel, int *flag);
+PMIC_STATUS mc13892_bklit_set_blink_p(enum lit_channel channel, int period);
+PMIC_STATUS mc13892_bklit_get_blink_p(enum lit_channel channel, int *period);
+
+#endif
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_ARCH_MXC_PMIC_LIGHT_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/pmic_power.h b/arch/arm/plat-mxc/include/mach/pmic_power.h
new file mode 100644
index 000000000000..c614c85d0c81
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/pmic_power.h
@@ -0,0 +1,1358 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+#ifndef __ASM_ARCH_MXC_PMIC_POWER_H__
+#define __ASM_ARCH_MXC_PMIC_POWER_H__
+
+/*!
+ * @defgroup PMIC_POWER PMIC Power Driver
+ * @ingroup PMIC_DRVRS
+ */
+
+/*!
+ * @file arch-mxc/pmic_power.h
+ * @brief This is the header of PMIC power driver.
+ *
+ * @ingroup PMIC_POWER
+ */
+
+#include <asm/ioctl.h>
+#include <mach/pmic_status.h>
+#include <mach/pmic_external.h>
+
+/*!
+ * @name IOCTL user space interface
+ */
+/*! @{ */
+
+/*!
+ * Turn on a regulator.
+ */
+#define PMIC_REGULATOR_ON _IOWR('p', 0xf0, int)
+
+/*!
+ * Turn off a regulator.
+ */
+#define PMIC_REGULATOR_OFF _IOWR('p', 0xf1, int)
+
+/*!
+ * Set regulator configuration.
+ */
+#define PMIC_REGULATOR_SET_CONFIG _IOWR('p', 0xf2, int)
+
+/*!
+ * Get regulator configuration.
+ */
+#define PMIC_REGULATOR_GET_CONFIG _IOWR('p', 0xf3, int)
+
+/*!
+ * Miscellaneous Power Test.
+ */
+#define PMIC_POWER_CHECK_MISC _IOWR('p', 0xf4, int)
+
+/*! @} */
+
+/*!
+ * This enumeration define all power interrupts
+ */
+typedef enum {
+ /*!
+ * BP turn on threshold detection
+ */
+ PWR_IT_BPONI = 0,
+ /*!
+ * End of life / low battery detect
+ */
+ PWR_IT_LOBATLI,
+ /*!
+ * Low battery warning
+ */
+ PWR_IT_LOBATHI,
+ /*!
+ * ON1B event
+ */
+ PWR_IT_ONOFD1I,
+ /*!
+ * ON2B event
+ */
+ PWR_IT_ONOFD2I,
+ /*!
+ * ON3B event
+ */
+ PWR_IT_ONOFD3I,
+ /*!
+ * System reset
+ */
+ PWR_IT_SYSRSTI,
+ /*!
+ * Power ready
+ */
+ PWR_IT_PWRRDYI,
+ /*!
+ * Power cut event
+ */
+ PWR_IT_PCI,
+ /*!
+ * Warm start event
+ */
+ PWR_IT_WARMI,
+ /*!
+ * Memory hold event
+ */
+} t_pwr_int;
+
+/*!
+ * VHOLD regulator output voltage setting.
+ */
+typedef enum {
+ VH_1_875V, /*!< 1.875V */
+ VH_2_5V, /*!< 2.5V */
+ VH_1_55V, /*!< 1.55V */
+ VH_PASSTHROUGH, /*!< Pass-through mode */
+} t_vhold_voltage;
+
+/*!
+ * PMIC power control configuration.
+ */
+
+typedef struct {
+ bool pc_enable; /*!< Power cut enable */
+ unsigned char pc_timer; /*!< Power cut timer value */
+ bool pc_count_enable; /*!< Power cut counter enable,
+ If TURE, Power cuts are disabled
+ when pc_count > pc_max_count;
+ If FALSE, Power cuts are not
+ disabled when
+ pc_count > pc_max_count */
+ unsigned char pc_count; /*!< Power cut count */
+ unsigned char pc_max_count; /*!< Power cut maximum count */
+ bool warm_enable; /*!< User Off state enable */
+ bool user_off_pc; /*!< Automatic transition to user off
+ during power cut */
+ bool clk_32k_enable; /*!< 32 kHz output buffer enable
+ during memory hold */
+ bool clk_32k_user_off; /*!< Keeps the CLK32KMCU active during
+ user off power cut modes */
+ bool en_vbkup1; /*!< enable VBKUP1 regulator */
+ bool auto_en_vbkup1; /*!< automatically enable VBKUP1
+ regulator in the memory hold
+ and user of modes */
+ t_vhold_voltage vhold_voltage; /*!< output voltage for VBKUP1 */
+ bool en_vbkup2; /*!< enable VBKUP2 regulator */
+ bool auto_en_vbkup2; /*!< automatically enable VBKUP2
+ regulator in the memory hold
+ and user of modes */
+ t_vhold_voltage vhold_voltage2; /*!< output voltage for VBKUP2 */
+ unsigned char mem_timer; /*!< duration of the memory hold
+ timer */
+ bool mem_allon; /*!< memory hold timer infinity mode,
+ If TRUE, the memory hold timer
+ will be set to infinity and
+ the mem_timer filed will be
+ ignored */
+} t_pc_config;
+
+/*!
+ * brief PMIC regulators.
+ */
+
+typedef enum {
+ SW_SW1A = 0, /*!< SW1A or SW1 */
+ SW_SW1B, /*!< SW1B */
+ SW_SW2A, /*!< SW2A or SW2 */
+ SW_SW2B, /*!< SW2B */
+ SW_SW3, /*!< SW3 */
+ SW_PLL, /*!< PLL */
+ REGU_VAUDIO, /*!< VAUDIO */
+ REGU_VIOHI, /*!< VIOHI */
+ REGU_VIOLO, /*!< VIOLO */
+ REGU_VDIG, /*!< VDIG */
+ REGU_VGEN, /*!< VGEN */
+ REGU_VRFDIG, /*!< VRFDIG */
+ REGU_VRFREF, /*!< VRFREF */
+ REGU_VRFCP, /*!< VRFCP */
+ REGU_VSIM, /*!< VSIM */
+ REGU_VESIM, /*!< VESIM */
+ REGU_VCAM, /*!< VCAM */
+ REGU_VRFBG, /*!< VRFBG */
+ REGU_VVIB, /*!< VVIB */
+ REGU_VRF1, /*!< VRF1 */
+ REGU_VRF2, /*!< VRF2 */
+ REGU_VMMC1, /*!< VMMC1 or VMMC */
+ REGU_VMMC2, /*!< VMMC2 */
+ REGU_GPO1, /*!< GPIO1 */
+ REGU_GPO2, /*!< GPO2 */
+ REGU_GPO3, /*!< GPO3 */
+ REGU_GPO4, /*!< GPO4 */
+ REGU_V1, /*!< V1 */
+ REGU_V2, /*!< V2 */
+ REGU_V3, /*!< V3 */
+ REGU_V4, /*!< V4 */
+} t_pmic_regulator;
+
+/*!
+ * @enum t_pmic_regulator_voltage_sw1
+ * @brief PMIC Switch mode regulator SW1 output voltages.
+ */
+
+typedef enum {
+ SW1_1V = 0, /*!< 1.0 V */
+ SW1_1_1V, /*!< 1.1 V */
+ SW1_1_2V, /*!< 1.2 V */
+ SW1_1_3V, /*!< 1.3 V */
+ SW1_1_4V, /*!< 1.4 V */
+ SW1_1_55V, /*!< 1.55 V */
+ SW1_1_625V, /*!< 1.625 V */
+ SW1_1_875V, /*!< 1.875 V */
+} t_pmic_regulator_voltage_sw1;
+
+/*!
+ * @enum t_pmic_regulator_voltage_sw1a
+ * @brief PMIC regulator SW1A output voltage.
+ */
+typedef enum {
+ SW1A_0_9V = 0, /*!< 0.900 V */
+ SW1A_0_925V, /*!< 0.925 V */
+ SW1A_0_95V, /*!< 0.950 V */
+ SW1A_0_975V, /*!< 0.975 V */
+ SW1A_1V, /*!< 1.000 V */
+ SW1A_1_025V, /*!< 1.025 V */
+ SW1A_1_05V, /*!< 1.050 V */
+ SW1A_1_075V, /*!< 1.075 V */
+ SW1A_1_1V, /*!< 1.100 V */
+ SW1A_1_125V, /*!< 1.125 V */
+ SW1A_1_15V, /*!< 1.150 V */
+ SW1A_1_175V, /*!< 1.175 V */
+ SW1A_1_2V, /*!< 1.200 V */
+ SW1A_1_225V, /*!< 1.225 V */
+ SW1A_1_25V, /*!< 1.250 V */
+ SW1A_1_275V, /*!< 1.275 V */
+ SW1A_1_3V, /*!< 1.300 V */
+ SW1A_1_325V, /*!< 1.325 V */
+ SW1A_1_35V, /*!< 1.350 V */
+ SW1A_1_375V, /*!< 1.375 V */
+ SW1A_1_4V, /*!< 1.400 V */
+ SW1A_1_425V, /*!< 1.425 V */
+ SW1A_1_45V, /*!< 1.450 V */
+ SW1A_1_475V, /*!< 1.475 V */
+ SW1A_1_5V, /*!< 1.500 V */
+ SW1A_1_525V, /*!< 1.525 V */
+ SW1A_1_55V, /*!< 1.550 V */
+ SW1A_1_575V, /*!< 1.575 V */
+ SW1A_1_6V, /*!< 1.600 V */
+ SW1A_1_625V, /*!< 1.625 V */
+ SW1A_1_65V, /*!< 1.650 V */
+ SW1A_1_675V, /*!< 1.675 V */
+ SW1A_1_7V, /*!< 1.700 V */
+ SW1A_1_8V = 36, /*!< 1.800 V */
+ SW1A_1_85V = 40, /*!< 1.850 V */
+ SW1A_2V = 44, /*!< 2_000 V */
+ SW1A_2_1V = 48, /*!< 2_100 V */
+ SW1A_2_2V = 52, /*!< 2_200 V */
+} t_pmic_regulator_voltage_sw1a;
+
+/*!
+ * @enum t_pmic_regulator_voltage_sw1b
+ * @brief PMIC regulator SW1B output voltage.
+ */
+typedef enum {
+ SW1B_0_9V = 0, /*!< 0.900 V */
+ SW1B_0_925V, /*!< 0.925 V */
+ SW1B_0_95V, /*!< 0.950 V */
+ SW1B_0_975V, /*!< 0.975 V */
+ SW1B_1V, /*!< 1.000 V */
+ SW1B_1_025V, /*!< 1.025 V */
+ SW1B_1_05V, /*!< 1.050 V */
+ SW1B_1_075V, /*!< 1.075 V */
+ SW1B_1_1V, /*!< 1.100 V */
+ SW1B_1_125V, /*!< 1.125 V */
+ SW1B_1_15V, /*!< 1.150 V */
+ SW1B_1_175V, /*!< 1.175 V */
+ SW1B_1_2V, /*!< 1.200 V */
+ SW1B_1_225V, /*!< 1.225 V */
+ SW1B_1_25V, /*!< 1.250 V */
+ SW1B_1_275V, /*!< 1.275 V */
+ SW1B_1_3V, /*!< 1.300 V */
+ SW1B_1_325V, /*!< 1.325 V */
+ SW1B_1_35V, /*!< 1.350 V */
+ SW1B_1_375V, /*!< 1.375 V */
+ SW1B_1_4V, /*!< 1.400 V */
+ SW1B_1_425V, /*!< 1.425 V */
+ SW1B_1_45V, /*!< 1.450 V */
+ SW1B_1_475V, /*!< 1.475 V */
+ SW1B_1_5V, /*!< 1.500 V */
+ SW1B_1_525V, /*!< 1.525 V */
+ SW1B_1_55V, /*!< 1.550 V */
+ SW1B_1_575V, /*!< 1.575 V */
+ SW1B_1_6V, /*!< 1.600 V */
+ SW1B_1_625V, /*!< 1.625 V */
+ SW1B_1_65V, /*!< 1.650 V */
+ SW1B_1_675V, /*!< 1.675 V */
+ SW1B_1_7V, /*!< 1.700 V */
+ SW1B_1_8V = 36, /*!< 1.800 V */
+ SW1B_1_85V = 40, /*!< 1.850 V */
+ SW1B_2V = 44, /*!< 2_000 V */
+ SW1B_2_1V = 48, /*!< 2_100 V */
+ SW1B_2_2V = 52, /*!< 2_200 V */
+} t_pmic_regulator_voltage_sw1b;
+
+/*!
+ * @enum t_pmic_regulator_voltage_sw2
+ * @brief PMIC Switch mode regulator SW2 output voltages.
+ */
+typedef enum {
+ SW2_1V = 0, /*!< 1.0 V */
+ SW2_1_1V, /*!< 1.1 V */
+ SW2_1_2V, /*!< 1.2 V */
+ SW2_1_3V, /*!< 1.3 V */
+ SW2_1_4V, /*!< 1.4 V */
+ SW2_1_55V, /*!< 1.55 V */
+ SW2_1_625V, /*!< 1.625 V */
+ SW2_1_875V, /*!< 1.875 V */
+} t_pmic_regulator_voltage_sw2;
+
+/*!
+ * @enum t_pmic_regulator_voltage_sw2a
+ * @brief PMIC regulator SW2A output voltage.
+ */
+typedef enum {
+ SW2A_0_9V = 0, /*!< 0.900 V */
+ SW2A_0_925V, /*!< 0.925 V */
+ SW2A_0_95V, /*!< 0.950 V */
+ SW2A_0_975V, /*!< 0.975 V */
+ SW2A_1V, /*!< 1.000 V */
+ SW2A_1_025V, /*!< 1.025 V */
+ SW2A_1_05V, /*!< 1.050 V */
+ SW2A_1_075V, /*!< 1.075 V */
+ SW2A_1_1V, /*!< 1.100 V */
+ SW2A_1_125V, /*!< 1.125 V */
+ SW2A_1_15V, /*!< 1.150 V */
+ SW2A_1_175V, /*!< 1.175 V */
+ SW2A_1_2V, /*!< 1.200 V */
+ SW2A_1_225V, /*!< 1.225 V */
+ SW2A_1_25V, /*!< 1.250 V */
+ SW2A_1_275V, /*!< 1.275 V */
+ SW2A_1_3V, /*!< 1.300 V */
+ SW2A_1_325V, /*!< 1.325 V */
+ SW2A_1_35V, /*!< 1.350 V */
+ SW2A_1_375V, /*!< 1.375 V */
+ SW2A_1_4V, /*!< 1.400 V */
+ SW2A_1_425V, /*!< 1.425 V */
+ SW2A_1_45V, /*!< 1.450 V */
+ SW2A_1_475V, /*!< 1.475 V */
+ SW2A_1_5V, /*!< 1.500 V */
+ SW2A_1_525V, /*!< 1.525 V */
+ SW2A_1_55V, /*!< 1.550 V */
+ SW2A_1_575V, /*!< 1.575 V */
+ SW2A_1_6V, /*!< 1.600 V */
+ SW2A_1_625V, /*!< 1.625 V */
+ SW2A_1_65V, /*!< 1.650 V */
+ SW2A_1_675V, /*!< 1.675 V */
+ SW2A_1_7V, /*!< 1.700 V */
+ SW2A_1_8V = 36, /*!< 1.800 V */
+ SW2A_1_9V = 40, /*!< 1.900 V */
+ SW2A_2V = 44, /*!< 2_000 V */
+ SW2A_2_1V = 48, /*!< 2_100 V */
+ SW2A_2_2V = 52, /*!< 2_200 V */
+} t_pmic_regulator_voltage_sw2a;
+
+/*!
+ * @enum t_pmic_regulator_voltage_sw2b
+ * @brief PMIC regulator SW2B output voltage.
+ */
+typedef enum {
+ SW2B_0_9V = 0, /*!< 0.900 V */
+ SW2B_0_925V, /*!< 0.925 V */
+ SW2B_0_95V, /*!< 0.950 V */
+ SW2B_0_975V, /*!< 0.975 V */
+ SW2B_1V, /*!< 1.000 V */
+ SW2B_1_025V, /*!< 1.025 V */
+ SW2B_1_05V, /*!< 1.050 V */
+ SW2B_1_075V, /*!< 1.075 V */
+ SW2B_1_1V, /*!< 1.100 V */
+ SW2B_1_125V, /*!< 1.125 V */
+ SW2B_1_15V, /*!< 1.150 V */
+ SW2B_1_175V, /*!< 1.175 V */
+ SW2B_1_2V, /*!< 1.200 V */
+ SW2B_1_225V, /*!< 1.225 V */
+ SW2B_1_25V, /*!< 1.250 V */
+ SW2B_1_275V, /*!< 1.275 V */
+ SW2B_1_3V, /*!< 1.300 V */
+ SW2B_1_325V, /*!< 1.325 V */
+ SW2B_1_35V, /*!< 1.350 V */
+ SW2B_1_375V, /*!< 1.375 V */
+ SW2B_1_4V, /*!< 1.400 V */
+ SW2B_1_425V, /*!< 1.425 V */
+ SW2B_1_45V, /*!< 1.450 V */
+ SW2B_1_475V, /*!< 1.475 V */
+ SW2B_1_5V, /*!< 1.500 V */
+ SW2B_1_525V, /*!< 1.525 V */
+ SW2B_1_55V, /*!< 1.550 V */
+ SW2B_1_575V, /*!< 1.575 V */
+ SW2B_1_6V, /*!< 1.600 V */
+ SW2B_1_625V, /*!< 1.625 V */
+ SW2B_1_65V, /*!< 1.650 V */
+ SW2B_1_675V, /*!< 1.675 V */
+ SW2B_1_7V, /*!< 1.700 V */
+ SW2B_1_8V = 36, /*!< 1.800 V */
+ SW2B_1_9V = 40, /*!< 1.900 V */
+ SW2B_2V = 44, /*!< 2_000 V */
+ SW2B_2_1V = 48, /*!< 2_100 V */
+ SW2B_2_2V = 52, /*!< 2_200 V */
+} t_pmic_regulator_voltage_sw2b;
+
+/*!
+ * @enum t_pmic_regulator_voltage_sw3
+ * @brief PMIC Switch mode regulator SW3 output voltages.
+ */
+typedef enum {
+ SW3_5V = 0, /*!< 5.0 V */
+ SW3_5_1V = 0, /*!< 5.1 V */
+ SW3_5_6V, /*!< 5.6 V */
+} t_pmic_regulator_voltage_sw3;
+
+/*!
+ * @enum t_switcher_factor
+ * @brief PLL multiplication factor
+ */
+typedef enum {
+ FACTOR_28 = 0, /*!< 917 504 kHz */
+ FACTOR_29, /*!< 950 272 kHz */
+ FACTOR_30, /*!< 983 040 kHz */
+ FACTOR_31, /*!< 1 015 808 kHz */
+ FACTOR_32, /*!< 1 048 576 kHz */
+ FACTOR_33, /*!< 1 081 344 kHz */
+ FACTOR_34, /*!< 1 114 112 kHz */
+ FACTOR_35, /*!< 1 146 880 kHz */
+} t_switcher_factor;
+
+/*!
+ * @enum t_pmic_regulator_voltage_violo
+ * @brief PMIC regulator VIOLO output voltage.
+ */
+typedef enum {
+ VIOLO_1_2V = 0, /*!< 1.2 V */
+ VIOLO_1_3V, /*!< 1.3 V */
+ VIOLO_1_5V, /*!< 1.5 V */
+ VIOLO_1_8V, /*!< 1.8 V */
+} t_pmic_regulator_voltage_violo;
+
+/*!
+ * @enum t_pmic_regulator_voltage_vdig
+ * @brief PMIC regulator VDIG output voltage.
+ */
+typedef enum {
+ VDIG_1_2V = 0, /*!< 1.2 V */
+ VDIG_1_3V, /*!< 1.3 V */
+ VDIG_1_5V, /*!< 1.5 V */
+ VDIG_1_8V, /*!< 1.8 V */
+} t_pmic_regulator_voltage_vdig;
+
+/*!
+ * @enum t_pmic_regulator_voltage_vgen
+ * @brief PMIC regulator VGEN output voltage.
+ */
+typedef enum {
+ VGEN_1_2V = 0, /*!< 1.2 V */
+ VENG_1_3V, /*!< 1.3 V */
+ VGEN_1_5V, /*!< 1.5 V */
+ VGEN_1_8V, /*!< 1.8 V */
+ VGEN_1_1V, /*!< 1.1 V */
+ VGEN_2V, /*!< 2 V */
+ VGEN_2_775V, /*!< 2.775 V */
+ VGEN_2_4V, /*!< 2.4 V */
+} t_pmic_regulator_voltage_vgen;
+
+/*!
+ * @enum t_pmic_regulator_voltage_vrfdig
+ * @brief PMIC regulator VRFDIG output voltage.
+ */
+typedef enum {
+ VRFDIG_1_2V = 0, /*!< 1.2 V */
+ VRFDIG_1_5V, /*!< 1.5 V */
+ VRFDIG_1_8V, /*!< 1.8 V */
+ VRFDIG_1_875V, /*!< 1.875 V */
+} t_pmic_regulator_voltage_vrfdig;
+
+/*!
+ * @enum t_pmic_regulator_voltage_vrfref
+ * @brief PMIC regulator VRFREF output voltage.
+ */
+typedef enum {
+ VRFREF_2_475V = 0, /*!< 2.475 V */
+ VRFREF_2_6V, /*!< 2.600 V */
+ VRFREF_2_7V, /*!< 2.700 V */
+ VRFREF_2_775V, /*!< 2.775 V */
+} t_pmic_regulator_voltage_vrfref;
+
+/*!
+ * @enum t_pmic_regulator_voltage_vrfcp
+ * @brief PMIC regulator VRFCP output voltage.
+ */
+typedef enum {
+ VRFCP_2_7V = 0, /*!< 2.700 V */
+ VRFCP_2_775V, /*!< 2.775 V */
+} t_pmic_regulator_voltage_vrfcp;
+
+/*!
+ * @enum t_pmic_regulator_voltage_vsim
+ * @brief PMIC linear regulator VSIM output voltage.
+ */
+typedef enum {
+ VSIM_1_8V = 0, /*!< 1.8 V */
+ VSIM_2_9V, /*!< 2.90 V */
+ VSIM_3V = 1, /*!< 3 V */
+} t_pmic_regulator_voltage_vsim;
+
+/*!
+ * @enum t_pmic_regulator_voltage_vesim
+ * @brief PMIC regulator VESIM output voltage.
+ */
+typedef enum {
+ VESIM_1_8V = 0, /*!< 1.80 V */
+ VESIM_2_9V, /*!< 2.90 V */
+} t_pmic_regulator_voltage_vesim;
+
+/*!
+ * @enum t_pmic_regulator_voltage_vcam
+ * @brief PMIC regulator VCAM output voltage.
+ */
+typedef enum {
+ VCAM_1_5V = 0, /*!< 1.50 V */
+ VCAM_1_8V, /*!< 1.80 V */
+ VCAM_2_5V, /*!< 2.50 V */
+ VCAM_2_55V, /*!< 2.55 V */
+ VCAM_2_6V, /*!< 2.60 V */
+ VCAM_2_75V, /*!< 2.75 V */
+ VCAM_2_8V, /*!< 2.80 V */
+ VCAM_3V, /*!< 3.00 V */
+} t_pmic_regulator_voltage_vcam;
+
+/*!
+ * @enum t_pmic_regulator_voltage_vvib
+ * @brief PMIC linear regulator V_VIB output voltage.
+ */
+typedef enum {
+ VVIB_1_3V = 0, /*!< 1.30 V */
+ VVIB_1_8V, /*!< 1.80 V */
+ VVIB_2V, /*!< 2 V */
+ VVIB_3V, /*!< 3 V */
+} t_pmic_regulator_voltage_vvib;
+
+/*!
+ * @enum t_pmic_regulator_voltage_vrf1
+ * @brief PMIC regulator VRF1 output voltage.
+ */
+typedef enum {
+ VRF1_1_5V = 0, /*!< 1.500 V */
+ VRF1_1_875V, /*!< 1.875 V */
+ VRF1_2_7V, /*!< 2.700 V */
+ VRF1_2_775V, /*!< 2.775 V */
+} t_pmic_regulator_voltage_vrf1;
+
+/*!
+ * @enum t_pmic_regulator_voltage_vrf2
+ * @brief PMIC regulator VRF2 output voltage.
+ */
+typedef enum {
+ VRF2_1_5V = 0, /*!< 1.500 V */
+ VRF2_1_875V, /*!< 1.875 V */
+ VRF2_2_7V, /*!< 2.700 V */
+ VRF2_2_775V, /*!< 2.775 V */
+} t_pmic_regulator_voltage_vrf2;
+
+/*!
+ * @enum t_pmic_regulator_voltage_vmmc
+ * @brief PMIC linear regulator VMMC output voltage.
+ */
+typedef enum {
+ VMMC_OFF = 0, /*!< Output off */
+ VMMC_1_6V, /*!< 1.6 V */
+ VMMC_1_8V, /*!< 1.8 V */
+ VMMC_2V, /*!< 2 V */
+ VMMC_2_2V, /*!< 2.2 V */
+ VMMC_2_4V, /*!< 2.4 V */
+ VMMC_2_6V, /*!< 2.6 V */
+ VMMC_2_8V, /*!< 2.8 V */
+ VMMC_3V, /*!< 3 V */
+ VMMC_3_2V, /*!< 3.2 V */
+ VMMC_3_3V, /*!< 3.3 V */
+ VMMC_3_4V, /*!< 3.4 V */
+} t_pmic_regulator_voltage_vmmc;
+
+/*!
+ * @enum t_pmic_regulator_voltage_vmmc1
+ * @brief PMIC regulator VMMC1 output voltage.
+ */
+typedef enum {
+ VMMC1_1_6V = 0, /*!< 1.60 V */
+ VMMC1_1_8V, /*!< 1.80 V */
+ VMMC1_2V, /*!< 2.00 V */
+ VMMC1_2_6V, /*!< 2.60 V */
+ VMMC1_2_7V, /*!< 2.70 V */
+ VMMC1_2_8V, /*!< 2.80 V */
+ VMMC1_2_9V, /*!< 2.90 V */
+ VMMC1_3V, /*!< 3.00 V */
+} t_pmic_regulator_voltage_vmmc1;
+
+/*!
+ * @enum t_pmic_regulator_voltage_vmmc2
+ * @brief PMIC regulator VMMC2 output voltage.
+ */
+typedef enum {
+ VMMC2_1_6V = 0, /*!< 1.60 V */
+ VMMC2_1_8V, /*!< 1.80 V */
+ VMMC2_2V, /*!< 2.00 V */
+ VMMC2_2_6V, /*!< 2.60 V */
+ VMMC2_2_7V, /*!< 2.70 V */
+ VMMC2_2_8V, /*!< 2.80 V */
+ VMMC2_2_9V, /*!< 2.90 V */
+ VMMC2_3V, /*!< 3.00 V */
+} t_pmic_regulator_voltage_vmmc2;
+
+/*!
+ * @enum t_pmic_regulator_voltage_v1
+ * @brief PMIC linear regulator V1 output voltages.
+ */
+typedef enum {
+ V1_2_775V = 0, /*!< 2.775 V */
+ V1_1_2V, /*!< 1.2 V */
+ V1_1_3V, /*!< 1.3 V */
+ V1_1_4V, /*!< 1.4 V */
+ V1_1_55V, /*!< 1.55 V */
+ V1_1_75V, /*!< 1.75 V */
+ V1_1_875V, /*!< 1.875 V */
+ V1_2_475V, /*!< 2.475 V */
+} t_pmic_regulator_voltage_v1;
+
+/*!
+ * @enum t_pmic_regulator_voltage_v2
+ * @brief PMIC linear regulator V2 output voltage, V2 has fixed
+ * output voltage 2.775 volts.
+ */
+typedef enum {
+ V2_2_775V = 0, /*!< 2.775 V */
+} t_pmic_regulator_voltage_v2;
+
+/*!
+ * @enum t_pmic_regulator_voltage_v3
+ * @brief PMIC linear regulator V3 output voltage.
+ */
+typedef enum {
+ V3_1_875V = 0, /*!< 1.875 V */
+ V3_2_775V, /*!< 2.775 V */
+} t_pmic_regulator_voltage_v3;
+
+/*!
+ * @enum t_pmic_regulator_voltage_v4
+ * @brief PMIC linear regulator V4 output voltage, V4 has fixed
+ * output voltage 2.775 volts.
+ */
+typedef enum {
+ V4_2_775V = 0, /*!< 2.775 V */
+} t_pmic_regulator_voltage_v4;
+
+/*!
+ * @union t_regulator_voltage
+ * @brief PMIC regulator output voltages.
+ */
+typedef union {
+ t_pmic_regulator_voltage_sw1 sw1; /*!< SW1 voltage */
+ t_pmic_regulator_voltage_sw1a sw1a; /*!< SW1A voltage */
+ t_pmic_regulator_voltage_sw1b sw1b; /*!< SW1B voltage */
+ t_pmic_regulator_voltage_sw2 sw2; /*!< SW2 voltage */
+ t_pmic_regulator_voltage_sw2a sw2a; /*!< SW2A voltage */
+ t_pmic_regulator_voltage_sw2b sw2b; /*!< SW2B voltage */
+ t_pmic_regulator_voltage_sw3 sw3; /*!< SW3 voltage */
+ t_pmic_regulator_voltage_violo violo; /*!< VIOLO voltage */
+ t_pmic_regulator_voltage_vdig vdig; /*!< VDIG voltage */
+ t_pmic_regulator_voltage_vgen vgen; /*!< VGEN voltage */
+ t_pmic_regulator_voltage_vrfdig vrfdig; /*!< VRFDIG voltage */
+ t_pmic_regulator_voltage_vrfref vrfref; /*!< VRFREF voltage */
+ t_pmic_regulator_voltage_vrfcp vrfcp; /*!< VRFCP voltage */
+ t_pmic_regulator_voltage_vsim vsim; /*!< VSIM voltage */
+ t_pmic_regulator_voltage_vesim vesim; /*!< VESIM voltage */
+ t_pmic_regulator_voltage_vcam vcam; /*!< VCAM voltage */
+ t_pmic_regulator_voltage_vvib vvib; /*!< VVIB voltage */
+ t_pmic_regulator_voltage_vrf1 vrf1; /*!< VRF1 voltage */
+ t_pmic_regulator_voltage_vrf2 vrf2; /*!< VRF2 voltage */
+ t_pmic_regulator_voltage_vmmc vmmc; /*!< VMMC voltage */
+ t_pmic_regulator_voltage_vmmc1 vmmc1; /*!< VMMC1 voltage */
+ t_pmic_regulator_voltage_vmmc2 vmmc2; /*!< VMMC2 voltage */
+ t_pmic_regulator_voltage_v1 v1; /*!< V1 voltage */
+ t_pmic_regulator_voltage_v2 v2; /*!< V2 voltage */
+ t_pmic_regulator_voltage_v3 v3; /*!< V3 voltage */
+ t_pmic_regulator_voltage_v4 v4; /*!< V4 voltage */
+} t_regulator_voltage;
+
+/*!
+ * @enum t_pmic_regulator_sw_mode
+ * @brief define switch mode regulator mode.
+ *
+ * The synchronous rectifier can be disabled (and pulse-skipping enabled)
+ * to improve low current efficiency. Software should disable synchronous
+ * rectifier / enable the pulse skipping for average loads less than
+ * approximately 30 mA, depending on the quiescent current penalty due to
+ * synchronous mode.
+ */
+typedef enum {
+ SYNC_RECT = 0,
+ NO_PULSE_SKIP,
+ PULSE_SKIP,
+ LOW_POWER,
+} t_pmic_regulator_sw_mode;
+
+/*!
+ * Generic PMIC switch mode regulator mode.
+ */
+typedef t_pmic_regulator_sw_mode t_regulator_sw_mode;
+typedef t_pmic_regulator_sw_mode t_regulator_stby_mode;
+
+/*!
+ * @enum t_regulator_lp_mode
+ * @brief Low power mode control modes.
+ */
+
+typedef enum {
+ /*!
+ * Low Power Mode is disabled
+ */
+ LOW_POWER_DISABLED = 0,
+ /*!
+ * Low Power Mode is controlled by STANDBY pin and/or LVS pin
+ */
+ LOW_POWER_CTRL_BY_PIN,
+ /*!
+ * Set Low Power mode no matter of hardware pins
+ */
+ LOW_POWER_EN,
+ /*!
+ * Set Low Power mode and control by STANDBY
+ */
+ LOW_POWER_AND_LOW_POWER_CTRL_BY_PIN,
+} t_regulator_lp_mode;
+
+/*!
+ * @enum t_switcher_dvs_speed
+ * @brief DVS speed setting
+ */
+typedef enum {
+ /*!
+ * Transition speed is dictated by the current
+ * limit and input -output conditions
+ */
+ DICTATED = 0,
+ /*!
+ * 25mV step each 4us
+ */
+ DVS_4US,
+ /*!
+ * 25mV step each 8us
+ */
+ DVS_8US,
+ /*!
+ * 25mV step each 16us
+ */
+ DVS_16US,
+} t_switcher_dvs_speed;
+
+/*!
+ * @struct t_regulator_config
+ * @brief regulator configuration.
+ *
+ */
+
+typedef struct {
+ /*!
+ * Switch mode regulator operation mode. This field only applies to
+ * switch mode regulators.
+ */
+ t_regulator_sw_mode mode;
+ /*!
+ * Switch mode stby regulator operation mode. This field only applies
+ * to switch mode regulators.
+ */
+ t_regulator_stby_mode stby_mode;
+ /*!
+ * Regulator output voltage.
+ */
+ t_regulator_voltage voltage;
+ /*!
+ * Regulator output voltage in LVS mode.
+ */
+ t_regulator_voltage voltage_lvs;
+ /*!
+ * Regulator output voltage in standby mode.
+ */
+ t_regulator_voltage voltage_stby;
+ /*!
+ * Regulator low power mode.
+ */
+ t_regulator_lp_mode lp_mode;
+ /*!
+ * Switcher dvs speed
+ */
+ t_switcher_dvs_speed dvs_speed;
+ /*!
+ * Switcher panic mode
+ */
+ bool panic_mode;
+ /*!
+ * Switcher softstart
+ */
+ bool softstart;
+ /*!
+ * PLL Multiplication factor
+ */
+ t_switcher_factor factor;
+} t_regulator_config;
+
+/*!
+ * @struct t_regulator_cfg_param
+ * @brief regulator configuration structure for IOCTL.
+ *
+ */
+typedef struct {
+ /*!
+ * Regulator.
+ */
+ t_pmic_regulator regulator;
+ /*!
+ * Regulator configuration.
+ */
+ t_regulator_config cfg;
+} t_regulator_cfg_param;
+
+/*!
+ * This struct list all state reads in Power Up Sense
+ */
+struct t_p_up_sense {
+ /*!
+ * power up sense ictest
+ */
+ bool state_ictest;
+ /*!
+ * power up sense clksel
+ */
+ bool state_clksel;
+ /*!
+ * power up mode supply 1
+ */
+ bool state_pums1;
+ /*!
+ * power up mode supply 2
+ */
+ bool state_pums2;
+ /*!
+ * power up mode supply 3
+ */
+ bool state_pums3;
+ /*!
+ * power up sense charge mode 0
+ */
+ bool state_chrgmode0;
+ /*!
+ * power up sense charge mode 1
+ */
+ bool state_chrgmode1;
+ /*!
+ * power up sense USB mode
+ */
+ bool state_umod;
+ /*!
+ * power up sense boot mode enable for USB/RS232
+ */
+ bool state_usben;
+ /*!
+ * power up sense switcher 1a1b joined
+ */
+ bool state_sw_1a1b_joined;
+ /*!
+ * power up sense switcher 1a1b joined
+ */
+ bool state_sw_2a2b_joined;
+};
+
+/*!
+ * This enumeration define all On_OFF button
+ */
+typedef enum {
+ /*!
+ * ON1B
+ */
+ BT_ON1B = 0,
+ /*!
+ * ON2B
+ */
+ BT_ON2B,
+ /*!
+ * ON3B
+ */
+ BT_ON3B,
+} t_button;
+
+#ifdef __KERNEL__
+/* EXPORTED FUNCTIONS */
+
+/*!
+ * This function sets user power off in power control register and thus powers
+ * off the phone.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+void pmic_power_off(void);
+
+/*!
+ * This function sets the power control configuration.
+ *
+ * @param pc_config power control configuration.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_set_pc_config(t_pc_config * pc_config);
+
+/*!
+ * This function retrives the power control configuration.
+ *
+ * @param pc_config pointer to power control configuration.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_get_pc_config(t_pc_config * pc_config);
+
+/*!
+ * This function turns on a regulator.
+ *
+ * @param regulator The regulator to be turned on.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_regulator_on(t_pmic_regulator regulator);
+
+/*!
+ * This function turns off a regulator.
+ *
+ * @param regulator The regulator to be turned off.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_regulator_off(t_pmic_regulator regulator);
+
+/*!
+ * This function sets the regulator output voltage.
+ *
+ * @param regulator The regulator to be turned off.
+ * @param voltage The regulator output voltage.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_regulator_set_voltage(t_pmic_regulator regulator,
+ t_regulator_voltage voltage);
+
+/*!
+ * This function retrieves the regulator output voltage.
+ *
+ * @param regulator The regulator to be turned off.
+ * @param voltage Pointer to regulator output voltage.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_regulator_get_voltage(t_pmic_regulator regulator,
+ t_regulator_voltage * voltage);
+
+/*!
+ * This function sets the DVS voltage
+ *
+ * @param regulator The regulator to be configured.
+ * @param dvs The switch Dynamic Voltage Scaling
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_switcher_set_dvs(t_pmic_regulator regulator,
+ t_regulator_voltage dvs);
+
+/*!
+ * This function gets the DVS voltage
+ *
+ * @param regulator The regulator to be handled.
+ * @param dvs The switch Dynamic Voltage Scaling
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_switcher_get_dvs(t_pmic_regulator regulator,
+ t_regulator_voltage * dvs);
+
+/*!
+ * This function sets the standby voltage
+ *
+ * @param regulator The regulator to be configured.
+ * @param stby The switch standby voltage
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_switcher_set_stby(t_pmic_regulator regulator,
+ t_regulator_voltage stby);
+
+/*!
+ * This function gets the standby voltage
+ *
+ * @param regulator The regulator to be handled.
+ * @param stby The switch standby voltage
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_switcher_get_stby(t_pmic_regulator regulator,
+ t_regulator_voltage * stby);
+
+/*!
+ * This function sets the switchers mode.
+ *
+ * @param regulator The regulator to be configured.
+ * @param mode The switcher mode
+ * @param stby Switch between main and standby.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_switcher_set_mode(t_pmic_regulator regulator,
+ t_regulator_sw_mode mode, bool stby);
+
+/*!
+ * This function gets the switchers mode.
+ *
+ * @param regulator The regulator to be handled.
+ * @param mode The switcher mode.
+ * @param stby Switch between main and standby.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_switcher_get_mode(t_pmic_regulator regulator,
+ t_regulator_sw_mode * mode, bool stby);
+
+/*!
+ * This function sets the switch dvs speed
+ *
+ * @param regulator The regulator to be configured.
+ * @param speed The dvs speed.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_switcher_set_dvs_speed(t_pmic_regulator regulator,
+ t_switcher_dvs_speed speed);
+
+/*!
+ * This function gets the switch dvs speed
+ *
+ * @param regulator The regulator to be handled.
+ * @param speed The dvs speed.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_switcher_get_dvs_speed(t_pmic_regulator regulator,
+ t_switcher_dvs_speed * speed);
+
+/*!
+ * This function sets the switch panic mode
+ *
+ * @param regulator The regulator to be configured.
+ * @param panic_mode Enable or disable panic mode
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_switcher_set_panic_mode(t_pmic_regulator regulator,
+ bool panic_mode);
+
+/*!
+ * This function gets the switch panic mode
+ *
+ * @param regulator The regulator to be handled
+ * @param panic_mode Enable or disable panic mode
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_switcher_get_panic_mode(t_pmic_regulator regulator,
+ bool * panic_mode);
+
+/*!
+ * This function sets the switch softstart mode
+ *
+ * @param regulator The regulator to be configured.
+ * @param softstart Enable or disable softstart.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_switcher_set_softstart(t_pmic_regulator regulator,
+ bool softstart);
+
+/*!
+ * This function gets the switch softstart mode
+ *
+ * @param regulator The regulator to be handled
+ * @param softstart Enable or disable softstart.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_switcher_get_softstart(t_pmic_regulator regulator,
+ bool * softstart);
+
+/*!
+ * This function sets the PLL multiplication factor
+ *
+ * @param regulator The regulator to be configured.
+ * @param factor The multiplication factor.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_switcher_set_factor(t_pmic_regulator regulator,
+ t_switcher_factor factor);
+
+/*!
+ * This function gets the PLL multiplication factor
+ *
+ * @param regulator The regulator to be handled
+ * @param factor The multiplication factor.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_switcher_get_factor(t_pmic_regulator regulator,
+ t_switcher_factor * factor);
+
+/*!
+ * This function enables or disables low power mode.
+ *
+ * @param regulator The regulator to be configured.
+ * @param mode Select nominal or low power mode.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_regulator_set_lp_mode(t_pmic_regulator regulator,
+ t_regulator_lp_mode lp_mode);
+
+/*!
+ * This function gets low power mode.
+ *
+ * @param regulator The regulator to be handled
+ * @param mode Select nominal or low power mode.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_regulator_get_lp_mode(t_pmic_regulator regulator,
+ t_regulator_lp_mode * lp_mode);
+
+/*!
+ * This function sets the regulator configuration.
+ *
+ * @param regulator The regulator to be turned off.
+ * @param config The regulator output configuration.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_regulator_set_config(t_pmic_regulator regulator,
+ t_regulator_config * config);
+
+/*!
+ * This function retrieves the regulator output configuration.
+ *
+ * @param regulator The regulator to be turned off.
+ * @param config Pointer to regulator configuration.
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_regulator_get_config(t_pmic_regulator regulator,
+ t_regulator_config * config);
+
+/*!
+ * This function enables automatically VBKUP2 in the memory hold modes.
+ *
+ * @param en if true, enable VBKUP2AUTOMH
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_vbkup2_auto_en(bool en);
+
+/*!
+ * This function gets state of automatically VBKUP2.
+ *
+ * @param en if true, VBKUP2AUTOMH is enabled
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_get_vbkup2_auto_state(bool * en);
+
+/*!
+ * This function enables battery detect function.
+ *
+ * @param en if true, enable BATTDETEN
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_bat_det_en(bool en);
+
+/*!
+ * This function gets state of battery detect function.
+ *
+ * @param en if true, BATTDETEN is enabled
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_get_bat_det_state(bool * en);
+
+/*!
+ * This function enables control of VVIB by VIBEN pin.
+ *
+ * @param en if true, enable VIBPINCTRL
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_vib_pin_en(bool en);
+
+/*!
+ * This function gets state of control of VVIB by VIBEN pin.
+ * @param en if true, VIBPINCTRL is enabled
+ *
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_gets_vib_pin_state(bool * en);
+
+/*!
+ * This function returns power up sense value
+ *
+ * @param p_up_sense value of power up sense
+ * @return This function returns PMIC_SUCCESS if successful.
+ */
+PMIC_STATUS pmic_power_get_power_mode_sense(struct t_p_up_sense *p_up_sense);
+
+/*!
+ * This function configures the Regen assignment for all regulator
+ *
+ * @param regulator type of regulator
+ * @param en_dis if true, the regulator is enabled by regen.
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_power_set_regen_assig(t_pmic_regulator regulator, bool en_dis);
+
+/*!
+ * This function gets the Regen assignment for all regulator
+ *
+ * @param regulator type of regulator
+ * @param en_dis return value, if true :
+ * the regulator is enabled by regen.
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_power_get_regen_assig(t_pmic_regulator regu, bool * en_dis);
+
+/*!
+ * This function sets the Regen polarity.
+ *
+ * @param en_dis If true regen is inverted.
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_power_set_regen_inv(bool en_dis);
+
+/*!
+ * This function gets the Regen polarity.
+ *
+ * @param en_dis If true regen is inverted.
+ *
+ * @return This function returns 0 if successful.
+ */
+
+PMIC_STATUS pmic_power_get_regen_inv(bool * en_dis);
+
+/*!
+ * This function enables esim control voltage.
+ *
+ * @param vesim if true, enable VESIMESIMEN
+ * @param vmmc1 if true, enable VMMC1ESIMEN
+ * @param vmmc2 if true, enable VMMC2ESIMEN
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_power_esim_v_en(bool vesim, bool vmmc1, bool vmmc2);
+
+/*!
+ * This function gets esim control voltage values.
+ *
+ * @param vesim if true, enable VESIMESIMEN
+ * @param vmmc1 if true, enable VMMC1ESIMEN
+ * @param vmmc2 if true, enable VMMC2ESIMEN
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_power_gets_esim_v_state(bool * vesim,
+ bool * vmmc1, bool * vmmc2);
+
+/*!
+ * This function enables auto reset after a system reset.
+ *
+ * @param en if true, the auto reset is enabled
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_power_set_auto_reset_en(bool en);
+
+/*!
+ * This function gets auto reset configuration.
+ *
+ * @param en if true, the auto reset is enabled
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_power_get_auto_reset_en(bool * en);
+
+/*!
+ * This function configures a system reset on a button.
+ *
+ * @param bt type of button.
+ * @param sys_rst if true, enable the system reset on this button
+ * @param deb_time sets the debounce time on this button pin
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_power_set_conf_button(t_button bt, bool sys_rst, int deb_time);
+
+/*!
+ * This function gets configuration of a button.
+ *
+ * @param bt type of button.
+ * @param sys_rst if true, the system reset is enabled on this button
+ * @param deb_time gets the debounce time on this button pin
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_power_get_conf_button(t_button bt,
+ bool * sys_rst, int *deb_time);
+
+/*!
+ * This function is used to subscribe on power event IT.
+ *
+ * @param event type of event.
+ * @param callback event callback function.
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_power_event_sub(t_pwr_int event, void *callback);
+
+/*!
+ * This function is used to un subscribe on power event IT.
+ *
+ * @param event type of event.
+ * @param callback event callback function.
+ *
+ * @return This function returns 0 if successful.
+ */
+PMIC_STATUS pmic_power_event_unsub(t_pwr_int event, void *callback);
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_ARCH_MXC_PMIC_POWER_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/pmic_rtc.h b/arch/arm/plat-mxc/include/mach/pmic_rtc.h
new file mode 100644
index 000000000000..d75c1eec4cb7
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/pmic_rtc.h
@@ -0,0 +1,153 @@
+/*
+ * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_PMIC_RTC_H__
+#define __ASM_ARCH_MXC_PMIC_RTC_H__
+
+/*!
+ * @defgroup PMIC_RTC PMIC RTC Driver
+ * @ingroup PMIC_DRVRS
+ */
+
+/*!
+ * @file arch-mxc/pmic_rtc.h
+ * @brief This is the header of PMIC RTC driver.
+ *
+ * @ingroup PMIC_RTC
+ */
+
+/*
+ * Includes
+ */
+#include <asm/ioctl.h>
+#include <mach/pmic_status.h>
+#include <mach/pmic_external.h>
+
+#define PMIC_RTC_SET_TIME _IOWR('p',0xd1, int)
+#define PMIC_RTC_GET_TIME _IOWR('p',0xd2, int)
+#define PMIC_RTC_SET_ALARM _IOWR('p',0xd3, int)
+#define PMIC_RTC_GET_ALARM _IOWR('p',0xd4, int)
+#define PMIC_RTC_WAIT_ALARM _IOWR('p',0xd5, int)
+#define PMIC_RTC_ALARM_REGISTER _IOWR('p',0xd6, int)
+#define PMIC_RTC_ALARM_UNREGISTER _IOWR('p',0xd7, int)
+
+/*!
+ * This enumeration define all RTC interrupt
+ */
+typedef enum {
+ /*!
+ * Time of day alarm
+ */
+ RTC_IT_ALARM,
+ /*!
+ * 1 Hz timetick
+ */
+ RTC_IT_1HZ,
+ /*!
+ * RTC reset occurred
+ */
+ RTC_IT_RST,
+} t_rtc_int;
+
+/*
+ * RTC PMIC API
+ */
+
+/* EXPORTED FUNCTIONS */
+#ifdef __KERNEL__
+
+/*!
+ * This function set the real time clock of PMIC
+ *
+ * @param pmic_time value of date and time
+ *
+ * @return This function returns PMIC_STATUS if successful.
+ */
+PMIC_STATUS pmic_rtc_set_time(struct timeval *pmic_time);
+
+/*!
+ * This function get the real time clock of PMIC
+ *
+ * @param pmic_time return value of date and time
+ *
+ * @return This function returns PMIC_STATUS if successful.
+ */
+PMIC_STATUS pmic_rtc_get_time(struct timeval *pmic_time);
+
+/*!
+ * This function set the real time clock alarm of PMIC
+ *
+ * @param pmic_time value of date and time
+ *
+ * @return This function returns PMIC_STATUS if successful.
+ */
+PMIC_STATUS pmic_rtc_set_time_alarm(struct timeval *pmic_time);
+
+/*!
+ * This function get the real time clock alarm of PMIC
+ *
+ * @param pmic_time return value of date and time
+ *
+ * @return This function returns PMIC_STATUS if successful.
+ */
+PMIC_STATUS pmic_rtc_get_time_alarm(struct timeval *pmic_time);
+
+/*!
+ * This function wait the Alarm event
+ *
+ * @return This function returns PMIC_STATUS if successful.
+ */
+PMIC_STATUS pmic_rtc_wait_alarm(void);
+
+/*!
+ * This function is used to un/subscribe on RTC event IT.
+ *
+ * @param event type of event.
+ * @param callback event callback function.
+ * @param sub define if Un/subscribe event.
+ *
+ * @return This function returns PMIC_STATUS if successful.
+ */
+PMIC_STATUS pmic_rtc_event(t_rtc_int event, void *callback, bool sub);
+
+/*!
+ * This function is used to subscribe on RTC event IT.
+ *
+ * @param event type of event.
+ * @param callback event callback function.
+ *
+ * @return This function returns PMIC_STATUS if successful.
+ */
+PMIC_STATUS pmic_rtc_event_sub(t_rtc_int event, void *callback);
+
+/*!
+ * This function is used to un-subscribe on RTC event IT.
+ *
+ * @param event type of event.
+ * @param callback event callback function.
+ *
+ * @return This function returns PMIC_STATUS if successful.
+ */
+PMIC_STATUS pmic_rtc_event_unsub(t_rtc_int event, void *callback);
+
+/*!
+ * This function is used to tell if PMIC RTC has been correctly loaded.
+ *
+ * @return This function returns 1 if RTC was successfully loaded
+ * 0 otherwise.
+ */
+int pmic_rtc_loaded(void);
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_ARCH_MXC_PMIC_RTC_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/pmic_status.h b/arch/arm/plat-mxc/include/mach/pmic_status.h
new file mode 100644
index 000000000000..a9287292e7db
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/pmic_status.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU Lesser General
+ * Public License. You may obtain a copy of the GNU Lesser General
+ * Public License Version 2.1 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/lgpl-license.html
+ * http://www.gnu.org/copyleft/lgpl.html
+ */
+#ifndef __ASM_ARCH_MXC_PMIC_STATUS_H__
+#define __ASM_ARCH_MXC_PMIC_STATUS_H__
+#include <asm-generic/errno-base.h>
+#ifdef __KERNEL__
+#include <asm/uaccess.h> /* copy_{from,to}_user() */
+#endif
+/*!
+ * @file arch-mxc/pmic_status.h
+ * @brief PMIC APIs return code definition.
+ *
+ * @ingroup PMIC_CORE
+ */
+
+/*!
+ * @enum PMIC_STATUS
+ * @brief Define return values for all PMIC APIs.
+ *
+ * These return values are used by all of the PMIC APIs.
+ *
+ * @ingroup PMIC
+ */
+typedef enum {
+ PMIC_SUCCESS = 0, /*!< The requested operation was successfully
+ completed. */
+ PMIC_ERROR = -1, /*!< The requested operation could not be completed
+ due to an error. */
+ PMIC_PARAMETER_ERROR = -2, /*!< The requested operation failed because
+ one or more of the parameters was
+ invalid. */
+ PMIC_NOT_SUPPORTED = -3, /*!< The requested operation could not be
+ completed because the PMIC hardware
+ does not support it. */
+ PMIC_SYSTEM_ERROR_EINTR = -EINTR,
+
+ PMIC_MALLOC_ERROR = -5, /*!< Error in malloc function */
+ PMIC_UNSUBSCRIBE_ERROR = -6, /*!< Error in un-subscribe event */
+ PMIC_EVENT_NOT_SUBSCRIBED = -7, /*!< Event occur and not subscribed */
+ PMIC_EVENT_CALL_BACK = -8, /*!< Error - bad call back */
+ PMIC_CLIENT_NBOVERFLOW = -9, /*!< The requested operation could not be
+ completed because there are too many
+ PMIC client requests */
+} PMIC_STATUS;
+
+/*
+ * Bitfield macros that use rely on bitfield width/shift information.
+ */
+#define BITFMASK(field) (((1U << (field ## _WID)) - 1) << (field ## _LSH))
+#define BITFVAL(field, val) ((val) << (field ## _LSH))
+#define BITFEXT(var, bit) ((var & BITFMASK(bit)) >> (bit ## _LSH))
+
+/*
+ * Macros implementing error handling
+ */
+#define CHECK_ERROR(a) \
+do { \
+ int ret = (a); \
+ if (ret != PMIC_SUCCESS) \
+ return ret; \
+} while (0)
+
+#define CHECK_ERROR_KFREE(func, freeptrs) \
+do { \
+ int ret = (func); \
+ if (ret != PMIC_SUCCESS) { \
+ freeptrs; \
+ return ret; \
+ } \
+} while (0);
+
+#endif /* __ASM_ARCH_MXC_PMIC_STATUS_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/sdma.h b/arch/arm/plat-mxc/include/mach/sdma.h
new file mode 100644
index 000000000000..453cf6585043
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/sdma.h
@@ -0,0 +1,505 @@
+
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_SDMA_H__
+#define __ASM_ARCH_MXC_SDMA_H__
+
+/*!
+ * @defgroup SDMA Smart Direct Memory Access (SDMA) Driver
+ */
+
+/*!
+ * @file arch-mxc/sdma.h
+ *
+ * @brief This file contains the SDMA API declarations.
+ *
+ * SDMA is responsible on moving data between peripherals and memories (MCU, EMI and DSP).
+ *
+ * @ingroup SDMA
+ */
+
+#include <linux/interrupt.h>
+#include <asm/dma.h>
+#include <stdarg.h>
+
+#include <mach/hardware.h>
+
+/*!
+ * This defines maximum DMA address
+ */
+#define MAX_DMA_ADDRESS 0xffffffff
+
+/*!
+ * This defines maximum number of DMA channels
+ */
+#ifdef CONFIG_MXC_SDMA_API
+#define MAX_DMA_CHANNELS 32
+#define MAX_BD_NUMBER 16
+#define MXC_SDMA_DEFAULT_PRIORITY 1
+#define MXC_SDMA_MIN_PRIORITY 1
+#define MXC_SDMA_MAX_PRIORITY 7
+#else
+#define MAX_DMA_CHANNELS 0
+#endif
+
+#define MXC_FIFO_MEM_DEST_FIXED 0x1
+#define MXC_FIFO_MEM_SRC_FIXED 0x2
+/*!
+ * This enumerates transfer types
+ */
+typedef enum {
+ emi_2_per = 0, /*!< EMI memory to peripheral */
+ emi_2_int, /*!< EMI memory to internal RAM */
+ emi_2_emi, /*!< EMI memory to EMI memory */
+ emi_2_dsp, /*!< EMI memory to DSP memory */
+ per_2_int, /*!< Peripheral to internal RAM */
+ per_2_emi, /*!< Peripheral to internal EMI memory */
+ per_2_dsp, /*!< Peripheral to DSP memory */
+ per_2_per, /*!< Peripheral to Peripheral */
+ int_2_per, /*!< Internal RAM to peripheral */
+ int_2_int, /*!< Internal RAM to Internal RAM */
+ int_2_emi, /*!< Internal RAM to EMI memory */
+ int_2_dsp, /*!< Internal RAM to DSP memory */
+ dsp_2_per, /*!< DSP memory to peripheral */
+ dsp_2_int, /*!< DSP memory to internal RAM */
+ dsp_2_emi, /*!< DSP memory to EMI memory */
+ dsp_2_dsp, /*!< DSP memory to DSP memory */
+ emi_2_dsp_loop, /*!< EMI memory to DSP memory loopback */
+ dsp_2_emi_loop, /*!< DSP memory to EMI memory loopback */
+ dvfs_pll, /*!< DVFS script with PLL change */
+ dvfs_pdr /*!< DVFS script without PLL change */
+} sdma_transferT;
+
+/*!
+ * This enumerates peripheral types
+ */
+typedef enum {
+ SSI, /*!< MCU domain SSI */
+ SSI_SP, /*!< Shared SSI */
+ MMC, /*!< MMC */
+ SDHC, /*!< SDHC */
+ UART, /*!< MCU domain UART */
+ UART_SP, /*!< Shared UART */
+ FIRI, /*!< FIRI */
+ CSPI, /*!< MCU domain CSPI */
+ CSPI_SP, /*!< Shared CSPI */
+ SIM, /*!< SIM */
+ ATA, /*!< ATA */
+ CCM, /*!< CCM */
+ EXT, /*!< External peripheral */
+ MSHC, /*!< Memory Stick Host Controller */
+ MSHC_SP, /*!< Shared Memory Stick Host Controller */
+ DSP, /*!< DSP */
+ MEMORY, /*!< Memory */
+ FIFO_MEMORY, /*!< FIFO type Memory */
+ SPDIF, /*!< SPDIF */
+ IPU_MEMORY, /*!< IPU Memory */
+ ASRC, /*!< ASRC */
+ ESAI, /*!< ESAI */
+} sdma_periphT;
+
+#ifndef TRANSFER_32BIT
+/*!
+ * This defines SDMA access data size
+ */
+#define TRANSFER_32BIT 0x00
+#define TRANSFER_8BIT 0x01
+#define TRANSFER_16BIT 0x02
+#define TRANSFER_24BIT 0x03
+
+#endif
+
+/*!
+ * This defines maximum device name length passed during mxc_request_dma().
+ */
+#define MAX_DEVNAME_LENGTH 32
+
+/*!
+ * This defines SDMA interrupt callback function prototype.
+ */
+typedef void (*dma_callback_t) (void *arg);
+
+/*!
+ * Structure containing sdma channel parameters.
+ */
+typedef struct {
+ __u32 watermark_level; /*!< Lower/upper threshold that
+ * triggers SDMA event
+ */
+ __u32 per_address; /*!< Peripheral source/destination
+ * physical address
+ */
+ sdma_periphT peripheral_type; /*!< Peripheral type */
+ sdma_transferT transfer_type; /*!< Transfer type */
+ int event_id; /*!< Event number,
+ * needed by all channels
+ * that started by peripherals dma
+ * request (per_2_*,*_2_per)
+ * Not used for memory and DSP
+ * transfers.
+ */
+ int event_id2; /*!< Second event number,
+ * used in ATA scripts only.
+ */
+ int bd_number; /*!< Buffer descriptors number.
+ * If not set, single buffer
+ * descriptor will be used.
+ */
+ dma_callback_t callback; /*! callback function */
+ void *arg; /*! callback argument */
+ unsigned long word_size:8; /*!< SDMA data access word size */
+} dma_channel_params;
+
+/*!
+ * Structure containing sdma request parameters.
+ */
+typedef struct {
+ /*! physical source memory address */
+ __u8 *sourceAddr;
+ /*! physical destination memory address */
+ __u8 *destAddr;
+ /*! amount of data to transfer,
+ * updated during mxc_dma_get_config
+ */
+ __u16 count;
+ /*!< DONE bit of the buffer descriptor,
+ * updated during mxc_dma_get_config
+ * 0 - means the BD is done and closed by SDMA
+ * 1 - means the BD is still being processed by SDMA
+ */
+ int bd_done;
+ /*!< CONT bit of the buffer descriptor,
+ * set it if full multi-buffer descriptor mechanism
+ * required.
+ */
+ int bd_cont;
+ /*!< ERROR bit of the buffer descriptor,
+ * updated during mxc_dma_get_config.
+ * If it is set - there was an error during BD processing.
+ */
+ int bd_error;
+} dma_request_t;
+
+/*!
+ * Structure containing sdma request parameters.
+ */
+typedef struct {
+ /*! address of ap_2_ap script */
+ int mxc_sdma_ap_2_ap_addr;
+ /*! address of ap_2_bp script */
+ int mxc_sdma_ap_2_bp_addr;
+ /*! address of ap_2_ap_fixed script */
+ int mxc_sdma_ap_2_ap_fixed_addr;
+ /*! address of bp_2_ap script */
+ int mxc_sdma_bp_2_ap_addr;
+ /*! address of loopback_on_dsp_side script */
+ int mxc_sdma_loopback_on_dsp_side_addr;
+ /*! address of mcu_interrupt_only script */
+ int mxc_sdma_mcu_interrupt_only_addr;
+
+ /*! address of firi_2_per script */
+ int mxc_sdma_firi_2_per_addr;
+ /*! address of firi_2_mcu script */
+ int mxc_sdma_firi_2_mcu_addr;
+ /*! address of per_2_firi script */
+ int mxc_sdma_per_2_firi_addr;
+ /*! address of mcu_2_firi script */
+ int mxc_sdma_mcu_2_firi_addr;
+
+ /*! address of uart_2_per script */
+ int mxc_sdma_uart_2_per_addr;
+ /*! address of uart_2_mcu script */
+ int mxc_sdma_uart_2_mcu_addr;
+ /*! address of per_2_app script */
+ int mxc_sdma_per_2_app_addr;
+ /*! address of mcu_2_app script */
+ int mxc_sdma_mcu_2_app_addr;
+ /*! address of per_2_per script */
+ int mxc_sdma_per_2_per_addr;
+
+ /*! address of uartsh_2_per script */
+ int mxc_sdma_uartsh_2_per_addr;
+ /*! address of uartsh_2_mcu script */
+ int mxc_sdma_uartsh_2_mcu_addr;
+ /*! address of per_2_shp script */
+ int mxc_sdma_per_2_shp_addr;
+ /*! address of mcu_2_shp script */
+ int mxc_sdma_mcu_2_shp_addr;
+
+ /*! address of ata_2_mcu script */
+ int mxc_sdma_ata_2_mcu_addr;
+ /*! address of mcu_2_ata script */
+ int mxc_sdma_mcu_2_ata_addr;
+
+ /*! address of app_2_per script */
+ int mxc_sdma_app_2_per_addr;
+ /*! address of app_2_mcu script */
+ int mxc_sdma_app_2_mcu_addr;
+ /*! address of shp_2_per script */
+ int mxc_sdma_shp_2_per_addr;
+ /*! address of shp_2_mcu script */
+ int mxc_sdma_shp_2_mcu_addr;
+
+ /*! address of mshc_2_mcu script */
+ int mxc_sdma_mshc_2_mcu_addr;
+ /*! address of mcu_2_mshc script */
+ int mxc_sdma_mcu_2_mshc_addr;
+
+ /*! address of spdif_2_mcu script */
+ int mxc_sdma_spdif_2_mcu_addr;
+ /*! address of mcu_2_spdif script */
+ int mxc_sdma_mcu_2_spdif_addr;
+
+ /*! address of asrc_2_mcu script */
+ int mxc_sdma_asrc_2_mcu_addr;
+
+ /*! address of ext_mem_2_ipu script */
+ int mxc_sdma_ext_mem_2_ipu_addr;
+
+ /*! address of descrambler script */
+ int mxc_sdma_descrambler_addr;
+
+ /*! address of dptc_dvfs script */
+ int mxc_sdma_dptc_dvfs_addr;
+
+ int mxc_sdma_utra_addr;
+
+ /*! address where ram code starts */
+ int mxc_sdma_ram_code_start_addr;
+ /*! size of the ram code */
+ int mxc_sdma_ram_code_size;
+ /*! RAM image address */
+ unsigned short *mxc_sdma_start_addr;
+} sdma_script_start_addrs;
+
+/*! Structure to store the initialized dma_channel parameters */
+typedef struct mxc_sdma_channel_params {
+ /*! Channel params */
+ dma_channel_params chnl_params;
+ /*! Channel type (static channel number or dynamic channel) */
+ unsigned int channel_num;
+ /*! Channel priority [0x1(lowest) - 0x7(highest)] */
+ unsigned int chnl_priority;
+} mxc_sdma_channel_params_t;
+
+/*! Private SDMA data structure */
+typedef struct mxc_dma_channel_private {
+ /*! ID of the buffer that was processed */
+ unsigned int buf_tail;
+ /*! Tasklet for the channel */
+ struct tasklet_struct chnl_tasklet;
+ /*! Flag indicates if interrupt is required after every BD transfer */
+ int intr_after_every_bd;
+} mxc_dma_channel_private_t;
+
+/*!
+ * Setup channel according to parameters.
+ * Must be called once after mxc_request_dma()
+ *
+ * @param channel channel number
+ * @param p channel parameters pointer
+ * @return 0 on success, error code on fail
+ */
+int mxc_dma_setup_channel(int channel, dma_channel_params * p);
+
+/*!
+ * Setup the channel priority. This can be used to change the default priority
+ * for the channel.
+ *
+ * @param channel channel number
+ * @param priority priority to be set for the channel
+ *
+ * @return 0 on success, error code on failure
+ */
+int mxc_dma_set_channel_priority(unsigned int channel, unsigned int priority);
+
+/*!
+ * Allocates dma channel.
+ * If channel's value is 0, then the function allocates a free channel
+ * dynamically and sets its value to channel.
+ * Else allocates requested channel if it is free.
+ * If the channel is busy or no free channels (in dynamic allocation) -EBUSY returned.
+ *
+ * @param channel pointer to channel number
+ * @param devicename device name
+ * @return 0 on success, error code on fail
+ */
+int mxc_request_dma(int *channel, const char *devicename);
+
+/*!
+ * Configures request parameters. Can be called multiple times after
+ * mxc_request_dma() and mxc_dma_setup_channel().
+ *
+ *
+ * @param channel channel number
+ * @param p request parameters pointer
+ * @param bd_index index of buffer descriptor to set
+ * @return 0 on success, error code on fail
+ */
+/* int mxc_dma_set_config(int channel, dma_request_t *p, int bd_index); */
+int mxc_dma_set_config(int channel, dma_request_t * p, int bd_index);
+
+/*!
+ * Returns request parameters.
+ *
+ * @param channel channel number
+ * @param p request parameters pointer
+ * @param bd_index index of buffer descriptor to get
+ * @return 0 on success, error code on fail
+ */
+/* int mxc_dma_get_config(int channel, dma_request_t *p, int bd_index); */
+int mxc_dma_get_config(int channel, dma_request_t * p, int bd_index);
+
+/*!
+ * This function is used by MXC IPC's write_ex2. It passes the a pointer to the
+ * data control structure to iapi_write_ipcv2()
+ *
+ * @param channel SDMA channel number
+ * @param ctrl_ptr Data Control structure pointer
+ */
+int mxc_sdma_write_ipcv2(int channel, void *ctrl_ptr);
+
+/*!
+ * This function is used by MXC IPC's read_ex2. It passes the a pointer to the
+ * data control structure to iapi_read_ipcv2()
+ *
+ * @param channel SDMA channel number
+ * @param ctrl_ptr Data Control structure pointer
+ */
+int mxc_sdma_read_ipcv2(int channel, void *ctrl_ptr);
+
+/*!
+ * Starts dma channel.
+ *
+ * @param channel channel number
+ */
+int mxc_dma_start(int channel);
+
+/*!
+ * Stops dma channel.
+ *
+ * @param channel channel number
+ */
+int mxc_dma_stop(int channel);
+
+/*!
+ * Frees dma channel.
+ *
+ * @param channel channel number
+ */
+void mxc_free_dma(int channel);
+
+/*!
+ * Sets callback function. Used with standard dma api
+ * for supporting interrupts
+ *
+ * @param channel channel number
+ * @param callback callback function pointer
+ * @param arg argument for callback function
+ */
+void mxc_dma_set_callback(int channel, dma_callback_t callback, void *arg);
+
+/*!
+ * Allocates uncachable buffer. Uses hash table.
+ *
+ * @param size size of allocated buffer
+ * @return pointer to buffer
+ */
+void *sdma_malloc(size_t size);
+
+#ifdef CONFIG_SDMA_IRAM
+/*!
+ * Allocates uncachable buffer from IRAM..
+ *
+ * @param size size of allocated buffer
+ * @return pointer to buffer
+ */
+void *sdma_iram_malloc(size_t size);
+#endif /*CONFIG_SDMA_IRAM */
+
+/*!
+ * Frees uncachable buffer. Uses hash table.
+ */
+void sdma_free(void *buf);
+
+/*!
+ * Converts virtual to physical address. Uses hash table.
+ *
+ * @param buf virtual address pointer
+ * @return physical address value
+ */
+unsigned long sdma_virt_to_phys(void *buf);
+
+/*!
+ * Converts physical to virtual address. Uses hash table.
+ *
+ * @param buf physical address value
+ * @return virtual address pointer
+ */
+void *sdma_phys_to_virt(unsigned long buf);
+
+/*!
+ * Configures the BD_INTR bit on a buffer descriptor parameters.
+ *
+ *
+ * @param channel channel number
+ * @param bd_index index of buffer descriptor to set
+ * @param bd_intr flag to set or clear the BD_INTR bit
+ */
+void mxc_dma_set_bd_intr(int channel, int bd_index, int bd_intr);
+
+/*!
+ * Gets the BD_INTR bit on a buffer descriptor.
+ *
+ *
+ * @param channel channel number
+ * @param bd_index index of buffer descriptor to set
+ *
+ * @return returns the BD_INTR bit status
+ */
+int mxc_dma_get_bd_intr(int channel, int bd_index);
+
+/*!
+ * Stop the current transfer
+ *
+ * @param channel channel number
+ * @param buffer_number number of buffers (beginning with 0),
+ * whose done bits should be reset to 0
+ */
+int mxc_dma_reset(int channel, int buffer_number);
+
+/*!
+ * This functions Returns the SDMA paramaters associated for a module
+ *
+ * @param channel_id the ID of the module requesting DMA
+ * @return returns the sdma parameters structure for the device
+ */
+mxc_sdma_channel_params_t *mxc_sdma_get_channel_params(mxc_dma_device_t
+ channel_id);
+
+/*!
+ * This functions marks the SDMA channels that are statically allocated
+ *
+ * @param chnl the channel array used to store channel information
+ */
+void mxc_get_static_channels(mxc_dma_channel_t * chnl);
+
+/*!
+ * Initializes SDMA driver
+ */
+int __init sdma_init(void);
+
+#define DEFAULT_ERR 1
+
+#endif
diff --git a/arch/arm/plat-mxc/include/mach/spba.h b/arch/arm/plat-mxc/include/mach/spba.h
new file mode 100644
index 000000000000..8d018be8a0b7
--- /dev/null
+++ b/arch/arm/plat-mxc/include/mach/spba.h
@@ -0,0 +1,66 @@
+
+/*
+ * Copyright 2004-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @defgroup SPBA Shared Peripheral Bus Arbiter (SPBA)
+ * @ingroup MSL_MX31 MSL_MX35 MSL_MX37 MSL_MX51 MSL_MXC91321
+ */
+
+/*!
+ * @file arch-mxc/spba.h
+ * @brief This file contains the Shared Peripheral Bus Arbiter (spba) API.
+ *
+ * @ingroup SPBA
+ */
+
+#ifndef __ASM_ARCH_MXC_SPBA_H__
+#define __ASM_ARCH_MXC_SPBA_H__
+
+#ifdef __KERNEL__
+
+#define MXC_SPBA_RAR_MASK 0x7
+
+/*!
+ * Defines three SPBA masters: A - ARM, C - SDMA (no master B for MX31)
+ */
+enum spba_masters {
+ SPBA_MASTER_A = 1,
+ SPBA_MASTER_B = 2,
+ SPBA_MASTER_C = 4,
+};
+
+/*!
+ * This function allows the three masters (A, B, C) to take ownership of a
+ * shared peripheral.
+ *
+ * @param mod specified module as defined in \b enum \b #spba_module
+ * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters
+ *
+ * @return 0 if successful; -1 otherwise.
+ */
+int spba_take_ownership(int mod, int master);
+
+/*!
+ * This function releases the ownership for a shared peripheral.
+ *
+ * @param mod specified module as defined in \b enum \b #spba_module
+ * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters
+ *
+ * @return 0 if successful; -1 otherwise.
+ */
+int spba_rel_ownership(int mod, int master);
+
+#endif /* __KERNEL__ */
+
+#endif /* __ASM_ARCH_MXC_SPBA_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/system.h b/arch/arm/plat-mxc/include/mach/system.h
index bbfc37465fc5..c1edb8f2420f 100644
--- 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-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2008 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
@@ -21,14 +21,17 @@
#ifndef __ASM_ARCH_MXC_SYSTEM_H__
#define __ASM_ARCH_MXC_SYSTEM_H__
-static inline void arch_idle(void)
-{
- cpu_do_idle();
-}
+/*!
+ * This function puts the CPU into idle mode. It is called by default_idle()
+ * in process.c file.
+ */
+extern void arch_idle(void);
-static inline void arch_reset(char mode)
-{
- cpu_reset(0);
-}
+/*
+ * This function resets the system. It is called by machine_restart().
+ *
+ * @param mode indicates different kinds of resets
+ */
+extern void arch_reset(char mode);
-#endif /* __ASM_ARCH_MXC_SYSTEM_H__ */
+#endif /* __ASM_ARCH_MXC_SYSTEM_H__ */
diff --git a/arch/arm/plat-mxc/include/mach/uncompress.h b/arch/arm/plat-mxc/include/mach/uncompress.h
index de6fe0365982..8314fafacfd5 100644
--- a/arch/arm/plat-mxc/include/mach/uncompress.h
+++ b/arch/arm/plat-mxc/include/mach/uncompress.h
@@ -27,6 +27,8 @@
#include <mach/hardware.h>
+unsigned int system_rev;
+
#define UART(x) (*(volatile unsigned long *)(serial_port + (x)))
#define USR2 0x98
diff --git a/arch/arm/plat-mxc/io.c b/arch/arm/plat-mxc/io.c
new file mode 100644
index 000000000000..7681ecf8dfb6
--- /dev/null
+++ b/arch/arm/plat-mxc/io.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * mxc custom ioremap implementation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+void *__iomem __mxc_ioremap(unsigned long cookie, size_t size,
+ unsigned int mtype)
+{
+ if (mtype == MT_DEVICE && IS_MEM_DEVICE_NONSHARED(cookie)) {
+ mtype = MT_DEVICE_NONSHARED;
+ }
+ return __arm_ioremap(cookie, size, mtype);
+}
+
+EXPORT_SYMBOL(__mxc_ioremap);
+
+void __mxc_iounmap(void __iomem * addr)
+{
+ extern void __iounmap(volatile void __iomem * addr);
+
+ __iounmap(addr);
+}
+
+EXPORT_SYMBOL(__mxc_iounmap);
diff --git a/arch/arm/plat-mxc/irq.c b/arch/arm/plat-mxc/irq.c
index d862c9e5f8db..70d9ce81b9d6 100644
--- a/arch/arm/plat-mxc/irq.c
+++ b/arch/arm/plat-mxc/irq.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de
*
* This program is free software; you can redistribute it and/or
@@ -19,6 +19,7 @@
#include <linux/irq.h>
#include <linux/io.h>
+#include <linux/sysdev.h>
#include <mach/common.h>
#define AVIC_BASE IO_ADDRESS(AVIC_BASE_ADDR)
@@ -32,8 +33,6 @@
#define AVIC_INTTYPEL (AVIC_BASE + 0x1C) /* int type reg low */
#define AVIC_NIPRIORITY(x) (AVIC_BASE + (0x20 + 4 * (7 - (x)))) /* int priority */
#define AVIC_NIVECSR (AVIC_BASE + 0x40) /* norm int vector/status */
-#define AVIC_FIVECSR (AVIC_BASE + 0x44) /* fast int vector/status */
-#define AVIC_INTSRCH (AVIC_BASE + 0x48) /* int source reg high */
#define AVIC_INTSRCL (AVIC_BASE + 0x4C) /* int source reg low */
#define AVIC_INTFRCH (AVIC_BASE + 0x50) /* int force reg high */
#define AVIC_INTFRCL (AVIC_BASE + 0x54) /* int force reg low */
@@ -42,10 +41,10 @@
#define AVIC_FIPNDH (AVIC_BASE + 0x60) /* fast int pending high */
#define AVIC_FIPNDL (AVIC_BASE + 0x64) /* fast int pending low */
-#define SYSTEM_PREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x20)
-#define SYSTEM_SREV_REG IO_ADDRESS(IIM_BASE_ADDR + 0x24)
-#define IIM_PROD_REV_SH 3
-#define IIM_PROD_REV_LEN 5
+#define IRQ_BIT(irq) (1 << (irq))
+
+static uint32_t saved_wakeup_low, saved_wakeup_high;
+static uint32_t suspend_wakeup_low, suspend_wakeup_high;
#ifdef CONFIG_MXC_IRQ_PRIOR
void imx_irq_set_priority(unsigned char irq, unsigned char prio)
@@ -77,12 +76,121 @@ static void mxc_unmask_irq(unsigned int irq)
__raw_writel(irq, AVIC_INTENNUM);
}
+/*!
+ * Set interrupt number "irq" in the AVIC as a wake-up source.
+ *
+ * @param irq interrupt source number
+ * @param enable enable as wake-up if equal to non-zero
+ * disble as wake-up if equal to zero
+ *
+ * @return This function returns 0 on success.
+ */
+static int mxc_set_wake_irq(unsigned int irq, unsigned int enable)
+{
+ uint32_t *wakeup_intr;
+ uint32_t irq_bit;
+
+ if (irq < 32) {
+ wakeup_intr = &suspend_wakeup_low;
+ irq_bit = IRQ_BIT(irq);
+ } else {
+ wakeup_intr = &suspend_wakeup_high;
+ irq_bit = IRQ_BIT(irq - 32);
+ }
+
+ if (enable) {
+ *wakeup_intr |= irq_bit;
+ } else {
+ *wakeup_intr &= ~irq_bit;
+ }
+
+ return 0;
+}
+
static struct irq_chip mxc_avic_chip = {
.ack = mxc_mask_irq,
.mask = mxc_mask_irq,
.unmask = mxc_unmask_irq,
+ .set_wake = mxc_set_wake_irq,
+};
+
+#ifdef CONFIG_PM
+/*!
+ * This function puts the AVIC in low-power mode/state.
+ * All the interrupts that are enabled are first saved.
+ * Only those interrupts which registers as a wake source by calling
+ * enable_irq_wake are enabled. All other interrupts are disabled.
+ *
+ * @param dev the system device structure used to give information
+ * on AVIC to suspend
+ * @param mesg the power state the device is entering
+ *
+ * @return The function always returns 0.
+ */
+static int mxc_avic_suspend(struct sys_device *dev, pm_message_t mesg)
+{
+ saved_wakeup_high = __raw_readl(AVIC_INTENABLEH);
+ saved_wakeup_low = __raw_readl(AVIC_INTENABLEL);
+
+ __raw_writel(suspend_wakeup_high, AVIC_INTENABLEH);
+ __raw_writel(suspend_wakeup_low, AVIC_INTENABLEL);
+
+ return 0;
+}
+
+/*!
+ * This function brings the AVIC back from low-power state.
+ * All the interrupts enabled before suspension are re-enabled from
+ * the saved information.
+ *
+ * @param dev the system device structure used to give information
+ * on AVIC to resume
+ *
+ * @return The function always returns 0.
+ */
+static int mxc_avic_resume(struct sys_device *dev)
+{
+ __raw_writel(saved_wakeup_high, AVIC_INTENABLEH);
+ __raw_writel(saved_wakeup_low, AVIC_INTENABLEL);
+
+ return 0;
+}
+
+#else
+#define mxc_avic_suspend NULL
+#define mxc_avic_resume NULL
+#endif /* CONFIG_PM */
+/*!
+ * This structure contains pointers to the power management callback functions.
+ */
+static struct sysdev_class mxc_avic_sysclass = {
+ .name = "mxc_irq",
+ .suspend = mxc_avic_suspend,
+ .resume = mxc_avic_resume,
};
+/*!
+ * This structure represents AVIC as a system device.
+ * System devices follow a slightly different driver model.
+ * They don't need to do dynammic driver binding, can't be probed,
+ * and don't reside on any type of peripheral bus.
+ * So, it is represented and treated a little differently.
+ */
+static struct sys_device mxc_avic_device = {
+ .id = 0,
+ .cls = &mxc_avic_sysclass,
+};
+
+/*
+ * This function is used to get the AVIC Lo and Hi interrupts
+ * that are enabled as wake up sources to wake up the core from suspend
+ */
+void mxc_get_wake_irq(u32 * wake_src[])
+{
+ *wake_src[0] = __raw_readl(AVIC_INTENABLEL);
+ *wake_src[1] = __raw_readl(AVIC_INTENABLEH);
+}
+
/*
* This function initializes the AVIC hardware and disables all the
* interrupts. It registers the interrupt enable and disable functions
@@ -91,7 +199,7 @@ static struct irq_chip mxc_avic_chip = {
void __init mxc_init_irq(void)
{
int i;
- u32 reg;
+ static int initialized;
/* put the AVIC into the reset value with
* all interrupts disabled
@@ -106,18 +214,46 @@ void __init mxc_init_irq(void)
/* all IRQ no FIQ */
__raw_writel(0, AVIC_INTTYPEH);
__raw_writel(0, AVIC_INTTYPEL);
- for (i = 0; i < MXC_MAX_INT_LINES; i++) {
- set_irq_chip(i, &mxc_avic_chip);
- set_irq_handler(i, handle_level_irq);
- set_irq_flags(i, IRQF_VALID);
+ if (!initialized) {
+ for (i = 0; i < MXC_MAX_INT_LINES; i++) {
+ set_irq_chip(i, &mxc_avic_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
}
/* Set default priority value (0) for all IRQ's */
for (i = 0; i < 8; i++)
__raw_writel(0, AVIC_NIPRIORITY(i));
- /* init architectures chained interrupt handler */
- mxc_register_gpios();
+ if (MXC_INT_FORCE >= 32)
+ __raw_writel(1 << (MXC_INT_FORCE & 31), AVIC_INTFRCH);
+ else if (MXC_INT_FORCE >= 0)
+ __raw_writel(1 << MXC_INT_FORCE, AVIC_INTFRCL);
+
+ initialized = 1;
printk(KERN_INFO "MXC IRQ initialized\n");
}
+
+/*!
+ * This function registers AVIC hardware as a system device.
+ * System devices will only be suspended with interrupts disabled, and
+ * after all other devices have been suspended. On resume, they will be
+ * resumed before any other devices, and also with interrupts disabled.
+ *
+ * @return This function returns 0 on success.
+ */
+static int __init mxc_avic_sysinit(void)
+{
+ int ret = 0;
+
+ ret = sysdev_class_register(&mxc_avic_sysclass);
+ if (ret == 0) {
+ ret = sysdev_register(&mxc_avic_device);
+ }
+
+ return ret;
+}
+
+arch_initcall(mxc_avic_sysinit);
diff --git a/arch/arm/plat-mxc/isp1301xc.c b/arch/arm/plat-mxc/isp1301xc.c
new file mode 100644
index 000000000000..dceea44fd4da
--- /dev/null
+++ b/arch/arm/plat-mxc/isp1301xc.c
@@ -0,0 +1,290 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/usb/fsl_xcvr.h>
+#include <linux/i2c.h>
+
+#include <mach/arc_otg.h>
+
+/*
+ * ISP1301 register addresses,all register of ISP1301
+ * is one-byte length register
+ */
+
+/* ISP1301: I2C device address */
+#define ISP1301_DEV_ADDR 0x2D
+
+/* ISP 1301 register set*/
+#define ISP1301_MODE_REG1_SET 0x04
+#define ISP1301_MODE_REG1_CLR 0x05
+
+#define ISP1301_CTRL_REG1_SET 0x06
+#define ISP1301_CTRL_REG1_CLR 0x07
+
+#define ISP1301_INT_SRC_REG 0x08
+#define ISP1301_INT_LAT_REG_SET 0x0a
+#define ISP1301_INT_LAT_REG_CLR 0x0b
+#define ISP1301_INT_FALSE_REG_SET 0x0c
+#define ISP1301_INT_FALSE_REG_CLR 0x0d
+#define ISP1301_INT_TRUE_REG_SET 0x0e
+#define ISP1301_INT_TRUE_REG_CLR 0x0f
+
+#define ISP1301_CTRL_REG2_SET 0x10
+#define ISP1301_CTRL_REG2_CLR 0x11
+
+#define ISP1301_MODE_REG2_SET 0x12
+#define ISP1301_MODE_REG2_CLR 0x13
+
+#define ISP1301_BCD_DEV_REG0 0x14
+#define ISP1301_BCD_DEV_REG1 0x15
+
+/* OTG Control register bit description */
+#define DP_PULLUP 0x01
+#define DM_PULLUP 0x02
+#define DP_PULLDOWN 0x04
+#define DM_PULLDOWN 0x08
+#define ID_PULLDOWN 0x10
+#define VBUS_DRV 0x20
+#define VBUS_DISCHRG 0x40
+#define VBUS_CHRG 0x80
+
+/* Mode Control 1 register bit description */
+#define SPEED_REG 0x01
+#define SUSPEND_REG 0x02
+#define DAT_SE0 0x04
+#define TRANSP_EN 0x08
+#define BDIS_ACON_EN 0x10
+#define OE_INT_EN 0x20
+#define UART_EN 0x40
+
+/* Mode Control 2 register bit description */
+#define SPD_SUSP_CTRL 0x02
+#define BI_DI 0x04
+
+static int isp1301_attach(struct i2c_adapter *adapter);
+static int isp1301_detach(struct i2c_client *client);
+
+static struct i2c_driver isp1301_i2c_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "isp1301 Client",
+ },
+ .attach_adapter = isp1301_attach,
+ .detach_client = isp1301_detach,
+};
+
+static struct i2c_client isp1301_i2c_client = {
+ .name = "isp1301 I2C dev",
+ .addr = ISP1301_DEV_ADDR,
+ .driver = &isp1301_i2c_driver,
+};
+
+static unsigned short normal_i2c[] = { ISP1301_DEV_ADDR, I2C_CLIENT_END };
+
+/* Magic definition of all other variables and things */
+I2C_CLIENT_INSMOD;
+
+static int isp1301_detect_client(struct i2c_adapter *adapter, int address,
+ int kind)
+{
+ isp1301_i2c_client.adapter = adapter;
+ if (i2c_attach_client(&isp1301_i2c_client)) {
+ isp1301_i2c_client.adapter = NULL;
+ printk(KERN_ERR "isp1301_attach: i2c_attach_client failed\n");
+ return -1;
+ }
+
+ printk(KERN_INFO "isp1301 Detected\n");
+ return 0;
+}
+
+/*!
+ * isp1301 I2C attach function
+ *
+ * @param adapter struct i2c_adapter *
+ * @return Error code indicating success or failure
+ */
+static int isp1301_attach(struct i2c_adapter *adapter)
+{
+ return i2c_probe(adapter, &addr_data, &isp1301_detect_client);
+}
+
+/*!
+ * isp1301 I2C detach function
+ *
+ * @param client struct i2c_client *
+ * @return Error code indicating success or failure
+ */
+static int isp1301_detach(struct i2c_client *client)
+{
+ int err;
+
+ if (!isp1301_i2c_client.adapter)
+ return -1;
+
+ err = i2c_detach_client(&isp1301_i2c_client);
+ isp1301_i2c_client.adapter = NULL;
+
+ return err;
+}
+
+static void isp1301_init(struct fsl_xcvr_ops *this)
+{
+ pr_debug("%s\n", __FUNCTION__);
+
+ i2c_add_driver(&isp1301_i2c_driver);
+}
+
+static void isp1301_uninit(struct fsl_xcvr_ops *this)
+{
+ // DDD do this for host only:
+ /* disable OTG VBUS */
+ i2c_del_driver(&isp1301_i2c_driver);
+}
+
+/* Write ISP1301 register*/
+static inline void isp1301_write_reg(char reg, char data)
+{
+ i2c_smbus_write_byte_data(&isp1301_i2c_client, reg, data);
+}
+
+/* read ISP1301 register*/
+static inline char isp1301_read_reg(char reg)
+{
+ return i2c_smbus_read_byte_data(&isp1301_i2c_client, reg);
+}
+
+/* set ISP1301 as USB host*/
+static inline void isp1301_set_serial_host(void)
+{
+ pr_debug("%s\n", __FUNCTION__);
+
+ isp1301_write_reg(ISP1301_MODE_REG2_CLR, 0xFF);
+#if defined(CONFIG_MXC_USB_SB3) || defined(CONFIG_MXC_USB_DB4)
+ isp1301_write_reg(ISP1301_MODE_REG2_SET, SPD_SUSP_CTRL | BI_DI);
+#else
+ isp1301_write_reg(ISP1301_MODE_REG2_SET, SPD_SUSP_CTRL);
+#endif
+
+ isp1301_write_reg(ISP1301_MODE_REG1_CLR, 0xFF);
+#if defined(CONFIG_MXC_USB_SB3) || defined(CONFIG_MXC_USB_SU6)
+ isp1301_write_reg(ISP1301_MODE_REG1_SET, DAT_SE0 | SPEED_REG);
+#else
+ isp1301_write_reg(ISP1301_MODE_REG1_SET, SPEED_REG);
+#endif
+
+ /* configure transceiver for host mode */
+ isp1301_write_reg(ISP1301_CTRL_REG1_SET,
+ (VBUS_DRV | DP_PULLDOWN | DM_PULLDOWN));
+}
+
+/* set ISP1301 as USB device */
+static inline void isp1301_set_serial_dev(void)
+{
+ pr_debug("%s\n", __FUNCTION__);
+
+ isp1301_write_reg(ISP1301_MODE_REG2_CLR, 0xFF);
+#if defined(CONFIG_MXC_USB_SB3) || defined(CONFIG_MXC_USB_DB4)
+ isp1301_write_reg(ISP1301_MODE_REG2_SET, SPD_SUSP_CTRL | BI_DI);
+#else
+ isp1301_write_reg(ISP1301_MODE_REG2_SET, SPD_SUSP_CTRL);
+#endif
+
+ isp1301_write_reg(ISP1301_MODE_REG1_CLR, 0xFF);
+#if defined(CONFIG_MXC_USB_SB3) || defined(CONFIG_MXC_USB_SU6)
+ isp1301_write_reg(ISP1301_MODE_REG1_SET, DAT_SE0 | SPEED_REG);
+#else
+ isp1301_write_reg(ISP1301_MODE_REG1_SET, SPEED_REG);
+#endif
+
+ /* FS mode, DP pull down, DM pull down */
+ isp1301_write_reg(ISP1301_CTRL_REG1_SET,
+ (DP_PULLDOWN | DM_PULLDOWN | DP_PULLUP));
+}
+
+static void isp1301_set_vbus_power(struct fsl_xcvr_ops *this,
+ struct fsl_usb2_platform_data *pdata, int on)
+{
+ pr_debug("%s(on=%d)\n", __FUNCTION__, on);
+ if (on) {
+ /* disable D+ pull-up */
+ isp1301_write_reg(ISP1301_CTRL_REG1_CLR, DP_PULLUP);
+ /* enable D+ pull-down */
+ isp1301_write_reg(ISP1301_CTRL_REG1_SET, DP_PULLDOWN);
+ /* turn on Vbus */
+ isp1301_write_reg(ISP1301_CTRL_REG1_SET, VBUS_DRV);
+ } else {
+ /* D+ pull up, D- pull down */
+ isp1301_write_reg(ISP1301_CTRL_REG1_SET,
+ (DP_PULLUP | DM_PULLDOWN));
+ /* disable D- pull up, disable D+ pull down */
+ isp1301_write_reg(ISP1301_CTRL_REG1_CLR,
+ (DM_PULLUP | DP_PULLDOWN));
+ }
+}
+
+/*
+ * Enable or disable the D+ pullup.
+ */
+static void isp1301_pullup(int on)
+{
+ pr_debug("%s(%d)\n", __func__, on);
+
+ if (on)
+ isp1301_write_reg(ISP1301_CTRL_REG1_SET, DP_PULLUP);
+ else
+ isp1301_write_reg(ISP1301_CTRL_REG1_CLR, DP_PULLUP);
+}
+
+static struct fsl_xcvr_ops isp1301_ops_otg = {
+ .name = "isp1301",
+ .xcvr_type = PORTSC_PTS_SERIAL,
+ .init = isp1301_init,
+ .uninit = isp1301_uninit,
+ .set_host = isp1301_set_serial_host,
+ .set_device = isp1301_set_serial_dev,
+ .set_vbus_power = isp1301_set_vbus_power,
+ .pullup = isp1301_pullup,
+};
+
+extern void fsl_usb_xcvr_register(struct fsl_xcvr_ops *xcvr_ops);
+
+static int __init isp1301xc_init(void)
+{
+ pr_debug("%s\n", __FUNCTION__);
+
+ fsl_usb_xcvr_register(&isp1301_ops_otg);
+
+ return 0;
+}
+
+extern void fsl_usb_xcvr_unregister(struct fsl_xcvr_ops *xcvr_ops);
+
+static void __exit isp1301xc_exit(void)
+{
+ fsl_usb_xcvr_unregister(&isp1301_ops_otg);
+}
+
+module_init(isp1301xc_init);
+module_exit(isp1301xc_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("isp1301");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/isp1504xc.c b/arch/arm/plat-mxc/isp1504xc.c
new file mode 100644
index 000000000000..7ef89db09364
--- /dev/null
+++ b/arch/arm/plat-mxc/isp1504xc.c
@@ -0,0 +1,279 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/delay.h>
+#include <linux/usb/fsl_xcvr.h>
+
+#include <mach/hardware.h>
+#include <mach/arc_otg.h>
+#include <asm/mach-types.h>
+
+/* ISP 1504 register addresses */
+#define ISP1504_VID_LOW 0x00 /* Vendor ID low */
+#define ISP1504_VID_HIGH 0x01 /* Vendor ID high */
+#define ISP1504_PID_LOW 0x02 /* Product ID low */
+#define ISP1504_PID_HIGH 0x03 /* Product ID high */
+#define ISP1504_FUNC 0x04 /* Function Control */
+#define ISP1504_ITFCTL 0x07 /* Interface Control */
+#define ISP1504_OTGCTL 0x0A /* OTG Control */
+
+/* add to above register address to access Set/Clear functions */
+#define ISP1504_REG_SET 0x01
+#define ISP1504_REG_CLEAR 0x02
+
+/* 1504 OTG Control Register bits */
+#define USE_EXT_VBUS_IND (1 << 7) /* Use ext. Vbus indicator */
+#define DRV_VBUS_EXT (1 << 6) /* Drive Vbus external */
+#define DRV_VBUS (1 << 5) /* Drive Vbus */
+#define CHRG_VBUS (1 << 4) /* Charge Vbus */
+#define DISCHRG_VBUS (1 << 3) /* Discharge Vbus */
+#define DM_PULL_DOWN (1 << 2) /* enable DM Pull Down */
+#define DP_PULL_DOWN (1 << 1) /* enable DP Pull Down */
+#define ID_PULL_UP (1 << 0) /* enable ID Pull Up */
+
+/* 1504 OTG Function Control Register bits */
+#define SUSPENDM (1 << 6) /* places the PHY into
+ low-power mode */
+#define DRV_RESET (1 << 5) /* Active HIGH transceiver
+ reset */
+
+/*!
+ * read ULPI register 'reg' thru VIEWPORT register 'view'
+ *
+ * @param reg register to read
+ * @param view the ULPI VIEWPORT register address
+ * @return return isp1504 register value
+ */
+static u8 isp1504_read(int reg, volatile u32 *view)
+{
+ u32 data;
+
+ /* make sure interface is running */
+ if (!(__raw_readl(view) && ULPIVW_SS)) {
+ __raw_writel(ULPIVW_WU, view);
+ do { /* wait for wakeup */
+ data = __raw_readl(view);
+ } while (data & ULPIVW_WU);
+ }
+
+ /* read the register */
+ __raw_writel((ULPIVW_RUN | (reg << ULPIVW_ADDR_SHIFT)), view);
+
+ do { /* wait for completion */
+ data = __raw_readl(view);
+ } while (data & ULPIVW_RUN);
+
+ return (u8) (data >> ULPIVW_RDATA_SHIFT) & ULPIVW_RDATA_MASK;
+}
+
+/*!
+ * set bits into OTG ISP1504 register 'reg' thru VIEWPORT register 'view'
+ *
+ * @param bits set value
+ * @param reg which register
+ * @param view the ULPI VIEWPORT register address
+ */
+static void isp1504_set(u8 bits, int reg, volatile u32 *view)
+{
+ u32 data;
+
+ /* make sure interface is running */
+ if (!(__raw_readl(view) && ULPIVW_SS)) {
+ __raw_writel(ULPIVW_WU, view);
+ do { /* wait for wakeup */
+ data = __raw_readl(view);
+ } while (data & ULPIVW_WU);
+ }
+
+ __raw_writel((ULPIVW_RUN | ULPIVW_WRITE |
+ ((reg + ISP1504_REG_SET) << ULPIVW_ADDR_SHIFT) |
+ ((bits & ULPIVW_WDATA_MASK) << ULPIVW_WDATA_SHIFT)),
+ view);
+
+ while (__raw_readl(view) & ULPIVW_RUN) /* wait for completion */
+ continue;
+}
+
+/*!
+ * clear bits in OTG ISP1504 register 'reg' thru VIEWPORT register 'view'
+ *
+ * @param bits bits to clear
+ * @param reg in this register
+ * @param view the ULPI VIEWPORT register address
+ */
+static void isp1504_clear(u8 bits, int reg, volatile u32 *view)
+{
+ __raw_writel((ULPIVW_RUN | ULPIVW_WRITE |
+ ((reg + ISP1504_REG_CLEAR) << ULPIVW_ADDR_SHIFT) |
+ ((bits & ULPIVW_WDATA_MASK) << ULPIVW_WDATA_SHIFT)),
+ view);
+
+ while (__raw_readl(view) & ULPIVW_RUN) /* wait for completion */
+ continue;
+}
+
+extern int gpio_usbotg_hs_active(void);
+
+static void isp1508_fix(u32 *view)
+{
+ if (!machine_is_mx31_3ds())
+ gpio_usbotg_hs_active();
+
+ /* Set bits IND_PASS_THRU and IND_COMPL */
+ isp1504_set(0x60, ISP1504_ITFCTL, view);
+
+ /* Set bit USE_EXT_VBUS_IND */
+ isp1504_set(USE_EXT_VBUS_IND, ISP1504_OTGCTL, view);
+}
+
+/*!
+ * set vbus power
+ *
+ * @param view viewport register
+ * @param on power on or off
+ */
+static void isp1504_set_vbus_power(struct fsl_xcvr_ops *this,
+ struct fsl_usb2_platform_data *pdata, int on)
+{
+ u32 *view = pdata->regs + ULPIVW_OFF;
+
+ pr_debug("real %s(on=%d) view=0x%p\n", __FUNCTION__, on, view);
+
+ pr_debug("ULPI Vendor ID 0x%x Product ID 0x%x\n",
+ (isp1504_read(ISP1504_VID_HIGH, view) << 8) |
+ isp1504_read(ISP1504_VID_LOW, view),
+ (isp1504_read(ISP1504_PID_HIGH, view) << 8) |
+ isp1504_read(ISP1504_PID_LOW, view));
+
+ pr_debug("OTG Control before=0x%x\n",
+ isp1504_read(ISP1504_OTGCTL, view));
+
+ if (on) {
+ isp1504_set(DRV_VBUS_EXT | /* enable external Vbus */
+ DRV_VBUS | /* enable internal Vbus */
+ USE_EXT_VBUS_IND | /* use external indicator */
+ CHRG_VBUS, /* charge Vbus */
+ ISP1504_OTGCTL, view);
+
+ } else {
+ isp1508_fix(view);
+
+ isp1504_clear(DRV_VBUS_EXT | /* disable external Vbus */
+ DRV_VBUS, /* disable internal Vbus */
+ ISP1504_OTGCTL, view);
+
+ isp1504_set(USE_EXT_VBUS_IND | /* use external indicator */
+ DISCHRG_VBUS, /* discharge Vbus */
+ ISP1504_OTGCTL, view);
+ }
+
+ pr_debug("OTG Control after = 0x%x\n",
+ isp1504_read(ISP1504_OTGCTL, view));
+}
+
+/*!
+ * set remote wakeup
+ *
+ * @param view viewport register
+ */
+static void isp1504_set_remote_wakeup(u32 * view)
+{
+ __raw_writel(~ULPIVW_WRITE & __raw_readl(view), view);
+ __raw_writel((1 << ULPIVW_PORT_SHIFT) | __raw_readl(view), view);
+ __raw_writel(ULPIVW_RUN | __raw_readl(view), view);
+
+ while (__raw_readl(view) & ULPIVW_RUN) /* wait for completion */
+ continue;
+}
+
+static void isp1504_init(struct fsl_xcvr_ops *this)
+{
+ pr_debug("%s:\n", __FUNCTION__);
+}
+
+static void isp1504_uninit(struct fsl_xcvr_ops *this)
+{
+ pr_debug("%s:\n", __FUNCTION__);
+}
+
+static void isp1504_suspend(struct fsl_xcvr_ops *this)
+{
+ pr_debug("%s\n", __func__);
+
+ /* send suspend command */
+ isp1504_clear(SUSPENDM, ISP1504_FUNC, &UOG_ULPIVIEW);
+ pr_debug("%s.\n", __func__);
+}
+
+/*!
+ * Set the 1504 transceiver to the proper mode for testing purposes.
+ *
+ * @param view the ULPI VIEWPORT register address
+ * @param test_mode Set the 1504 transceiver to disable bit stuffing and NRZI
+ */
+ static void isp1504_set_test_mode(volatile u32 *view, enum usb_test_mode test_mode)
+{
+ if (test_mode == USB_TEST_J || test_mode == USB_TEST_K) {
+ printk(KERN_INFO "udc: disable bit stuffing and NRZI\n");
+ /* Disable bit-stuffing and NRZI encoding. */
+ isp1504_set(0x10, 0x04, view);
+ }
+}
+
+static struct fsl_xcvr_ops isp1504_ops = {
+ .name = "isp1504",
+ .xcvr_type = PORTSC_PTS_ULPI,
+ .init = isp1504_init,
+ .uninit = isp1504_uninit,
+ .suspend = isp1504_suspend,
+ .set_vbus_power = isp1504_set_vbus_power,
+ .set_remote_wakeup = isp1504_set_remote_wakeup,
+ .set_test_mode = isp1504_set_test_mode,
+};
+
+extern void fsl_usb_xcvr_register(struct fsl_xcvr_ops *xcvr_ops);
+extern int fsl_usb_xcvr_suspend(struct fsl_xcvr_ops *xcvr_ops);
+
+static int __init isp1504xc_init(void)
+{
+ pr_debug("%s\n", __FUNCTION__);
+
+ fsl_usb_xcvr_register(&isp1504_ops);
+
+ /* suspend isp1504 */
+ if (fsl_usb_xcvr_suspend(&isp1504_ops))
+ pr_debug("%s: failed to suspend isp1504\n", __func__);
+
+ return 0;
+}
+
+extern void fsl_usb_xcvr_unregister(struct fsl_xcvr_ops *xcvr_ops);
+
+static void __exit isp1504xc_exit(void)
+{
+ fsl_usb_xcvr_unregister(&isp1504_ops);
+}
+
+module_init(isp1504xc_init);
+module_exit(isp1504xc_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("isp1504 xcvr driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/leds.c b/arch/arm/plat-mxc/leds.c
new file mode 100644
index 000000000000..e059d238f82b
--- /dev/null
+++ b/arch/arm/plat-mxc/leds.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*
+ * The LED can be used for debugging purpose. To enalbe the LEDs, in the
+ * config file, select:
+ * CONFIG_LEDS
+ * CONFIG_LEDS_TIMER --- enable the OS tick LED once every 50 ticks (.5sec)
+ * CONFIG_LEDS_CPU --- enable the cpu idle in/out LED (blink fast)
+ *
+ * The two LEDs can be disabled through user space by issuing:
+ * echo "claim" > /sys/devices/system/leds/leds0/event
+ * To release the LEDs back to the normal operation, do:
+ * echo "release" > /sys/devices/system/leds/leds0/event
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/ioport.h>
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+#include <asm/leds.h>
+
+#define LED_STATE_ENABLED (1 << 0)
+#define LED_STATE_CLAIMED (1 << 1)
+
+static unsigned int led_state;
+static unsigned int hw_led_state;
+
+static void mxc_leds_event(led_event_t evt)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ switch (evt) {
+ case led_start:
+ hw_led_state = MXC_BD_LED1 | MXC_BD_LED2;
+ led_state = LED_STATE_ENABLED;
+ break;
+
+ case led_stop:
+ case led_halted:
+ hw_led_state = 0;
+ led_state &= ~LED_STATE_ENABLED;
+ MXC_BD_LED_OFF(MXC_BD_LED1 | MXC_BD_LED2);
+ break;
+
+ case led_claim:
+ led_state |= LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+ case led_release:
+ led_state &= ~LED_STATE_CLAIMED;
+ hw_led_state = 0;
+ break;
+
+#ifdef CONFIG_LEDS_TIMER
+ case led_timer:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state ^= MXC_BD_LED1;
+ break;
+#endif
+
+#ifdef CONFIG_LEDS_CPU
+ case led_idle_start:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state &= ~MXC_BD_LED2;
+ break;
+
+ case led_idle_end:
+ if (!(led_state & LED_STATE_CLAIMED))
+ hw_led_state |= MXC_BD_LED2;
+ break;
+#endif
+
+ default:
+ break;
+ }
+
+ if (led_state & LED_STATE_ENABLED) {
+ MXC_BD_LED_OFF(~hw_led_state);
+ MXC_BD_LED_ON(hw_led_state);
+ }
+
+ local_irq_restore(flags);
+}
+
+static int __init mxc_leds_init(void)
+{
+ led_state = LED_STATE_ENABLED;
+ leds_event = mxc_leds_event;
+ return 0;
+}
+
+core_initcall(mxc_leds_init);
diff --git a/arch/arm/plat-mxc/mc13783_xc.c b/arch/arm/plat-mxc/mc13783_xc.c
new file mode 100644
index 000000000000..3fad32f3b230
--- /dev/null
+++ b/arch/arm/plat-mxc/mc13783_xc.c
@@ -0,0 +1,299 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/usb/fsl_xcvr.h>
+#include <mach/pmic_external.h>
+#include <mach/pmic_convity.h>
+#include <mach/arc_otg.h>
+
+/* Events to be passed to the thread */
+#define MC13783_USB_VBUS_ON 0x0001
+#define MC13783_USB_VBUS_OFF 0x0002
+#define MC13783_USB_DETECT_MINI_A 0x0004
+#define MC13783_USB_DETECT_MINI_B 0x0008
+
+extern void otg_set_serial_peripheral(void);
+extern void otg_set_serial_host(void);
+
+static unsigned int p_event;
+static PMIC_CONVITY_EVENTS g_event;
+static PMIC_CONVITY_HANDLE pmic_handle = (PMIC_CONVITY_HANDLE) NULL;
+
+static void xc_workqueue_handler(struct work_struct *work);
+
+DECLARE_WORK(xc_work, xc_workqueue_handler);
+
+DECLARE_MUTEX(pmic_mx);
+
+static void pmic_event_handler(const PMIC_CONVITY_EVENTS event)
+{
+ if (event & USB_DETECT_4V4_RISE)
+ pr_debug("%s: USB_DETECT_4V4_RISE\n", __func__);
+
+ if (event & USB_DETECT_4V4_FALL)
+ pr_debug("%s: USB_DETECT_4V4_FALL\n", __func__);
+
+ if (event & USB_DETECT_2V0_RISE)
+ pr_debug("%s: USB_DETECT_2V0_RISE\n", __func__);
+
+ if (event & USB_DETECT_2V0_FALL)
+ pr_debug("%s: USB_DETECT_2V0_FALL\n", __func__);
+
+ if (event & USB_DETECT_0V8_RISE)
+ pr_debug("%s: USB_DETECT_0V8_RISE\n", __func__);
+
+ if (event & USB_DETECT_0V8_FALL)
+ pr_debug("%s: USB_DETECT_0V8_FALL\n", __func__);
+
+ if (event & USB_DETECT_MINI_B) {
+ pr_debug("%s: USB_DETECT_MINI_B\n", __func__);
+ otg_set_serial_peripheral();
+ g_event = USB_DETECT_MINI_B;
+ p_event = MC13783_USB_DETECT_MINI_B;
+ schedule_work(&xc_work);
+ }
+ if (event & USB_DETECT_MINI_A) {
+ pr_debug("%s: USB_DETECT_MINI_A\n", __func__);
+ otg_set_serial_host();
+ g_event = USB_DETECT_MINI_A;
+ p_event = MC13783_USB_DETECT_MINI_A;
+ schedule_work(&xc_work);
+ }
+
+ /*
+ * Mini-B cable insertion/removal does not generate cable-detect
+ * event, so we rely on the VBUS changes to identify a mini-b cable
+ * connect. This logic is only used if mini-b is the first cable that
+ * is connected after bootup. At all other times, removal of mini-a
+ * cable is used to initialize peripheral.
+ */
+ if (g_event != USB_DETECT_MINI_A && g_event != USB_DETECT_MINI_B) {
+ if ((event & USB_DETECT_0V8_RISE) &&
+ (event & USB_DETECT_2V0_RISE) &&
+ (event & USB_DETECT_4V4_RISE)) {
+ otg_set_serial_peripheral();
+ g_event = USB_DETECT_MINI_B;
+ p_event = MC13783_USB_DETECT_MINI_B;
+ schedule_work(&xc_work);
+ }
+ }
+}
+
+static int usb_pmic_mod_init(void)
+{
+ PMIC_STATUS rs = PMIC_ERROR;
+
+ init_MUTEX_LOCKED(&pmic_mx);
+
+ rs = pmic_convity_open(&pmic_handle, USB);
+ if (rs != PMIC_SUCCESS) {
+ printk(KERN_ERR "pmic_convity_open returned error %d\n", rs);
+ return rs;
+ }
+
+ rs = pmic_convity_set_callback(pmic_handle, pmic_event_handler,
+ USB_DETECT_4V4_RISE | USB_DETECT_4V4_FALL
+ | USB_DETECT_2V0_RISE |
+ USB_DETECT_2V0_FALL | USB_DETECT_0V8_RISE
+ | USB_DETECT_0V8_FALL | USB_DETECT_MINI_A
+ | USB_DETECT_MINI_B);
+
+ if (rs != PMIC_SUCCESS) {
+ printk(KERN_ERR
+ "pmic_convity_set_callback returned error %d\n", rs);
+ return rs;
+ }
+
+ return rs;
+}
+
+static void usb_pmic_mod_exit(void)
+{
+ PMIC_STATUS rs;
+
+ pmic_convity_set_mode(pmic_handle, RS232_1);
+ pmic_convity_clear_callback(pmic_handle);
+
+ if (pmic_handle != (PMIC_CONVITY_HANDLE) NULL) {
+ rs = pmic_convity_close(pmic_handle);
+ if (rs != PMIC_SUCCESS) {
+ printk(KERN_ERR
+ "pmic_convity_close() returned error %d", rs);
+ } else {
+ pmic_handle = (PMIC_CONVITY_HANDLE) NULL;
+ }
+ }
+}
+
+static inline void mc13783_set_host(void)
+{
+ PMIC_STATUS rs = PMIC_ERROR;
+
+ rs = pmic_convity_usb_otg_clear_config(pmic_handle, USB_OTG_SE0CONN);
+ rs |= pmic_convity_usb_otg_clear_config(pmic_handle, USB_PU);
+
+ rs |= pmic_convity_usb_otg_set_config(pmic_handle, USB_UDM_PD);
+ rs |= pmic_convity_usb_otg_set_config(pmic_handle, USB_UDP_PD);
+
+ if (rs != PMIC_SUCCESS)
+ printk(KERN_ERR "mc13783_set_host failed\n");
+
+}
+
+static inline void mc13783_set_peripheral(void)
+{
+ PMIC_STATUS rs = PMIC_ERROR;
+
+ rs = pmic_convity_usb_otg_clear_config(pmic_handle, USB_UDM_PD);
+ rs |= pmic_convity_usb_otg_clear_config(pmic_handle, USB_UDP_PD);
+
+ rs |= pmic_convity_usb_set_speed(pmic_handle, USB_FULL_SPEED);
+ rs |= pmic_convity_usb_otg_set_config(pmic_handle, USB_OTG_SE0CONN);
+ rs |= pmic_convity_usb_otg_set_config(pmic_handle, USB_PU);
+
+ if (rs != PMIC_SUCCESS)
+ printk(KERN_ERR "mc13783_set_peripheral failed\n");
+}
+
+void mc13783_set_vbus_power(struct fsl_xcvr_ops *this,
+ struct fsl_usb2_platform_data *pdata, int on)
+{
+ if (on) {
+ p_event = MC13783_USB_VBUS_ON;
+ schedule_work(&xc_work);
+ }
+}
+
+static struct fsl_xcvr_ops mc13783_ops_otg = {
+ .name = "mc13783",
+ .xcvr_type = PORTSC_PTS_SERIAL,
+ .set_host = mc13783_set_host,
+ .set_device = mc13783_set_peripheral,
+ .set_vbus_power = mc13783_set_vbus_power,
+};
+
+extern void fsl_usb_xcvr_register(struct fsl_xcvr_ops *xcvr_ops);
+
+static void xc_workqueue_handler(struct work_struct *work)
+{
+ PMIC_STATUS rs = PMIC_ERROR;
+
+ down(&pmic_mx);
+
+ switch (p_event) {
+ case MC13783_USB_VBUS_OFF:
+ mc13783_set_peripheral();
+ break;
+ case MC13783_USB_VBUS_ON:
+ mc13783_set_host();
+ break;
+ case MC13783_USB_DETECT_MINI_B:
+ rs = pmic_convity_set_output(pmic_handle, true, false);
+ rs |=
+ pmic_convity_usb_otg_clear_config(pmic_handle,
+ USB_VBUS_CURRENT_LIMIT_LOW_30MS);
+
+ if (rs != PMIC_SUCCESS)
+ printk(KERN_ERR "MC13783_USB_VBUS_OFF failed\n");
+ break;
+ case MC13783_USB_DETECT_MINI_A:
+ rs = pmic_convity_set_output(pmic_handle, true, true);
+ rs |=
+ pmic_convity_usb_otg_set_config(pmic_handle,
+ USB_VBUS_CURRENT_LIMIT_LOW_30MS);
+
+ if (rs != PMIC_SUCCESS)
+ printk(KERN_ERR "MC13783_USB_VBUS_ON failed\n");
+ break;
+ default:
+ break;
+ }
+ up(&pmic_mx);
+}
+
+int mc13783xc_init(void)
+{
+ PMIC_STATUS rs = PMIC_ERROR;
+
+#if defined(CONFIG_MXC_USB_SB3)
+ int xc_mode = USB_SINGLE_ENDED_BIDIR;
+#elif defined(CONFIG_MXC_USB_SU6)
+ int xc_mode = USB_SINGLE_ENDED_UNIDIR;
+#elif defined(CONFIG_MXC_USB_DB4)
+ int xc_mode = USB_DIFFERENTIAL_BIDIR;
+#else
+ int xc_mode = USB_DIFFERENTIAL_UNIDIR;
+#endif
+
+ rs = usb_pmic_mod_init();
+ if (rs != PMIC_SUCCESS) {
+ usb_pmic_mod_exit();
+ printk(KERN_ERR "usb_pmic_mod_init failed\n");
+ return rs;
+ }
+
+ rs = pmic_convity_usb_set_xcvr(pmic_handle, xc_mode);
+ rs |= pmic_convity_usb_otg_set_config(pmic_handle, USB_OTG_SE0CONN);
+ rs |= pmic_convity_usb_otg_set_config(pmic_handle, USBXCVREN);
+ rs |= pmic_convity_set_output(pmic_handle, false, true);
+
+ rs |= pmic_convity_usb_otg_set_config(pmic_handle, USB_PULL_OVERRIDE);
+ rs |= pmic_convity_usb_otg_clear_config(pmic_handle, USB_USBCNTRL);
+ rs |= pmic_convity_usb_otg_clear_config(pmic_handle, USB_DP150K_PU);
+
+ if (rs != PMIC_SUCCESS)
+ printk(KERN_ERR "pmic configuration failed\n");
+
+ fsl_usb_xcvr_register(&mc13783_ops_otg);
+
+ mc13783_set_peripheral();
+
+ return rs;
+}
+
+extern void fsl_usb_xcvr_unregister(struct fsl_xcvr_ops *xcvr_ops);
+
+void mc13783xc_uninit(void)
+{
+ /* Clear stuff from init */
+ pmic_convity_usb_otg_clear_config(pmic_handle, USB_OTG_SE0CONN);
+ pmic_convity_usb_otg_clear_config(pmic_handle, USBXCVREN);
+ pmic_convity_set_output(pmic_handle, false, false);
+ pmic_convity_usb_otg_clear_config(pmic_handle, USB_PULL_OVERRIDE);
+
+ /* Clear host mode */
+ pmic_convity_usb_otg_clear_config(pmic_handle, USB_UDP_PD);
+ pmic_convity_usb_otg_clear_config(pmic_handle, USB_UDM_PD);
+
+ /* Clear peripheral mode */
+ pmic_convity_usb_otg_clear_config(pmic_handle, USB_PU);
+
+ /* Vbus off */
+ pmic_convity_set_output(pmic_handle, true, false);
+ pmic_convity_usb_otg_clear_config(pmic_handle,
+ USB_VBUS_CURRENT_LIMIT_LOW_30MS);
+
+ usb_pmic_mod_exit();
+
+ fsl_usb_xcvr_unregister(&mc13783_ops_otg);
+}
+
+module_init(mc13783xc_init);
+module_exit(mc13783xc_uninit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("mc13783xc");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/sdma/Makefile b/arch/arm/plat-mxc/sdma/Makefile
new file mode 100644
index 000000000000..59f94b2da7d0
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/Makefile
@@ -0,0 +1,18 @@
+ifneq ($(KBUILD_SRC),)
+ccflags-y += -I$(KBUILD_SRC)/arch/arm/plat-mxc/sdma/iapi/include \
+ -I$(KBUILD_SRC)/include/linux \
+ -DMCU -DOS=LINUX \
+ -DL_I_T_T_L_E_ENDIAN=0 -DB_I_G_ENDIAN=1 \
+ -DENDIANNESS=L_I_T_T_L_E_ENDIAN
+else
+ccflags-y += -Iarch/arm/plat-mxc/sdma/iapi/include \
+ -Iinclude/linux \
+ -DMCU -DOS=LINUX \
+ -DL_I_T_T_L_E_ENDIAN=0 -DB_I_G_ENDIAN=1 \
+ -DENDIANNESS=L_I_T_T_L_E_ENDIAN
+endif
+
+obj-y += dma_sdma.o
+obj-$(CONFIG_MXC_SDMA_API) += sdma.o
+obj-$(CONFIG_MXC_SDMA_API) += iapi/
+obj-$(CONFIG_MXC_SDMA_API) += sdma_malloc.o
diff --git a/arch/arm/plat-mxc/sdma/dma_sdma.c b/arch/arm/plat-mxc/sdma/dma_sdma.c
new file mode 100644
index 000000000000..a05016d5ac86
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/dma_sdma.c
@@ -0,0 +1,684 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file plat-mxc/sdma/dma_sdma.c
+ * @brief Front-end to the DMA handling. This handles the allocation/freeing
+ * of DMA channels, and provides a unified interface to the machines
+ * DMA facilities. This file contains functions for Smart DMA.
+ *
+ * @ingroup SDMA
+ */
+
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <mach/dma.h>
+#include <mach/hardware.h>
+
+#ifdef CONFIG_MXC_SDMA_API
+
+static mxc_dma_channel_t mxc_sdma_channels[MAX_DMA_CHANNELS];
+static mxc_dma_channel_private_t mxc_sdma_private[MAX_DMA_CHANNELS];
+
+extern struct clk *mxc_sdma_ahb_clk, *mxc_sdma_ipg_clk;
+
+/*!
+ * Tasket to handle processing the channel buffers
+ *
+ * @param arg channel id
+ */
+static void mxc_sdma_channeltasklet(unsigned long arg)
+{
+ dma_request_t request_t;
+ dma_channel_params chnl_param;
+ mxc_dma_channel_t *chnl_info;
+ mxc_dma_channel_private_t *data_priv;
+ int bd_intr = 0, error = MXC_DMA_DONE;
+
+ chnl_info = &mxc_sdma_channels[arg];
+ data_priv = chnl_info->private;
+ chnl_param =
+ mxc_sdma_get_channel_params(chnl_info->channel)->chnl_params;
+
+ mxc_dma_get_config(arg, &request_t, data_priv->buf_tail);
+
+ while (request_t.bd_done == 0) {
+ bd_intr = mxc_dma_get_bd_intr(arg, data_priv->buf_tail);
+ if ((data_priv->buf_tail += 1) >= chnl_param.bd_number) {
+ data_priv->buf_tail = 0;
+ }
+ chnl_info->active = 0;
+ if (request_t.bd_error) {
+ error = MXC_DMA_TRANSFER_ERROR;
+ }
+
+ if (bd_intr != 0) {
+ chnl_info->cb_fn(chnl_info->cb_args, error,
+ request_t.count);
+ error = MXC_DMA_DONE;
+ }
+
+ if (data_priv->buf_tail == chnl_info->curr_buf) {
+ break;
+ }
+ memset(&request_t, 0, sizeof(dma_request_t));
+ mxc_dma_get_config(arg, &request_t, data_priv->buf_tail);
+ }
+}
+
+/*!
+ * This function is generally called by the driver at open time.
+ * The DMA driver would do any initialization steps that is required
+ * to get the channel ready for data transfer.
+ *
+ * @param channel_id a pre-defined id. The peripheral driver would specify
+ * the id associated with its peripheral. This would be
+ * used by the DMA driver to identify the peripheral
+ * requesting DMA and do the necessary setup on the
+ * channel associated with the particular peripheral.
+ * The DMA driver could use static or dynamic DMA channel
+ * allocation.
+ * @param dev_name module name or device name
+ * @return returns a negative number on error if request for a DMA channel did not
+ * succeed, returns the channel number to be used on success.
+ */
+int mxc_dma_request(mxc_dma_device_t channel_id, char *dev_name)
+{
+ mxc_sdma_channel_params_t *chnl;
+ mxc_dma_channel_private_t *data_priv;
+ int ret = 0, i = 0, channel_num = 0;
+
+ chnl = mxc_sdma_get_channel_params(channel_id);
+ if (chnl == NULL) {
+ return -EINVAL;
+ }
+
+ /* Enable the SDMA clock */
+ clk_enable(mxc_sdma_ahb_clk);
+ clk_enable(mxc_sdma_ipg_clk);
+
+ channel_num = chnl->channel_num;
+ if (chnl->channel_num == MXC_DMA_DYNAMIC_CHANNEL) {
+ /* Get the first free channel */
+ for (i = (MAX_DMA_CHANNELS - 1); i > 0; i--) {
+ /* See if channel is available */
+ if ((mxc_sdma_channels[i].dynamic != 1)
+ || (mxc_sdma_channels[i].lock != 0)) {
+ continue;
+ }
+ channel_num = i;
+ /* Check to see if we can get this channel */
+ ret = mxc_request_dma(&channel_num, dev_name);
+ if (ret == 0) {
+ break;
+ } else {
+ continue;
+ }
+ }
+ if (ret != 0) {
+ /* No free channel */
+ goto err_ret;
+ }
+ } else {
+ if (mxc_sdma_channels[chnl->channel_num].lock == 1) {
+ ret = -ENODEV;
+ goto err_ret;
+ }
+ ret = mxc_request_dma(&channel_num, dev_name);
+ if (ret != 0) {
+ goto err_ret;
+ }
+ }
+
+ ret = mxc_dma_setup_channel(channel_num, &chnl->chnl_params);
+
+ if (ret == 0) {
+ if (chnl->chnl_priority != MXC_SDMA_DEFAULT_PRIORITY) {
+ ret =
+ mxc_dma_set_channel_priority(channel_num,
+ chnl->chnl_priority);
+ if (ret != 0) {
+ pr_info("Failed to set channel prority,\
+ continue with the existing \
+ priority\n");
+ goto err_ret;
+ }
+ }
+ mxc_sdma_channels[channel_num].lock = 1;
+ if ((chnl->chnl_params.transfer_type == per_2_emi)
+ || (chnl->chnl_params.transfer_type == dsp_2_emi)) {
+ mxc_sdma_channels[channel_num].mode = MXC_DMA_MODE_READ;
+ } else {
+ mxc_sdma_channels[channel_num].mode =
+ MXC_DMA_MODE_WRITE;
+ }
+ mxc_sdma_channels[channel_num].channel = channel_id;
+ data_priv = mxc_sdma_channels[channel_num].private;
+ tasklet_init(&data_priv->chnl_tasklet,
+ mxc_sdma_channeltasklet, channel_num);
+ if ((channel_id == MXC_DMA_ATA_RX)
+ || (channel_id == MXC_DMA_ATA_TX)) {
+ data_priv->intr_after_every_bd = 0;
+ } else {
+ data_priv->intr_after_every_bd = 1;
+ }
+ }
+ err_ret:
+ if (ret != 0) {
+ clk_disable(mxc_sdma_ahb_clk);
+ clk_disable(mxc_sdma_ipg_clk);
+ channel_num = -ENODEV;
+ }
+
+ return channel_num;
+}
+
+/*!
+ * This function is generally called by the driver at close time. The DMA
+ * driver would do any cleanup associated with this channel.
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @return returns a negative number on error or 0 on success
+ */
+int mxc_dma_free(int channel_num)
+{
+ mxc_dma_channel_private_t *data_priv;
+
+ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+ return -EINVAL;
+ }
+
+ if (mxc_sdma_channels[channel_num].lock != 1) {
+ return -ENODEV;
+ }
+
+ mxc_free_dma(channel_num);
+
+ /* Disable the SDMA clock */
+ clk_disable(mxc_sdma_ahb_clk);
+ clk_disable(mxc_sdma_ipg_clk);
+
+ mxc_sdma_channels[channel_num].lock = 0;
+ mxc_sdma_channels[channel_num].active = 0;
+ mxc_sdma_channels[channel_num].curr_buf = 0;
+ data_priv = mxc_sdma_channels[channel_num].private;
+ data_priv->buf_tail = 0;
+ tasklet_kill(&data_priv->chnl_tasklet);
+
+ return 0;
+}
+
+/*!
+ * Callback function called from the SDMA Interrupt routine
+ *
+ * @param arg driver specific argument that was registered
+ */
+static void mxc_dma_chnl_callback(void *arg)
+{
+ int priv;
+ mxc_dma_channel_private_t *data_priv;
+
+ priv = (int)arg;
+ data_priv = mxc_sdma_channels[priv].private;
+ /* Process the buffers in a tasklet */
+ tasklet_schedule(&data_priv->chnl_tasklet);
+}
+
+/*!
+ * This function would just configure the buffers specified by the user into
+ * dma channel. The caller must call mxc_dma_enable to start this transfer.
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @param dma_buf an array of physical addresses to the user defined
+ * buffers. The caller must guarantee the dma_buf is
+ * available until the transfer is completed.
+ * @param num_buf number of buffers in the array
+ * @param mode specifies whether this is READ or WRITE operation
+ * @return This function returns a negative number on error if buffer could not be
+ * added with DMA for transfer. On Success, it returns 0
+ */
+int mxc_dma_config(int channel_num, mxc_dma_requestbuf_t * dma_buf,
+ int num_buf, mxc_dma_mode_t mode)
+{
+ int ret = 0, i = 0, prev_buf;
+ mxc_dma_channel_t *chnl_info;
+ mxc_dma_channel_private_t *data_priv;
+ mxc_sdma_channel_params_t *chnl;
+ dma_channel_params chnl_param;
+ dma_request_t request_t;
+
+ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+ return -EINVAL;
+ }
+
+ if (num_buf <= 0) {
+ return -EINVAL;
+ }
+
+ chnl_info = &mxc_sdma_channels[channel_num];
+ data_priv = chnl_info->private;
+ if (chnl_info->lock != 1) {
+ return -ENODEV;
+ }
+
+ /* Check to see if all buffers are taken */
+ if (chnl_info->active == 1) {
+ return -EBUSY;
+ }
+
+ chnl = mxc_sdma_get_channel_params(chnl_info->channel);
+ chnl_param = chnl->chnl_params;
+
+ /* Re-setup the SDMA channel if the transfer direction is changed */
+ if ((chnl_param.peripheral_type != MEMORY) && (mode != chnl_info->mode)) {
+ if (chnl_param.peripheral_type == DSP) {
+ if (mode == MXC_DMA_MODE_READ) {
+ chnl_param.transfer_type = dsp_2_emi;
+ } else {
+ chnl_param.transfer_type = emi_2_dsp;
+ }
+ } else if (chnl_param.peripheral_type == FIFO_MEMORY) {
+ if (mode == MXC_DMA_MODE_READ)
+ chnl_param.per_address = MXC_FIFO_MEM_SRC_FIXED;
+ else
+ chnl_param.per_address =
+ MXC_FIFO_MEM_DEST_FIXED;
+ } else {
+ if (mode == MXC_DMA_MODE_READ) {
+ chnl_param.transfer_type = per_2_emi;
+ } else {
+ chnl_param.transfer_type = emi_2_per;
+ }
+ }
+ chnl_param.callback = mxc_dma_chnl_callback;
+ chnl_param.arg = (void *)channel_num;
+ ret = mxc_dma_setup_channel(channel_num, &chnl_param);
+ if (ret != 0) {
+ return ret;
+ }
+ if (chnl->chnl_priority != MXC_SDMA_DEFAULT_PRIORITY) {
+ ret =
+ mxc_dma_set_channel_priority(channel_num,
+ chnl->chnl_priority);
+ if (ret != 0) {
+ pr_info("Failed to set channel prority,\
+ continue with the existing \
+ priority\n");
+ }
+ }
+ chnl_info->mode = mode;
+ }
+
+ for (i = 0; i < num_buf; i++, dma_buf++) {
+ /* Check to see if all buffers are taken */
+ if (chnl_info->active == 1) {
+ break;
+ }
+ request_t.destAddr = (__u8 *) dma_buf->dst_addr;
+ request_t.sourceAddr = (__u8 *) dma_buf->src_addr;
+ request_t.count = dma_buf->num_of_bytes;
+ request_t.bd_cont = 1;
+ ret = mxc_dma_set_config(channel_num, &request_t,
+ chnl_info->curr_buf);
+ if (ret != 0) {
+ break;
+ }
+ if (data_priv->intr_after_every_bd == 0) {
+ if (i == num_buf - 1) {
+ mxc_dma_set_bd_intr(channel_num,
+ chnl_info->curr_buf, 1);
+ } else {
+ mxc_dma_set_bd_intr(channel_num,
+ chnl_info->curr_buf, 0);
+ }
+ }
+
+ prev_buf = chnl_info->curr_buf;
+ if ((chnl_info->curr_buf += 1) >= chnl_param.bd_number) {
+ chnl_info->curr_buf = 0;
+ }
+ if (chnl_info->curr_buf == data_priv->buf_tail) {
+ if ((data_priv->intr_after_every_bd == 0)
+ && (i != num_buf - 1)) {
+ /*
+ * Set the BD_INTR flag on the last BD that
+ * was queued
+ */
+ mxc_dma_set_bd_intr(channel_num, prev_buf, 1);
+ }
+ chnl_info->active = 1;
+ }
+ }
+
+ if (i == 0) {
+ return -EBUSY;
+ }
+ return 0;
+}
+
+/*!
+ * This function would just configure the scatterlist specified by the
+ * user into dma channel. This is a slight variation of mxc_dma_config(),
+ * it is provided for the convenience of drivers that have a scatterlist
+ * passed into them. It is the calling driver's responsibility to have the
+ * correct physical address filled in the "dma_address" field of the
+ * scatterlist.
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @param sg a scatterlist of buffers. The caller must guarantee
+ * the dma_buf is available until the transfer is
+ * completed.
+ * @param num_buf number of buffers in the array
+ * @param num_of_bytes total number of bytes to transfer. If set to 0, this
+ * would imply to use the length field of the scatterlist
+ * for each DMA transfer. Else it would calculate the size
+ * for each DMA transfer.
+ * @param mode specifies whether this is READ or WRITE operation
+ * @return This function returns a negative number on error if buffer could not
+ * be added with DMA for transfer. On Success, it returns 0
+ */
+int mxc_dma_sg_config(int channel_num, struct scatterlist *sg,
+ int num_buf, int num_of_bytes, mxc_dma_mode_t mode)
+{
+ int ret = 0, i = 0;
+ mxc_dma_requestbuf_t *dma_buf;
+
+ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+ return -EINVAL;
+ }
+
+ if (mxc_sdma_channels[channel_num].lock != 1) {
+ return -ENODEV;
+ }
+
+ dma_buf =
+ (mxc_dma_requestbuf_t *) kmalloc(num_buf *
+ sizeof(mxc_dma_requestbuf_t),
+ GFP_KERNEL);
+
+ if (dma_buf == NULL) {
+ return -EFAULT;
+ }
+
+ for (i = 0; i < num_buf; i++) {
+ if (mode == MXC_DMA_MODE_READ) {
+ (dma_buf + i)->dst_addr = sg->dma_address;
+ } else {
+ (dma_buf + i)->src_addr = sg->dma_address;
+ }
+
+ if ((num_of_bytes > sg->length) || (num_of_bytes == 0)) {
+ (dma_buf + i)->num_of_bytes = sg->length;
+ } else {
+ (dma_buf + i)->num_of_bytes = num_of_bytes;
+ }
+ sg++;
+ num_of_bytes -= (dma_buf + i)->num_of_bytes;
+ }
+
+ ret = mxc_dma_config(channel_num, dma_buf, num_buf, mode);
+ kfree(dma_buf);
+ return ret;
+}
+
+/*!
+ * This function is provided if the driver would like to set/change its
+ * callback function.
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @param callback a callback function to provide notification on transfer
+ * completion, user could specify NULL if he does not wish
+ * to be notified
+ * @param arg an argument that gets passed in to the callback
+ * function, used by the user to do any driver specific
+ * operations.
+ * @return this function returns a negative number on error if the callback
+ * could not be set for the channel or 0 on success
+ */
+int mxc_dma_callback_set(int channel_num,
+ mxc_dma_callback_t callback, void *arg)
+{
+ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+ return -EINVAL;
+ }
+
+ if (mxc_sdma_channels[channel_num].lock != 1) {
+ return -ENODEV;
+ }
+
+ mxc_sdma_channels[channel_num].cb_fn = callback;
+ mxc_sdma_channels[channel_num].cb_args = arg;
+
+ mxc_dma_set_callback(channel_num, mxc_dma_chnl_callback,
+ (void *)channel_num);
+
+ return 0;
+}
+
+/*!
+ * This stops the DMA channel and any ongoing transfers. Subsequent use of
+ * mxc_dma_enable() will restart the channel and restart the transfer.
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @return returns a negative number on error or 0 on success
+ */
+int mxc_dma_disable(int channel_num)
+{
+ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+ return -EINVAL;
+ }
+
+ if (mxc_sdma_channels[channel_num].lock != 1) {
+ return -ENODEV;
+ }
+
+ mxc_dma_stop(channel_num);
+ return 0;
+}
+
+/*!
+ * This starts DMA transfer. Or it restarts DMA on a stopped channel
+ * previously stopped with mxc_dma_disable().
+ *
+ * @param channel_num the channel number returned at request time. This
+ * would be used by the DMA driver to identify the calling
+ * driver and do the necessary cleanup on the channel
+ * associated with the particular peripheral
+ * @return returns a negative number on error or 0 on success
+ */
+int mxc_dma_enable(int channel_num)
+{
+ if ((channel_num >= MAX_DMA_CHANNELS) || (channel_num < 0)) {
+ return -EINVAL;
+ }
+
+ if (mxc_sdma_channels[channel_num].lock != 1) {
+ return -ENODEV;
+ }
+
+ mxc_dma_start(channel_num);
+ return 0;
+}
+
+/*!
+ * Initializes dma structure with dma_operations
+ *
+ * @param dma dma structure
+ * @return returns 0 on success
+ */
+static int __init mxc_dma_init(void)
+{
+ int i;
+ for (i = 0; i < MAX_DMA_CHANNELS; i++) {
+ mxc_sdma_channels[i].active = 0;
+ mxc_sdma_channels[i].lock = 0;
+ mxc_sdma_channels[i].curr_buf = 0;
+ mxc_sdma_channels[i].dynamic = 1;
+ mxc_sdma_private[i].buf_tail = 0;
+ mxc_sdma_channels[i].private = &mxc_sdma_private[i];
+ }
+ /*
+ * Make statically allocated channels unavailable for dynamic channel
+ * requests
+ */
+ mxc_get_static_channels(mxc_sdma_channels);
+
+ return 0;
+}
+
+arch_initcall(mxc_dma_init);
+
+#else
+int mxc_request_dma(int *channel, const char *devicename)
+{
+ return -ENODEV;
+}
+
+int mxc_dma_setup_channel(int channel, dma_channel_params * p)
+{
+ return -ENODEV;
+}
+
+int mxc_dma_set_channel_priority(unsigned int channel, unsigned int priority)
+{
+ return -ENODEV;
+}
+
+int mxc_dma_set_config(int channel, dma_request_t * p, int bd_index)
+{
+ return -ENODEV;
+}
+
+int mxc_dma_get_config(int channel, dma_request_t * p, int bd_index)
+{
+ return -ENODEV;
+}
+
+int mxc_dma_start(int channel)
+{
+ return -ENODEV;
+}
+
+int mxc_dma_stop(int channel)
+{
+ return -ENODEV;
+}
+
+void mxc_free_dma(int channel)
+{
+}
+
+void mxc_dma_set_callback(int channel, dma_callback_t callback, void *arg)
+{
+}
+
+void *sdma_malloc(size_t size)
+{
+ return 0;
+}
+
+void sdma_free(void *buf)
+{
+}
+
+void *sdma_phys_to_virt(unsigned long buf)
+{
+ return 0;
+}
+
+unsigned long sdma_virt_to_phys(void *buf)
+{
+ return 0;
+}
+
+int mxc_dma_request(mxc_dma_device_t channel_id, char *dev_name)
+{
+ return -ENODEV;
+}
+
+int mxc_dma_free(int channel_num)
+{
+ return -ENODEV;
+}
+
+int mxc_dma_config(int channel_num, mxc_dma_requestbuf_t * dma_buf,
+ int num_buf, mxc_dma_mode_t mode)
+{
+ return -ENODEV;
+}
+
+int mxc_dma_sg_config(int channel_num, struct scatterlist *sg,
+ int num_buf, int num_of_bytes, mxc_dma_mode_t mode)
+{
+ return -ENODEV;
+}
+
+int mxc_dma_callback_set(int channel_num, mxc_dma_callback_t callback,
+ void *arg)
+{
+ return -ENODEV;
+}
+
+int mxc_dma_disable(int channel_num)
+{
+ return -ENODEV;
+}
+
+int mxc_dma_enable(int channel_num)
+{
+ return -ENODEV;
+}
+
+EXPORT_SYMBOL(mxc_request_dma);
+EXPORT_SYMBOL(mxc_dma_setup_channel);
+EXPORT_SYMBOL(mxc_dma_set_channel_priority);
+EXPORT_SYMBOL(mxc_dma_set_config);
+EXPORT_SYMBOL(mxc_dma_get_config);
+EXPORT_SYMBOL(mxc_dma_start);
+EXPORT_SYMBOL(mxc_dma_stop);
+EXPORT_SYMBOL(mxc_free_dma);
+EXPORT_SYMBOL(mxc_dma_set_callback);
+EXPORT_SYMBOL(sdma_malloc);
+EXPORT_SYMBOL(sdma_free);
+EXPORT_SYMBOL(sdma_phys_to_virt);
+EXPORT_SYMBOL(sdma_virt_to_phys);
+
+#endif
+
+EXPORT_SYMBOL(mxc_dma_request);
+EXPORT_SYMBOL(mxc_dma_free);
+EXPORT_SYMBOL(mxc_dma_config);
+EXPORT_SYMBOL(mxc_dma_sg_config);
+EXPORT_SYMBOL(mxc_dma_callback_set);
+EXPORT_SYMBOL(mxc_dma_disable);
+EXPORT_SYMBOL(mxc_dma_enable);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXC Linux SDMA API");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/sdma/iapi/Makefile b/arch/arm/plat-mxc/sdma/iapi/Makefile
new file mode 100644
index 000000000000..b6a5d6aebda0
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for I.API sources.
+#
+
+obj-y := src/ \ No newline at end of file
diff --git a/arch/arm/plat-mxc/sdma/iapi/include/epm.h b/arch/arm/plat-mxc/sdma/iapi/include/epm.h
new file mode 100644
index 000000000000..a12fff923a15
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/include/epm.h
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2007-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#ifndef __ASM_ARCH_MXC_SDMA_REGS_H__
+#define __ASM_ARCH_MXC_SDMA_REGS_H__
+
+#include <mach/hardware.h>
+
+/* SDMA Reg definition */
+#define SDMA_BASE_IO_ADDR IO_ADDRESS(SDMA_BASE_ADDR)
+
+#define SDMA_H_C0PTR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x000))
+#define SDMA_H_INTR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x004))
+#define SDMA_H_STATSTOP *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x008))
+#define SDMA_H_START *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x00C))
+#define SDMA_H_EVTOVR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x010))
+#define SDMA_H_DSPOVR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x014))
+#define SDMA_H_HOSTOVR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x018))
+#define SDMA_H_EVTPEND *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x01C))
+#define SDMA_H_DSPENBL *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x020))
+#define SDMA_H_RESET *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x024))
+#define SDMA_H_EVTERR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x028))
+#define SDMA_H_INTRMSK *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x02C))
+#define SDMA_H_PSW *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x030))
+#define SDMA_H_EVTERRDBG *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x034))
+#define SDMA_H_CONFIG *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x038))
+#define SDMA_ONCE_ENB *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x040))
+#define SDMA_ONCE_DATA *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x044))
+#define SDMA_ONCE_INSTR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x048))
+#define SDMA_ONCE_STAT *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x04C))
+#define SDMA_ONCE_CMD *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x050))
+#define SDMA_EVT_MIRROR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x054))
+#define SDMA_ILLINSTADDR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x058))
+#define SDMA_CHN0ADDR *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x05C))
+#define SDMA_ONCE_RTB *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x060))
+#define SDMA_XTRIG_CONF1 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x070))
+#define SDMA_XTRIG_CONF2 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x074))
+
+#ifdef MXC_SDMA_V2
+#define SDMA_CHNENBL_0 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x200))
+#define SDMA_CHNENBL_1 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x204))
+#define SDMA_CHNENBL_2 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x208))
+#define SDMA_CHNENBL_3 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x20C))
+#define SDMA_CHNENBL_4 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x210))
+#define SDMA_CHNENBL_5 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x214))
+#define SDMA_CHNENBL_6 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x218))
+#define SDMA_CHNENBL_7 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x21C))
+#define SDMA_CHNENBL_8 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x220))
+#define SDMA_CHNENBL_9 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x224))
+#define SDMA_CHNENBL_10 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x228))
+#define SDMA_CHNENBL_11 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x22C))
+#define SDMA_CHNENBL_12 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x230))
+#define SDMA_CHNENBL_13 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x234))
+#define SDMA_CHNENBL_14 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x238))
+#define SDMA_CHNENBL_15 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x23C))
+#define SDMA_CHNENBL_16 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x240))
+#define SDMA_CHNENBL_17 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x244))
+#define SDMA_CHNENBL_18 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x248))
+#define SDMA_CHNENBL_19 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x24C))
+#define SDMA_CHNENBL_20 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x250))
+#define SDMA_CHNENBL_21 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x254))
+#define SDMA_CHNENBL_22 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x258))
+#define SDMA_CHNENBL_23 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x25C))
+#define SDMA_CHNENBL_24 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x260))
+#define SDMA_CHNENBL_25 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x264))
+#define SDMA_CHNENBL_26 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x268))
+#define SDMA_CHNENBL_27 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x26C))
+#define SDMA_CHNENBL_28 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x270))
+#define SDMA_CHNENBL_29 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x274))
+#define SDMA_CHNENBL_30 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x278))
+#define SDMA_CHNENBL_31 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x27C))
+#define SDMA_CHNENBL_32 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x280))
+#define SDMA_CHNENBL_33 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x284))
+#define SDMA_CHNENBL_34 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x288))
+#define SDMA_CHNENBL_35 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x28C))
+#define SDMA_CHNENBL_36 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x290))
+#define SDMA_CHNENBL_37 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x294))
+#define SDMA_CHNENBL_38 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x298))
+#define SDMA_CHNENBL_39 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x29C))
+#define SDMA_CHNENBL_40 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x2A0))
+#define SDMA_CHNENBL_41 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x2A4))
+#define SDMA_CHNENBL_42 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x2A8))
+#define SDMA_CHNENBL_43 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x2AC))
+#define SDMA_CHNENBL_44 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x2B0))
+#define SDMA_CHNENBL_45 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x2B4))
+#define SDMA_CHNENBL_46 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x2B8))
+#define SDMA_CHNENBL_47 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x2BC))
+
+#define SDMA_ONCE_COUNT *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x300))
+#define SDMA_ONCE_ECTL *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x304))
+#define SDMA_ONCE_EAA *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x308))
+#define SDMA_ONCE_EAB *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x30C))
+#define SDMA_ONCE_EAM *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x310))
+#define SDMA_ONCE_ED *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x314))
+#define SDMA_ONCE_EDM *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x318))
+#define SDMA_ONCE_PCMATCH *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x31C))
+
+#else
+
+#define SDMA_CHNENBL_0 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x080))
+#define SDMA_CHNENBL_1 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x084))
+#define SDMA_CHNENBL_2 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x088))
+#define SDMA_CHNENBL_3 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x08C))
+#define SDMA_CHNENBL_4 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x090))
+#define SDMA_CHNENBL_5 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x094))
+#define SDMA_CHNENBL_6 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x098))
+#define SDMA_CHNENBL_7 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x09C))
+#define SDMA_CHNENBL_8 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0A0))
+#define SDMA_CHNENBL_9 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0A4))
+#define SDMA_CHNENBL_10 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0A8))
+#define SDMA_CHNENBL_11 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0AC))
+#define SDMA_CHNENBL_12 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0B0))
+#define SDMA_CHNENBL_13 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0B4))
+#define SDMA_CHNENBL_14 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0B8))
+#define SDMA_CHNENBL_15 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0BC))
+#define SDMA_CHNENBL_16 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0C0))
+#define SDMA_CHNENBL_17 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0C4))
+#define SDMA_CHNENBL_18 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0C8))
+#define SDMA_CHNENBL_19 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0CC))
+#define SDMA_CHNENBL_20 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0D0))
+#define SDMA_CHNENBL_21 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0D4))
+#define SDMA_CHNENBL_22 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0D8))
+#define SDMA_CHNENBL_23 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0DC))
+#define SDMA_CHNENBL_24 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0E0))
+#define SDMA_CHNENBL_25 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0E4))
+#define SDMA_CHNENBL_26 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0E8))
+#define SDMA_CHNENBL_27 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0EC))
+#define SDMA_CHNENBL_28 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0F0))
+#define SDMA_CHNENBL_29 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0F4))
+#define SDMA_CHNENBL_30 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0F8))
+#define SDMA_CHNENBL_31 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x0FC))
+
+#define SDMA_ONCE_COUNT *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x200))
+#define SDMA_ONCE_ECTL *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x204))
+#define SDMA_ONCE_EAA *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x208))
+#define SDMA_ONCE_EAB *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x20C))
+#define SDMA_ONCE_EAM *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x210))
+#define SDMA_ONCE_ED *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x214))
+#define SDMA_ONCE_EDM *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x218))
+#define SDMA_ONCE_PCMATCH *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x21C))
+
+#endif /* MXC_SDMA_V2 */
+
+#define SDMA_CHNPRI_0 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x100))
+#define SDMA_CHNPRI_1 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x104))
+#define SDMA_CHNPRI_2 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x108))
+#define SDMA_CHNPRI_3 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x10C))
+#define SDMA_CHNPRI_4 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x110))
+#define SDMA_CHNPRI_5 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x114))
+#define SDMA_CHNPRI_6 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x118))
+#define SDMA_CHNPRI_7 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x11C))
+#define SDMA_CHNPRI_8 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x120))
+#define SDMA_CHNPRI_9 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x124))
+#define SDMA_CHNPRI_10 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x128))
+#define SDMA_CHNPRI_11 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x12C))
+#define SDMA_CHNPRI_12 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x130))
+#define SDMA_CHNPRI_13 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x134))
+#define SDMA_CHNPRI_14 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x138))
+#define SDMA_CHNPRI_15 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x13C))
+#define SDMA_CHNPRI_16 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x140))
+#define SDMA_CHNPRI_17 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x144))
+#define SDMA_CHNPRI_18 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x148))
+#define SDMA_CHNPRI_19 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x14C))
+#define SDMA_CHNPRI_20 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x150))
+#define SDMA_CHNPRI_21 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x154))
+#define SDMA_CHNPRI_22 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x158))
+#define SDMA_CHNPRI_23 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x15C))
+#define SDMA_CHNPRI_24 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x160))
+#define SDMA_CHNPRI_25 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x164))
+#define SDMA_CHNPRI_26 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x168))
+#define SDMA_CHNPRI_27 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x16C))
+#define SDMA_CHNPRI_28 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x170))
+#define SDMA_CHNPRI_29 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x174))
+#define SDMA_CHNPRI_30 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x178))
+#define SDMA_CHNPRI_31 *((volatile unsigned long *)(SDMA_BASE_IO_ADDR + 0x17C))
+
+#endif /* _mcuEpm_h */
diff --git a/arch/arm/plat-mxc/sdma/iapi/include/iapi.h b/arch/arm/plat-mxc/sdma/iapi/include/iapi.h
new file mode 100644
index 000000000000..d7300218057b
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/include/iapi.h
@@ -0,0 +1,49 @@
+/******************************************************************************
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: iapi.h
+ *
+ * $Id iapi.h $
+ *
+ * Description:
+ * Unique include for the whole IAPI library.
+ *
+ *
+ * http//compass.mot.com/go/115342679
+ *
+ * $Log iapi.h $
+ *
+ * ***************************************************************************/
+
+#ifndef _iapi_h
+#define _iapi_h
+
+/* ****************************************************************************
+ * Include File Section
+ * ***************************************************************************/
+
+#include "sdmaStruct.h"
+#include "iapiDefaults.h"
+#include "iapiLow.h"
+#include "iapiMiddle.h"
+#include "iapiHigh.h"
+
+#ifdef MCU
+#include "iapiLowMcu.h"
+#include "iapiMiddleMcu.h"
+#endif /* MCU */
+
+
+
+#endif /* _iapi_h */
diff --git a/arch/arm/plat-mxc/sdma/iapi/include/iapiDefaults.h b/arch/arm/plat-mxc/sdma/iapi/include/iapiDefaults.h
new file mode 100644
index 000000000000..b03a53ae1893
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/include/iapiDefaults.h
@@ -0,0 +1,128 @@
+/******************************************************************************
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: iapiDefaults.h
+ *
+ * $Id iapiDefaults.h $
+ *
+ * Description:
+ * This library is written in C to guarantee functionality and integrity in
+ * the usage of SDMA virtual DMA channels. This API (Application Programming
+ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
+ * fashion.
+ *
+ *
+ *
+ *
+ * $Log iapiDefaults.h $
+ *
+ *****************************************************************************/
+
+
+#ifndef _iapi_defaults_h
+#define _iapi_defaults_h
+
+/******************************************************************************
+ * Include File Section
+ *****************************************************************************/
+#include "epm.h"
+#include "sdmaStruct.h"
+
+/* ****************************************************************************
+ * Macro-command Section
+ * ***************************************************************************/
+
+/**
+ * Error codes
+ * lower 5 bits free to include channel number when available
+ * and bit number 6 must be set when channel number is available
+ *
+ * Note :
+ * 1) Abbreviations / naming convention :
+ * - BD : Buffer Descriptor
+ * - CC : Channel Context
+ * - CCB : Channel Control Block
+ * - CD : Channel Descriptor
+ * - B : Buffer
+ * - CH : Channel
+ *
+ */
+#define IAPI_SUCCESS 0
+#define IAPI_FAILURE -1
+#define IAPI_ERR_CH_AVAILABLE 0x00020
+#define IAPI_ERR_NO_ERROR 0x00000
+#define IAPI_ERR_NO_CCB_DEFINED 0x01000
+#define IAPI_ERR_BD_UNINITIALIZED 0x02000
+#define IAPI_ERR_BD_ALLOCATED 0x03000
+#define IAPI_ERR_BD_ALLOCATION 0x04000
+#define IAPI_ERR_CCB_ALLOC_FAILED 0x05000
+#define IAPI_ERR_CCB_UNINITIALIZED 0x06000
+#define IAPI_ERR_CC_ALREADY_DEFINED 0x07000
+#define IAPI_ERR_CC_ALLOC_FAILED 0x08000
+#define IAPI_ERR_CD_ALREADY_DEFINED 0x09000
+#define IAPI_ERR_CD_ALLOC_FAILED 0x0A000
+#define IAPI_ERR_CD_CHANGE_CH_NUMBER 0x0B000
+#define IAPI_ERR_CD_CHANGE_CCB_PTR 0x0C000
+#define IAPI_ERR_CD_CHANGE_UNKNOWN 0x0D000
+#define IAPI_ERR_CD_CHANGE 0x0E000
+#define IAPI_ERR_CD_UNINITIALIZED 0x0F000
+#define IAPI_ERR_CLOSE 0x10000
+#define IAPI_ERR_B_ALLOC_FAILED 0x11000
+#define IAPI_ERR_CONFIG_OVERRIDE 0x12000
+#define IAPI_ERR_CH_IN_USE 0x13000
+#define IAPI_ERR_CALLBACKSYNCH_UNKNOWN 0x14000
+#define IAPI_ERR_INVALID_PARAMETER 0x15000
+#define IAPI_ERR_TRUST 0x16000
+#define IAPI_ERR_CHANNEL_UNINITIALIZED 0x17000
+#define IAPI_ERR_RROR_BIT_READ 0x18000
+#define IAPI_ERR_RROR_BIT_WRITE 0x19000
+#define IAPI_ERR_NOT_ALLOWED 0x1A000
+#define IAPI_ERR_NO_OS_FN 0x1B000
+
+
+/*
+ * Global Variable Section
+ */
+
+/*
+ * Table to hold pointers to the callback functions registered by the users of
+ *I.API
+ */
+extern void (* callbackIsrTable[CH_NUM])(channelDescriptor * cd_p, void * arg);
+
+/*
+ * Table to hold user registered data pointers, to be privided in the callback
+ *function
+ */
+extern void * userArgTable[CH_NUM];
+
+/* channelDescriptor data structure filled with default data*/
+extern channelDescriptor iapi_ChannelDefaults;
+
+/* Global variable to hold the last error encountered in I.API operations*/
+extern unsigned int iapi_errno;
+
+/* Used in synchronization, to mark started channels*/
+extern volatile unsigned long iapi_SDMAIntr;
+
+/* Hold a pointer to the start of the CCB array, to be used in the IRQ routine
+ *to find the channel descriptor for the channed sending the interrupt to the
+ *core.
+ */
+extern channelControlBlock * iapi_CCBHead;
+
+/* configs_data structure filled with default data*/
+extern configs_data iapi_ConfigDefaults;
+
+#endif /* iapiDefaults_h */
diff --git a/arch/arm/plat-mxc/sdma/iapi/include/iapiHigh.h b/arch/arm/plat-mxc/sdma/iapi/include/iapiHigh.h
new file mode 100644
index 000000000000..14cfae539eb8
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/include/iapiHigh.h
@@ -0,0 +1,136 @@
+/******************************************************************************
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: iapiHigh.h
+ *
+ * $Id iapiHigh.h $
+ *
+ * Description:
+ * prototypes for high level function of I.API
+ *
+ *
+ * http://venerque.sps.mot.com/pjt/sfs/www/iapi/softsim_api.pdf
+ *
+ * $Log iapiHigh.h
+ *
+ * ***************************************************************************/
+
+#ifndef _iapiHigh_h
+#define _iapiHigh_h
+
+/* ****************************************************************************
+ * Include File Section
+ *****************************************************************************/
+#include "sdmaStruct.h"
+
+/* ****************************************************************************
+ * Macro-command Section
+ *****************************************************************************/
+enum {
+ IAPI_CHANGE_CHANDESC,
+ IAPI_CHANGE_BDNUM,
+ IAPI_CHANGE_BUFFSIZE,
+ IAPI_CHANGE_CHANBLOCK,
+ IAPI_CHANGE_INSTANCE,
+ IAPI_CHANGE_OWNERSHIP,
+ IAPI_CHANGE_SYNCH,
+ IAPI_CHANGE_TRUST,
+ IAPI_CHANGE_CALLBACKFUNC,
+ IAPI_CHANGE_CHANCCB,
+ IAPI_CHANGE_PRIORITY,
+ IAPI_CHANGE_BDWRAP,
+ IAPI_CHANGE_WATERMARK,
+ IAPI_CHANGE_SET_BDCONT,
+ IAPI_CHANGE_UNSET_BDCONT,
+ IAPI_CHANGE_SET_BDEXTD,
+ IAPI_CHANGE_UNSET_BDEXTD,
+ IAPI_CHANGE_EVTMASK1,
+ IAPI_CHANGE_EVTMASK2,
+ IAPI_CHANGE_PERIPHADDR,
+ IAPI_CHANGE_SET_BDINTR,
+ IAPI_CHANGE_UNSET_BDINTR,
+ IAPI_CHANGE_SET_TRANSFER_CD,
+ IAPI_CHANGE_FORCE_CLOSE,
+ IAPI_CHANGE_SET_TRANSFER,
+ IAPI_CHANGE_USER_ARG,
+ IAPI_CHANGE_SET_BUFFERADDR,
+ IAPI_CHANGE_SET_EXTDBUFFERADDR,
+ IAPI_CHANGE_SET_COMMAND,
+ IAPI_CHANGE_SET_COUNT,
+ IAPI_CHANGE_SET_STATUS,
+ IAPI_CHANGE_GET_BUFFERADDR,
+ IAPI_CHANGE_GET_EXTDBUFFERADDR,
+ IAPI_CHANGE_GET_COMMAND,
+ IAPI_CHANGE_GET_COUNT,
+ IAPI_CHANGE_GET_STATUS,
+ IAPI_CHANGE_SET_ENDIANNESS
+};
+
+
+/*
+ * Public Function Prototype Section
+ */
+int iapi_Open ( channelDescriptor * cd_p, unsigned char channelNumber );
+int iapi_Close( channelDescriptor * cd_p );
+int iapi_Read ( channelDescriptor * cd_p, void * buf, unsigned short nbyte );
+int iapi_Write( channelDescriptor * cd_p, void * buf, unsigned short nbyte );
+int iapi_MemCopy(channelDescriptor * cd_p, void* dest, void* src,
+ unsigned long size);
+int iapi_IoCtl( channelDescriptor * cd_p, unsigned long ctlRequest,
+ unsigned long param);
+
+
+int iapi_Read_ipcv2( channelDescriptor * cd_p, void * data_control_struct_ipcv2);
+
+int iapi_Write_ipcv2( channelDescriptor * cd_p, void * data_control_struct_ipcv2);
+
+#ifdef MCU
+int iapi_Init(channelDescriptor * cd_p, configs_data * config_p,
+ unsigned short* ram_image, unsigned short code_size,
+ unsigned long start_addr);
+#endif /* MCU */
+#ifdef DSP
+int iapi_Init(channelDescriptor * cd_p);
+#endif /* DSP */
+
+int iapi_StartChannel(unsigned char channel);
+int iapi_StopChannel(unsigned char channel);
+int iapi_SynchChannel(unsigned char channel);
+
+int iapi_GetChannelNumber(channelDescriptor * cd_p);
+unsigned long iapi_GetError(channelDescriptor * cd_p);
+int iapi_GetCount(channelDescriptor * cd_p);
+int iapi_GetCountAll(channelDescriptor * cd_p);
+
+#ifndef IRQ_KEYWORD
+#define IRQ_KEYWORD
+#endif /* IRQ_KEYWORD */
+
+IRQ_KEYWORD void IRQ_Handler(void);
+
+#ifdef MCU
+int iapi_GetScript(channelDescriptor * cd_p, void * buf, unsigned short size,
+ unsigned long address);
+int iapi_GetContext(channelDescriptor * cd_p, void * buf,
+ unsigned char channel);
+int iapi_SetScript(channelDescriptor * cd_p, void * buf, unsigned short nbyte,
+ unsigned long destAddr);
+int iapi_SetContext(channelDescriptor * cd_p, void * buf,
+ unsigned char channel);
+int iapi_AssignScript(channelDescriptor * cd_p, script_data * data_p);
+
+int iapi_SetChannelEventMapping(unsigned char event, unsigned long channel_map);
+#endif /* MCU */
+
+#endif /* _iapiHigh_h */
diff --git a/arch/arm/plat-mxc/sdma/iapi/include/iapiLow.h b/arch/arm/plat-mxc/sdma/iapi/include/iapiLow.h
new file mode 100644
index 000000000000..43aff7a4e903
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/include/iapiLow.h
@@ -0,0 +1,78 @@
+/******************************************************************************
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: iapiLow.h
+ *
+ * $Id iapiLow.h $
+ *
+ * Description:
+ * prototypes for low level function of I.API
+ *
+ *
+ *
+ *
+ * $Log iapiLow.h
+ *
+ * ***************************************************************************/
+
+#ifndef _iapiLow_h
+#define _iapiLow_h
+
+/* ****************************************************************************
+ * Boolean identifiers
+ *****************************************************************************/
+#define NO_OS 0
+#define LINUX 1
+#define SYMBIAN 2
+#define WINCE 3
+
+/* ****************************************************************************
+ * Include File Section
+ *****************************************************************************/
+#include "sdmaStruct.h"
+#include "iapiDefaults.h"
+#include "iapiOS.h"
+#ifdef MCU
+#include "iapiLowMcu.h"
+#endif /*MCU*/
+#if OS == NO_OS
+#include <stdlib.h>
+#elif OS == LINUX
+#include <linux/types.h>
+#endif
+
+
+/* ****************************************************************************
+ * Macro-command Section
+ *****************************************************************************/
+
+#define GOTO_SLEEP(x) (iapi_GotoSleep)(x)
+#define INIT_SLEEP(x) (iapi_InitSleep)(x)
+
+/* ****************************************************************************
+ * Public Function Prototype Section
+ *****************************************************************************/
+void iapi_lowStartChannel ( unsigned char channel );
+void iapi_lowStopChannel ( unsigned char channel );
+void iapi_AttachCallbackISR (channelDescriptor * cd_p,
+ void (* func_p)(channelDescriptor * cd_p, void * arg));
+void iapi_DetachCallbackISR (channelDescriptor * cd_p);
+void iapi_ChangeCallbackISR (channelDescriptor * cd_p,
+ void (* func_p)(channelDescriptor * cd_p, void * arg));
+void iapi_lowSynchChannel ( unsigned char channel );
+void iapi_SetBufferDescriptor(bufferDescriptor *bd_p, unsigned char command,
+ unsigned char status, unsigned short count,
+ void * buffAddr, void * extBufferAddr);
+
+#endif /* _iapiLow_h */
diff --git a/arch/arm/plat-mxc/sdma/iapi/include/iapiLowDsp.h b/arch/arm/plat-mxc/sdma/iapi/include/iapiLowDsp.h
new file mode 100644
index 000000000000..0adaa2548b9e
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/include/iapiLowDsp.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/* ****************************************************************************
+ *
+ * File: iapiLowDsp.h
+ *
+ * $Id iapiLowDsp.h $
+ *
+ * Description:
+ * prototypes for low level function of I.API for DSP side only
+ *
+ *
+ *
+ *
+ * $Log iapiLowDsp.h
+ *
+ * ***************************************************************************/
+
+#ifndef _iapiLowDsp_h
+#define _iapiLowDsp_h
+
+/* ****************************************************************************
+ * Include File Section
+ *****************************************************************************/
+
+
+/* ****************************************************************************
+ * Public Function Prototype Section
+ *****************************************************************************/
+/* WARNING !!!!!
+ * This file is empty and it is normal, because there is no low level functions
+ * dedicated to the DSP but the file (iapi_LowDsp.h) must still exist because
+ * some project directly links the file. Previously, there were function
+ * iapi_EnableInterrupts,iapi_DisableInterrupts,iapi_WaitCore,iapi_StartChannel
+ * iapi_StopChannel but they are common to both MCU and DSP, so they have been
+ * moved to iapi_Low.h file.
+ */
+
+#endif /* _iapiLowDsp_h */
diff --git a/arch/arm/plat-mxc/sdma/iapi/include/iapiLowMcu.h b/arch/arm/plat-mxc/sdma/iapi/include/iapiLowMcu.h
new file mode 100644
index 000000000000..12bea564c116
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/include/iapiLowMcu.h
@@ -0,0 +1,60 @@
+/******************************************************************************
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: iapiLowMcu.h
+ *
+ * $Id iapiLowMcu.h $
+ *
+ * Description:
+ * prototypes for low level function of I.API of MCU side only
+ *
+ *
+ *
+ *
+ * $Log iapiLowMcu.h $
+ *
+ * ***************************************************************************/
+
+#ifndef _iapiLowMcu_h
+#define _iapiLowMcu_h
+
+/******************************************************************************
+ * Include File Section
+ *****************************************************************************/
+#include "sdmaStruct.h"
+#include "iapiDefaults.h"
+
+/* ****************************************************************************
+ * Public Function Prototype Section
+ * ***************************************************************************/
+
+
+void iapi_InitChannelTables ( void );
+int iapi_ChannelConfig(unsigned char channel, unsigned eventOverride,
+ unsigned mcuOverride, unsigned dspOverride);
+int iapi_Channel0Command(channelDescriptor * cd_p, void * buf,
+ unsigned short nbyte, unsigned char command);
+void iapi_lowGetScript(channelDescriptor * cd_p, void * buf, unsigned short size,
+ unsigned long address);
+void iapi_lowGetContext(channelDescriptor * cd_p, void * buf,
+ unsigned char channel);
+void iapi_lowSetScript(channelDescriptor * cd_p, void * buf, unsigned short nbyte,
+ unsigned long destAddr);
+void iapi_lowSetContext(channelDescriptor * cd_p, void * buf,
+ unsigned char channel);
+int iapi_lowAssignScript(channelDescriptor * cd_p, script_data * data_p);
+
+int iapi_lowSetChannelEventMapping(unsigned char event, unsigned long channel_map);
+
+#endif /* _iapiLowMcu_h */
diff --git a/arch/arm/plat-mxc/sdma/iapi/include/iapiMiddle.h b/arch/arm/plat-mxc/sdma/iapi/include/iapiMiddle.h
new file mode 100644
index 000000000000..2470ffcaabf1
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/include/iapiMiddle.h
@@ -0,0 +1,52 @@
+/******************************************************************************
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: iapiMiddle.h
+ *
+ * $Id iapiMiddle.h $
+ *
+ * Description:
+ * prototypes for middle level function of I.API
+ *
+ *
+ *
+ *
+ * $Log iapiMiddle.h
+ *
+ * ***************************************************************************/
+
+#ifndef _iapiMiddle_h
+#define _iapiMiddle_h
+
+/* ****************************************************************************
+ * Include File Section
+ ******************************************************************************/
+#include "sdmaStruct.h"
+#ifdef MCU
+#include "iapiMiddleMcu.h"
+#endif /* MCU */
+
+/* ****************************************************************************
+ * Public Function Prototype Section
+ ******************************************************************************/
+bufferDescriptor * iapi_AllocBD (channelControlBlock * ccb_p);
+int iapi_AllocContext(contextData ** ctxd_p, unsigned char channel);
+int iapi_AllocChannelDesc(channelDescriptor ** cd_p, unsigned char channel);
+int iapi_ChangeChannelDesc (channelDescriptor * cd_p,
+ unsigned char whatToChange, unsigned long newval);
+void iapi_InitializeCallbackISR (void (* func_p)(channelDescriptor * cd_p,
+ void * arg));
+int iapi_InitializeMemory (channelControlBlock * ccb_p);
+
+#endif /* iapiMiddle_h */
diff --git a/arch/arm/plat-mxc/sdma/iapi/include/iapiMiddleMcu.h b/arch/arm/plat-mxc/sdma/iapi/include/iapiMiddleMcu.h
new file mode 100644
index 000000000000..a47c02d4440b
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/include/iapiMiddleMcu.h
@@ -0,0 +1,41 @@
+/******************************************************************************
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: iapiMiddleMcu.h
+ *
+ * $Id iapiMiddleMcu.h $
+ *
+ * Description:
+ * prototypes for middle level function of I.API
+ *
+ *
+ *
+ *
+ * $Log iapiMiddleMcu.h
+ *
+ * ***************************************************************************/
+
+#ifndef _iapiMiddleMcu_h
+#define _iapiMiddleMcu_h
+
+/* ****************************************************************************
+ * Include File Section
+ ******************************************************************************/
+#include "sdmaStruct.h"
+
+/* ****************************************************************************
+ * Public Function Prototype Section
+ ******************************************************************************/
+
+#endif /* iapiMiddleMcu_h */
diff --git a/arch/arm/plat-mxc/sdma/iapi/include/iapiOS.h b/arch/arm/plat-mxc/sdma/iapi/include/iapiOS.h
new file mode 100644
index 000000000000..17186dae0fd5
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/include/iapiOS.h
@@ -0,0 +1,96 @@
+/******************************************************************************
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: iapiOS.h
+ *
+ * $Id iapiOS.h $
+ *
+ * Description:
+ * prototypes for OS level function of I.API
+ *
+ *
+ *
+ *
+ * $Log iapiOS.h
+ *
+ * ***************************************************************************/
+
+#ifndef _iapiOS_h
+#define _iapiOS_h
+
+/* ****************************************************************************
+ * Boolean identifiers
+ *****************************************************************************/
+#define NO_OS 0
+#define LINUX 1
+#define SYMBIAN 2
+#define WINCE 3
+
+/* ****************************************************************************
+ * Include File Section
+ *****************************************************************************/
+#include "sdmaStruct.h"
+#include "iapiDefaults.h"
+#ifdef MCU
+#include "iapiLowMcu.h"
+#endif /*MCU*/
+#if OS == NO_OS
+#include <stdlib.h>
+#elif OS == LINUX
+#include <linux/types.h>
+#endif
+
+/* ****************************************************************************
+ * Macro-command Section
+ *****************************************************************************/
+#define SDMA_ERAM 0
+#define SDMA_IRAM 1
+#ifdef CONFIG_SDMA_IRAM
+#define MALLOC(x, s) (s == SDMA_ERAM)? (* iapi_Malloc)(x):(* iapi_iram_Malloc)(x)
+#else /*CONFIG_SDMA_IRAM */
+#define MALLOC(x, s) (* iapi_Malloc)(x)
+#endif /*CONFIG_SDMA_IRAM */
+#define FREE(x) if (x!=NULL) (* iapi_Free)(x)
+
+#define GOTO_SLEEP(x) (iapi_GotoSleep)(x)
+#define INIT_SLEEP(x) (iapi_InitSleep)(x)
+
+/* ****************************************************************************
+ * Public Function Prototype Section
+ *****************************************************************************/
+
+#ifdef CONFIG_SDMA_IRAM
+extern void*(* iapi_iram_Malloc) (size_t size);
+#endif /*CONFIG_SDMA_IRAM*/
+
+extern void*(* iapi_Malloc) (size_t size);
+extern void (* iapi_Free) (void * ptr);
+
+extern void*(* iapi_Virt2Phys) (void * ptr);
+extern void*(* iapi_Phys2Virt) (void * ptr);
+
+extern void (* iapi_WakeUp)(int);
+extern void (* iapi_GotoSleep)(int);
+extern void (* iapi_InitSleep)(int);
+
+extern void*(* iapi_memcpy)(void *dest, const void *src, size_t count);
+extern void*(* iapi_memset)(void *dest, int c, size_t count);
+
+extern void (* iapi_EnableInterrupts)(void);
+extern void (* iapi_DisableInterrupts)(void);
+
+extern int (* iapi_GetChannel)(int);
+extern int (* iapi_ReleaseChannel)(int);
+
+#endif /* _iapiOS_h */
diff --git a/arch/arm/plat-mxc/sdma/iapi/include/sdmaStruct.h b/arch/arm/plat-mxc/sdma/iapi/include/sdmaStruct.h
new file mode 100644
index 000000000000..995d21553f8a
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/include/sdmaStruct.h
@@ -0,0 +1,425 @@
+/******************************************************************************
+ *
+ * Copyright 2007-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: sdmaStruct.h
+ *
+ * $Id sdmaStruct.h $
+ *
+ * Description: provides necessary definitions and inclusion for ipcmStruct.c
+ *
+ * $Log $
+ *
+ *****************************************************************************/
+#ifndef _sdmaStruct_h
+#define _sdmaStruct_h
+
+/* ****************************************************************************
+ * Include File Section
+ ******************************************************************************/
+
+/* ****************************************************************************
+ * Macro-command Section
+ ******************************************************************************/
+
+/**
+ * Identifier NULL
+ */
+#ifndef NULL
+#define NULL 0
+#endif
+
+/**
+ * Boolean identifiers
+ */
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+/**
+ * Number of channels
+ */
+#define CH_NUM 32
+/**
+ * Number of events
+ */
+#ifdef MXC_SDMA_V2
+#define EVENTS_NUM 48
+#else
+#define EVENTS_NUM 32
+#endif
+/**
+ * Channel configuration
+ */
+#define DONT_OWN_CHANNEL 0
+#define OWN_CHANNEL 1
+
+/**
+ * Ownership (value defined to computed decimal value)
+ */
+#define CH_OWNSHP_OFFSET_EVT 0
+#define CH_OWNSHP_OFFSET_MCU 1
+#define CH_OWNSHP_OFFSET_DSP 2
+/**
+ * Indexof the greg which holds address to start a script from when channel
+ * becomes current.
+ */
+#define SDMA_NUMBER_GREGS 8
+
+/**
+ * Channel contexts management
+ */
+
+#define CHANNEL_CONTEXT_BASE_ADDRESS 0x800
+/**
+ * Buffer descriptor status values.
+ */
+#define BD_DONE 0x01
+#define BD_WRAP 0x02
+#define BD_CONT 0x04
+#define BD_INTR 0x08
+#define BD_RROR 0x10
+#define BD_LAST 0x20
+#define BD_EXTD 0x80
+
+
+/**
+ * Data Node descriptor status values.
+ */
+#define DND_END_OF_FRAME 0x80
+#define DND_END_OF_XFER 0x40
+#define DND_DONE 0x20
+#define DND_UNUSED 0x01
+
+/**
+ * IPCV2 descriptor status values.
+ */
+#define BD_IPCV2_END_OF_FRAME 0x40
+
+
+#define IPCV2_MAX_NODES 50
+/**
+ * Error bit set in the CCB status field by the SDMA,
+ * in setbd routine, in case of a transfer error
+ */
+#define DATA_ERROR 0x10000000
+
+/**
+ * Buffer descriptor commands.
+ */
+#define C0_ADDR 0x01
+#define C0_LOAD 0x02
+#define C0_DUMP 0x03
+#define C0_SETCTX 0x07
+#define C0_GETCTX 0x03
+#define C0_SETDM 0x01
+#define C0_SETPM 0x04
+#define C0_GETDM 0x02
+#define C0_GETPM 0x08
+/**
+ * Transfer types, encoded in the BD command field
+ */
+#define TRANSFER_32BIT 0x00
+#define TRANSFER_8BIT 0x01
+#define TRANSFER_16BIT 0x02
+#define TRANSFER_24BIT 0x03
+/**
+ * Change endianness indicator in the BD command field
+ */
+#define CHANGE_ENDIANNESS 0x80
+/**
+ * Size in bytes
+ */
+#define SDMA_BD_SIZE 8
+#define SDMA_EXTENDED_BD_SIZE 12
+#define BD_NUMBER 4
+/**
+ * Channel interrupt policy
+ */
+#define DEFAULT_POLL 0
+#define CALLBACK_ISR 1
+/**
+ * Channel status
+ */
+#define UNINITIALIZED 0
+#define INITIALIZED 1
+
+/**
+ * IoCtl particular values
+ */
+#define SET_BIT_ALL 0xFFFFFFFF
+#define BD_NUM_OFFSET 16
+#define BD_NUM_MASK 0xFFFF0000
+
+/**
+ * Maximum values for IoCtl calls, used in high or middle level calls
+ */
+#define MAX_BD_NUM 256
+#define MAX_BD_SIZE 65536
+#define MAX_BLOCKING 2
+#define MAX_SYNCH 2
+#define MAX_OWNERSHIP 8
+#define MAX_CH_PRIORITY 8
+#define MAX_TRUST 2
+#define MAX_WML 256
+
+
+/**
+ * Access to channelDescriptor fields
+ */
+enum {
+ IAPI_CHANNELNUMBER,
+ IAPI_BUFFERDESCNUMBER,
+ IAPI_BUFFERSIZE,
+ IAPI_BLOCKING,
+ IAPI_CALLBACKSYNCH,
+ IAPI_OWNERSHIP,
+ IAPI_PRIORITY,
+ IAPI_TRUST,
+ IAPI_UNUSED,
+ IAPI_CALLBACKISR_PTR,
+ IAPI_CCB_PTR,
+ IAPI_BDWRAP,
+ IAPI_WML
+};
+
+/**
+ * Default values for channel descriptor - nobody ownes the channel
+ */
+#define CD_DEFAULT_OWNERSHIP 7
+
+
+/**
+ * User Type Section
+ */
+
+/**
+ * Command/Mode/Count of buffer descriptors
+ */
+
+#if (ENDIANNESS==B_I_G_ENDIAN)
+typedef struct iapi_modeCount_ipcv2 {
+ unsigned long status : 8; /**< L, E , D bits stored here */
+ unsigned long reserved : 8;
+ unsigned long count : 16; /**< <size of the buffer pointed by this BD */
+} modeCount_ipcv2;
+#else
+typedef struct iapi_modeCount_ipcv2 {
+ unsigned long count : 16; /**<size of the buffer pointed by this BD */
+ unsigned long reserved : 8; /**Reserved*/
+ unsigned long status : 8; /**< L, E , D bits stored here */
+} modeCount_ipcv2;
+#endif
+/**
+ * Data Node descriptor - IPCv2
+ * (differentiated between evolutions of SDMA)
+ */
+typedef struct iapi_dataNodeDescriptor {
+ modeCount_ipcv2 mode; /**<command, status and count */
+ void * bufferAddr; /**<address of the buffer described */
+} dataNodeDescriptor;
+
+#if (ENDIANNESS==B_I_G_ENDIAN)
+typedef struct iapi_modeCount_ipcv1_v2 {
+ unsigned long endianness: 1;
+ unsigned long reserved: 7;
+ unsigned long status : 8; /**< E,R,I,C,W,D status bits stored here */
+ unsigned long count : 16; /**< size of the buffer pointed by this BD */
+} modeCount_ipcv1_v2;
+#else
+typedef struct iapi_modeCount_ipcv1_v2 {
+ unsigned long count : 16; /**<size of the buffer pointed by this BD */
+ unsigned long status : 8; /**< E,R,I,C,W,D status bits stored here */
+ unsigned long reserved: 7;
+ unsigned long endianness: 1;
+} modeCount_ipcv1_v2;
+#endif
+/**
+ * Buffer descriptor
+ * (differentiated between evolutions of SDMA)
+ */
+typedef struct iapi_bufferDescriptor_ipcv1_v2 {
+ modeCount_ipcv1_v2 mode; /**<command, status and count */
+ void * bufferAddr; /**<address of the buffer described */
+ void * extBufferAddr; /**<extended buffer address */
+} bufferDescriptor_ipcv1_v2;
+
+
+/**
+ * Mode/Count of data node descriptors - IPCv2
+ */
+
+#if (ENDIANNESS==B_I_G_ENDIAN)
+typedef struct iapi_modeCount {
+ unsigned long command : 8; /**< command mostlky used for channel 0 */
+ unsigned long status : 8; /**< E,R,I,C,W,D status bits stored here */
+ unsigned long count : 16; /**< size of the buffer pointed by this BD */
+} modeCount;
+#else
+typedef struct iapi_modeCount {
+ unsigned long count : 16; /**<size of the buffer pointed by this BD */
+ unsigned long status : 8; /**< E,R,I,C,W,D status bits stored here */
+ unsigned long command : 8; /**< command mostlky used for channel 0 */
+} modeCount;
+#endif
+
+
+/**
+ * Buffer descriptor
+ * (differentiated between evolutions of SDMA)
+ */
+typedef struct iapi_bufferDescriptor {
+ modeCount mode; /**<command, status and count */
+ void * bufferAddr; /**<address of the buffer described */
+ void * extBufferAddr; /**<extended buffer address */
+} bufferDescriptor;
+
+
+
+struct iapi_channelControlBlock;
+struct iapi_channelDescriptor;
+/**
+ * Channel Descriptor
+ */
+typedef struct iapi_channelDescriptor {
+ unsigned char channelNumber ;/**<stores the channel number */
+ unsigned char bufferDescNumber;/**<number of BD's automatically allocated for this channel */
+ unsigned short bufferSize ;/**<size (in bytes) of buffer descriptors */
+ unsigned long blocking :3;/**<blocking / non blocking feature selection */
+ unsigned long callbackSynch :1;/**<polling/ callback method selection */
+ unsigned long ownership :3;/**<ownership of the channel (host+dedicated+event)*/
+ unsigned long priority :3;/**<reflects the SDMA channel priority register */
+ unsigned long trust :1;/**<trusted buffers or kernel allocated */
+ unsigned long useDataSize :1;/**<indicates if the dataSize field is meaningfull */
+ unsigned long dataSize :2;/**<data transfer size - 8,16,24 or 32 bits*/
+ unsigned long forceClose :1;/**<if TRUE, close channel even with BD owned by SDMA*/
+ unsigned long scriptId :7;/**<number of the script */
+ unsigned long watermarkLevel:10;/**<Watermark level for the peripheral access*/
+ unsigned long eventMask1; /**<First Event mask */
+ unsigned long eventMask2; /**<Second Event mask */
+ unsigned long peripheralAddr; /**<Address of the peripheral or its fifo when needed */
+ void (* callbackISR_ptr)(struct iapi_channelDescriptor*, void*); /**<pointer to the callback function (or NULL) */
+ struct iapi_channelControlBlock * ccb_ptr; /**<pointer to the channel control block associated to this channel */
+} channelDescriptor;
+
+/**
+ * Channel Status
+ */
+typedef struct iapi_channelStatus {
+ unsigned long unused :29;/**<*/
+ unsigned long openedInit : 1;/**<channel is initialized or not */
+ unsigned long stateDirection: 1;/**<sdma is reading/writing (as seen from channel owner core) */
+ unsigned long execute : 1;/**<channel is being processed (started) or not */
+} channelStatus;
+
+/**
+ * Channel control Block
+ */
+typedef struct iapi_channelControlBlock {
+ bufferDescriptor * currentBDptr; /**<current buffer descriptor processed */
+ bufferDescriptor * baseBDptr; /**<first element of buffer descriptor array */
+ channelDescriptor * channelDescriptor; /**<pointer to the channel descriptor */
+ channelStatus status; /**<open/close ; started/stopped ; read/write */
+} channelControlBlock;
+
+/**
+ * Context structure.
+ */
+#if (ENDIANNESS==B_I_G_ENDIAN)
+typedef struct iapi_stateRegisters {
+ unsigned long sf : 1;/**<source falut while loading data */
+ unsigned long unused0: 1;/**<*/
+ unsigned long rpc :14;/**<return program counter */
+ unsigned long t : 1;/**<test bit:status of arithmetic & test instruction*/
+ unsigned long unused1: 1;/**<*/
+ unsigned long pc :14;/**<program counter */
+ unsigned long lm : 2;/**<loop mode */
+ unsigned long epc :14;/**<loop end program counter */
+ unsigned long df : 1;/**<destiantion falut while storing data */
+ unsigned long unused2: 1;/**<*/
+ unsigned long spc :14;/**<loop start program counter */
+} stateRegiters;
+#else
+typedef struct iapi_stateRegisters {
+ unsigned long pc :14;/**<program counter */
+ unsigned long unused1: 1;/**<*/
+ unsigned long t : 1;/**<test bit: status of arithmetic & test instruction*/
+ unsigned long rpc :14;/**<return program counter */
+ unsigned long unused0: 1;/**<*/
+ unsigned long sf : 1;/**<source falut while loading data */
+ unsigned long spc :14;/**<loop start program counter */
+ unsigned long unused2: 1;/**<*/
+ unsigned long df : 1;/**<destiantion falut while storing data */
+ unsigned long epc :14;/**<loop end program counter */
+ unsigned long lm : 2;/**<loop mode */
+} stateRegiters;
+#endif
+
+/**
+ * This is SDMA version of SDMA
+ */
+typedef struct iapi_contextData {
+ stateRegiters channelState; /**<channel state bits */
+ unsigned long gReg[ SDMA_NUMBER_GREGS ]; /**<general registers */
+ unsigned long mda; /**<burst dma destination address register */
+ unsigned long msa; /**<burst dma source address register */
+ unsigned long ms; /**<burst dma status register */
+ unsigned long md; /**<burst dma data register */
+ unsigned long pda; /**<peripheral dma destination address register */
+ unsigned long psa; /**<peripheral dma source address register */
+ unsigned long ps; /**<peripheral dma status register */
+ unsigned long pd; /**<peripheral dma data register */
+ unsigned long ca; /**<CRC polynomial register */
+ unsigned long cs; /**<CRC accumulator register */
+ unsigned long dda; /**<dedicated core destination address register */
+ unsigned long dsa; /**<dedicated core source address register */
+ unsigned long ds; /**<dedicated core status register */
+ unsigned long dd; /**<dedicated core data register */
+ unsigned long scratch0; /**<scratch */
+ unsigned long scratch1; /**<scratch */
+ unsigned long scratch2; /**<scratch */
+ unsigned long scratch3; /**<scratch */
+ unsigned long scratch4; /**<scratch */
+ unsigned long scratch5; /**<scratch */
+ unsigned long scratch6; /**<scratch */
+ unsigned long scratch7; /**<scratch */
+
+} contextData;
+
+/**
+ *This structure holds the necessary data for the assignment in the
+ * dynamic channel-script association
+ */
+typedef struct iapi_script_data {
+ unsigned short load_address;/**<start address of the script*/
+ unsigned long wml; /**<parameters for the channel descriptor*/
+ unsigned long shp_addr; /**<shared peripheral base address*/
+ unsigned long event_mask1; /**<First Event mask */
+ unsigned long event_mask2; /**<Second Event mask */
+} script_data;
+
+/**
+ *This structure holds the the useful bits of the CONFIG register
+ */
+typedef struct iapi_configs_data {
+ unsigned long dspdma :1; /*indicates if the DSPDMA is used */
+ unsigned long rtdobs :1; /*indicates if Real-Time Debug pins are enabled */
+ unsigned long acr :1; /**indicates if AHB freq /core freq = 2 or 1 */
+ unsigned long csm :2; /**indicates which context switch mode is selected*/
+} configs_data;
+
+#endif /* _sdmaStruct_h */
diff --git a/arch/arm/plat-mxc/sdma/iapi/src/Makefile b/arch/arm/plat-mxc/sdma/iapi/src/Makefile
new file mode 100644
index 000000000000..4c112bf22384
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/src/Makefile
@@ -0,0 +1,18 @@
+#
+# Makefile for I.API sources.
+#
+ifneq ($(KBUILD_SRC),)
+ccflags-y += -I$(KBUILD_SRC)/arch/arm/plat-mxc/sdma/iapi/include \
+ -I$(KBUILD_SRC)/include/linux \
+ -DMCU -DOS=LINUX \
+ -DL_I_T_T_L_E_ENDIAN=0 -DB_I_G_ENDIAN=1 \
+ -DENDIANNESS=L_I_T_T_L_E_ENDIAN
+else
+ccflags-y += -Iarch/arm/plat-mxc/sdma/iapi/include \
+ -Iinclude/linux \
+ -DMCU -DOS=LINUX \
+ -DL_I_T_T_L_E_ENDIAN=0 -DB_I_G_ENDIAN=1 \
+ -DENDIANNESS=L_I_T_T_L_E_ENDIAN
+endif
+
+obj-y += iapiLow.o iapiLowMcu.o iapiMiddle.o iapiMiddleMcu.o iapiHigh.o iapiDefaults.o iapiOS.o
diff --git a/arch/arm/plat-mxc/sdma/iapi/src/iapiDefaults.c b/arch/arm/plat-mxc/sdma/iapi/src/iapiDefaults.c
new file mode 100644
index 000000000000..345c240cb15c
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/src/iapiDefaults.c
@@ -0,0 +1,110 @@
+/******************************************************************************
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: iapiDefaults.c
+ *
+ * $Id iapiDefaults.c $
+ *
+ * Description:
+ * This library is written in C to guarantee functionality and integrity in
+ * the usage of SDMA virtual DMA channels. This API (Application Programming
+ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
+ * fashion.
+ *
+ * Usage:
+ *
+ * Files:
+ *
+ *
+* /
+ *
+ * $Log iapiDefaults.c $
+ *
+ *****************************************************************************/
+
+/* ****************************************************************************
+ * Include File Section
+ ******************************************************************************/
+#include "iapiDefaults.h"
+
+/* ****************************************************************************
+ * Global Variable Section
+ ******************************************************************************/
+
+/**
+ * @brief System Call-back ISRs Table
+ */
+void (* callbackIsrTable[CH_NUM])(channelDescriptor* cd_p, void* arg);
+
+/**
+ * @brief User registered pointers table
+ */
+void * userArgTable[CH_NUM];
+
+/**
+ * @brief Pointer to the first CCB in the CCB array
+ */
+channelControlBlock * iapi_CCBHead = NULL;
+
+
+/**Default channel description.
+ *
+ * Initialization values are:\n
+ * - channelNumber = 0
+ * - bufferDescNumber = 1
+ * - bufferSize = 8
+ * - blocking = 0
+ * - callbackSynch = DEFAULT_POLL
+ * - ownership = CD_DEFAULT_OWNERSHIP
+ * - priority = 1
+ * - trust = TRUE
+ * - useDataSize = 0
+ * - dataSize = 0
+ * - forceClose = 0
+ * - scriptId = 0
+ * - watermarkLevel = 0
+ * - eventMask1 = 0
+ * - eventMask2 = 0
+ * - peripheralAddr = NULL
+ * - callbackISR_ptr = NULL
+ * - iapi_channelControlBlock = NULL
+ */
+channelDescriptor iapi_ChannelDefaults = {0, 1, 8, 0, DEFAULT_POLL,
+ CD_DEFAULT_OWNERSHIP, 1, TRUE, 0, 0, 0, 0,
+ 0, 0x00, 0x00, 0x00, NULL, NULL};
+
+/**
+ * Integrated error management
+ */
+unsigned int iapi_errno = 0;
+volatile unsigned long iapi_SDMAIntr = 0;
+
+/* Default config register.
+ * Initialization values are:
+ * dspdma used
+ * Real-Time Debug pins disabled
+ * AHB freq / core freq = 2
+ * dynamic context switch
+*/
+configs_data iapi_ConfigDefaults = {1, 0, 0, 3};
+
+#ifdef SDMA_SKYE
+/* Default sdma State : UNDEF
+ *possible value are UNDEF, OPEN, LOCK, CLOSED, CLOSE_LOCK
+ */
+
+sdmaState iapi_SdmaState= UNDEF;
+#endif
+
+/* ***************************************************************************/
diff --git a/arch/arm/plat-mxc/sdma/iapi/src/iapiHigh.c b/arch/arm/plat-mxc/sdma/iapi/src/iapiHigh.c
new file mode 100644
index 000000000000..abdd2d89ab67
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/src/iapiHigh.c
@@ -0,0 +1,2798 @@
+/******************************************************************************
+ *
+ * Copyright 2007-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: iapiHigh.c
+ *
+ * $Id iapiHigh.c $
+ *
+ * Description:
+ * This library is written in C to guarantee functionality and integrity in
+ * the usage of SDMA virtual DMA channels. This API (Application Programming
+ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
+ * fashion.
+ * These are the HIGH level functions of the I.API.
+ *
+ *
+ * /
+ *
+ * $Log iapiHigh.c $
+ *
+ *****************************************************************************/
+
+/* ****************************************************************************
+ * Include File Section
+ *****************************************************************************/
+#include <stdarg.h>
+#include <string.h>
+
+#include "epm.h"
+#include "iapi.h"
+
+/* ****************************************************************************
+ * External Reference Section (for compatibility with already developed code)
+ *****************************************************************************/
+static void iapi_read_ipcv2_callback(struct iapi_channelDescriptor* cd_p, void* data);
+
+/* ****************************************************************************
+ * Global Variable Section
+ *****************************************************************************/
+#define MAX_CHANNEL 32
+
+static dataNodeDescriptor* dnd_read_control_struct[MAX_CHANNEL];
+
+/* MASK to get Nullify all the bits of Status in Data Node descriptor apart from L, E and D*/
+
+#define GET_LED_MASK 0xE0
+
+/*Table defines mapping of Data Node Descriptor to Buffer Descriptor status*/
+
+static unsigned char dnd_2_bd_status[]=
+{
+0x85, /*00 L = 0, E = 0, D = 0*/
+0x00, /*01*/
+0x00, /*02*/
+0x00, /*03*/
+0x00, /*04*/
+0x00, /*05*/
+0x00, /*06*/
+0x00, /*07*/
+0x00, /*08*/
+0x00, /*09*/
+0x00, /*0A*/
+0x00, /*0B*/
+0x00, /*0C*/
+0x00, /*0D*/
+0x00, /*0E*/
+0x00, /*0F*/
+0x00, /*10*/
+0x00,/*11*/
+0x00,/*12*/
+0x00,/*13*/
+0x00,/*14*/
+0x00,/*15*/
+0x00,/*16*/
+0x00,/*17*/
+0x00,/*18*/
+0x00,/*19*/
+0x00,/*1A*/
+0x00,/*1B*/
+0x00,/*1C*/
+0x00,/*1D*/
+0x00,/*1E*/
+0x00,/*1F*/
+0x84,/*20 L = 0, E = 0, D = 1 */
+0x00,/*21*/
+0x00,/*22*/
+0x00,/*23*/
+0x00,/*24*/
+0x00,/*25*/
+0x00,/*26*/
+0x00,/*27*/
+0x00,/*28*/
+0x00,/*29*/
+0x00,/*2A*/
+0x00,/*2B*/
+0x00,/*2C*/
+0x00,/*2D*/
+0x00,/*2E*/
+0x00,/*2F*/
+0x00,/*30*/
+0x00,/*31*/
+0x00,/*32*/
+0x00,/*33*/
+0x00,/*34*/
+0x00,/*35*/
+0x00,/*36*/
+0x00,/*37*/
+0x00,/*38*/
+0x00,/*39*/
+0x00,/*3A*/
+0x00,/*3B*/
+0x00,/*3C*/
+0x00,/*3D*/
+0x00,/*3E*/
+0x00,/*3F*/
+0xAB,/*40 L = 0, E = 1, D = 0*/
+0x00,/*41*/
+0x00,/*42*/
+0x00,/*43*/
+0x00,/*44*/
+0x00,/*45*/
+0x00,/*46*/
+0x00,/*47*/
+0x00,/*48*/
+0x00,/*49*/
+0x00,/*4A*/
+0x00,/*4B*/
+0x00,/*4C*/
+0x00,/*4D*/
+0x00,/*4E*/
+0x00,/*4F*/
+0x00,/*50*/
+0x00,/*51*/
+0x00,/*52*/
+0x00,/*53*/
+0x00,/*54*/
+0x00,/*55*/
+0x00,/*56*/
+0x00,/*57*/
+0x00,/*58*/
+0x00,/*59*/
+0x00,/*5A*/
+0x00,/*5B*/
+0x00,/*5C*/
+0x00,/*5D*/
+0x00,/*5E*/
+0x00,/*5F*/
+0xAA,/*60 L = 0, E = 1, D = 1*/
+0x00,/*61*/
+0x00,/*62*/
+0x00,/*63*/
+0x00,/*64*/
+0x00,/*65*/
+0x00,/*66*/
+0x00,/*67*/
+0x00,/*68*/
+0x00,/*69*/
+0x00,/*6A*/
+0x00,/*6B*/
+0x00,/*6C*/
+0x00,/*6D*/
+0x00,/*6E*/
+0x00,/*6F*/
+0x00,/*70*/
+0x00,/*71*/
+0x00,/*72*/
+0x00,/*73*/
+0x00,/*74*/
+0x00,/*75*/
+0x00,/*76*/
+0x00,/*77*/
+0x00,/*78*/
+0x00,/*79*/
+0x00,/*7A*/
+0x00,/*7B*/
+0x00,/*7C*/
+0x00,/*7D*/
+0x00,/*7E*/
+0x00,/*7F*/
+0xC5,/*80 L = 1, E = 0, D = 0*/
+0x00,/*81*/
+0x00,/*82*/
+0x00,/*83*/
+0x00,/*84*/
+0x00,/*85*/
+0x00,/*86*/
+0x00,/*87*/
+0x00,/*88*/
+0x00,/*89*/
+0x00,/*8A*/
+0x00,/*8B*/
+0x00,/*8C*/
+0x00,/*8D*/
+0x00,/*8E*/
+0x00,/*8F*/
+0x00,/*90*/
+0x00,/*91*/
+0x00,/*92*/
+0x00,/*93*/
+0x00,/*94*/
+0x00,/*95*/
+0x00,/*96*/
+0x00,/*97*/
+0x00,/*98*/
+0x00,/*99*/
+0x00,/*9A*/
+0x00,/*9B*/
+0x00,/*9C*/
+0x00,/*9D*/
+0x00,/*9E*/
+0x00,/*9F*/
+0xC4,/*A0 L = 1, E = 0, D = 1*/
+0x00,/*A1*/
+0x00,/*A2*/
+0x00,/*A3*/
+0x00,/*A4*/
+0x00,/*A5*/
+0x00,/*A6*/
+0x00,/*A7*/
+0x00,/*A8*/
+0x00,/*A9*/
+0x00,/*AA*/
+0x00,/*AB*/
+0x00,/*AC*/
+0x00,/*AD*/
+0x00,/*AE*/
+0x00,/*AF*/
+0x00,/*B0*/
+0x00,/*B1*/
+0x00,/*B2*/
+0x00,/*B3*/
+0x00,/*B4*/
+0x00,/*B5*/
+0x00,/*B6*/
+0x00,/*B7*/
+0x00,/*B8*/
+0x00,/*B9*/
+0x00,/*BA*/
+0x00,/*BB*/
+0x00,/*BC*/
+0x00,/*BD*/
+0x00,/*BE*/
+0x00,/*BF*/
+0xEB,/*C0 L = 1, E = 1, D = 0*/
+0x00,/*C1*/
+0x00,/*C2*/
+0x00,/*C3*/
+0x00,/*C4*/
+0x00,/*C5*/
+0x00,/*C6*/
+0x00,/*C7*/
+0x00,/*C8*/
+0x00,/*C9*/
+0x00,/*CA*/
+0x00,/*CB*/
+0x00,/*CC*/
+0x00,/*CD*/
+0x00,/*CE*/
+0x00,/*CF*/
+0x00,/*D0*/
+0x00,/*D1*/
+0x00,/*D2*/
+0x00,/*D3*/
+0x00,/*D4*/
+0x00,/*D5*/
+0x00,/*D6*/
+0x00,/*D7*/
+0x00,/*D8*/
+0x00,/*D9*/
+0x00,/*DA*/
+0x00,/*DB*/
+0x00,/*DC*/
+0x00,/*DD*/
+0x00,/*DE*/
+0x00,/*DF*/
+0xEA,/*E0 L = 1, E = 1, D = 1*/
+0x00,/*E1*/
+0x00,/*E2*/
+0x00,/*E3*/
+0x00,/*E4*/
+0x00,/*E5*/
+0x00,/*E6*/
+0x00,/*E7*/
+0x00,/*E8*/
+0x00,/*E9*/
+0x00,/*EA*/
+0x00,/*EB*/
+0x00,/*EC*/
+0x00,/*ED*/
+0x00,/*EE*/
+0x00,/*EF*/
+0x00,/*F0*/
+0x00,/*F1*/
+0x00,/*F2*/
+0x00,/*F3*/
+0x00,/*F4*/
+0x00,/*F5*/
+0x00,/*F6*/
+0x00,/*F7*/
+0x00,/*F8*/
+0x00,/*F9*/
+0x00,/*FA*/
+0x00,/*FB*/
+0x00,/*FC*/
+0x00,/*FD*/
+0x00,/*FE*/
+0x00/*FF*/
+};
+/* ****************************************************************************
+ * Function Section
+ *****************************************************************************/
+
+/* ***************************************************************************/
+/**Opens an SDMA channel to be used by the library.
+ *
+ * <b>Algorithm:</b>\n
+ *
+ * - Check if initialization is necessary.
+ * - Check that user initialized OS dependant functions.
+ * - Test validity of input parameters
+ * - Check whole channel control block data structure
+ * - Finish initializations (tables with default values)
+ * - Initialize channel 0 is dedicated to communications with SDMA
+ * - Check channel control block definition
+ * - if the channel descriptor is not initialized, initialize it with
+ * the default value
+ * - If buffer descriptor already allocated, exit with iapi_errno filled
+ * complete the lowest bits with the number of 'D' bits set
+ * - Buffer Descriptors allocation
+ * - Channel's configuration properties (mcu side only)
+ * - read/write direction => enable/disable channel setting
+ *
+ * @param *cd_p -If channelNumber is 0, it is pointer to channel descriptor for the channnel 0 to be opened and
+ has default values.
+ * For other channels,this function should be called after channel 0 has been opened, and it is channel descriptor for
+ channel 0.Must be allocated.
+ * @param channelNumber channel to be opened
+ *
+ * @return
+ * - IAPI_SUCCESS : OK
+ * - -iapi_errno : close failed, return negated value of iapi_errno
+ */
+int
+iapi_Open (channelDescriptor * cd_p, unsigned char channelNumber)
+{
+ channelControlBlock * ccb_p;
+ channelControlBlock * local_ccb_p;
+ channelDescriptor * local_cd_p;
+ bufferDescriptor * bd_p;
+ unsigned char index = 0;
+ int result = IAPI_SUCCESS;
+#ifdef MCU
+ volatile unsigned long * channelPriorityMatx;
+#endif /* MCU */
+
+
+ /*
+ * 1. Check if initialization is necessary
+ */
+ if (cd_p == NULL){
+ result = IAPI_ERR_CD_UNINITIALIZED |
+ IAPI_ERR_CH_AVAILABLE | channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* Verify these functions every time*/
+ if((iapi_GetChannel == NULL)||(iapi_ReleaseChannel == NULL))
+ {
+ result = IAPI_ERR_NO_OS_FN | channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* Try to aquire channel*/
+ if(iapi_GetChannel(channelNumber) != 0)
+ {
+ result = IAPI_ERR_CH_IN_USE | channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+
+ if (channelNumber == 0 && cd_p->ccb_ptr == NULL){
+ /* Verify that the user initialized all OS dependant functions required
+ * by the library.
+ */
+ if((iapi_Malloc == NULL)||(iapi_Free == NULL)||(iapi_Virt2Phys == NULL)||
+ (iapi_Phys2Virt == NULL)||(iapi_GotoSleep == NULL)||
+ (iapi_WakeUp == NULL)||(iapi_InitSleep == NULL)||(iapi_memset == NULL)||
+ (iapi_memcpy == NULL))
+ {
+ result = IAPI_ERR_NO_OS_FN | channelNumber;
+ iapi_errno = result;
+ iapi_ReleaseChannel(channelNumber);
+ return -result;
+ }
+ /* Whole channel control block data structure */
+ ccb_p = (channelControlBlock *)
+ MALLOC(CH_NUM*sizeof(channelControlBlock), SDMA_IRAM);
+ if (ccb_p == NULL){
+ result = IAPI_ERR_CCB_ALLOC_FAILED |
+ IAPI_ERR_CH_AVAILABLE | channelNumber;
+ iapi_errno = result;
+ iapi_ReleaseChannel(channelNumber);
+ return -result;
+ }
+ /* Zero-out the CCB structures array just allocated*/
+ iapi_memset(ccb_p, 0x00, CH_NUM*sizeof(channelControlBlock));
+ /* Save the address of the CCB structures array*/
+ iapi_CCBHead = ccb_p;
+
+ cd_p->ccb_ptr = (struct iapi_channelControlBlock *)ccb_p;
+ ccb_p->channelDescriptor = cd_p;
+#ifdef MCU
+ /* finish initializations */
+ iapi_InitChannelTables();
+#endif /* MCU */
+ /* Channel 0 is dedicated to communications with SDMA */
+ cd_p->ownership = ((DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT ) |
+ ( OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU ) |
+ (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP ));
+ cd_p->bufferDescNumber = 1;
+ }
+
+ /*
+ * 2. Check channel control block
+ */
+ ccb_p = cd_p->ccb_ptr;
+ if (ccb_p == NULL){
+ result = IAPI_ERR_NO_CCB_DEFINED | IAPI_ERR_CH_AVAILABLE|channelNumber;
+ iapi_errno = result;
+ iapi_ReleaseChannel(channelNumber);
+ return -result;
+ }
+
+ /* Control block & Descriptor associated with the channel being worked on */
+ local_ccb_p = &ccb_p[channelNumber];
+ local_cd_p = ccb_p[channelNumber].channelDescriptor;
+
+ /* If the channel is not initialized, initialize it with the default value */
+ if (local_cd_p == NULL){
+ result = iapi_AllocChannelDesc (&local_cd_p, channelNumber);
+ if ( result!= IAPI_SUCCESS)
+ {
+ iapi_ReleaseChannel(channelNumber);
+ return result; //is allready negated from iapi_AllocChannelDesc
+ }
+
+ local_cd_p->ccb_ptr = (struct iapi_channelControlBlock *)local_ccb_p;
+ local_ccb_p->channelDescriptor = local_cd_p;
+ }
+
+ /*
+ * 3. If buffer descriptor already allocated, exit with iapi_errno filled
+ */
+ if ( local_ccb_p->baseBDptr != NULL ){
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(local_ccb_p->baseBDptr);
+ result = IAPI_ERR_BD_ALLOCATED;
+ for (index=1 ; index< local_cd_p->bufferDescNumber ; index++){
+ if ((bd_p->mode.status & BD_DONE) == BD_DONE){
+ /* complete the lowest bits with the number of 'D' bits set */
+ result++;
+ }
+ bd_p++;
+ }
+ iapi_errno = result;
+ iapi_ReleaseChannel(channelNumber);
+ return -result;
+ }
+
+ /*
+ * 4. Buffer Descriptors allocation
+ */
+ iapi_InitializeMemory(local_ccb_p);
+
+#ifdef MCU
+ /*
+ * 5. Channel's configuration properties (mcu side only)
+ */
+ iapi_ChannelConfig( channelNumber,
+ ( local_cd_p->ownership >> CH_OWNSHP_OFFSET_EVT ) & 1UL,
+ ( local_cd_p->ownership >> CH_OWNSHP_OFFSET_MCU ) & 1UL,
+ ( local_cd_p->ownership >> CH_OWNSHP_OFFSET_DSP ) & 1UL);
+#endif /* MCU */
+
+ /* Setting interrupt handling */
+ iapi_ChangeCallbackISR(local_cd_p, local_cd_p->callbackISR_ptr);
+
+ /* Call initialization fn for polling synch on this channel*/
+ INIT_SLEEP(channelNumber);
+
+ /* No user arg pointer yet*/
+ userArgTable[cd_p->channelNumber]= NULL;
+
+ /*
+ * 6. read/write direction => enable/disable channel
+ */
+#ifdef MCU
+ channelPriorityMatx = &SDMA_CHNPRI_0;
+ channelPriorityMatx[channelNumber] = 1;
+#endif /* MCU */
+
+ local_ccb_p->status.openedInit = TRUE;
+ iapi_ReleaseChannel(channelNumber);
+ return IAPI_SUCCESS;
+}
+
+/* ***************************************************************************/
+/** Attempts to read nbyte from the data buffer descriptor associated with the
+ * channel channelNumber, into the user's data buffer pointed to by buf.
+ *
+ * <b>Algorithm:</b>\n
+ * - Check data structures are properly initialized:
+ * - Channel descriptor validity
+ * - Control block & Descriptor associated with the channel being worked on
+ * - Check initialization has been done for trusted channels
+ * - If transfer data size is used, check validity of combination transfer
+ * size/requested bytes
+ * - Set the 'D' done bits on all buffer descriptors
+ * - Starting of the channel
+ * - Synchronization mechanism handling:
+ * - for callback: just exit function
+ * - for polling: call the synchronization function then read data from
+ * buffer until either nbyte parameter is reached or all buffer descriptors
+ * have been processed.
+ *
+ * <b>Notes:</b>\n
+ * 1) Virtual DMA SDMA channels are unidirectional, an iapi_Read authorized
+ * on a channel means that we are expecting to receive from the SDMA. The
+ * meaning of an interrupt received from the SDMA is therefore that the
+ * data has been copied from the SDMA to the host's data buffers and is
+ * already passed on upper layers of the application.\n
+ *
+ * @param *cd_p chanenl descriptor for the channel to read from
+ * @param *buf buffer to receive the data
+ * @param nbyte number of bytes to read from channel
+ *
+ * @return
+ * - number of bytes read
+ * - -iapi_errno : in case of failure return negated value of iapi_errno
+ */
+int
+iapi_Read (channelDescriptor * cd_p, void * buf, unsigned short nbyte)
+{
+ int index = 0;
+ int readBytes;
+ int toRead;
+ int result = IAPI_SUCCESS;
+ unsigned int copyFinished;
+ int bufsize;
+ bufferDescriptor * bd_p;
+ channelControlBlock * ccb_p;
+ unsigned char * local_buf;
+ unsigned char chNum;
+ unsigned char div;
+
+ iapi_errno = IAPI_ERR_NO_ERROR;
+
+ /*
+ * 1. Check data structures are properly initialized
+ */
+ /* Channel descriptor validity */
+ if (cd_p == NULL){
+ result = IAPI_ERR_CD_UNINITIALIZED;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* Channel control block validity */
+ if (cd_p->ccb_ptr == NULL){
+ result = IAPI_ERR_CCB_UNINITIALIZED;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* Control block & Descriptor associated with the channel being worked on */
+ chNum = cd_p->channelNumber;
+ ccb_p = cd_p->ccb_ptr;
+
+ /* Try to aquire channel*/
+ if(iapi_GetChannel(chNum) != 0)
+ {
+ result = IAPI_ERR_CH_IN_USE | chNum;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* Check if channel is already opened/initialized */
+ if (ccb_p->status.openedInit == FALSE) {
+ result = IAPI_ERR_CHANNEL_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | chNum;
+ iapi_errno = result;
+ iapi_ReleaseChannel(chNum);
+ return -result;
+ }
+
+ /* Buffer descriptor validity */
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr);
+ if (bd_p == NULL ){
+ result = IAPI_ERR_BD_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | chNum;
+ iapi_errno = result;
+ iapi_ReleaseChannel(chNum);
+ return -result;
+ }
+
+
+ /* Check initialization has been done for trusted channels */
+ if (cd_p->trust == TRUE) {
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr);
+ for(index=0 ; index < cd_p->bufferDescNumber ; index++){
+ if ((bd_p->bufferAddr == NULL) || (bd_p->mode.count == 0)){
+ result = IAPI_ERR_BD_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | chNum;
+ iapi_errno = result;
+ iapi_ReleaseChannel(chNum);
+ return -result;
+ }
+ bd_p++;
+ }
+ }
+
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr);
+ /*If transfer data size is used, check that the required read length is
+ * divisible by transfer data size expressed in bytes
+ */
+ if(cd_p->useDataSize)
+ {
+ /*Check for divisibility only if data size different then 8bit*/
+ if(cd_p->dataSize != TRANSFER_8BIT)
+ {
+ switch(cd_p->dataSize)
+ {
+ case TRANSFER_32BIT:
+ div = 4;
+ break;
+ case TRANSFER_16BIT:
+ div = 2;
+ break;
+ case TRANSFER_24BIT:
+ div = 3;
+ break;
+ /*we should not get to default*/
+ default:
+ result = IAPI_ERR_INVALID_PARAMETER | chNum;
+ iapi_errno = result;
+ iapi_ReleaseChannel(chNum);
+ return -result;
+ }
+ /*check the total number of bytes requested*/
+ if((nbyte % div) != 0)
+ {
+ result = IAPI_ERR_INVALID_PARAMETER | chNum;
+ iapi_errno = result;
+ iapi_ReleaseChannel(chNum);
+ return -result;
+ }
+ /*now check the length of every BD*/
+ for(index=0 ; index < cd_p->bufferDescNumber ; index++)
+ {
+ if((bd_p->mode.count % div) != 0)
+ {
+ result = IAPI_ERR_INVALID_PARAMETER | chNum;
+ iapi_errno = result;
+ iapi_ReleaseChannel(chNum);
+ return -result;
+ }
+ bd_p++;
+ }
+ }
+ }
+
+ /*
+ * 2. Set the 'D' done bits on all buffer descriptors
+ */
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr);
+ for (index=0 ; index < cd_p->bufferDescNumber ; index++) {
+ bd_p->mode.status |= BD_DONE;
+ bd_p++;
+ }
+
+ /*
+ * 3. Starting of the channel
+ */
+ iapi_lowStartChannel (chNum);
+ ccb_p->status.execute = TRUE;
+ readBytes = 0;
+
+ /*
+ * 4. Synchronization mechanism handling
+ */
+ if( cd_p->callbackSynch == DEFAULT_POLL){
+ iapi_SynchChannel(chNum);
+
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr);
+ toRead = nbyte;
+ copyFinished = FALSE;
+ local_buf = (unsigned char *)buf;
+
+ /*
+ * Check the 'RROR' bit on all buffer descriptors, set error number
+ * and return IAPI_FAILURE if set.
+ */
+ for (index=0 ; index < cd_p->bufferDescNumber ; index++)
+ {
+ if(bd_p->mode.status & BD_RROR)
+ {
+ result = IAPI_ERR_RROR_BIT_READ | chNum;
+ iapi_errno = result;
+ iapi_ReleaseChannel(chNum);
+ return -result;
+ }
+ bd_p++;
+ }
+
+
+ /*
+ * 5. Read loop
+ */
+
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr);
+ while (!copyFinished)
+ {
+ if (!(bd_p->mode.status & BD_DONE))
+ {
+ if (cd_p->trust == FALSE) {
+ bufsize = cd_p->bufferSize;
+ } else {
+ bufsize = bd_p->mode.count;
+ }
+ /*if L bit is set, read only "count" bytes and exit the loop*/
+ if(bd_p->mode.status & BD_LAST)
+ {
+ bufsize = bd_p->mode.count;
+ copyFinished = TRUE;
+ }
+ if (toRead > bufsize)
+ {
+ if (cd_p->trust == FALSE)
+ {
+ iapi_memcpy(local_buf, iapi_Phys2Virt(bd_p->bufferAddr), bufsize);
+ local_buf += bufsize;
+ }
+ readBytes += bufsize;
+ toRead -= bufsize;
+ /*advance bd_p only if bit L is not set. The loop will exit anyway.*/
+ if(!(bd_p->mode.status & BD_LAST))
+ {
+ if (bd_p->mode.status & BD_WRAP)
+ {
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr);
+ }
+ else if(((bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr) +
+ (cd_p->bufferDescNumber - 1)*sizeof(bufferDescriptor)) != bd_p)
+ {
+ bd_p++;
+ }
+ else
+ {
+ /* finished here : end of buffer descriptors */
+ copyFinished = TRUE;
+ }
+ }
+ }
+ else
+ {
+ if (cd_p->trust == FALSE)
+ {
+ iapi_memcpy(local_buf, iapi_Phys2Virt(bd_p->bufferAddr), toRead);
+ local_buf += toRead;
+ }
+ readBytes += toRead;
+ toRead = 0;
+ /* finished successfully : readBytes = nbytes */
+ copyFinished = TRUE;
+ }
+ }
+ else
+ {
+ /* finished here : buffer not already done*/
+ copyFinished = TRUE;
+ }
+ }
+ iapi_ReleaseChannel(chNum);
+ }
+
+ /*
+ *If synchronization type is callback, the user of I.API must
+ *release the channel
+ */
+ return readBytes;
+}
+
+/* ***************************************************************************/
+/*Attempts to write nbyte from the buffer pointed to by buf to the channel
+ * data buffers associated with the opened channel number channelNumber
+ *
+ * <b>Algorithm:</b>\n
+ *
+ * - Check data structures are properly initialized:
+ * - Channel descriptor validity
+ * - Channel control block validity
+ * - Buffer descriptor validity
+ * - If transfer data size is used, check validity of combination transfer
+ * size/requested bytes
+ * - Write loop\n
+ * Write occurs in the buffer acceded form buffer descriptor and continues
+ * to the "next" buffer which can be:\n
+ * -# the last BD of the ring so re-start from beginning\n
+ * -# the last BD of the BD array but no ring so finish\n
+ * -# (general case) the next BD in the BD array\n
+ * And copy continues until data fit in the current buffer or the nbyte
+ * parameter is reached.
+ * - Starting of the channel
+ *
+ * <b>Notes:</b>\n
+ * 1) Virtual DMA SDMA channels are unidirectionnal, an iapi_Write authorized
+ * on a channel means that we are expecting to send to the SDMA. The
+ * meaning of an interrupt received from the SDMA is therfore that the
+ * data has been delivered to the SDMA.
+ *
+ * @param *cd_p chanenl descriptor for the channel to write to
+ * @param *buf buffer with data to be written
+ * @param nbyte number of bytes to write to channel
+ *
+ * @return
+ * - number of bytes written
+ * - -iapi_errno if failure
+ */
+int
+iapi_Write (channelDescriptor * cd_p, void * buf, unsigned short nbyte)
+{
+ unsigned int writtenBytes = 0;
+ unsigned int toWrite;
+ int result = IAPI_SUCCESS;
+ unsigned int copyFinished;
+ unsigned int buffsize;
+ unsigned int index = 0;
+ bufferDescriptor * bd_p;
+ channelControlBlock * ccb_p;
+ unsigned char * local_buf;
+ unsigned char chNum;
+ unsigned char div;
+
+ iapi_errno = IAPI_ERR_NO_ERROR;
+
+ /*
+ * 1. Check data structures are properly initialized
+ */
+ /* Channel descriptor validity */
+ if (cd_p == NULL){
+ result = IAPI_ERR_CD_UNINITIALIZED;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* Channel control block validity */
+ if (cd_p->ccb_ptr == NULL){
+ result = IAPI_ERR_CCB_UNINITIALIZED;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* Control block & Descriptpor associated with the channel being worked on */
+ chNum = cd_p->channelNumber;
+ ccb_p = cd_p->ccb_ptr;
+
+ /* Try to aquire channel*/
+ if(iapi_GetChannel(chNum) != 0)
+ {
+ result = IAPI_ERR_CH_IN_USE | chNum;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* Buffer descriptor validity */
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr);
+ if (bd_p == NULL ){
+ result = IAPI_ERR_BD_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | chNum;
+ iapi_errno = result;
+ iapi_ReleaseChannel(chNum);
+ return -result;
+ }
+
+ /* Check initialization has been done for trusted channels */
+ if (cd_p->trust == TRUE) {
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr);
+ for(index=0 ; index < cd_p->bufferDescNumber ; index++){
+ if ((bd_p->bufferAddr == NULL) || (bd_p->mode.count == 0)){
+ result = IAPI_ERR_BD_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | chNum;
+ iapi_errno = result;
+ iapi_ReleaseChannel(chNum);
+ return -result;
+ }
+ bd_p++;
+ }
+ }
+
+
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr);
+ /*If transfer data size is used, check that the required write length is
+ * divisible by transfer data size expressed in bytes
+ */
+ if(cd_p->useDataSize)
+ {
+ /*Check for divisibility only if data size different then 8bit*/
+ if(cd_p->dataSize != TRANSFER_8BIT)
+ {
+ switch(cd_p->dataSize)
+ {
+ case TRANSFER_32BIT:
+ div = 4;
+ break;
+ case TRANSFER_16BIT:
+ div = 2;
+ break;
+ case TRANSFER_24BIT:
+ div = 3;
+ break;
+ /*we should not get to default*/
+ default:
+ result = IAPI_ERR_INVALID_PARAMETER | chNum;
+ iapi_errno = result;
+ iapi_ReleaseChannel(chNum);
+ return -result;
+ }
+ /*check the total number of bytes requested*/
+ if((nbyte % div) != 0)
+ {
+ result = IAPI_ERR_INVALID_PARAMETER | chNum;
+ iapi_errno = result;
+ iapi_ReleaseChannel(chNum);
+ return -result;
+ }
+ /*now check the length of every BD*/
+ for(index=0 ; index < cd_p->bufferDescNumber ; index++)
+ {
+ if((bd_p->mode.count % div) != 0)
+ {
+ result = IAPI_ERR_INVALID_PARAMETER | chNum;
+ iapi_errno = result;
+ iapi_ReleaseChannel(chNum);
+ return -result;
+ }
+ bd_p++;
+ }
+ }
+ }
+
+ /*
+ * 2. Write loop
+ */
+
+ local_buf = (unsigned char *)buf;
+ toWrite = nbyte;
+ copyFinished = FALSE;
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr);
+
+ while (!copyFinished){
+
+ /* variable buffsize contains the nb of bytes that the SDMA will transfer at each pass of the while loop*/
+
+ /* in NON trusted mode, buffsize is copied from Channel descriptor bufferSize (same size for all transfers) */
+ if (cd_p->trust == FALSE) {
+ buffsize = cd_p->bufferSize;
+ }
+ /* in TRUSTED mode, it's up to the user to specify the size of each buffer thru an IoCtl call */
+ /* This IoCtl has directly modified the bd_p->mode.count */
+ /* therefore, buffersize is copied from the bd_p->mode.count */
+ else {
+ buffsize = bd_p->mode.count;
+ }
+
+ /* in any mode (trusted or non trusted), the transfer size must be overridden by */
+ /* "toWrite" when there is less remaining bytes to transfer than the current buffer size */
+ if (toWrite < buffsize) {
+ buffsize = toWrite;
+ }
+
+
+ if (!(bd_p->mode.status & BD_DONE)){
+ /* More data to write than a single buffer can contain */
+ if (cd_p->trust == FALSE ){
+ iapi_memcpy(iapi_Phys2Virt(bd_p->bufferAddr), local_buf, buffsize);
+ local_buf += buffsize;
+ }
+
+ /* update the BD count that will be used by the SDMA to transfer the proper nb of bytes */
+ bd_p->mode.count = buffsize;
+
+ bd_p->mode.status |= BD_DONE;
+ writtenBytes += buffsize;
+ toWrite -= buffsize;
+ /* Prepares access to the "next" buffer */
+ /* - case 1 - finished successfully : writtenBytes = nbytes */
+ if (toWrite == 0) {
+ copyFinished = TRUE;
+ }
+ /* - case 2 - Last BD and WRAP bit set so re-start from beginning */
+ /*else if ((bd_p->mode.status & BD_WRAP)){
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr);
+ }*/
+ /* - case 3 - Last BD of the BD but nor ring*/
+ else if (((bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr) +
+ (cd_p->bufferDescNumber - 1) * sizeof(bufferDescriptor)) == bd_p){
+ copyFinished = TRUE;
+ }
+ /* - case 4 - general : next BD in the BD array */
+ else {
+ bd_p++;
+ }
+
+ } else {
+ /* finished here : buffer not already done */
+ copyFinished = TRUE;
+ }
+ }
+
+ ccb_p->currentBDptr = ccb_p->baseBDptr;
+
+ /*
+ * 3. Starting of the channel
+ */
+ iapi_lowStartChannel(chNum);
+ ccb_p->status.execute = TRUE;
+
+ if( cd_p->callbackSynch == DEFAULT_POLL)
+ {
+ iapi_SynchChannel(chNum);
+ /*
+ * Check the 'RROR' bit on all buffer descriptors, set error number
+ * and return IAPI_FAILURE if set.
+ */
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr);
+ for (index=0 ; index < cd_p->bufferDescNumber ; index++)
+ {
+ if(bd_p->mode.status & BD_RROR)
+ {
+ result = IAPI_ERR_RROR_BIT_WRITE | chNum;
+ iapi_errno = result;
+ iapi_ReleaseChannel(chNum);
+ return -result;
+ }
+ bd_p++;
+ }
+ iapi_ReleaseChannel(chNum);
+ }
+
+ /*
+ *If synchronization type is callback, the user of I.API must
+ *release the channel
+ */
+ return writtenBytes;
+}
+
+
+
+
+/* ***************************************************************************/
+/* This function is used to receive data from the SDMA.
+ *
+ * <b>Algorithm:</b>\n
+ *
+ * The data control structure would be copied to IPCv1 complied Buffer
+ * Descriptor Array. This array shall be allocated from non cacheable memory.
+ * It would then provide this buffer descriptor array as an input to SDMA using
+ * channel control block and then configure the Host Enable (HE) or
+ * DSP enable (DE) bit of SDMA for the channel used for this transfer depending
+ * on the source.
+ *
+ * <b>Notes:</b>\n
+ * Virtual DMA channels are unidirectional, an iapi_Write_ipcv2 authorized
+ * on a channel means that source processor is expecting to send to the destination
+ * processor. The meaning of an interrupt received from the SDMA notifies that the
+ * data has been delivered to the destination processor.
+ *
+ * @param *cd_p chanenl descriptor for the channel to receive from
+ * @param *data_control_struct_ipcv2
+
+ * Data Control structure:
+ * -------------------------
+ * | Data Node Descriptor 1|
+ * -------------------------
+ * | Data Node Descriptor 2|
+ * -------------------------
+ * | : |
+ * | : |
+ * -------------------------
+ * |Data Node Descriptor n |
+ * -------------------------
+ *
+ * Data Node Descriptor (Buffer Descriptor):
+ *------------------------------------------------------------------------------
+ *| 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 … 0|
+ *------------------------------------------------------------------------------
+ *| L E D R R R R R |<---- Reserved ----> |<- Length-> |
+ *------------------------------------------------------------------------------
+ *| <---------------------------- Data Ptr ----------------------------------->|
+ *------------------------------------------------------------------------------
+ *
+ * L bit (LAST): If set, means that this buffer of data is the last buffer of the frame
+ * E bit (END): If set, we reached the end of the buffers passed to the function
+ * D bit (DONE): Only valid on the read callback. When set, means that the buffer has been
+ * filled by the SDMA.
+ * Length: Length of data pointed by this node in bytes
+ * Data Ptr: Pointer to the data pointed to by this node.
+ * The Function Shall not be called for the same channel unless the Read callback has been
+ * received for channel for which it has been called already.
+ *
+ * @return
+ * - IAPI_SUCCESS on success, IAPI_ERROR otherwise
+ *
+ *- -iapi_errno if failure
+ */
+
+int iapi_Read_ipcv2( channelDescriptor * cd_p, void * data_control_struct_ipcv2)
+{
+ channelControlBlock * ccb_p;
+
+
+/* The Parameters passed are considered to be validated by the upper layers*/
+
+ bufferDescriptor_ipcv1_v2 *bd_ipcv2_p;
+ dataNodeDescriptor *dnd_p = (dataNodeDescriptor*)data_control_struct_ipcv2;
+
+ ccb_p = cd_p->ccb_ptr;
+ iapi_errno = IAPI_ERR_NO_ERROR;
+
+ if(ccb_p->baseBDptr == NULL)
+{
+ iapi_errno = IAPI_ERR_BD_UNINITIALIZED;
+ return -(IAPI_ERR_BD_UNINITIALIZED);
+}
+
+ ccb_p->currentBDptr = ccb_p->baseBDptr;
+
+ /* Copy the data Node descriptor information to new BDs */
+ bd_ipcv2_p = (bufferDescriptor_ipcv1_v2*)iapi_Phys2Virt(ccb_p->baseBDptr);
+
+ while(1)
+ {
+ bd_ipcv2_p->bufferAddr = dnd_p->bufferAddr;
+ bd_ipcv2_p->mode.count = dnd_p->mode.count;
+#ifdef MCU
+ bd_ipcv2_p->mode.endianness = 1;
+#endif
+#ifdef DSP
+ bd_ipcv2_p->mode.endianness = 0;
+#endif
+
+ bd_ipcv2_p->mode.status = dnd_2_bd_status[dnd_p->mode.status & GET_LED_MASK];
+
+ if((dnd_p->mode.status & DND_END_OF_XFER) != 0)
+ {
+ /* Break the loop at End of Transfer */
+ break;
+
+ }
+ bd_ipcv2_p++;
+ dnd_p++;
+
+ }
+ /*
+ * Store the buffer address
+ */
+ dnd_read_control_struct[cd_p->channelNumber] = (dataNodeDescriptor*)data_control_struct_ipcv2;
+ /*
+ * Register the Call Back
+ */
+
+ iapi_AttachCallbackISR(cd_p, iapi_read_ipcv2_callback);
+
+ /*
+ * Starting of the channel
+ */
+ iapi_lowStartChannel(cd_p->channelNumber);
+ ccb_p->status.execute = TRUE;
+
+ return IAPI_SUCCESS;
+
+}
+
+
+/* ***************************************************************************/
+/*
+ * The function is used send a group of buffers to SDMA.
+ * <b>Algorithm:</b>\n
+ *
+ * The data control structure would be copied to IPCv1 complied Buffer
+ * Descriptor Array. This array shall be allocated from non cacheable memory.
+ * It would then provide this buffer descriptor array as an input to SDMA using
+ * channel control block and then configure the Host Enable (HE) or
+ * DSP enable (DE) bit of SDMA for the channel used for this transfer depending
+ * on the source.
+ * The Function Shall not be called for the same channel unless the Read callback has been
+ * received for channel for which it has been called already.
+ *
+ * <b>Notes:</b>\n
+ * Virtual DMA channels are unidirectional, an iapi_Write_ipcv2 authorized
+ * on a channel means that source processor is expecting to send to the destination
+ * processor. The meaning of an interrupt received from the SDMA notifies that the
+ * data has been delivered to the destination processor.
+ *
+ * @param *cd_p chanenl descriptor for the channel to write to
+ * @param *data_control_struct_ipcv2
+
+ * Data Control structure:
+ * -------------------------
+ * | Data Node Descriptor 1|
+ * -------------------------
+ * | Data Node Descriptor 2|
+ * -------------------------
+ * | : |
+ * | : |
+ * -------------------------
+ * |Data Node Descriptor n |
+ * -------------------------
+ *
+ * Data Node Descriptor (Buffer Descriptor):
+ *------------------------------------------------------------------------------
+ *| 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 … 0|
+ *------------------------------------------------------------------------------
+ *| L E D R R R R R |<---- Reserved ----> |<- Length-> |
+ *------------------------------------------------------------------------------
+ *| <---------------------------- Data Ptr ----------------------------------->|
+ *------------------------------------------------------------------------------
+ *
+ * L bit (LAST): If set, means that this buffer of data is the last buffer of the frame
+ * E bit (END): If set, we reached the end of the buffers passed to the function
+ * D bit (DONE): Only valid on the read callback. When set, means that the buffer has been
+ * filled by the SDMA.
+ * Length: Length of data pointed by this node in bytes
+ * Data Ptr: Pointer to the data pointed to by this node.
+ *
+ *
+ * @return
+ * - iapi sucess on success.
+ * - -iapi_errno if failure
+ */
+
+int iapi_Write_ipcv2( channelDescriptor * cd_p, void * data_control_struct_ipcv2)
+{
+
+ channelControlBlock * ccb_p;
+
+/* The Parameters passed are considered to be validated by the upper layers*/
+
+ bufferDescriptor_ipcv1_v2 *bd_ipcv2_p;
+ dataNodeDescriptor *dnd_p = (dataNodeDescriptor*)data_control_struct_ipcv2;
+ ccb_p = cd_p->ccb_ptr;
+ iapi_errno = IAPI_ERR_NO_ERROR;
+
+ if(ccb_p->baseBDptr == NULL)
+{
+ iapi_errno = IAPI_ERR_BD_UNINITIALIZED;
+ return -(IAPI_ERR_BD_UNINITIALIZED);
+}
+
+
+ ccb_p->currentBDptr = ccb_p->baseBDptr;
+
+ bd_ipcv2_p = (bufferDescriptor_ipcv1_v2*)iapi_Phys2Virt(ccb_p->currentBDptr);
+ /* Copy the data Node descriptor information to new BDs */
+ while(1)
+ {
+ bd_ipcv2_p->bufferAddr = dnd_p->bufferAddr;
+ bd_ipcv2_p->mode.count = dnd_p->mode.count;
+
+#ifdef MCU
+ bd_ipcv2_p->mode.endianness = 1;
+#endif
+#ifdef DSP
+ bd_ipcv2_p->mode.endianness = 0;
+#endif
+
+ bd_ipcv2_p->mode.status = dnd_2_bd_status[dnd_p->mode.status & GET_LED_MASK];
+
+ if((dnd_p->mode.status & DND_END_OF_XFER) != 0)
+ {
+ /* Break the loop at End of Transfer */
+ break;
+ }
+ bd_ipcv2_p++;
+ dnd_p++;
+
+ }
+
+ /*
+ * Starting of the channel
+ */
+ iapi_lowStartChannel(cd_p->channelNumber);
+ ccb_p->status.execute = TRUE;
+
+ return IAPI_SUCCESS;
+
+}
+
+/* ***************************************************************************/
+/** Call back ISR for the IPCv2 Receive.
+ *
+ * <b>Algorithm:</b>\n
+ * - This would copy back the informationfrom IPCv1 BD to IPCv2 BD on
+ * the receiving processor
+ *
+ * @return
+ * - void
+ */
+
+void iapi_read_ipcv2_callback(struct iapi_channelDescriptor* cd_p, void* data)
+{
+ dataNodeDescriptor *dnd_p = dnd_read_control_struct[cd_p->channelNumber];//cd_p->ccb_ptr->channelDNDBuffer;
+ bufferDescriptor_ipcv1_v2 *bd_ipcv2_p = (bufferDescriptor_ipcv1_v2*)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ int index = MAX_BD_NUM - 1;
+
+
+ do
+ {
+ dnd_p->mode.status = 0;
+ dnd_p->mode.count = bd_ipcv2_p->mode.count;
+
+ dnd_p->mode.status |= bd_ipcv2_p->mode.status & BD_DONE ? 0x00 : DND_DONE ;
+ dnd_p->mode.status |= bd_ipcv2_p->mode.status & BD_IPCV2_END_OF_FRAME ? DND_END_OF_FRAME : 0x00;
+ dnd_p->mode.status |= bd_ipcv2_p->mode.status & BD_LAST ? DND_END_OF_XFER : 0x00;
+ cd_p->ccb_ptr->currentBDptr = (bufferDescriptor*)iapi_Virt2Phys(bd_ipcv2_p);
+
+ if((bd_ipcv2_p->mode.status & BD_LAST) != 0 ||
+ (bd_ipcv2_p->mode.status & BD_CONT) == 0
+ )
+ break;
+ dnd_p++;
+ bd_ipcv2_p++;
+
+ }while(index--);
+
+ /*Call back the Original ISR */
+ cd_p->callbackISR_ptr(cd_p, data);
+}
+
+/* ***************************************************************************/
+/**Terminates a channel.
+ *
+ * <b>Algorithm:</b>\n
+ * - Check input parameters ans data structures
+ * - Check that all buffes have been processed (test all 'D' bits)
+ * - Stop the channel execution
+ * - Free alocated memory structures
+ * - Re-instantiate default interrupt handling
+ *
+ * @param *cd_p chanenl descriptor for the channel to close
+ *
+ * @return
+ * - IAPI_SUCCESS : OK
+ * - -iapi_errno : close failed
+ */
+int
+iapi_Close (channelDescriptor * cd_p)
+{
+ int index = 0;
+ int result = IAPI_SUCCESS;
+ unsigned char chNum;
+ bufferDescriptor * bd_p;
+ channelControlBlock * ccb_p;
+
+ /*
+ * 1. Check input parameters ans data structures
+ */
+ if (cd_p != NULL){
+ if (cd_p->ccb_ptr != NULL) {
+ chNum = cd_p->channelNumber;
+ ccb_p = cd_p->ccb_ptr;
+ } else {
+ result = IAPI_ERR_NO_CCB_DEFINED | IAPI_ERR_CH_AVAILABLE;
+ iapi_errno = result;
+ return -result;
+ }
+ } else {
+ result = IAPI_ERR_CD_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE;
+ iapi_errno = result;
+ return -result;
+ }
+ /* Try to aquire channel*/
+ if(iapi_GetChannel(chNum) != 0)
+ {
+ result = IAPI_ERR_CH_IN_USE | chNum;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /*
+ * 2. Check that all buffes have been processed (test all 'D' bits),
+ * only if the forceClose bit in channel descriptor is set to FALSE
+ */
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr);
+ if (bd_p == NULL){
+ result = IAPI_ERR_BD_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE | chNum;
+ iapi_errno = result;
+ return -result;
+ }
+ if(cd_p->forceClose == FALSE)
+ {
+ for (index=cd_p->bufferDescNumber ; index>0 ; index--){
+ if (bd_p->mode.status & BD_DONE){
+ result = IAPI_ERR_CLOSE | IAPI_ERR_CH_AVAILABLE | chNum;
+ iapi_errno = result;
+ iapi_ReleaseChannel(chNum);
+ return -result;
+ }
+ bd_p++;
+ }
+ }
+ /*if the closing is forced,mark channel unused,set BD ownership to processor*/
+ else
+ {
+ ccb_p->status.execute = FALSE;
+ for (index=cd_p->bufferDescNumber ; index>0 ; index--)
+ {
+ bd_p->mode.status &= ~BD_DONE;
+ bd_p++;
+ }
+ }
+
+ /*
+ * 3. Stop the channel execution
+ */
+ iapi_lowStopChannel(chNum);
+
+ /*
+ * 4. Free alocated memory structures
+ */
+ if (cd_p->trust == FALSE ){
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr);
+ for (index=cd_p->bufferDescNumber ; index>0 ; index--){
+ FREE (iapi_Phys2Virt(bd_p->bufferAddr));
+ bd_p++;
+ }
+ }
+
+ /*
+ * 5. Re-instantiate default interrupt handling
+ */
+ iapi_DetachCallbackISR (cd_p);
+ FREE ((bufferDescriptor *)iapi_Phys2Virt(ccb_p->baseBDptr));
+ FREE (cd_p);
+ ccb_p->baseBDptr = NULL;
+ ccb_p->currentBDptr = NULL;
+ ccb_p->channelDescriptor = NULL;
+ ccb_p->status.openedInit = FALSE;
+
+ iapi_ReleaseChannel(chNum);
+
+ return IAPI_SUCCESS;
+}
+
+/* ***************************************************************************/
+/**The request argument selects the control function to be performed.
+ *
+ * <b>Algorithm:</b>\n
+ *
+ * - Check data structures are properly initialized:
+ * - Channel descriptor validity
+ * - Channel control block validity
+ * - The ctlRequest parameter contains in the lower 16 bits the control code of
+ * the change to be performed, and in the upper 16 bits, the BD to be
+ * modified if the change affects a BD od the channel.
+ * - Selection of the parameter to change and appropriate sanity checks:
+ * - Channel Descriptor: changes the pointer to the channel descriptor
+ * structure, the pointer to the new channel descriptor is given in the third
+ * argument call
+ * - Buffer Descriptor Number: changes the number of buffer descriptor for the
+ * channel
+ * - Buffer size: changes the size of the data buffers pointed to by the
+ * buffer descriptor; note that all buffer descriptors are assumed to have the
+ * same size for a given buffer descripotr chain
+ * - Blocking policy: changes the blocking policy for the read and write calls
+ * - Ownership: changes direction: turnaround
+ * - Synchronization method: changes the callback type, default or user. The*
+ * callback function table is set accordingly
+ * - Trust property: trust can only be changed through ChangeChannelDesc first
+ * request, this guarantees the close/open sequence for the channel
+ * - Callback Interrupt service routine pointer: changes the callback function
+ * pointer, when this method is used, to replace it with a new one
+ * - Channel control block pointer: not available
+ * - Priority: changes the channel priority directly in SDMA register
+ * - Watermark level: changes the value of the peripheral watermark level that
+ * passed to the script. The new value is passed in the third parameter call.
+ * - Wrap bit: changes to set to 1 the Wrap bit of the last buffer descriptor
+ *
+ * @param *cd_p channel descriptor for the channel to modify
+ * @param ctlRequest request control code and, if tha case, number of BD to be
+ * changed
+ * @param param parameter for the modification
+ *
+ * @return
+ * - IAPI_SUCCESS : OK
+ * - -iapi_errno : operation failed
+ */
+int
+iapi_IoCtl (channelDescriptor * cd_p, unsigned long ctlRequest,
+ unsigned long param)
+{
+ int retvalue;
+ int result = IAPI_SUCCESS;
+ unsigned char chNum;
+ unsigned long clean_ctlRequest; /* lower 16 bits of the ctlRequest*/
+ unsigned long bd_num; /* upper 16 bits of the ctlRequest*/
+
+ /*
+ * 1. Check data structures are properly initialized
+ */
+ /* Channel descriptor validity */
+ if (cd_p == NULL){
+ result = IAPI_ERR_CD_UNINITIALIZED;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* Channel control block validity */
+ if (cd_p->ccb_ptr == NULL){
+ result = IAPI_ERR_CCB_UNINITIALIZED;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* Control block & Descriptor associated with the channel being worked on */
+ chNum = cd_p->channelNumber;
+
+ /* Remove, if exists, BD number specified in upper bits of ctlRequest*/
+ clean_ctlRequest = ctlRequest & (~BD_NUM_MASK);
+
+ /* Extract, if exists, BD number specified in upper bits of ctlRequest*/
+ bd_num = (ctlRequest & BD_NUM_MASK) >> BD_NUM_OFFSET;
+
+ /* Check that the bd_num is valid*/
+ if(bd_num > cd_p->bufferDescNumber)
+ {
+ result = IAPI_ERR_INVALID_PARAMETER | chNum;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /*All checks OK, try to aquire channel*/
+ if(iapi_GetChannel(chNum) != 0)
+ {
+ result = IAPI_ERR_CH_IN_USE | chNum;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /*
+ * 2. Selection of the parameter to change and appropriate sanity checks
+ */
+ switch (clean_ctlRequest){
+
+ /*
+ * Channel Descriptor
+ * --- Changes the pointer to the channel descriptor structure: the pointer
+ * to the new channel descriptor is given in the third argument call.
+ */
+ case IAPI_CHANGE_CHANDESC:
+ if ((void *) param == NULL) {
+ result = IAPI_ERR_INVALID_PARAMETER;
+ iapi_errno = result;
+ iapi_ReleaseChannel(chNum);
+ return -result;
+ } else {
+ channelDescriptor * chParam = (channelDescriptor *)param;
+ if (chParam->channelNumber != chNum){
+ /* Release ch so it can be aquired by the Close fn*/
+ iapi_ReleaseChannel(chNum);
+ result = iapi_Close(cd_p);
+ if (result == IAPI_SUCCESS){
+ FREE((void*)cd_p);
+ iapi_AllocChannelDesc (&cd_p, chParam->channelNumber);
+ iapi_memcpy((void*)cd_p, (void*)chParam, sizeof (channelDescriptor));
+ /* Channel is released allready, so Open can get the channel*/
+ result = iapi_Open(cd_p, chParam->channelNumber);
+ if(result != IAPI_SUCCESS)
+ {
+ return result; /* error code already set in iapi_Open*/
+ }
+ } else {
+ return result; /* error code already set in iapi_Close*/
+ }
+ } else {
+ result = IAPI_ERR_CD_CHANGE | IAPI_ERR_CH_AVAILABLE |
+ cd_p->channelNumber;
+ iapi_ReleaseChannel(chNum);
+ iapi_errno = result;
+ return -result;
+ }
+ return IAPI_SUCCESS;
+ }
+
+ /*
+ * Buffer Descriptor Number
+ * --- Changes the number of buffer descriptor for the channel.
+ */
+ case IAPI_CHANGE_BDNUM:
+ result = iapi_ChangeChannelDesc(cd_p, IAPI_BUFFERDESCNUMBER, param);
+ iapi_ReleaseChannel(chNum);
+ return result;
+
+ /*
+ * Buffer size
+ * --- Changes the size of the data buffers pointed to by the buffer
+ * descriptor; note that all buffer descriptors are assumed to have the
+ * same size for a given buffer descripotr chain.
+ */
+ case IAPI_CHANGE_BUFFSIZE:
+ result = iapi_ChangeChannelDesc(cd_p, IAPI_BUFFERSIZE, param);
+ iapi_ReleaseChannel(chNum);
+ return result;
+
+ /*
+ * Blocking policy
+ * --- Changes the blocking policy for the read and write calls.
+ */
+ case IAPI_CHANGE_CHANBLOCK:
+ result = iapi_ChangeChannelDesc(cd_p, IAPI_BLOCKING, param);
+ iapi_ReleaseChannel(chNum);
+ return result;
+
+ /*
+ * Ownership
+ * --- Changes direction: turnaround
+ */
+ case IAPI_CHANGE_OWNERSHIP:
+ result = iapi_ChangeChannelDesc(cd_p, IAPI_OWNERSHIP, param);
+ iapi_ReleaseChannel(chNum);
+ return result;
+
+ /*
+ * Synchronization method
+ * --- Changes the callback type, default or user. The callback function
+ * table is set accordingly.
+ */
+ case IAPI_CHANGE_SYNCH:
+ result = iapi_ChangeChannelDesc(cd_p, IAPI_CALLBACKSYNCH, param);
+ iapi_ReleaseChannel(chNum);
+ return result;
+
+ /*
+ * Trust property
+ * --- trust can only be changed through ChangeChannelDesc first request,
+ * this guarantees the close/open sequence for the channel.
+ */
+ case IAPI_CHANGE_TRUST:
+ result = iapi_ChangeChannelDesc(cd_p, IAPI_TRUST, param);
+ iapi_ReleaseChannel(chNum);
+ return result;
+
+ /*
+ * Callback Interrupt service routine pointer
+ * --- Cahnges the callback function pointer, when this method is used, to
+ * replace it with a new one.
+ */
+ case IAPI_CHANGE_CALLBACKFUNC:
+ result = iapi_ChangeChannelDesc(cd_p, IAPI_CALLBACKISR_PTR, param);
+ iapi_ReleaseChannel(chNum);
+ return result;
+
+ /*
+ * Channel control block pointer
+ * --- NA
+ */
+ case IAPI_CHANGE_CHANCCB:
+ result = iapi_ChangeChannelDesc(cd_p, IAPI_CCB_PTR, param);
+ iapi_ReleaseChannel(chNum);
+ return result;
+
+#ifdef MCU
+ /*
+ * Priority
+ * --- Changes the channel priority directly in SDMA register
+ */
+ case IAPI_CHANGE_PRIORITY:
+ {
+ volatile unsigned long * ChannelPriorities = &SDMA_CHNPRI_0;
+ if(param < MAX_CH_PRIORITY)
+ {
+ ChannelPriorities[ cd_p->channelNumber ] = param;
+ }
+ else
+ {
+ iapi_ReleaseChannel(chNum);
+ return IAPI_FAILURE;
+ }
+ }
+ break;
+#endif /* MCU */
+
+ /*
+ * Wrap
+ * --- Set to 1 the wrap bit of the last buffer descriptor of the array.
+ * it provides the possibility to have a circular buffer structure.
+ */
+ case IAPI_CHANGE_BDWRAP:
+ {
+ result = iapi_ChangeChannelDesc(cd_p,IAPI_BDWRAP , param);
+ iapi_ReleaseChannel(chNum);
+ return result;
+ }
+
+ /*
+ * Watermark
+ * --- Changes the value of the peripheral watermark level that triggers
+ * a DMA request. It impacts context of the channel, therefore channel 0
+ * must be started to update the context with this new value.
+ */
+ case IAPI_CHANGE_WATERMARK:
+ {
+ result = iapi_ChangeChannelDesc(cd_p,IAPI_WML , param);
+ iapi_ReleaseChannel(chNum);
+ return result;
+ }
+ /*
+ * INTR
+ * --- Set the INTR bit on specified BD or on all BD's if SET_BIT_ALL
+ * is passed as parameter.
+ */
+ case IAPI_CHANGE_SET_BDINTR:
+ {
+ bufferDescriptor * bde_p;
+ int j = 0;
+
+ retvalue = IAPI_SUCCESS;
+ if(param == SET_BIT_ALL)
+ {
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ for(j = 0; j < cd_p->bufferDescNumber; j++)
+ {
+ bde_p->mode.status |= BD_INTR;
+ bde_p++;
+ }
+ }
+ else if(param < cd_p->bufferDescNumber)
+ {
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr) +
+ param;
+ bde_p->mode.status |= BD_INTR;
+ }
+ else
+ {
+ retvalue = IAPI_FAILURE;
+ }
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+ /*
+ * INTR
+ * --- Unset the INTR bit on specified BD or on all BD's if SET_BIT_ALL
+ * is passed as parameter.
+ */
+ case IAPI_CHANGE_UNSET_BDINTR:
+ {
+ bufferDescriptor * bde_p;
+
+ int j = 0;
+
+ retvalue = IAPI_SUCCESS;
+ if(param == SET_BIT_ALL)
+ {
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ for(j = 0; j < cd_p->bufferDescNumber; j++)
+ {
+ bde_p->mode.status &= ~BD_INTR;
+ bde_p++;
+ }
+ }
+ else if(param < cd_p->bufferDescNumber)
+ {
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr) +
+ param;
+ bde_p->mode.status &= ~BD_INTR;
+ }
+ else
+ {
+ retvalue = IAPI_FAILURE;
+ }
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+/*
+ * EventMask1
+ * --- Changes the value of the eventMask1
+ */
+ case IAPI_CHANGE_EVTMASK1:
+ {
+ cd_p->eventMask1 = param;
+ }
+ break;
+ /*
+ * EventMask2
+ * --- Changes the value of the eventMask2
+ */
+ case IAPI_CHANGE_EVTMASK2:
+ {
+ cd_p->eventMask2 = param;
+ }
+ break;
+ /*
+ * Peripheral Address
+ * --- Changes the value of the peripheralAddr
+ */
+ case IAPI_CHANGE_PERIPHADDR:
+ {
+ cd_p->peripheralAddr = param;
+ }
+ break;
+ /*
+ * Cont
+ * --- Set the CONT bit on specified BD on all BD's if SET_BIT_ALL
+ * is passed as parameter.
+ */
+ case IAPI_CHANGE_SET_BDCONT:
+ {
+ bufferDescriptor * bde_p;
+ int j = 0;
+
+ retvalue = IAPI_SUCCESS;
+ if(param == SET_BIT_ALL)
+ {
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ for(j = 0; j < cd_p->bufferDescNumber; j++)
+ {
+ bde_p->mode.status |= BD_CONT;
+ bde_p++;
+ }
+ }
+ else if(param < cd_p->bufferDescNumber)
+ {
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr) +
+ param;
+ bde_p->mode.status |= BD_CONT;
+ }
+ else
+ {
+ retvalue = IAPI_FAILURE;
+ }
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+ /*
+ * Cont
+ * --- Unset the CONT bit on specified BD or on all BD's if SET_BIT_ALL
+ * is passed as parameter.
+ */
+ case IAPI_CHANGE_UNSET_BDCONT:
+ {
+ bufferDescriptor * bde_p;
+
+ int j = 0;
+
+ retvalue = IAPI_SUCCESS;
+ if(param == SET_BIT_ALL)
+ {
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ for(j = 0; j < cd_p->bufferDescNumber; j++)
+ {
+ bde_p->mode.status &= ~BD_CONT;
+ bde_p++;
+ }
+ }
+ else if(param < cd_p->bufferDescNumber)
+ {
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr) +
+ param;
+ bde_p->mode.status &= ~BD_CONT;
+ }
+ else
+ {
+ retvalue = IAPI_FAILURE;
+ }
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+
+ /*
+ * EXTD
+ * --- Set the EXTD bit on specified BD or on all BD's if SET_BIT_ALL
+ * is passed as parameter.
+ */
+ case IAPI_CHANGE_SET_BDEXTD:
+ {
+ bufferDescriptor * bde_p;
+ int j = 0;
+
+ retvalue = IAPI_SUCCESS;
+ if(param == SET_BIT_ALL)
+ {
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ for(j = 0; j < cd_p->bufferDescNumber; j++)
+ {
+ bde_p->mode.status |= BD_EXTD;
+ bde_p++;
+ }
+ }
+ else if(param < cd_p->bufferDescNumber)
+ {
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr) +
+ param;
+ bde_p->mode.status |= BD_EXTD;
+ }
+ else
+ {
+ retvalue = IAPI_FAILURE;
+ }
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+ /*
+ * EXTD
+ * --- Unset the EXTD bit on specified BD or on all BD's if SET_BIT_ALL
+ * is passed as parameter.
+ */
+ case IAPI_CHANGE_UNSET_BDEXTD:
+ {
+ bufferDescriptor * bde_p;
+
+ int j = 0;
+
+ retvalue = IAPI_SUCCESS;
+ if(param == SET_BIT_ALL)
+ {
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ for(j = 0; j < cd_p->bufferDescNumber; j++)
+ {
+ bde_p->mode.status &= ~BD_EXTD;
+ bde_p++;
+ }
+ }
+ else if(param < cd_p->bufferDescNumber)
+ {
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr) +
+ param;
+ bde_p->mode.status &= ~BD_EXTD;
+ }
+ else
+ {
+ retvalue = IAPI_FAILURE;
+ }
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+
+ /*
+ * TRANSFER SIZE to be used for this channel
+ * --- Set the transfer size used indicator and code for transfer size in
+ * the CD
+ */
+case IAPI_CHANGE_SET_TRANSFER_CD:
+ {
+ bufferDescriptor * bde_p;
+ int j = 0;
+ retvalue = IAPI_SUCCESS;
+ if((param == TRANSFER_8BIT) || (param == TRANSFER_16BIT) ||
+ (param == TRANSFER_24BIT) || (param == TRANSFER_32BIT))
+ {
+ cd_p->useDataSize = TRUE;
+ cd_p->dataSize = param;
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ for(j = 0; j < cd_p->bufferDescNumber; j++)
+ {
+ bde_p->mode.command = param;
+ bde_p++;
+ }
+ }
+ else
+ {
+ retvalue = IAPI_FAILURE;
+ }
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+
+
+ /*
+ * USER_ARG
+ * --- Set the user selectable pointer to be received by the callback
+ * function, if IRQ synch is used
+ */
+ case IAPI_CHANGE_USER_ARG:
+ {
+ userArgTable[cd_p->channelNumber]= (void*)param;
+ iapi_ReleaseChannel(chNum);
+ return IAPI_SUCCESS;
+ }
+ /*
+ * FORCE_CLOSE
+ * --- Set the forceClose bit in channelDescriptor to value passed in param.
+ * If this bit is TRUE, the channel in closed even if some BD are still
+ * owned by the SDMA.
+ */
+ case IAPI_CHANGE_FORCE_CLOSE:
+ {
+ retvalue = IAPI_SUCCESS;
+ if((param == TRUE) || (param == FALSE))
+ {
+ cd_p->forceClose = param;
+ }
+ else
+ {
+ iapi_errno = IAPI_ERR_INVALID_PARAMETER | cd_p->channelNumber;
+ retvalue = -iapi_errno;
+ }
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+ /*
+ * TRANSFER type
+ * --- Set the last 2 bits in the command field of the BD to specify the
+ * transfer type 8, 16, 24, or 32 bits on all BD's, allready set in the CD
+ */
+ case IAPI_CHANGE_SET_TRANSFER:
+ {
+ bufferDescriptor * bde_p;
+ int j = 0;
+
+ retvalue = IAPI_SUCCESS;
+ if((param == TRANSFER_8BIT)||(param == TRANSFER_16BIT)||
+ (param == TRANSFER_24BIT)||(param == TRANSFER_32BIT))
+ {
+ bde_p = cd_p->ccb_ptr->baseBDptr;
+ for(j = 0; j < cd_p->bufferDescNumber; j++)
+ {
+ bde_p->mode.command = param;
+ bde_p++;
+ }
+ }
+ else
+ {
+ retvalue = IAPI_FAILURE;
+ }
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+ /*
+ * BUFFER address
+ * --- Change buffer address in BD specified in the upper 16 bits of the
+ * ctlRequest.
+ */
+ case IAPI_CHANGE_SET_BUFFERADDR:
+ {
+ bufferDescriptor * bde_p;
+ retvalue = IAPI_SUCCESS;
+
+ /* Get pointer to the BD structure to change*/
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ bde_p+= bd_num;
+
+ /* DO NOT translate address to physical */
+ bde_p->bufferAddr = (void*)param;
+
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+ /*
+ * BUFFER address
+ * --- Get the buffer address from the BD specified in the upper 16 bits of the
+ * ctlRequest.
+ */
+ case IAPI_CHANGE_GET_BUFFERADDR:
+ {
+ bufferDescriptor * bde_p;
+ retvalue = IAPI_SUCCESS;
+
+ /* Get pointer to the BD structure to change*/
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ bde_p+= bd_num;
+ /* Translate to virtual*/
+ *((unsigned long*)param) = (unsigned long)bde_p->bufferAddr;
+
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+ /*
+ * EXTENDED BUFFER address
+ * --- Change extended buffer address in BD specified in the upper 16 bits
+ * of the ctlRequest.
+ */
+ case IAPI_CHANGE_SET_EXTDBUFFERADDR:
+ {
+ bufferDescriptor * bde_p;
+ retvalue = IAPI_SUCCESS;
+
+ /* Get pointer to the BD structure to change*/
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ bde_p+= bd_num;
+
+ /* DO NOT translate address to physical. The user might want something else
+ *here
+ */
+ bde_p->extBufferAddr = (void*)param;
+
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+ /*
+ * EXTENDED BUFFER address
+ * --- Get extended buffer address from the BD specified in the upper 16 bits
+ * of the ctlRequest.
+ */
+ case IAPI_CHANGE_GET_EXTDBUFFERADDR:
+ {
+ bufferDescriptor * bde_p;
+ retvalue = IAPI_SUCCESS;
+
+ /* Get pointer to the BD structure to change*/
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ bde_p+= bd_num;
+
+ /* DO NOT translate address to vitual - user knows what is here.
+ */
+ *((unsigned long*)param) = (unsigned long)bde_p->extBufferAddr;
+
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+ /*
+ * COMMAND field
+ * --- Change command field in BD specified in the upper 16 bits of the
+ * ctlRequest.
+ */
+ case IAPI_CHANGE_SET_COMMAND:
+ {
+ bufferDescriptor * bde_p;
+ retvalue = IAPI_SUCCESS;
+
+ /* Get pointer to the BD structure to change*/
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ bde_p+= bd_num;
+ /* Update command field*/
+ bde_p->mode.command = param;
+
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+ /*
+ * COMMAND field
+ * --- Get the command field from the BD specified in the upper 16 bits
+ * of the ctlRequest.
+ */
+ case IAPI_CHANGE_GET_COMMAND:
+ {
+ bufferDescriptor * bde_p;
+ retvalue = IAPI_SUCCESS;
+
+ /* Get pointer to the BD structure to change*/
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ bde_p+= bd_num;
+ /* Get the command field*/
+ *((unsigned long*)param) = bde_p->mode.command;
+
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+ /*
+ * COUNT field
+ * --- Change count field in BD specified in the upper 16 bits of the
+ * ctlRequest.
+ */
+ case IAPI_CHANGE_SET_COUNT:
+ {
+ bufferDescriptor * bde_p;
+ retvalue = IAPI_SUCCESS;
+
+ /* Get pointer to the BD structure to change*/
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ bde_p+= bd_num;
+ /* Update count field*/
+ bde_p->mode.count = param;
+
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+ /*
+ * COUNT field
+ * --- Get the count field of the BD specified in the upper 16 bits of the
+ * ctlRequest.
+ */
+ case IAPI_CHANGE_GET_COUNT:
+ {
+ bufferDescriptor * bde_p;
+ retvalue = IAPI_SUCCESS;
+
+ /* Get pointer to the BD structure to change*/
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ bde_p+= bd_num;
+ /* Update count field*/
+ *((unsigned long*)param) = bde_p->mode.count;
+
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+ /*
+ * STATUS field
+ * --- Change status field in BD specified in the upper 16 bits of the
+ * ctlRequest.
+ */
+ case IAPI_CHANGE_SET_STATUS:
+ {
+ bufferDescriptor * bde_p;
+ retvalue = IAPI_SUCCESS;
+
+ /* Get pointer to the BD structure to change*/
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ bde_p+= bd_num;
+ /* Update status field*/
+ bde_p->mode.status = param;
+
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+ /*
+ * STATUS field
+ * --- Get the status field of the BD specified in the upper 16 bits
+ * of the ctlRequest.
+ */
+ case IAPI_CHANGE_GET_STATUS:
+ {
+ bufferDescriptor * bde_p;
+ retvalue = IAPI_SUCCESS;
+
+ /* Get pointer to the BD structure to change*/
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ bde_p+= bd_num;
+ /* Update status field*/
+ *((unsigned long*)param) = bde_p->mode.status;
+
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+
+#ifdef MCU
+ /*
+ * Endianness
+ * --- Set the ENDIANNESS indicator in the command filed of the specified BD
+ * or on all BD's if SET_BIT_ALL is passed as parameter.
+ */
+ case IAPI_CHANGE_SET_ENDIANNESS:
+ {
+ bufferDescriptor * bde_p;
+ int j = 0;
+
+ retvalue = IAPI_SUCCESS;
+ if(param == SET_BIT_ALL)
+ {
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ for(j = 0; j < cd_p->bufferDescNumber; j++)
+ {
+ bde_p->mode.command = CHANGE_ENDIANNESS;
+ bde_p++;
+ }
+ }
+ else if(param < cd_p->bufferDescNumber)
+ {
+ bde_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr) +
+ param;
+ bde_p->mode.command = CHANGE_ENDIANNESS;
+ }
+ else
+ {
+ retvalue = IAPI_FAILURE;
+ }
+ iapi_ReleaseChannel(chNum);
+ return retvalue;
+ }
+#endif
+
+#ifdef SDMA_SKYE
+#ifdef MCU
+
+ /*
+ * SDMA State
+ * --- Enter the SDMA into LOCK Mode. No RAM updation allowed except same Context
+ * update with same PC Value.
+ */
+ case IAPI_ENTER_LOCK_MODE:
+ {
+ if(param == RESET_CLEAR_LOCK)
+ {
+ SDMA_SDMA_LOCK = (1 << RESET_CLR_BIT_OFFSET);
+ SDMA_SDMA_LOCK = (1 << LOCK_BIT_OFFSET);
+ iapi_SdmaState = LOCK;
+ }
+ else if(param == RESET_NOCLEAR_LOCK)
+ {
+ SDMA_SDMA_LOCK = (1 << LOCK_BIT_OFFSET);
+ iapi_SdmaState = LOCK;
+ }
+
+ }
+ break;
+
+#endif
+#endif
+ default:
+ retvalue = IAPI_ERR_CD_CHANGE_UNKNOWN | IAPI_ERR_CH_AVAILABLE | chNum;
+ iapi_errno = retvalue;
+ iapi_ReleaseChannel(chNum);
+ return -retvalue;
+ }
+
+
+ iapi_ReleaseChannel(chNum);
+ return IAPI_SUCCESS;
+}
+/* ***************************************************************************/
+/**Initialization of the SDMA - opening of channel 0, download RAM image.
+ *
+ * <b>Algorithm:</b>\n
+ * - open channel 0
+ * - if ram_image pointer passed is not NULL, download RAM image to SDMA
+ *
+ * @param
+ * - cd_p channel descriptor pointer for channel 0
+ * - ram_image pointer to RAM image to download, or NULL if this operation
+ * is not required
+ * - code_size size of the RAM image, in bytes
+ * - start_addr start address for the RAM image
+ *
+ * @return
+ * - IAPI_SUCCESS if all operations were successful
+ * - negated I.API error code if any operation failed
+ */
+#ifdef MCU
+int
+iapi_Init(channelDescriptor * cd_p, configs_data * config_p, unsigned short* ram_image,
+ unsigned short code_size, unsigned long start_addr)
+{
+#endif
+#ifdef DSP
+int
+iapi_Init(channelDescriptor * cd_p)
+{
+#endif
+
+int retvalue = IAPI_SUCCESS; /* Variable to store the results from I.API calls */
+
+ /* Check initialization not allredy done*/
+ if(iapi_CCBHead != NULL)
+ {
+ retvalue = IAPI_ERR_NOT_ALLOWED;
+ iapi_errno = retvalue;
+ return -retvalue;
+ }
+ /* Be sure SDMA has not started yet */
+#ifdef MCU
+ SDMA_H_C0PTR = 0x0;
+#endif
+#ifdef DSP
+ SDMA_D_C0PTR = 0x0;
+#endif
+
+ /*Try to open channel 0*/
+ retvalue = iapi_Open(cd_p, 0);
+ if(retvalue != IAPI_SUCCESS)
+ {
+ return retvalue;
+ }
+
+#ifdef MCU
+ /* Set Command Channel (Channel Zero) */
+ SDMA_CHN0ADDR = 0x4050;
+
+ /* Set bits of CONFIG register but with static context switching */
+ SDMA_H_CONFIG = (config_p->dspdma << 12) | (config_p->rtdobs << 11) |
+ (config_p->acr << 4) | (0);
+
+ /* Send the address for the host channel table to the SDMA*/
+ SDMA_H_C0PTR = (unsigned long)iapi_Virt2Phys(iapi_CCBHead);
+ /* If required, download the RAM image for SDMA*/
+ if(ram_image != NULL)
+ {
+ retvalue = iapi_SetScript(cd_p, (void*)ram_image, code_size,
+ start_addr);
+ }
+
+ /* Set bits of CONFIG register with given context switching mode */
+ SDMA_H_CONFIG = (config_p->dspdma << 12) | (config_p->rtdobs << 11) |
+ (config_p->acr << 4) | (config_p->csm);
+
+#endif
+#ifdef DSP
+ /* Send the address for the host channel table to the SDMA*/
+ SDMA_D_C0PTR = (unsigned long)iapi_Virt2Phys(iapi_CCBHead);
+#endif
+
+#ifdef SDMA_SKYE
+ iapi_SdmaState = OPEN;
+#endif
+
+ return retvalue;
+}
+
+
+/* ***************************************************************************/
+/**High layer interface for starting a channel
+ *
+ * <b>Algorithm:</b>\n
+ * - call low layer function for starting a channel
+ *
+ * @return
+ * - IAPI_SUCCESS
+ */
+int
+iapi_StartChannel(unsigned char channel)
+{
+ iapi_lowStartChannel(channel);
+ return IAPI_SUCCESS;
+}
+/* ***************************************************************************/
+/**High layer interface for stopping a channel
+ *
+ * <b>Algorithm:</b>\n
+ * - call low layer function for stopping a channel
+ *
+ * @return
+ * - IAPI_SUCCESS
+ */
+int
+iapi_StopChannel(unsigned char channel)
+{
+ iapi_lowStopChannel(channel);
+ return IAPI_SUCCESS;
+}
+
+/* ***************************************************************************/
+/**High layer interface for synchronising a channel
+ *
+ * <b>Algorithm:</b>\n
+ * - call low layer function for stopping a channel
+ *
+ * @return
+ * - IAPI_SUCCESS
+ */
+int iapi_SynchChannel(unsigned char channel)
+{
+ iapi_lowSynchChannel(channel);
+ return IAPI_SUCCESS;
+}
+
+#ifdef MCU
+/* ***************************************************************************/
+/**High layer interface for getting program memory data from SDMA
+ *
+ * <b>Algorithm:</b>\n
+ * - call coresponding low layer function
+ *
+ * @return
+ * - IAPI_SUCCESS
+ */
+int
+iapi_GetScript(channelDescriptor * cd_p, void * buf, unsigned short size,
+ unsigned long address)
+{
+ iapi_lowGetScript(cd_p, buf, size, address);
+ return IAPI_SUCCESS;
+}
+
+/* ***************************************************************************/
+/**High layer interface for getting data memory from SDMA
+ *
+ * <b>Algorithm:</b>\n
+ * - call coresponding low layer function
+ *
+ * @return
+ * - IAPI_SUCCESS
+ */
+int
+iapi_GetContext(channelDescriptor * cd_p, void * buf,
+ unsigned char channel)
+{
+ iapi_lowGetContext(cd_p, buf, channel);
+ return IAPI_SUCCESS;
+}
+
+/* ***************************************************************************/
+/**High layer interface for set program memory data to SDMA - e.g. scripts
+ *
+ * <b>Algorithm:</b>\n
+ * - call coresponding low layer function
+ *
+ * @return
+ * - IAPI_SUCCESS
+ */
+int
+iapi_SetScript(channelDescriptor * cd_p, void * buf, unsigned short nbyte,
+ unsigned long destAddr)
+{
+ iapi_lowSetScript(cd_p, buf, nbyte, destAddr);
+ return IAPI_SUCCESS;
+}
+
+/* ***************************************************************************/
+/**High layer interface for set data memory to SDMA - e.g. contexts.
+ *
+ * <b>Algorithm:</b>\n
+ * - call coresponding low layer function
+ *
+ * @return
+ * - IAPI_SUCCESS
+ */
+int
+iapi_SetContext(channelDescriptor * cd_p, void * buf,
+ unsigned char channel)
+{
+ iapi_lowSetContext(cd_p, buf, channel);
+ return IAPI_SUCCESS;
+}
+
+/* ***************************************************************************/
+/**High layer interface used to associate specified channel with a script.
+ *
+ * <b>Algorithm:</b>\n
+ * - call coresponding low layer function
+ *
+ * @return
+ * - IAPI_SUCCESS
+ */
+int
+iapi_AssignScript(channelDescriptor * cd_p, script_data * data_p)
+{
+ /* VERIFY THAT THE CHANNEL IT IS OPENED !!!!*/
+ return iapi_lowAssignScript(cd_p, data_p);
+}
+
+/* ***************************************************************************/
+/**High layer interface used to associate specified channel with a script.
+ *
+ * <b>Algorithm:</b>\n
+ * - call coresponding low layer function
+ *
+ * @return
+ * - IAPI_SUCCESS
+ */
+int
+iapi_SetChannelEventMapping(unsigned char event, unsigned long channel_map)
+{
+ return iapi_lowSetChannelEventMapping(event, channel_map);
+}
+#endif
+
+
+
+#ifdef DSP
+#define SDMA_DI SDMA_D_INTR
+void IRQ_Handler();
+#pragma interrupt IRQ_Handler
+#endif
+
+#ifdef MCU
+#define SDMA_DI SDMA_H_INTR
+#endif
+
+#ifndef IRQ_KEYWORD
+#define IRQ_KEYWORD
+#endif /* IRQ_KEYWORD */
+
+/* ***************************************************************************/
+/**
+ *@brief Find the first set bit in data parameter.
+ *
+ * Find the first set bit in unsigned integer parameter data. Data is scanned
+ * from MSB to LSB, searching for the set bit. The value returned is the
+ * offset from the most significant bit of data. If bit 31 is set, the value
+ * returned is zero. If no bits are set, a value of 32 is returned. This is compliant
+ * with the MCore FF1 instruction.
+ *
+ *
+ *
+ * @param
+ * - data: variable to check
+ *
+ * @return
+ * - the offset of the most significant bit set from the MSB
+ */
+unsigned int
+quartz_FF1( unsigned int data )
+{
+ register unsigned int result = 0;
+ while ( (result <= 31 ) && !( data & 0x80000000U) )
+ {
+ data <<= 1U;
+ result++;
+ }
+
+ return result;
+}
+
+IRQ_KEYWORD
+void
+IRQ_Handler(void)
+{
+ unsigned int intrReg;/* interrupt register mask for clearing the interrupt bit */
+ unsigned char chNum; /* SDMA channel number generating the a IRQ*/
+
+ /* Disable interrupts */
+ iapi_DisableInterrupts();
+ /*
+ * Clear interrupt in SDMA DI register => ACK to the SDMA the IT request.
+ * Get each interrupt number, clear them one after the other.
+ */
+ if(SDMA_DI != 0)
+ {
+ chNum = (unsigned char)(CH_NUM - 1 - quartz_FF1(SDMA_DI));
+ intrReg = (unsigned int)(1 << chNum);
+ }
+ else
+ {
+ chNum = 32;
+ intrReg = 0;
+ }
+
+ while (intrReg != 0)
+ {
+ SDMA_DI &= intrReg;
+ iapi_SDMAIntr |= intrReg;
+ iapi_WakeUp(chNum);
+ if (callbackIsrTable[chNum] != NULL)
+ {
+ /* release channel before callback, so IoCtl's are available*/
+ iapi_ReleaseChannel(chNum);
+ callbackIsrTable[chNum](iapi_CCBHead[chNum].channelDescriptor,
+ userArgTable[chNum]);
+ }
+
+ chNum = (unsigned char)(CH_NUM - 1 - quartz_FF1(SDMA_DI));
+ intrReg = (unsigned int)(1 << chNum);
+ }
+
+ /* Enable interrupts */
+ iapi_EnableInterrupts();
+}
+
+/* ***************************************************************************/
+/**
+ *@brief Perform a memory copy operation, in the memory of the same processor
+ *
+ * Size bytes are copied from the src address to dest address. It is used
+ * the channel pointed by cd_p, which must be configured prior to this call:
+ * opened, associated with the script to perform the operation - DSP_2_DSP,
+ * or MCU_2_MCU - and have the synchronization option set.
+ *
+ *
+ *
+ * @param
+ * - cd_p: channel configured to perform DSP_2_DSP or MCU_2_MCU transfers
+ * - dest: destination memory address
+ * - src : source memory address
+ * - size: number of bytes to copy from src to dest
+ *
+ * @return
+ * - the offset of the most significant bit set from the MSB
+ */
+
+int iapi_MemCopy(channelDescriptor * cd_p, void* dest, void* src, unsigned long size)
+{
+ int result = IAPI_SUCCESS;
+ bufferDescriptor * bd_p;
+
+ /* Channel descriptor validity */
+ if (cd_p == NULL)
+ {
+ result = IAPI_ERR_CD_UNINITIALIZED;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* Check and set correct parameter */
+ if(cd_p->trust != TRUE)
+ {
+ result = iapi_ChangeChannelDesc(cd_p, IAPI_TRUST, TRUE);
+ }
+
+ if(cd_p->bufferDescNumber != 1)
+ {
+ result = iapi_ChangeChannelDesc(cd_p, IAPI_BUFFERDESCNUMBER, 1);
+ if(result != IAPI_SUCCESS)
+ {
+ return result;
+ }
+ }
+
+ if(cd_p->bufferSize != size)
+ {
+ result = iapi_ChangeChannelDesc(cd_p, IAPI_BUFFERSIZE, size);
+ if(result != IAPI_SUCCESS)
+ {
+ return result;
+ }
+ }
+ /* Set addresses*/
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ bd_p->bufferAddr = iapi_Virt2Phys(src);
+ bd_p->extBufferAddr = iapi_Virt2Phys(dest);
+
+ /* Set mode*/
+ bd_p->mode.count = size;
+ bd_p->mode.command = 0x00;
+ bd_p->mode.status = BD_INTR|BD_EXTD|BD_DONE|BD_WRAP;
+
+ /*Decide if we sleep or not*/
+ if(cd_p->callbackSynch == DEFAULT_POLL)
+ {
+ iapi_StartChannel(cd_p->channelNumber);
+ /* Call synchronization routine*/
+ iapi_SynchChannel(cd_p->channelNumber);
+ }
+ else
+ {
+ /* Just start the channel*/
+ iapi_StartChannel(cd_p->channelNumber);
+ }
+
+ return result;
+}
+
+/* ***************************************************************************/
+/**Return the channel number from the channel descriptor
+ *
+ * @param cd_p pointer to channel descriptor to obtain the channel number
+ *
+ * @return
+ * - the channel number
+ *
+ */
+int iapi_GetChannelNumber(channelDescriptor * cd_p)
+{
+ return cd_p->channelNumber;
+}
+
+/* ***************************************************************************/
+/**Return the error bit from the current BD of the channel
+ *
+ *
+ * @param cd_p pointer to channel descriptor
+ *
+ * @return
+ * - 0 if no error detected
+ * - BD_RROR | DATA_ERROR if error detected
+ *
+ */
+unsigned long iapi_GetError(channelDescriptor * cd_p)
+{
+ return ((cd_p->ccb_ptr->currentBDptr->mode.status & BD_RROR) |
+ (*(unsigned long*)&cd_p->ccb_ptr->status & DATA_ERROR));
+}
+
+/* ***************************************************************************/
+/**Return the count from the current BD of the channel
+ *
+ *
+ * @param cd_p pointer to channel descriptor
+ *
+ * @return
+ * - count field of the current BD for the channel
+ *
+ */
+int iapi_GetCount(channelDescriptor * cd_p)
+{
+ return (int)(cd_p->ccb_ptr->currentBDptr->mode.count);
+}
+
+/* ***************************************************************************/
+/**Return the sum of counts for all the BD's owned by the processor for
+ * the channel specified by the received parameter.
+ *
+ *
+ * @param cd_p pointer to channel descriptor
+ *
+ * @return
+ * - sum of count fields
+ *
+ */
+int iapi_GetCountAll(channelDescriptor * cd_p)
+{
+ int retval = 0;
+ int i = 0;
+ bufferDescriptor* bd_p;
+
+ bd_p = cd_p->ccb_ptr->baseBDptr;
+
+ while((i < cd_p->bufferDescNumber) && ((bd_p->mode.status & BD_DONE) == 0))
+ {
+ retval += bd_p->mode.count;
+ i++;
+ bd_p++;
+ }
+ return retval;
+}
diff --git a/arch/arm/plat-mxc/sdma/iapi/src/iapiLow.c b/arch/arm/plat-mxc/sdma/iapi/src/iapiLow.c
new file mode 100644
index 000000000000..1470f2f366fd
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/src/iapiLow.c
@@ -0,0 +1,150 @@
+/******************************************************************************
+ *
+ * Copyright 2007-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: iapiLow.c
+ *
+ * $Id iapiLow.c $
+ *
+ * Description:
+ * This library is written in C to guarantee functionality and integrity in
+ * the usage of SDMA virtual DMA channels. This API (Application Programming
+ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
+ * fashion.
+ * These are the LOW level functions of the I.API.
+ *
+ *
+ * /
+ *
+ * $Log iapiLow.c $
+ *
+ *****************************************************************************/
+
+/* ****************************************************************************
+ * Include File Section
+ *****************************************************************************/
+#include "epm.h"
+#include "iapiLow.h"
+
+/**
+ * Function Section
+ */
+
+
+/* ***************************************************************************/
+/**Records an ISR callback function pointer into the ISR callback
+ * function table
+ *
+ * @param cd_p channel descriptor to attach callback to
+ * @param func_p pointer to the callback function to be registered
+ *
+ * @return none
+ */
+void
+iapi_AttachCallbackISR (channelDescriptor * cd_p,
+ void (* func_p)(channelDescriptor * cd_p, void * arg))
+
+{
+ if (cd_p->callbackSynch == CALLBACK_ISR) {
+ iapi_DisableInterrupts();
+ callbackIsrTable[cd_p->channelNumber] = func_p;
+ iapi_EnableInterrupts();
+ } else if (cd_p->callbackSynch == DEFAULT_POLL) {
+ callbackIsrTable[cd_p->channelNumber] = NULL;
+ } else {
+ iapi_errno = IAPI_ERR_CALLBACKSYNCH_UNKNOWN | IAPI_ERR_CH_AVAILABLE |
+ cd_p->channelNumber;
+ }
+}
+
+
+/* ***************************************************************************/
+/**Detaches (removes) an ISR callback function pointer from the ISR callback
+ * function table
+ *
+ * <b>Algorithm:</b>\n
+ * - Attach a null function to replace the original one.
+ *
+ * @param cd_p channel descriptor to detach callback from
+ *
+ * @return none
+ */
+void
+iapi_DetachCallbackISR (channelDescriptor * cd_p)
+
+{
+ iapi_AttachCallbackISR (cd_p, NULL);
+}
+
+/* ***************************************************************************/
+/**Updates an ISR callback function pointer into the ISR callback function
+ * table
+ *
+ * <b>Algorithm:</b>\n
+ * - Detach the old function pointer (if any) and attach the new one
+ *
+ * @param cd_p channel descriptor to attach callback to
+ * @param func_p pointer to the callback function to be registered
+ *
+ * @return none
+ */
+void
+iapi_ChangeCallbackISR (channelDescriptor * cd_p,
+ void (* func_p)(channelDescriptor * cd_p, void * arg))
+{
+ iapi_DetachCallbackISR(cd_p);
+ iapi_AttachCallbackISR(cd_p, func_p);
+}
+
+/* ***************************************************************************/
+/**Loop while the channel is not done on the SDMA
+ *
+ * <b>Algorithm:</b>\n
+ * - Loop doing nothing but checking the I.API global variable to indicate
+ * that the channel has been completed (interrupt from SDMA)
+ *
+ * <b>Notes:</b>\n
+ * - The ISR must update the I.API global variable iapi_SDMAIntr.
+ *
+ * @param channel channel number to poll on
+ *
+ * @return none
+ */
+void
+iapi_lowSynchChannel (unsigned char channel)
+{
+ while (!((1UL << channel) & iapi_SDMAIntr)) ;
+ iapi_SDMAIntr &= ~(1UL << channel);
+}
+
+/* ***************************************************************************/
+/**Fill the buffer descriptor with the values given in parameter.
+ *
+ * @return none
+ */
+void
+iapi_SetBufferDescriptor( bufferDescriptor * bd_p, unsigned char command,
+ unsigned char status, unsigned short count,
+ void * buffAddr, void * extBufferAddr)
+{
+ bd_p->mode.command = command;
+ bd_p->mode.status = status;
+ bd_p->mode.count = count;
+ if (buffAddr != NULL) {
+ bd_p->bufferAddr = iapi_Virt2Phys(buffAddr);
+ } else {
+ bd_p->bufferAddr = buffAddr;
+ }
+ bd_p->extBufferAddr = extBufferAddr;
+}
+
diff --git a/arch/arm/plat-mxc/sdma/iapi/src/iapiLowDsp.c b/arch/arm/plat-mxc/sdma/iapi/src/iapiLowDsp.c
new file mode 100644
index 000000000000..df7d44a9bd46
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/src/iapiLowDsp.c
@@ -0,0 +1,79 @@
+/******************************************************************************
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: iapiLowDsp.c
+ *
+ * $Id iapiLowDsp.c $
+ *
+ * Description:
+ * This library is written in C to guarantee functionality and integrity in
+ * the usage of SDMA virtual DMA channels. This API (Application Programming
+ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
+ * fashion.
+ * These are the LOW level functions of the I.API specific to MCU.
+ *
+ *
+ *
+ *
+ * $Log iapiLowDsp.c $
+ *
+ *****************************************************************************/
+
+/* ****************************************************************************
+ * Include File Section
+ *****************************************************************************/
+#include "epm.h"
+#include "iapiLow.h"
+
+/* ****************************************************************************
+ * Function Section
+ *****************************************************************************/
+#ifdef DSP
+
+/* ***************************************************************************/
+/**Starts the channel (core specific register)
+ *
+ * <b>Algorithm:</b>\n
+ * - Bit numbered "channel" of DspEnStartReg register is set
+ *
+ * @param channel channel to start
+ *
+ * @return none
+ */
+void
+iapi_lowStartChannel (unsigned char channel)
+{
+ SDMA_D_START |= (1 << channel);
+}
+
+/* ***************************************************************************/
+/**Stops the channel (core specific register)
+ *
+ * <b>Algorithm:</b>
+ * - Bit numbered "channel" of DspEnStopReg register is cleared
+ *
+ * <b>Notes:</b>\n
+ * - This is a write one to clear register
+ *
+ * @param channel channel to stop
+ *
+ * @return none
+ */
+void
+iapi_lowStopChannel (unsigned char channel)
+{
+ SDMA_D_STATSTOP &= (1 << channel);
+}
+
+#endif /* DSP */
diff --git a/arch/arm/plat-mxc/sdma/iapi/src/iapiLowMcu.c b/arch/arm/plat-mxc/sdma/iapi/src/iapiLowMcu.c
new file mode 100644
index 000000000000..1d7951153270
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/src/iapiLowMcu.c
@@ -0,0 +1,516 @@
+/******************************************************************************
+ *
+ * Copyright 2007-2008 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: iapiLowMcu.c
+ *
+ * $Id iapiLowMcu.c $
+ *
+ * Description:
+ * This library is written in C to guarantee functionality and integrity in
+ * the usage of SDMA virtual DMA channels. This API (Application Programming
+ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
+ * fashion.
+ * These are the LOW level functions of the I.API specific to MCU.
+ *
+ *
+ * http://compass/mot.com/go/115342679
+ *
+ * $Log iapiLowMcu.c $
+ *
+ *****************************************************************************/
+
+/* ****************************************************************************
+ * Include File Section
+ *****************************************************************************/
+#include <string.h>
+
+#include "epm.h"
+#include "iapiLow.h"
+
+/* ****************************************************************************
+ * Function Section
+ *****************************************************************************/
+#ifdef MCU
+
+/* ***************************************************************************/
+/**Send a command on SDMA's channel zero.
+ * Check if buffer descriptor is already used by the sdma, if yes return
+ * an error as c0BDNum is wrong.
+ *
+ * <b>Notes</b>\n
+ * There is an upgrade in the script on the Context load command and
+ * the fact that the context structure has a fixed length of 20 or 24
+ * depending on SDMA versions.
+ *
+ * @return
+ * - IAPI_SUCCESS
+ * - -iapi_errno if failure
+ */
+int
+iapi_Channel0Command( channelDescriptor * cd_p, void * buf,
+ unsigned short nbyte, unsigned char command)
+{
+ channelControlBlock * ccb_p;
+ bufferDescriptor * bd_p;
+ int result = IAPI_SUCCESS;
+ unsigned char chNum;
+
+
+ /*
+ * Check data structures are properly initialized
+ */
+ /* Channel descriptor validity */
+ if (cd_p == NULL){
+ result = IAPI_ERR_CD_UNINITIALIZED;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* Channel control block validity */
+ if (cd_p->ccb_ptr == NULL){
+ result = IAPI_ERR_CCB_UNINITIALIZED;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* Control block & Descriptpor associated with the channel being worked on */
+ chNum = cd_p->channelNumber;
+ ccb_p = cd_p->ccb_ptr;
+
+ /* Is channel already in use ? */
+ if (ccb_p->baseBDptr != NULL ) {
+ result = IAPI_ERR_BD_ALLOCATED | IAPI_ERR_CH_AVAILABLE | chNum;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* Allocation of buffer descriptors */
+ bd_p = (bufferDescriptor *)MALLOC(sizeof( bufferDescriptor ), SDMA_ERAM);
+ if (bd_p != NULL) {
+ ccb_p->baseBDptr = (bufferDescriptor *)iapi_Virt2Phys(bd_p);
+ } else {
+ result = IAPI_ERR_BD_ALLOCATION | IAPI_ERR_CH_AVAILABLE | chNum;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* Buffer descriptor setting */
+ iapi_SetBufferDescriptor( bd_p, command , BD_WRAP|BD_DONE|BD_INTR , nbyte,
+ buf,NULL);
+
+ /* Actually the transfer */
+ iapi_lowStartChannel( cd_p->channelNumber );
+ iapi_lowSynchChannel( cd_p->channelNumber );
+
+ /* Cleaning of allocation */
+ FREE( bd_p );
+ ccb_p->baseBDptr = NULL;
+
+ return IAPI_SUCCESS;
+
+}
+
+/* ***************************************************************************/
+/**Starts the channel (core specific register)
+ *
+ * <b>Algorithm:</b>\n
+ * - Bit numbered "channel" of HostEnStartReg register is set
+ *
+ * @param channel channel to start
+ *
+ * @return none
+ */
+void
+iapi_lowStartChannel (unsigned char channel)
+{
+ SDMA_H_START |= 1 << channel;
+}
+
+/* ***************************************************************************/
+/**Stops the channel (core specific register)
+ *
+ * <b>Algorithm:</b>
+ * - Bit numbered "channel" of HostEnStopReg register is cleared
+ *
+ * <b>Notes:</b>\n
+ * - This is a write one to clear register
+ *
+ * @param channel channel to stop
+ *
+ * @return none
+ */
+void
+iapi_lowStopChannel (unsigned char channel)
+{
+ SDMA_H_STATSTOP &= 1 << channel;
+}
+
+/* ***************************************************************************/
+/**Initialize the initial priority of registers and channel enable
+ * RAM from the MCU side. No channels are enabled, all priorities are set to 0.
+ *
+ * @return none
+ */
+void
+iapi_InitChannelTables(void)
+{
+
+ /* No channel is enabled*/
+ iapi_memset((void *)&SDMA_CHNENBL_0, 0x00, sizeof(unsigned long)*EVENTS_NUM);
+ /* All channels have priority 0*/
+ iapi_memset((void *)&SDMA_CHNPRI_0, 0x00, sizeof(unsigned long)*CH_NUM);
+}
+
+/* ***************************************************************************/
+/** The host enable (HE), hosts override (HO), dsp enable (DE), dsp override
+ * (DO) registers are involved here.
+ * Host and Dsp enable registers are here to signify that the MCU or DSP side
+ * have prepared the appropriate buffers and are now ready. If the channel is
+ * owned by the MCU the override bit for that channel needs to be cleared :
+ * the host allows the channel to be used.\n
+ *
+ * Then the override bits can define (mcuOverride dspOverride):\n
+ * - 0 0 channel is public: transfer to/from MCU to DSP
+ * - 0 1 channel if owned by DSP
+ * - 1 0 channel if owned by MCU
+ * - 1 1 channel zero config
+ *
+ * See also :\n
+ * IAPI Table 1.1 "Channel configuration properties"
+ *
+ * @param channel channel to configure
+ * @param eventOverride event ownership
+ * @param mcuOverride ARM ownership
+ * @param dspOverride DSP ownership
+ *
+ * @return
+ * - -iapi_errno if the 3 override parameters are all set
+ * - IAPI_SUCCESS in other cases (valid cases)
+ */
+int
+iapi_ChannelConfig (unsigned char channel, unsigned eventOverride,
+ unsigned mcuOverride, unsigned dspOverride)
+{
+ int result = IAPI_SUCCESS;
+
+ if ( ( eventOverride == 1 ) &&
+ ( mcuOverride == 1 ) &&
+ ( dspOverride == 1 ) ){
+ result = IAPI_ERR_CONFIG_OVERRIDE ;
+ iapi_errno = result;
+ return -result;
+ } else {
+ /*
+ * DSP side
+ */
+ if ( dspOverride ){
+ SDMA_H_DSPOVR &= ~( 1 << channel );
+ } else {
+ SDMA_H_DSPOVR |= ( 1 << channel );
+ }
+ /*
+ * Event
+ */
+ if ( eventOverride ){
+ SDMA_H_EVTOVR &= ~( 1 << channel );
+ } else {
+ SDMA_H_EVTOVR |= ( 1 << channel );
+ }
+ /*
+ * MCU side
+ */
+ if ( mcuOverride ) {
+ SDMA_H_HOSTOVR &= ~( 1 << channel );
+ } else {
+ SDMA_H_HOSTOVR |= ( 1 << channel );
+ }
+ }
+ return IAPI_SUCCESS;
+}
+/* ***************************************************************************/
+/**Load the context data of a channel from SDMA
+ *
+ * <b>Algorithm:</b>\n
+ * - Setup BD with appropiate parameters
+ * - Start channel
+ * - Poll for answer
+ *
+ * @param *cd_p channel descriptor for channel 0
+ * @param *buf pointer to receive context data
+ * @param channel channel for which the context data is requested
+ *
+ * @return none
+ */
+void
+iapi_lowGetContext(channelDescriptor * cd_p, void * buf, unsigned char channel)
+{
+ bufferDescriptor * bd_p;
+
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+
+ /*Setup buffer descriptor with channel 0 command*/
+ iapi_SetBufferDescriptor(&bd_p[0],
+ C0_GETDM,
+ (unsigned char)(BD_DONE | BD_INTR | BD_WRAP | BD_EXTD),
+ (unsigned short)sizeof(contextData)/4,
+ buf,
+ (void *)(CHANNEL_CONTEXT_BASE_ADDRESS + (sizeof(contextData)*channel/4)));
+ /* Receive, polling method*/
+ iapi_lowStartChannel(cd_p->channelNumber);
+ iapi_lowSynchChannel(cd_p->channelNumber);
+}
+/* ***************************************************************************/
+/**Read "size" byte /2 at SDMA address (address) and write them in buf
+ *
+ * <b>Algorithm:</b>\n
+ * - Setup BD with appropiate parameters (C0_GETPM)
+ * - Start channel
+ * - Poll for answer
+ *
+ * <b>Notes</b>\n
+ * - Parameter "size" is in bytes, it represents the size of "buf", e.g.
+ * the size in bytes of the script to be loaded.
+ * - Parameter "address" denotes the RAM address for the script in SDMA
+ *
+ * @param *cd_p channel descriptor for channel 0
+ * @param *buf pointer to receive the data
+ * @param size number of bytes to read
+ * @param address address in SDMA RAM to start reading from
+ *
+ * @return none
+ */
+void
+iapi_lowGetScript(channelDescriptor * cd_p, void * buf, unsigned short size,
+ unsigned long address)
+{
+ bufferDescriptor * bd_p;
+
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+
+ /*Setup buffer descriptor with channel 0 command*/
+ iapi_SetBufferDescriptor(&bd_p[0],
+ C0_GETPM,
+ (unsigned char)(BD_DONE | BD_INTR | BD_WRAP | BD_EXTD),
+ (unsigned short)size/2,/*count in shorts*/
+ buf,
+ (void *)address);
+ /* Receive, polling method*/
+ iapi_lowStartChannel(cd_p->channelNumber);
+ iapi_lowSynchChannel(cd_p->channelNumber);
+}
+
+/* ***************************************************************************/
+/**Load a SDMA script to SDMA
+ *
+ * <b>Algorithm:</b>\n
+ * - Setup BD with appropiate parameters (C0_SETPM)
+ * - Start channel
+ * - Poll for answer
+ *
+ * <b>Notes</b>\b
+ * - Parameter "size" is in bytes, it represents the size of "buf", e.g.
+ * the size in bytes of the script to be uploaded.
+ * - Parameter "address" denotes the RAM address for the script in SDMA
+ *
+ * @param *cd_p channel descriptor for channel 0
+ * @param *buf pointer to the script
+ * @param size size of the script, in bytes
+ * @param address address in SDMA RAM to place the script
+ *
+ * @return none
+ */
+void
+iapi_lowSetScript(channelDescriptor * cd_p, void * buf, unsigned short size,
+ unsigned long address)
+{
+ bufferDescriptor * bd_p;
+
+ bd_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+
+ /*Setup buffer descriptor with channel 0 command*/
+ iapi_SetBufferDescriptor(&bd_p[0],
+ C0_SETPM,
+ (unsigned char)(BD_DONE | BD_INTR | BD_WRAP | BD_EXTD),
+ (unsigned short)size/2,/*count in shorts*/
+ buf,
+ (void *)(address));
+ /* Receive, polling method*/
+ iapi_lowStartChannel(cd_p->channelNumber);
+ iapi_lowSynchChannel(cd_p->channelNumber);
+}
+
+
+/* ***************************************************************************/
+/**Load the context for a channel to SDMA
+ *
+ * <b>Algorithm:</b>\n
+ * - Send context and poll for answer.
+ *
+ * @param *cd_p channel descriptor for channel 0
+ * @param *buf pointer to context data
+ * @param channel channel to place the context for
+ *
+ * @return none
+ */
+void
+iapi_lowSetContext(channelDescriptor * cd_p, void * buf, unsigned char channel)
+{
+
+ bufferDescriptor * local_bd_p;
+#ifdef SDMA_SKYE
+
+ unsigned char command =0;
+
+ local_bd_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+
+
+ command = channel <<3 ;
+ command = command | C0_SETCTX;
+ iapi_SetBufferDescriptor( &local_bd_p[0],
+ command,
+ (unsigned char)(BD_DONE | BD_INTR | BD_WRAP),
+ (unsigned short)(sizeof(contextData)/4),
+ buf,
+ NULL);
+#else
+
+ local_bd_p = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+
+
+
+
+ iapi_SetBufferDescriptor( &local_bd_p[0],
+ C0_SETDM,
+ (unsigned char)(BD_DONE | BD_INTR | BD_WRAP|BD_EXTD),
+ (unsigned short)(sizeof(contextData)/4),
+ buf,
+ (void *)(2048+(sizeof(contextData)/4)*channel));
+#endif
+ /* Send */
+ iapi_lowStartChannel( cd_p->channelNumber );
+ iapi_lowSynchChannel( cd_p->channelNumber );
+
+}
+
+/* ***************************************************************************/
+/**Associate specified channel with the script starting at the
+ * specified address. Channel 0 command is used to load the set-up context
+ * for the channel. The address used must be generated by the GUI tool
+ * used to create RAM images for SDMA.
+ *
+ * <b>Algorithm:</b>\n
+ * - Set-up and load the context.
+ *
+ * @param *cd_p pointer to the channel descriptor of the channel
+ * @param *data_p: pointer to the data identifying the script to be associated
+ * with the channel
+ *
+ * @return
+ * - IAPI_SUCCESS : OK
+ * - -iapi_errno : operation failed, return negated value of iapi_errno
+ */
+
+int
+iapi_lowAssignScript(channelDescriptor * cd_p, script_data * data_p)
+{
+ contextData * chContext; /* context to be loaded for the channel */
+ channelDescriptor * cd0_p; /* pointer to channel descriptor of channel 0*/
+ int result = IAPI_SUCCESS;
+
+ /*Verify passed data*/
+ if(cd_p == NULL || data_p == NULL)
+ {
+ result = IAPI_ERR_INVALID_PARAMETER;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* Allocate context and initialize PC to required script start adress*/
+ chContext = (contextData *) MALLOC(sizeof(contextData), SDMA_ERAM);
+ if (chContext == NULL)
+ {
+ result = IAPI_ERR_B_ALLOC_FAILED | cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+
+ iapi_memset(chContext, 0x00, sizeof(contextData));
+ chContext->channelState.pc = data_p->load_address;
+
+ /* Send by context the event mask,base address for peripheral
+ * and watermark level
+ */
+ chContext->gReg[0] = data_p->event_mask2;
+ chContext->gReg[1] = data_p->event_mask1;
+ chContext->gReg[6] = data_p->shp_addr;
+ chContext->gReg[7] = data_p->wml;
+
+ /* Set transmited data to the CD*/
+ cd_p->watermarkLevel = data_p->wml;
+ cd_p->eventMask1 = data_p->event_mask1;
+ cd_p->eventMask2 = data_p->event_mask2;
+
+ /* Get the cd0_p*/
+ cd0_p = (cd_p->ccb_ptr - cd_p->channelNumber)->channelDescriptor;
+
+ /*load the context*/
+ iapi_lowSetContext(cd0_p, chContext, cd_p->channelNumber);
+
+ /* release allocated memory*/
+ FREE(chContext);
+
+ return IAPI_SUCCESS;
+}
+
+/* ***************************************************************************/
+/** Set the channels to be triggered by an event. The for every channel that
+ *must be triggered by the event, the corresponding bit from channel_map
+ *parameter must be set to 1. (e.g. for the event to trigger channels 31 and
+ *0 one must pass 0x80000001)
+ *
+ *
+ * <b>Algorithm:</b>\n
+ * - Update the register from Channel Enable RAM with the channel_map
+ *
+ * @param event event for which to set the channel association
+ * @param channel_map channels to be triggered by event. Put the corresponding
+ * bit from this 32-bit value to 1 for every channel that should be
+ * triggered by the event.
+ *
+ * @return
+ * - IAPI_SUCCESS : OK
+ * - -iapi_errno : operation failed, return negated value of iapi_errno
+ */
+int
+iapi_lowSetChannelEventMapping(unsigned char event, unsigned long channel_map)
+{
+ volatile unsigned long * channelEnableMatx;
+ int result = IAPI_SUCCESS;
+
+ /* Check validity of event*/
+ if (event < EVENTS_NUM)
+ {
+ channelEnableMatx = &SDMA_CHNENBL_0;
+ channelEnableMatx[event] |= channel_map;
+ return result;
+ }
+ else
+ {
+ result = IAPI_ERR_INVALID_PARAMETER | event;
+ iapi_errno = result;
+ return -result;
+ }
+}
+
+#endif /* MCU */
diff --git a/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddle.c b/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddle.c
new file mode 100644
index 000000000000..3b8d7a7c4f2e
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddle.c
@@ -0,0 +1,623 @@
+/******************************************************************************
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: iapiMiddle.c
+ *
+ * $Id iapiMiddle.c $
+ *
+ * Description:
+ * This library is written in C to guarantee functionality and integrity in
+ * the usage of SDMA virtual DMA channels. This API (Application Programming
+ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
+ * fashion.
+ * These are the MIDDLE level functions of the I.API.
+ *
+ *
+ *
+ *
+ * $Log iapiMiddle.c $
+ *
+ *****************************************************************************/
+
+
+/* ****************************************************************************
+ * Include File Section
+ *****************************************************************************/
+#include "epm.h"
+#include <string.h>
+
+#include "iapiLow.h"
+#include "iapiMiddle.h"
+
+/* ****************************************************************************
+ * Global Variable Section
+ *****************************************************************************/
+
+
+/* ****************************************************************************
+ * Function Section
+ *****************************************************************************/
+
+/* ***************************************************************************/
+/**Allocates one Buffer Descriptor structure using information present in the
+ * channel descriptor.
+ *
+ * @param *ccb_p channel control block used to get the channel descriptor
+ *
+ * @return
+ * - pointer on the new Buffer Descriptor
+ * - NULL if allocation failed
+ *
+ */
+bufferDescriptor *
+iapi_AllocBD (channelControlBlock * ccb_p)
+
+{
+ bufferDescriptor * ptrBD = NULL;
+
+ if (ccb_p->channelDescriptor->bufferDescNumber != 0){
+#ifdef CONFIG_SDMA_IRAM
+ channelDescriptor * cd_p = ccb_p->channelDescriptor;
+ if(cd_p->channelNumber >= MXC_DMA_CHANNEL_IRAM) {
+ ptrBD = (bufferDescriptor *)
+ MALLOC( ccb_p->channelDescriptor->bufferDescNumber *
+ sizeof(bufferDescriptor), SDMA_IRAM);
+ } else
+#endif /*CONFIG_SDMA_IRAM*/
+ {
+ ptrBD = (bufferDescriptor *)
+ MALLOC( ccb_p->channelDescriptor->bufferDescNumber *
+ sizeof(bufferDescriptor), SDMA_ERAM);
+ }
+ }
+ if (ptrBD != NULL) {
+ ptrBD->mode.command = 0;
+ ptrBD->mode.status = 0;
+ ptrBD->mode.count = 0;
+ ptrBD->bufferAddr = NULL;
+ }
+
+ return ptrBD;
+}
+
+/* ***************************************************************************/
+/**Allocate one channel context data structure.
+ *
+ * @param **ctxd_p pointer to context data to be allocated
+ * @param channel channel number of context data structure
+ *
+ * @return
+ * - IAPI_SUCCESS
+ * - -iapi_errno if allocation failed
+ */
+int
+iapi_AllocContext(contextData ** ctxd_p, unsigned char channel)
+{
+ contextData * ctxData;
+ int result = IAPI_SUCCESS;
+
+ if (*ctxd_p != NULL){
+ result = IAPI_ERR_CC_ALREADY_DEFINED | IAPI_ERR_CH_AVAILABLE | channel;
+ iapi_errno = result;
+ return -result;
+ }
+
+ ctxData = (contextData *)MALLOC(sizeof(contextData), SDMA_ERAM);
+
+ if (ctxData !=NULL) {
+ *ctxd_p = ctxData;
+ return IAPI_SUCCESS;
+
+ } else {
+ *ctxd_p = NULL;
+ result = IAPI_ERR_CC_ALLOC_FAILED | IAPI_ERR_CH_AVAILABLE | channel;
+ iapi_errno = result;
+ return -result;
+ }
+}
+
+/* ***************************************************************************/
+/**Allocates channel description and fill in with default values.
+ *
+ * <b>Algorithm:</b>\n
+ * - Check channel properties.
+ * - Then modifies the properties of the channel description with default
+ *
+ * @param **cd_p pointer to channel descriptor to be allocated
+ * @param channel channel number of channel descriptor
+ *
+ * @return
+ * - IAPI_SUCCESS
+ * - -iapi_errno if allocation failed
+ *
+ */
+int
+iapi_AllocChannelDesc (channelDescriptor ** cd_p, unsigned char channel)
+{
+#ifdef MCU
+ volatile unsigned long * chPriorities = &SDMA_CHNPRI_0;
+#endif /* MCU */
+ channelDescriptor * tmpCDptr;
+ int result = IAPI_SUCCESS;
+
+
+ if (*cd_p != NULL){
+ result = IAPI_ERR_CD_ALREADY_DEFINED | IAPI_ERR_CH_AVAILABLE | channel;
+ iapi_errno = result;
+ return -result;
+ }
+
+ tmpCDptr = (channelDescriptor *)MALLOC(sizeof(channelDescriptor), SDMA_ERAM);
+
+ if (tmpCDptr != NULL){
+ iapi_memcpy(tmpCDptr, &iapi_ChannelDefaults, sizeof (channelDescriptor));
+ tmpCDptr->channelNumber = channel;
+#ifdef MCU
+ if (chPriorities[channel] != 0) {
+ tmpCDptr->priority = chPriorities[channel];
+ } else {
+ chPriorities[channel] = tmpCDptr->priority;
+ }
+#endif
+ * cd_p = tmpCDptr ;
+ return IAPI_SUCCESS;
+ } else {
+ * cd_p = NULL;
+ result = IAPI_ERR_CD_ALLOC_FAILED | IAPI_ERR_CH_AVAILABLE | channel;
+ iapi_errno = result;
+ return -result;
+ }
+}
+
+/* ***************************************************************************/
+/**Changes channel description information after performing sanity checks.
+ *
+ * <b>Algorithm:</b>\n
+ * - Check channel properties.
+ * - Then modifies the properties of the channel description.
+ *
+ * @param *cd_p channel descriptor of the channel to change
+ * @param whatToChange control code indicating the desired change
+ * @param newval new value
+ *
+ * @return
+ * - IAPI_SUCCESS
+ * - IAPI_FAILURE if change failed
+ *
+ */
+int
+iapi_ChangeChannelDesc (channelDescriptor * cd_p, unsigned char whatToChange,
+ unsigned long newval)
+{
+ bufferDescriptor * tmpBDptr;
+ unsigned char index = 0;
+ int result = IAPI_SUCCESS;
+
+ /* verify parameter validity */
+ if (cd_p == NULL) {
+ result = IAPI_ERR_CD_UNINITIALIZED;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* verify channel descriptor initialization */
+ if (cd_p->ccb_ptr == NULL){
+ result = IAPI_ERR_CCB_UNINITIALIZED | IAPI_ERR_CH_AVAILABLE |
+ cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /* verify channel is not in use */
+ tmpBDptr = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ for (index=cd_p->bufferDescNumber ; index>0 ; index--){
+ if (tmpBDptr->mode.status & BD_DONE){
+ result = IAPI_ERR_CH_IN_USE | IAPI_ERR_CH_AVAILABLE |
+ cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+ tmpBDptr++;
+ }
+
+ /* Select the change accorded to the selector given in parameter */
+ switch (whatToChange){
+
+ /*
+ * Channel Number
+ */
+ case IAPI_CHANNELNUMBER:
+ /* Channel number can not be changed (description remains attached) */
+ result = IAPI_ERR_CD_CHANGE_CH_NUMBER | IAPI_ERR_CH_AVAILABLE |
+ cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+
+ /*
+ * Buffer Descriptor Number
+ */
+ case IAPI_BUFFERDESCNUMBER:
+ if (newval < MAX_BD_NUM){
+ if (newval != cd_p->bufferDescNumber){
+ /* Free memory used for previous old data */
+ if (cd_p->ccb_ptr->baseBDptr != NULL){
+ tmpBDptr = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ for (index=0 ; index < cd_p->bufferDescNumber ; index++){
+ if (tmpBDptr->bufferAddr != NULL){
+ if (cd_p->trust == FALSE) {
+ FREE(iapi_Phys2Virt(tmpBDptr->bufferAddr));
+ }
+ }
+ tmpBDptr ++ ;
+ }
+ FREE((bufferDescriptor *)iapi_Phys2Virt((cd_p->ccb_ptr)->baseBDptr));
+ }
+ (cd_p->ccb_ptr)->baseBDptr = NULL;
+ (cd_p->ccb_ptr)->currentBDptr = NULL;
+ /* Allocate and initialize structures */
+ cd_p->bufferDescNumber = (unsigned char)newval;
+ cd_p->ccb_ptr->status.openedInit = FALSE;
+ if (IAPI_SUCCESS !=iapi_InitializeMemory (cd_p->ccb_ptr))
+ {
+ result = IAPI_ERR_BD_ALLOCATION | cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+ cd_p->ccb_ptr->status.openedInit = TRUE;
+ }
+ break;
+ } else {
+ result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
+ cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /*
+ * Buffer size
+ */
+ case IAPI_BUFFERSIZE:
+ if (newval < MAX_BD_SIZE)
+ {
+ if (newval != cd_p->bufferSize)
+ {
+ /* Free memory used for previous old data */
+ if (cd_p->ccb_ptr->baseBDptr != NULL)
+ {
+ tmpBDptr = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ for (index=0 ; index < cd_p->bufferDescNumber ; index++)
+ {
+ if (cd_p->trust == FALSE)
+ {
+ FREE(iapi_Phys2Virt(tmpBDptr->bufferAddr));
+ }
+ tmpBDptr ++ ;
+ }
+ FREE((bufferDescriptor *)iapi_Phys2Virt((cd_p->ccb_ptr)->baseBDptr));
+ }
+ (cd_p->ccb_ptr)->baseBDptr = NULL;
+ (cd_p->ccb_ptr)->currentBDptr = NULL;
+ /* Allocate and initialize structures */
+ cd_p->bufferSize = (unsigned short)newval;
+ cd_p->ccb_ptr->status.openedInit = FALSE;
+ if (IAPI_SUCCESS !=iapi_InitializeMemory (cd_p->ccb_ptr))
+ {
+ result = IAPI_ERR_BD_ALLOCATION | cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+ cd_p->ccb_ptr->status.openedInit = TRUE;
+ }
+ break;
+ }
+ else
+ {
+ result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
+ cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+
+
+ /*
+ * Blocking / non blocking feature
+ */
+ case IAPI_BLOCKING:
+ if (newval < MAX_BLOCKING){
+ cd_p->blocking = newval;
+ break;
+ } else {
+ result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
+ cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /*
+ * Synchronization method
+ */
+ case IAPI_CALLBACKSYNCH:
+ if (newval < MAX_SYNCH){
+ cd_p->callbackSynch = newval;
+ iapi_ChangeCallbackISR( cd_p, cd_p->callbackISR_ptr);
+ break;
+ } else {
+ result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
+ cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+
+
+ /*
+ * Ownership of the channel
+ */
+ case IAPI_OWNERSHIP:
+#ifdef DSP
+ result = IAPI_ERR_NOT_ALLOWED | cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+#endif /* DSP */
+#ifdef MCU
+ if (newval < MAX_OWNERSHIP){
+ cd_p->ownership = newval;
+ iapi_ChannelConfig( cd_p->channelNumber,
+ ( newval >> CH_OWNSHP_OFFSET_EVT ) & 1,
+ ( newval >> CH_OWNSHP_OFFSET_MCU ) & 1,
+ ( newval >> CH_OWNSHP_OFFSET_DSP ) & 1);
+ break;
+ } else {
+ result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
+ cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+
+#endif /* MCU */
+
+ /*
+ * Priority
+ */
+ case IAPI_PRIORITY:
+#ifdef DSP
+ result = IAPI_ERR_NOT_ALLOWED | cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+#endif /* DSP */
+
+#ifdef MCU
+ if (newval < MAX_CH_PRIORITY){
+ volatile unsigned long * ChannelPriorities = &SDMA_CHNPRI_0;
+ ChannelPriorities[ cd_p->channelNumber ] = newval;
+ break;
+ } else {
+ result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
+ cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+#endif /* MCU */
+
+
+ /*
+ * "Trust" property
+ */
+ case IAPI_TRUST:
+ if (newval < MAX_TRUST){
+ if (cd_p->trust != newval){
+ cd_p->trust = newval;
+ if (newval == FALSE) {
+ if (IAPI_SUCCESS !=iapi_InitializeMemory (cd_p->ccb_ptr))
+ {
+ result = IAPI_ERR_BD_ALLOCATION | cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+ }
+ }
+ break;
+ } else {
+ result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
+ cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+
+ /*
+ * Callback function pointer
+ */
+ case IAPI_CALLBACKISR_PTR:
+ if ( (void *)newval != NULL){
+ {
+ union {
+ void * voidstar;
+ void (* funcptr)(channelDescriptor * cd_p, void * arg);
+ } value;
+ value.voidstar = (void*) newval;
+ cd_p->callbackISR_ptr = value.funcptr;
+ }
+ iapi_ChangeCallbackISR( cd_p, cd_p->callbackISR_ptr);
+ break;
+ } else {
+ result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
+ cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+
+
+ /*
+ * Channel Control Block pointer
+ */
+ case IAPI_CCB_PTR:
+ cd_p->ccb_ptr = (channelControlBlock *)newval;
+ cd_p->ccb_ptr->channelDescriptor = cd_p;
+ break;
+
+ /*
+ * WRAP/UNWRAP
+ */
+ case IAPI_BDWRAP:
+ /* point to first BD */
+ tmpBDptr = (bufferDescriptor *)iapi_Phys2Virt(cd_p->ccb_ptr->baseBDptr);
+ /* to point to last BD */
+ tmpBDptr += cd_p->bufferDescNumber - 1;
+ if (newval == TRUE){
+ /* wrap last BD */
+ tmpBDptr->mode.status |= BD_WRAP;
+ break;
+ }
+ else if (newval == FALSE){
+ /* unwrap last BD */
+ tmpBDptr->mode.status &= ~BD_WRAP;
+ break;
+ }
+ else {
+ result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
+ cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+
+
+ /*
+ * Watermark level
+ */
+ case IAPI_WML:
+#ifdef DSP
+ result = IAPI_ERR_NOT_ALLOWED | cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+#endif /* DSP */
+#ifdef MCU
+ if (newval < MAX_WML){
+ if (cd_p->watermarkLevel != newval){
+ cd_p->watermarkLevel = newval;
+ }
+ break;
+ }
+ else {
+ result = IAPI_ERR_INVALID_PARAMETER | IAPI_ERR_CH_AVAILABLE |
+ cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+#endif /* MCU */
+
+ /*
+ * Detect errors
+ */
+ default:
+ result = IAPI_ERR_CD_CHANGE_UNKNOWN | IAPI_ERR_CH_AVAILABLE |
+ cd_p->channelNumber;
+ iapi_errno = result;
+ return -result;
+ }
+
+ return IAPI_SUCCESS;
+}
+
+
+/* ***************************************************************************/
+/**Initialize a table of function pointers that contain the interrupt Service
+ * Routine callback pointers for the SDMA channels with a default value
+ *
+ * <b>Algorithm:</b>\n
+ * - Loop on each element of the global IAPI variable callbackIsrTable
+ *
+ * @param *func_p default callback functon for all SDMA channels
+ *
+ * @return none
+ */
+void
+iapi_InitializeCallbackISR(void(* func_p)(channelDescriptor * cd_p, void * arg))
+{
+ unsigned long chCnt;
+
+ for (chCnt = 0 ; chCnt < CH_NUM ; chCnt++){
+ callbackIsrTable[chCnt] = func_p;
+ }
+}
+
+/* ***************************************************************************/
+/**For the specified channel control block, attach the array of buffer
+ * descriptors, the channel description structure and initialize channel's
+ * status using information in the channel descriptor.
+ *
+ * @param *ccb_p pointer to channel control block
+ *
+ * @return none
+ *
+ */
+int
+iapi_InitializeMemory (channelControlBlock * ccb_p)
+{
+ bufferDescriptor * bd_p;
+ unsigned char index;
+ int result = IAPI_SUCCESS;
+
+ /* Attach the array of Buffer descriptors */
+ bd_p = iapi_AllocBD( ccb_p );
+ if (bd_p != NULL)
+ {
+ ccb_p->baseBDptr = (bufferDescriptor *)iapi_Virt2Phys(bd_p);
+ ccb_p->currentBDptr = ccb_p->baseBDptr;
+ for(index=0 ;index < ccb_p->channelDescriptor->bufferDescNumber-1 ; index++)
+ {
+ if (ccb_p->channelDescriptor->trust == TRUE)
+ {
+ iapi_SetBufferDescriptor(bd_p,
+ (unsigned char)ccb_p->channelDescriptor->dataSize,
+ BD_CONT|BD_EXTD, ccb_p->channelDescriptor->bufferSize,
+ NULL, NULL);
+ }
+ else
+ {
+ if (ccb_p->channelDescriptor->bufferSize != 0)
+ {
+ iapi_SetBufferDescriptor(bd_p,
+ (unsigned char)ccb_p->channelDescriptor->dataSize,
+ BD_CONT|BD_EXTD, ccb_p->channelDescriptor->bufferSize,
+ MALLOC(ccb_p->channelDescriptor->bufferSize, SDMA_ERAM), NULL);
+ }
+ }
+ bd_p++;
+ }
+
+ if (ccb_p->channelDescriptor->trust == TRUE)
+ {
+ iapi_SetBufferDescriptor(bd_p,
+ (unsigned char)ccb_p->channelDescriptor->dataSize,
+ BD_EXTD|BD_WRAP|BD_INTR, ccb_p->channelDescriptor->bufferSize,
+ NULL, NULL);
+ }
+ else
+ {
+ if (ccb_p->channelDescriptor->bufferSize != 0)
+ {
+ iapi_SetBufferDescriptor(bd_p,
+ (unsigned char)ccb_p->channelDescriptor->dataSize,
+ BD_EXTD|BD_WRAP|BD_INTR,
+ ccb_p->channelDescriptor->bufferSize,
+ MALLOC(ccb_p->channelDescriptor->bufferSize, SDMA_ERAM), NULL);
+ }
+ }
+ }
+ else
+ {
+ result = IAPI_ERR_BD_ALLOCATION;
+ return -result;
+ }
+ return result;
+}
diff --git a/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddleMcu.c b/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddleMcu.c
new file mode 100644
index 000000000000..8dc814418e4c
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/src/iapiMiddleMcu.c
@@ -0,0 +1,52 @@
+/******************************************************************************
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: iapiMiddleMcu.c
+ *
+ * $Id iapiMiddleMcu.c $
+ *
+ * Description:
+ * This library is written in C to guarantee functionality and integrity in
+ * the usage of SDMA virtual DMA channels. This API (Application Programming
+ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
+ * fashion.
+ * These are the MIDDLE level functions of the I.API specific to MCU.
+ *
+ *
+ *
+ *
+ * $Log iapiMiddleMcu.c $
+ *
+ *****************************************************************************/
+
+/* ****************************************************************************
+ * Include File Section
+ *****************************************************************************/
+#include "epm.h"
+#include <string.h>
+
+#include "iapiLow.h"
+#include "iapiMiddle.h"
+
+/* ****************************************************************************
+ * Global Variable Section
+ *****************************************************************************/
+
+/*extern void * __HEAP_START;
+extern void * __HEAP_END;
+*/
+
+/* ****************************************************************************
+ * Function Section
+ *****************************************************************************/
diff --git a/arch/arm/plat-mxc/sdma/iapi/src/iapiOS.c b/arch/arm/plat-mxc/sdma/iapi/src/iapiOS.c
new file mode 100644
index 000000000000..643cab549742
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/iapi/src/iapiOS.c
@@ -0,0 +1,64 @@
+/******************************************************************************
+ *
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ ******************************************************************************
+ *
+ * File: iapiOS.c
+ *
+ * $Id iapiOS.c $
+ *
+ * Description:
+ * This library is written in C to guarantee functionality and integrity in
+ * the usage of SDMA virtual DMA channels. This API (Application Programming
+ * Interface) allow SDMA channels' access in an OPEN, READ, WRITE, CLOSE
+ * fashion.
+ * These are the OS level functions of the I.API - are OS dependant and must
+ * be provided by the user of I.API.
+ *
+ *
+ * /
+ *
+ * $Log iapiOS.c $
+ *
+ *****************************************************************************/
+
+/* ****************************************************************************
+ * Include File Section
+ *****************************************************************************/
+#include "epm.h"
+#include "iapiLow.h"
+
+/**
+ * Function Section
+ */
+#ifdef CONFIG_SDMA_IRAM
+void*(* iapi_iram_Malloc) (size_t size);
+#endif /*CONFIG_SDMA_IRAM*/
+
+void*(* iapi_Malloc) (size_t size);
+void (* iapi_Free) (void * ptr);
+
+void*(* iapi_Virt2Phys) (void * ptr);
+void*(* iapi_Phys2Virt) (void * ptr);
+
+void (* iapi_WakeUp)(int);
+void (* iapi_GotoSleep)(int);
+void (* iapi_InitSleep)(int);
+
+void*(* iapi_memcpy)(void *dest, const void *src, size_t count);
+void*(* iapi_memset)(void *dest, int c, size_t count);
+
+void (* iapi_EnableInterrupts)(void);
+void (* iapi_DisableInterrupts)(void);
+
+int (* iapi_GetChannel)(int);
+int (* iapi_ReleaseChannel)(int);
diff --git a/arch/arm/plat-mxc/sdma/sdma.c b/arch/arm/plat-mxc/sdma/sdma.c
new file mode 100644
index 000000000000..1ec54a137e8c
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/sdma.c
@@ -0,0 +1,1397 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file plat-mxc/sdma/sdma.c
+ * @brief This file contains functions for Smart DMA API
+ *
+ * SDMA (Smart DMA) is used for transferring data between MCU and peripherals
+ *
+ * @ingroup SDMA
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+#include <linux/clk.h>
+#include <linux/semaphore.h>
+#include <linux/spinlock.h>
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/proc_fs.h>
+
+#include <asm/uaccess.h>
+#include <asm/irq.h>
+#include <mach/dma.h>
+#include <mach/hardware.h>
+
+#include "iapi.h"
+
+#define M3_BASE_ADDRESS CSD0_BASE_ADDR
+#define CHAD(ch) sdma_data[0].cd->ccb_ptr[ch].channelDescriptor
+
+/*!
+ * SDMA status mutex
+ */
+static struct semaphore sdma_status_mutex;
+
+/*!
+ * SDMA channel sleep queues
+ */
+//static struct semaphore sdma_sleep_mutex[MAX_DMA_CHANNELS];
+static wait_queue_head_t sdma_sleep_queue[MAX_DMA_CHANNELS];
+
+/*!
+ * SDMA channel synchronization
+ */
+static struct semaphore sdma_synch_mutex[MAX_DMA_CHANNELS];
+
+/*!
+ * SDMA buffers pool initialization function
+ */
+extern void init_sdma_pool(void);
+
+/*!
+ * Flags are save and restored during interrupt handler
+ */
+unsigned long flags;
+
+struct clk *mxc_sdma_ahb_clk, *mxc_sdma_ipg_clk;
+
+/*!
+ * Structure containing sdma channels information.
+ */
+typedef struct {
+ /*! Channel number */
+ int channel;
+ /*! Channel usage name */
+ int in_use;
+ /*! Name of device using the channel */
+ char devicename[MAX_DEVNAME_LENGTH];
+ /*! Transfer type. Needed for setting SDMA script */
+ sdma_transferT transfer_type;
+ /*! Peripheral type. Needed for setting SDMA script */
+ sdma_periphT peripheral_type;
+ /*! Watermark level of device's fifo */
+ __u32 watermark_level;
+ /*! Peripheral event id */
+ int event_id;
+ /*! Peripheral event id2 (for channels that use 2 events) */
+ int event_id2;
+ /*! Running status (boolean) */
+ int running;
+ /*! buffer descriptors number */
+ int bd_number;
+ /*! callback function */
+ dma_callback_t callback;
+ /*! callback argument */
+ void *arg;
+ /*! SDMA data access word size */
+ unsigned long word_size:8;
+ /*! channel descriptor pointer */
+ channelDescriptor *cd;
+} sdma_struct;
+
+/*!
+ * Used to save the status of channels.
+ */
+static sdma_struct sdma_data[MAX_DMA_CHANNELS];
+
+/*!
+ * Stores the start address of the SDMA scripts
+ */
+static sdma_script_start_addrs sdma_script_addrs;
+
+extern void mxc_sdma_get_script_info(sdma_script_start_addrs * sdma_script_add);
+
+/*!
+ * Init sleep mutex of the channel
+ *
+ * @param channel channel number
+ */
+static void sdma_init_sleep(int channel)
+{
+ init_waitqueue_head(&sdma_sleep_queue[channel]);
+}
+
+/*!
+ * Puts channel to sleep
+ *
+ * @param channel channel number
+ */
+static void sdma_sleep_channel(int channel)
+{
+ while ((iapi_SDMAIntr & (1 << channel)) == 0) {
+ wait_event_interruptible(sdma_sleep_queue[channel],
+ ((iapi_SDMAIntr & (1 << channel)) !=
+ 0));
+ }
+}
+
+/*!
+ * Wake up channel from sleep
+ *
+ * @param channel channel number
+ */
+static void sdma_wakeup_channel(int channel)
+{
+ wake_up_interruptible(&sdma_sleep_queue[channel]);
+}
+
+/*!
+ * Sdma interrupt handler routine.
+ * Calls channels callback function
+ *
+ * @param irq the interrupt number
+ * @param dev_id driver private data
+ * @return the function returns \b IRQ_RETVAL(1) - interrupt was handled
+ */
+static irqreturn_t sdma_int_handler(int irq, void *dev_id)
+{
+ IRQ_Handler();
+ return IRQ_RETVAL(1);
+}
+
+/*!
+ * I.API channel callback function
+ *
+ * @param cd channel descriptor structure
+ * @param channel_data SDMA struct of the current channel
+ */
+static void iapi_interrupt_callback(channelDescriptor * cd,
+ sdma_struct * channel_data)
+{
+ int channel;
+ dma_callback_t callback;
+ void *arg;
+
+ channel = channel_data->channel;
+
+ channel_data->running = 0;
+
+ arg = channel_data->arg;
+
+ if (arg == 0) {
+ arg = (void *)&channel;
+ }
+
+ callback = channel_data->callback;
+
+ if (callback != 0) {
+ callback(arg);
+ }
+}
+
+/*!
+ * Returns pc of SDMA script according to peripheral and transfer type
+ *
+ * @param peripheral_type peripheral type
+ * @param transfer_type transfer type
+ *
+ * @return PC of SDMA script
+*/
+static unsigned short sdma_get_pc(sdma_periphT peripheral_type,
+ sdma_transferT transfer_type)
+{
+ int res = 0;
+
+ if (peripheral_type == MEMORY) {
+ switch (transfer_type) {
+ case emi_2_int:
+ res = sdma_script_addrs.mxc_sdma_ap_2_ap_addr;
+ break;
+ case emi_2_emi:
+ res = sdma_script_addrs.mxc_sdma_ap_2_ap_addr;
+ break;
+ case int_2_emi:
+ res = sdma_script_addrs.mxc_sdma_ap_2_ap_addr;
+ break;
+ default:
+ res = -EINVAL;
+ }
+ } else if (peripheral_type == DSP) {
+ switch (transfer_type) {
+ case emi_2_dsp:
+ res = sdma_script_addrs.mxc_sdma_ap_2_bp_addr;
+ break;
+ case dsp_2_emi:
+ res = sdma_script_addrs.mxc_sdma_bp_2_ap_addr;
+ break;
+ case dsp_2_emi_loop:
+ res =
+ sdma_script_addrs.
+ mxc_sdma_loopback_on_dsp_side_addr;
+ break;
+ case emi_2_dsp_loop:
+ res =
+ sdma_script_addrs.mxc_sdma_mcu_interrupt_only_addr;
+ break;
+ default:
+ res = -EINVAL;
+ }
+ } else if (peripheral_type == FIRI) {
+ switch (transfer_type) {
+ case per_2_int:
+ res = sdma_script_addrs.mxc_sdma_firi_2_per_addr;
+ break;
+ case per_2_emi:
+ res = sdma_script_addrs.mxc_sdma_firi_2_mcu_addr;
+ break;
+ case int_2_per:
+ res = sdma_script_addrs.mxc_sdma_per_2_firi_addr;
+ break;
+ case emi_2_per:
+ res = sdma_script_addrs.mxc_sdma_mcu_2_firi_addr;
+ break;
+ default:
+ res = -EINVAL;
+ }
+ } else if (peripheral_type == UART) {
+ switch (transfer_type) {
+ case per_2_int:
+ res = sdma_script_addrs.mxc_sdma_uart_2_per_addr;
+ break;
+ case per_2_emi:
+ res = sdma_script_addrs.mxc_sdma_uart_2_mcu_addr;
+ break;
+ case int_2_per:
+ res = sdma_script_addrs.mxc_sdma_per_2_app_addr;
+ break;
+ case emi_2_per:
+ res = sdma_script_addrs.mxc_sdma_mcu_2_app_addr;
+ break;
+ default:
+ res = -EINVAL;
+ }
+ } else if (peripheral_type == UART_SP) {
+ switch (transfer_type) {
+ case per_2_int:
+ res = sdma_script_addrs.mxc_sdma_uartsh_2_per_addr;
+ break;
+ case per_2_emi:
+ res = sdma_script_addrs.mxc_sdma_uartsh_2_mcu_addr;
+ break;
+ case int_2_per:
+ res = sdma_script_addrs.mxc_sdma_per_2_shp_addr;
+ break;
+ case emi_2_per:
+ res = sdma_script_addrs.mxc_sdma_mcu_2_shp_addr;
+ break;
+ default:
+ res = -EINVAL;
+ }
+ } else if (peripheral_type == ATA) {
+ switch (transfer_type) {
+ case per_2_emi:
+ res = sdma_script_addrs.mxc_sdma_ata_2_mcu_addr;
+ break;
+ case emi_2_per:
+ res = sdma_script_addrs.mxc_sdma_mcu_2_ata_addr;
+ break;
+ default:
+ res = -EINVAL;
+ }
+ } else if (peripheral_type == CSPI || peripheral_type == EXT ||
+ peripheral_type == SSI) {
+ switch (transfer_type) {
+ case per_2_int:
+ res = sdma_script_addrs.mxc_sdma_app_2_per_addr;
+ break;
+ case per_2_emi:
+ res = sdma_script_addrs.mxc_sdma_app_2_mcu_addr;
+ break;
+ case int_2_per:
+ res = sdma_script_addrs.mxc_sdma_per_2_app_addr;
+ break;
+ case emi_2_per:
+ res = sdma_script_addrs.mxc_sdma_mcu_2_app_addr;
+ break;
+ default:
+ res = -EINVAL;
+ }
+ } else if (peripheral_type == SSI_SP || peripheral_type == MMC ||
+ peripheral_type == SDHC || peripheral_type == CSPI_SP ||
+ peripheral_type == ESAI || peripheral_type == MSHC_SP) {
+ switch (transfer_type) {
+ case per_2_int:
+ res = sdma_script_addrs.mxc_sdma_shp_2_per_addr;
+ break;
+ case per_2_emi:
+ res = sdma_script_addrs.mxc_sdma_shp_2_mcu_addr;
+ break;
+ case int_2_per:
+ res = sdma_script_addrs.mxc_sdma_per_2_shp_addr;
+ break;
+ case emi_2_per:
+ res = sdma_script_addrs.mxc_sdma_mcu_2_shp_addr;
+ break;
+ default:
+ res = -EINVAL;
+ }
+ } else if (peripheral_type == ASRC) {
+ switch (transfer_type) {
+ case per_2_emi:
+ res = sdma_script_addrs.mxc_sdma_shp_2_mcu_addr;
+ break;
+ case emi_2_per:
+ res = sdma_script_addrs.mxc_sdma_mcu_2_shp_addr;
+ break;
+ case per_2_per:
+ res = sdma_script_addrs.mxc_sdma_per_2_per_addr;
+ break;
+ default:
+ res = -EINVAL;
+ }
+ } else if (peripheral_type == MSHC) {
+ switch (transfer_type) {
+ case per_2_emi:
+ res = sdma_script_addrs.mxc_sdma_mshc_2_mcu_addr;
+ break;
+ case emi_2_per:
+ res = sdma_script_addrs.mxc_sdma_mcu_2_mshc_addr;
+ break;
+ default:
+ res = -EINVAL;
+ }
+ } else if (peripheral_type == CCM) {
+ switch (transfer_type) {
+ case per_2_emi:
+ res = sdma_script_addrs.mxc_sdma_dptc_dvfs_addr;
+ break;
+ default:
+ res = -EINVAL;
+ }
+ } else if (peripheral_type == FIFO_MEMORY) {
+ res = sdma_script_addrs.mxc_sdma_ap_2_ap_fixed_addr;
+ } else if (peripheral_type == SPDIF) {
+ switch (transfer_type) {
+ case per_2_emi:
+ res = sdma_script_addrs.mxc_sdma_spdif_2_mcu_addr;
+ break;
+ case emi_2_per:
+ res = sdma_script_addrs.mxc_sdma_mcu_2_spdif_addr;
+ break;
+ default:
+ res = -EINVAL;
+ }
+ } else if (peripheral_type == IPU_MEMORY) {
+ if (transfer_type == emi_2_per) {
+ res = sdma_script_addrs.mxc_sdma_ext_mem_2_ipu_addr;
+ } else {
+ res = -EINVAL;
+ }
+ }
+
+ if (res < 0) {
+ printk(KERN_ERR "SDMA script not found\n");
+ }
+
+ return res;
+
+}
+
+/*!
+ * Downloads channel context according to channel parameters
+ *
+ * @param channel channel number
+ * @param p channel parameters
+ */
+static int sdma_load_context(int channel, dma_channel_params * p)
+{
+ script_data context;
+ int res;
+ int event1_greater_than_32;
+ int event2_greater_than_32;
+
+ res = 0;
+
+ memset(&context, 0, sizeof(script_data));
+ context.load_address = sdma_get_pc(p->peripheral_type,
+ p->transfer_type);
+
+ if (context.load_address > 0) {
+ if ((p->peripheral_type != MEMORY)
+ && (p->peripheral_type != DSP)) {
+ /* Handle multiple event channels differently */
+ if (p->event_id2) {
+ if (p->event_id2 < 32) {
+ context.event_mask2 =
+ 0x1 << p->event_id2;
+ event2_greater_than_32 = 0;
+ } else {
+ context.event_mask2 =
+ 0x1 << (p->event_id2 - 32);
+ event2_greater_than_32 = 1 << 31;
+ }
+ if (p->event_id < 32) {
+ context.event_mask1 =
+ 0x1 << p->event_id;
+ event1_greater_than_32 = 0;
+ } else {
+ context.event_mask1 =
+ 0x1 << (p->event_id - 32);
+ event1_greater_than_32 = 1 << 30;
+ }
+ } else {
+ event1_greater_than_32 = 0;
+ event2_greater_than_32 = 0;
+ if (p->event_id < 32) {
+ context.event_mask1 =
+ 0x1 << p->event_id;
+ context.event_mask2 = 0;
+ } else {
+ context.event_mask1 = 0;
+ context.event_mask2 =
+ 0x1 << (p->event_id - 32);
+ }
+ }
+ /* Watermark Level */
+ context.wml =
+ event2_greater_than_32 | event1_greater_than_32 |
+ p->watermark_level;
+
+ /* Address */
+ context.shp_addr = (unsigned long)(p->per_address);
+ iapi_IoCtl(sdma_data[channel].cd,
+ IAPI_CHANGE_PERIPHADDR, p->per_address);
+ } else {
+ context.wml = M3_BASE_ADDRESS;
+ }
+
+ sdma_data[channel].transfer_type = p->transfer_type;
+ sdma_data[channel].peripheral_type = p->peripheral_type;
+ sdma_data[channel].watermark_level = p->watermark_level;
+ iapi_AssignScript(sdma_data[channel].cd, &context);
+ } else {
+ res = context.load_address;
+ }
+
+ return res;
+}
+
+/*!
+ * Setup channel according to parameters. Must be called once after mxc_request_dma()
+ *
+ * @param channel channel number
+ * @param p channel parameters pointer
+ * @return 0 on success, error code on fail
+ */
+int mxc_dma_setup_channel(int channel, dma_channel_params * p)
+{
+ int err = 0;
+ int i;
+
+ mxc_dma_stop(channel);
+
+ for (i = 0; i < sdma_data[channel].bd_number; i++) {
+ iapi_IoCtl(sdma_data[channel].cd,
+ (i << BD_NUM_OFFSET) |
+ IAPI_CHANGE_SET_STATUS, (unsigned long)0);
+ }
+
+ sdma_data[channel].bd_number = (p->bd_number <= 0) ? 1 : p->bd_number;
+
+ sdma_data[channel].word_size = p->word_size;
+
+ sdma_data[channel].event_id = p->event_id;
+ sdma_data[channel].event_id2 = p->event_id2;
+
+ sdma_data[channel].callback = p->callback;
+
+ sdma_data[channel].arg = p->arg;
+
+ err = iapi_IoCtl(sdma_data[channel].cd,
+ IAPI_CHANGE_BDNUM, sdma_data[channel].bd_number);
+
+ if (err < 0) {
+ printk(KERN_ERR "Failed allocating buffer \
+descriptors (0x%x)\n", err);
+ err = -ENOMEM;
+ goto setup_channel_fail;
+ }
+
+ if (channel != 0) {
+ switch (p->transfer_type) {
+ case dsp_2_per:
+ break;
+ case emi_2_per:
+ case int_2_per:
+ case per_2_int:
+ case per_2_emi:
+ /*
+ * Peripheral <------> Memory
+ * evtOvr = 0 dspOvr = 1
+ */
+ iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_OWNERSHIP,
+ (OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) |
+ (OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) |
+ (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP));
+ if (p->event_id) {
+ err = iapi_SetChannelEventMapping(p->event_id,
+ 0x1 <<
+ channel);
+ }
+ if (!err && p->event_id2) {
+ err = iapi_SetChannelEventMapping(p->event_id2,
+ 0x1 <<
+ channel);
+ }
+ break;
+ case emi_2_dsp:
+ case int_2_dsp:
+ case dsp_2_int:
+ case dsp_2_emi:
+ case dsp_2_dsp:
+ /*
+ * DSP <-----------> Memory
+ * evtOvr = 1 dspOvr = 0
+ */
+ iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_OWNERSHIP,
+ (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) |
+ (OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) |
+ (OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP));
+ break;
+ case emi_2_int:
+ case emi_2_emi:
+ case int_2_int:
+ case int_2_emi:
+ case emi_2_dsp_loop:
+ case dsp_2_emi_loop:
+ /* evtOvr = 1 dspOvr = 1 */
+ iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_OWNERSHIP,
+ (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) |
+ (OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) |
+ (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP));
+ break;
+ case per_2_dsp:
+ /* evtOvr = 0 dspOvr = 0 */
+ iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_OWNERSHIP,
+ (OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) |
+ (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) |
+ (OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP));
+ err = iapi_SetChannelEventMapping(p->event_id,
+ 0x1 << channel);
+ break;
+ default:
+ break;
+ printk(KERN_ERR "Wrong SDMA transfer type\n");
+ err = -EINVAL;
+ }
+ if (err == 0) {
+ err = sdma_load_context(channel, p);
+ iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_PRIORITY,
+ MXC_SDMA_DEFAULT_PRIORITY);
+ }
+ }
+ setup_channel_fail:
+ return err;
+}
+
+/*!
+ * Setup the channel priority. This can be used to change the default priority
+ * for the channel.
+ *
+ * @param channel channel number
+ * @param priority priority to be set for the channel
+ *
+ * @return 0 on success, error code on failure
+ */
+int mxc_dma_set_channel_priority(unsigned int channel, unsigned int priority)
+{
+ if (priority < MXC_SDMA_MIN_PRIORITY
+ || priority > MXC_SDMA_MAX_PRIORITY) {
+ return -EINVAL;
+ }
+ return iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_PRIORITY,
+ priority);
+}
+
+/*!
+ * Allocates dma channel.
+ * If channel's value is 0, then the function allocates a free channel
+ * dynamically and sets its value to channel.
+ * Else allocates requested channel if it is free.
+ * If the channel is busy or no free channels (in dynamic allocation) -EBUSY returned.
+ *
+ * @param channel pointer to channel number
+ * @param devicename device name
+ * @return 0 on success, error code on fail
+ */
+int mxc_request_dma(int *channel, const char *devicename)
+{
+ int i, res;
+
+ res = 0;
+
+ down(&sdma_status_mutex);
+
+ /* Dynamic allocation */
+ if (*channel == 0) {
+ for (i = MAX_DMA_CHANNELS - 1; i > 0; i--) {
+#ifdef CONFIG_SDMA_IRAM
+ /*TODO:It will be removed after DPTC used UDMA interface */
+ if (i >= MXC_DMA_CHANNEL_IRAM)
+ continue;
+#endif /*CONFIG_SDMA_IRAM */
+ if (!sdma_data[i].in_use) {
+ *channel = i;
+ break;
+ }
+ }
+ }
+
+ if (*channel > 0 && *channel < MAX_DMA_CHANNELS &&
+ sdma_data[*channel].in_use == 0) {
+ res = iapi_Open(sdma_data[0].cd, *channel);
+
+ if (res < 0) {
+ printk(KERN_ERR "Failed iapi_Open channel %d, 0x%x\n",
+ *channel, res);
+ } else {
+ sdma_data[*channel].in_use = 1;
+ strcpy(sdma_data[*channel].devicename, devicename);
+ sdma_data[*channel].cd = CHAD(*channel);
+
+ iapi_IoCtl(sdma_data[*channel].cd, IAPI_CHANGE_SYNCH,
+ CALLBACK_ISR);
+ iapi_IoCtl(sdma_data[*channel].cd,
+ IAPI_CHANGE_CALLBACKFUNC,
+ (unsigned long)iapi_interrupt_callback);
+ iapi_IoCtl(sdma_data[*channel].cd,
+ IAPI_CHANGE_USER_ARG,
+ (unsigned long)&(sdma_data[*channel]));
+ }
+ } else {
+ res = -EBUSY;
+ }
+
+ up(&sdma_status_mutex);
+
+ return res;
+}
+
+/*!
+ * Configures request parameters. Can be called multiple times after
+ * mxc_request_dma() and mxc_dma_setup_channel().
+ *
+ *
+ * @param channel channel number
+ * @param p request parameters pointer
+ * @param bd_index index of buffer descriptor to set
+ * @return 0 on success, error code on fail
+ */
+int mxc_dma_set_config(int channel, dma_request_t * p, int bd_index)
+{
+ unsigned char param;
+
+ if (!sdma_data[channel].in_use) {
+ return -EINVAL;
+ }
+
+ iapi_IoCtl(sdma_data[channel].cd,
+ (bd_index << BD_NUM_OFFSET) |
+ IAPI_CHANGE_SET_TRANSFER_CD, sdma_data[channel].word_size);
+
+ param = BD_DONE | BD_INTR | BD_EXTD;
+
+ if (sdma_data[channel].bd_number > 1 && p->bd_cont == 1) {
+ param |= BD_CONT;
+ }
+
+ if (bd_index == sdma_data[channel].bd_number - 1) {
+ param |= BD_WRAP;
+ }
+
+ switch (sdma_data[channel].transfer_type) {
+ case emi_2_per:
+ case dsp_2_per:
+ case int_2_per:
+ case emi_2_dsp:
+ case int_2_dsp:
+ case emi_2_dsp_loop:
+ iapi_IoCtl(sdma_data[channel].cd,
+ (bd_index << BD_NUM_OFFSET) |
+ IAPI_CHANGE_SET_BUFFERADDR,
+ (unsigned long)p->sourceAddr);
+ break;
+ case per_2_int:
+ case per_2_emi:
+ case per_2_dsp:
+ case dsp_2_int:
+ case dsp_2_emi:
+ case dsp_2_dsp:
+ case dsp_2_emi_loop:
+ iapi_IoCtl(sdma_data[channel].cd,
+ (bd_index << BD_NUM_OFFSET) |
+ IAPI_CHANGE_SET_BUFFERADDR,
+ (unsigned long)p->destAddr);
+ break;
+ case emi_2_int:
+ case emi_2_emi:
+ case int_2_int:
+ case int_2_emi:
+ iapi_IoCtl(sdma_data[channel].cd,
+ (bd_index << BD_NUM_OFFSET) |
+ IAPI_CHANGE_SET_BUFFERADDR,
+ (unsigned long)p->sourceAddr);
+ iapi_IoCtl(sdma_data[channel].cd,
+ (bd_index << BD_NUM_OFFSET) |
+ IAPI_CHANGE_SET_EXTDBUFFERADDR,
+ (unsigned long)p->destAddr);
+ break;
+ default:
+ break;
+ }
+
+ /* Change the endianness for DSP to MCU Data transfers */
+ if (sdma_data[channel].transfer_type == dsp_2_emi ||
+ sdma_data[channel].transfer_type == emi_2_dsp) {
+ iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_SET_ENDIANNESS,
+ SET_BIT_ALL);
+ }
+
+ iapi_IoCtl(sdma_data[channel].cd,
+ (bd_index << BD_NUM_OFFSET) |
+ IAPI_CHANGE_SET_COUNT, p->count);
+
+ iapi_IoCtl(sdma_data[channel].cd,
+ (bd_index << BD_NUM_OFFSET) | IAPI_CHANGE_SET_STATUS, param);
+
+ return 0;
+}
+
+/*!
+ * Configures the BD_INTR bit on a buffer descriptor parameters.
+ *
+ *
+ * @param channel channel number
+ * @param bd_index index of buffer descriptor to set
+ * @param bd_intr flag to set or clear the BD_INTR bit
+ * @return 0 on success, error code on fail
+ */
+void mxc_dma_set_bd_intr(int channel, int bd_index, int bd_intr)
+{
+ unsigned long param;
+
+ iapi_IoCtl(sdma_data[channel].cd,
+ (bd_index << BD_NUM_OFFSET) |
+ IAPI_CHANGE_GET_STATUS, (unsigned long)&param);
+
+ if (bd_intr) {
+ param |= BD_INTR;
+ } else {
+ param &= ~BD_INTR;
+ }
+ iapi_IoCtl(sdma_data[channel].cd,
+ (bd_index << BD_NUM_OFFSET) | IAPI_CHANGE_SET_STATUS, param);
+
+}
+
+/*!
+ * Gets the BD_INTR bit on a buffer descriptor.
+ *
+ *
+ * @param channel channel number
+ * @param bd_index index of buffer descriptor to set
+ *
+ * @return returns the BD_INTR bit status
+ */
+int mxc_dma_get_bd_intr(int channel, int bd_index)
+{
+ unsigned long bd_status = 0;
+
+ iapi_IoCtl(sdma_data[channel].cd,
+ (bd_index << BD_NUM_OFFSET) |
+ IAPI_CHANGE_GET_STATUS, (unsigned long)&bd_status);
+
+ return (bd_status & BD_INTR);
+}
+
+/*!
+ * Stop the current transfer
+ *
+ * @param channel channel number
+ * @param buffer_number number of buffers (beginning with 0),
+ * whose done bits should be reset to 0
+ */
+int mxc_dma_reset(int channel, int buffer_number)
+{
+ unsigned char param = 0;
+ int i = 0;
+
+ if (!sdma_data[channel].in_use) {
+ return -EINVAL;
+ }
+
+ /* clear the BD_DONE bits for all the necessary buffers */
+ for (i = 0; i < buffer_number; i++) {
+
+ iapi_IoCtl(sdma_data[channel].cd, (i << BD_NUM_OFFSET) |
+ IAPI_CHANGE_GET_STATUS, (unsigned long)&param);
+
+ /* clear the BD_DONE bit of the buffer */
+ param = param & (~BD_DONE);
+
+ iapi_IoCtl(sdma_data[channel].cd, (i << BD_NUM_OFFSET) |
+ IAPI_CHANGE_SET_STATUS, param);
+ }
+
+ return 0;
+}
+
+/*!
+ * Returns request parameters.
+ *
+ * @param channel channel number
+ * @param p request parameters pointer
+ * @param bd_index index of buffer descriptor to get
+ * @return 0 on success, error code on fail
+ */
+int mxc_dma_get_config(int channel, dma_request_t * p, int bd_index)
+{
+ int err = 0;
+ unsigned long bd_status;
+ unsigned long bd_count;
+ __u8 *sourceAddr;
+ __u8 *destAddr;
+
+ iapi_IoCtl(sdma_data[channel].cd,
+ (bd_index << BD_NUM_OFFSET) |
+ IAPI_CHANGE_GET_STATUS, (unsigned long)&bd_status);
+ iapi_IoCtl(sdma_data[channel].cd,
+ (bd_index << BD_NUM_OFFSET) |
+ IAPI_CHANGE_GET_COUNT, (unsigned long)&bd_count);
+ iapi_IoCtl(sdma_data[channel].cd,
+ (bd_index << BD_NUM_OFFSET) |
+ IAPI_CHANGE_GET_BUFFERADDR, (unsigned long)&sourceAddr);
+
+ switch (sdma_data[channel].transfer_type) {
+ case emi_2_per:
+ case dsp_2_per:
+ case int_2_per:
+ case emi_2_dsp:
+ case int_2_dsp:
+ case emi_2_dsp_loop:
+ p->sourceAddr = sourceAddr;
+ break;
+ case per_2_int:
+ case per_2_emi:
+ case per_2_dsp:
+ case dsp_2_int:
+ case dsp_2_emi:
+ case dsp_2_dsp:
+ case dsp_2_emi_loop:
+ p->destAddr = sourceAddr;
+ break;
+ case emi_2_int:
+ case emi_2_emi:
+ case int_2_int:
+ case int_2_emi:
+ p->sourceAddr = sourceAddr;
+ iapi_IoCtl(sdma_data[channel].cd,
+ (bd_index << BD_NUM_OFFSET) |
+ IAPI_CHANGE_GET_EXTDBUFFERADDR,
+ (unsigned long)&destAddr);
+ p->destAddr = destAddr;
+ break;
+ default:
+ break;
+ }
+
+ p->count = bd_count;
+ p->bd_done = bd_status & BD_DONE;
+ p->bd_cont = bd_status & BD_CONT;
+ p->bd_error = bd_status & BD_RROR;
+
+ return err;
+}
+
+/*!
+ * This function is used by MXC IPC's write_ex2. It passes the pointer to the
+ * data control structure to iapi_write_ipcv2()
+ *
+ * @param channel SDMA channel number
+ * @param ctrl_ptr Data Control structure pointer
+ */
+int mxc_sdma_write_ipcv2(int channel, void *ctrl_ptr)
+{
+ return iapi_Write_ipcv2(sdma_data[channel].cd, ctrl_ptr);
+}
+
+/*!
+ * This function is used by MXC IPC's read_ex2. It passes the pointer to the
+ * data control structure to iapi_read_ipcv2()
+ *
+ * @param channel SDMA channel number
+ * @param ctrl_ptr Data Control structure pointer
+ */
+int mxc_sdma_read_ipcv2(int channel, void *ctrl_ptr)
+{
+ return iapi_Read_ipcv2(sdma_data[channel].cd, ctrl_ptr);
+}
+
+/*!
+ * Starts dma channel.
+ *
+ * @param channel channel number
+ */
+int mxc_dma_start(int channel)
+{
+ if (sdma_data[channel].running == 0) {
+ sdma_data[channel].running = 1;
+ iapi_StartChannel(channel);
+ }
+
+ return 0;
+}
+
+/*!
+ * Stops dma channel.
+ *
+ * @param channel channel number
+ */
+int mxc_dma_stop(int channel)
+{
+ iapi_StopChannel(channel);
+ sdma_data[channel].running = 0;
+
+ return 0;
+}
+
+/*!
+ * Frees dma channel.
+ *
+ * @param channel channel number
+ */
+void mxc_free_dma(int channel)
+{
+ int i;
+
+ mxc_dma_stop(channel);
+
+ if (sdma_data[channel].event_id != 0) {
+ iapi_SetChannelEventMapping(sdma_data[channel].event_id, 0x0);
+ }
+ if (sdma_data[channel].event_id2 != 0) {
+ iapi_SetChannelEventMapping(sdma_data[channel].event_id2, 0x0);
+ }
+
+ sdma_data[channel].event_id = 0;
+
+ iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_PRIORITY, 0x0);
+ iapi_IoCtl(sdma_data[channel].cd, IAPI_CHANGE_OWNERSHIP,
+ (OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) |
+ (OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) |
+ (OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP));
+
+ for (i = 0; i < sdma_data[channel].bd_number; i++) {
+ iapi_IoCtl(sdma_data[channel].cd,
+ (i << BD_NUM_OFFSET) |
+ IAPI_CHANGE_SET_STATUS, (unsigned long)0);
+ }
+
+ iapi_Close(sdma_data[channel].cd);
+
+ strcpy(sdma_data[channel].devicename, "not used");
+
+ sdma_data[channel].in_use = 0;
+}
+
+/*!
+ * Initializes channel's priorities
+ *
+ */
+static void __init init_priorities(void)
+{
+ iapi_IoCtl(sdma_data[0].cd, IAPI_CHANGE_PRIORITY, 0x7);
+}
+
+/*!
+ * Initializes events table
+ */
+static void __init init_event_table(void)
+{
+ int channel;
+
+ for (channel = 0; channel < MAX_DMA_CHANNELS; channel++) {
+ iapi_SetChannelEventMapping(channel, 0);
+ }
+}
+
+/*!
+ * Sets callback function. Used with standard dma api
+ * for supporting interrupts
+ *
+ * @param channel channel number
+ * @param callback callback function pointer
+ * @param arg argument for callback function
+ */
+void mxc_dma_set_callback(int channel, dma_callback_t callback, void *arg)
+{
+ sdma_data[channel].callback = callback;
+ sdma_data[channel].arg = arg;
+}
+
+/*!
+ * Synchronization function used by I.API
+ *
+ * @param channel channel number
+ */
+static int getChannel(int channel)
+{
+ if (irqs_disabled() || in_atomic()) {
+ if (down_trylock(&sdma_synch_mutex[channel])) {
+ return -EBUSY;
+ }
+ } else {
+ if (down_interruptible(&sdma_synch_mutex[channel])) {
+ return -EBUSY;
+ }
+ }
+
+ return 0;
+}
+
+/*!
+ * Synchronization function used by I.API
+ *
+ * @param channel channel number
+ */
+static int releaseChannel(int channel)
+{
+ up(&sdma_synch_mutex[channel]);
+ return 0;
+}
+
+/*!
+ * Unmask interrupt function. Used by I.API
+ *
+ */
+static void unmask_sdma_interrupt(void)
+{
+ /* Commented out tp take care of the PREEMPT_RT option
+ * local_irq_restore(flags);
+ */
+}
+
+/*!
+ * Mask interrupt function. Used by I.API
+ *
+ */
+static void mask_sdma_interrupt(void)
+{
+ /* Commented to take of the PREEMPT_RT option
+ * local_irq_save(flags);
+ */
+}
+
+/*!
+ * Initializes I.API
+ */
+static void __init init_iapi_struct(void)
+{
+ channelDescriptor *cd;
+
+ printk(KERN_INFO "Using SDMA I.API\n");
+
+ iapi_Malloc = &sdma_malloc;
+#ifdef CONFIG_SDMA_IRAM
+ iapi_iram_Malloc = &sdma_iram_malloc;
+#endif /*CONFIG_SDMA_IRAM */
+
+ iapi_Free = &sdma_free;
+ iapi_Virt2Phys = (void *(*)(void *))&sdma_virt_to_phys;
+ iapi_Phys2Virt = (void *(*)(void *))&sdma_phys_to_virt;
+ iapi_memset = &memset;
+ iapi_memcpy = &memcpy;
+
+ iapi_GotoSleep = &sdma_sleep_channel;
+ iapi_WakeUp = &sdma_wakeup_channel;
+ iapi_InitSleep = &sdma_init_sleep;
+ iapi_ReleaseChannel = &releaseChannel;
+ iapi_GetChannel = &getChannel;
+
+ iapi_EnableInterrupts = &unmask_sdma_interrupt;
+ iapi_DisableInterrupts = &mask_sdma_interrupt;
+
+ cd = kmalloc(sizeof(channelDescriptor), GFP_KERNEL);
+
+ memset(cd, 0, sizeof(channelDescriptor));
+
+ sdma_data[0].cd = cd;
+}
+
+/*!
+ * Initializes channel synchronization mutexes
+ */
+static void __init init_mutexes(void)
+{
+ int i;
+
+ for (i = 0; i < MAX_DMA_CHANNELS; i++) {
+ init_MUTEX(&sdma_synch_mutex[i]);
+ }
+
+ init_MUTEX(&sdma_status_mutex);
+}
+
+/*!
+ * Channels status read proc file system function
+ *
+ * @param buf pointer to the buffer the data shuld be written to.
+ * @param start pointer to the pointer where the new data is
+ * written to.
+ * procedure should update the start pointer to point to
+ * where in the buffer the data was written.
+ * @param offset offset from start of the file
+ * @param count number of bytes to read.
+ * @param eof pointer to eof flag. sould be set to 1 when
+ * reaching eof.
+ * @param data driver specific data pointer.
+ *
+ * @return number byte read from the log buffer.
+ */
+static int proc_read_channels(char *buf, char **start, off_t offset, int count,
+ int *eof, void *data)
+{
+ char *log;
+ char *log_ptr;
+ char tmp[48];
+ int i;
+
+ log = kmalloc(4096, GFP_KERNEL);
+ memset(log, 0, 4096);
+ log_ptr = log;
+
+ for (i = 0; i < MAX_DMA_CHANNELS; i++) {
+ if (sdma_data[i].in_use == 0) {
+ continue;
+ }
+
+ memset(tmp, 0, 48);
+ sprintf(tmp, "Channel %d: %s\n", i, sdma_data[i].devicename);
+
+ strcpy(log_ptr, tmp);
+ log_ptr += strlen(tmp);
+ }
+
+ if (offset > strlen(log)) {
+ *eof = 1;
+ count = 0;
+ } else {
+ if (offset + count > strlen(log)) {
+ count = strlen(log) - offset;
+ *eof = 1;
+ } else {
+ *eof = 0;
+ }
+
+ memcpy(buf, log, count);
+ *start = buf;
+ kfree(log);
+ }
+
+ return count;
+}
+
+/*!
+ * SDMA proc file system read function
+ */
+static int __init init_proc_fs(void)
+{
+ struct proc_dir_entry *sdma_proc_dir;
+ int res;
+
+ res = 0;
+
+ sdma_proc_dir = proc_mkdir("sdma", NULL);
+ create_proc_read_entry("channels", 0, sdma_proc_dir,
+ proc_read_channels, NULL);
+
+ if (res < 0) {
+ printk(KERN_WARNING "Failed create SDMA proc entry\n");
+ }
+
+ return res;
+}
+
+/*!
+ * Initializes SDMA private data
+ */
+static void __init init_sdma_data(void)
+{
+ int i;
+
+ memset(sdma_data, 0, sizeof(sdma_struct) * MAX_DMA_CHANNELS);
+ sdma_data[0].in_use = 1;
+ strcpy(sdma_data[0].devicename, "MCU");
+
+ for (i = 0; i < MAX_DMA_CHANNELS; i++) {
+ sdma_data[i].channel = i;
+ }
+}
+
+#if defined(CONFIG_MXC_SUPER_GEM)
+/*!
+ * Initialize the Super GEM SDMA channel
+ *
+ * @return returns -1 on error, 0 on success.
+ */
+static int __init init_super_gem(void)
+{
+ channelDescriptor *cd;
+ script_data context;
+ int res = 0;
+
+ res = iapi_Open(sdma_data[0].cd, MXC_DMA_CHANNEL_GEM);
+ if (res < 0) {
+ return -1;
+ }
+ sdma_data[MXC_DMA_CHANNEL_GEM].in_use = 1;
+ cd = CHAD(MXC_DMA_CHANNEL_GEM);
+ memset(&context, 0, sizeof(script_data));
+ context.load_address = sdma_script_addrs.mxc_sdma_utra_addr;
+ context.wml = M3_BASE_ADDRESS;
+ res = iapi_AssignScript(cd, &context);
+ if (res < 0) {
+ iapi_Close(cd);
+ sdma_data[MXC_DMA_CHANNEL_GEM].in_use = 0;
+ return -1;
+ }
+ res =
+ iapi_IoCtl(cd, IAPI_CHANGE_OWNERSHIP,
+ (OWN_CHANNEL << CH_OWNSHP_OFFSET_EVT) |
+ (DONT_OWN_CHANNEL << CH_OWNSHP_OFFSET_MCU) |
+ (OWN_CHANNEL << CH_OWNSHP_OFFSET_DSP));
+ if (res < 0) {
+ iapi_Close(cd);
+ sdma_data[MXC_DMA_CHANNEL_GEM].in_use = 0;
+ return -1;
+ }
+ /* Set EP=1, which is required to start SuperGem script the first time */
+ /* This can be done only on the AP side */
+ SDMA_H_EVTPEND |= 1 << MXC_DMA_CHANNEL_GEM;
+
+ res =
+ iapi_SetChannelEventMapping(DMA_REQ_GEM, 1 << MXC_DMA_CHANNEL_GEM);
+ if (res < 0) {
+ iapi_Close(cd);
+ sdma_data[MXC_DMA_CHANNEL_GEM].in_use = 0;
+ return -1;
+ }
+
+ return 0;
+}
+#endif
+
+/*!
+ * Initializes dma
+ */
+int __init sdma_init(void)
+{
+ int res = 0;
+ configs_data confreg_data;
+
+ /* Initialize to the default values */
+ confreg_data = iapi_ConfigDefaults;
+
+ confreg_data.dspdma = MXC_SDMA_DSPDMA;
+ /* Set ACR bit */
+ mxc_sdma_ahb_clk = clk_get(NULL, "sdma_ahb_clk");
+ mxc_sdma_ipg_clk = clk_get(NULL, "sdma_ipg_clk");
+ clk_enable(mxc_sdma_ahb_clk);
+ clk_enable(mxc_sdma_ipg_clk);
+ if (clk_get_rate(mxc_sdma_ahb_clk) / clk_get_rate(mxc_sdma_ipg_clk) < 2) {
+ printk(KERN_INFO "Setting SDMA ACR\n");
+ confreg_data.acr = 1;
+ }
+
+ init_sdma_data();
+
+ init_sdma_pool();
+
+ res = request_irq(MXC_INT_SDMA, sdma_int_handler, 0, "mxcsdma", 0);
+
+ if (res < 0) {
+ goto sdma_init_fail;
+ }
+
+ init_mutexes();
+
+ init_iapi_struct();
+
+ mxc_sdma_get_script_info(&sdma_script_addrs);
+
+ res = iapi_Init(sdma_data[0].cd, &confreg_data,
+ sdma_script_addrs.mxc_sdma_start_addr,
+ sdma_script_addrs.mxc_sdma_ram_code_size * 2,
+ sdma_script_addrs.mxc_sdma_ram_code_start_addr);
+
+ if (res < 0) {
+ free_irq(MXC_INT_SDMA, 0);
+ goto sdma_init_fail;
+ }
+
+ init_priorities();
+
+ init_event_table();
+
+#if defined(CONFIG_MXC_SUPER_GEM)
+ res = init_super_gem();
+ if (res < 0) {
+ free_irq(MXC_INT_SDMA, 0);
+ goto sdma_init_fail;
+ }
+#endif
+
+ init_proc_fs();
+
+ printk(KERN_INFO "MXC DMA API initialized\n");
+
+ clk_disable(mxc_sdma_ahb_clk);
+ clk_disable(mxc_sdma_ipg_clk);
+ return res;
+
+ sdma_init_fail:
+ printk(KERN_ERR "Error 0x%x in sdma_init\n", res);
+ clk_disable(mxc_sdma_ahb_clk);
+ clk_disable(mxc_sdma_ipg_clk);
+ return res;
+
+}
+
+arch_initcall(sdma_init);
+
+EXPORT_SYMBOL(mxc_request_dma);
+EXPORT_SYMBOL(mxc_free_dma);
+EXPORT_SYMBOL(mxc_dma_setup_channel);
+EXPORT_SYMBOL(mxc_dma_set_channel_priority);
+EXPORT_SYMBOL(mxc_dma_set_config);
+EXPORT_SYMBOL(mxc_dma_get_config);
+EXPORT_SYMBOL(mxc_dma_set_bd_intr);
+EXPORT_SYMBOL(mxc_dma_get_bd_intr);
+EXPORT_SYMBOL(mxc_dma_reset);
+EXPORT_SYMBOL(mxc_sdma_write_ipcv2);
+EXPORT_SYMBOL(mxc_sdma_read_ipcv2);
+EXPORT_SYMBOL(mxc_dma_start);
+EXPORT_SYMBOL(mxc_dma_stop);
+EXPORT_SYMBOL(sdma_malloc);
+EXPORT_SYMBOL(sdma_free);
+EXPORT_SYMBOL(mxc_dma_set_callback);
+EXPORT_SYMBOL(sdma_virt_to_phys);
+EXPORT_SYMBOL(sdma_phys_to_virt);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXC Linux SDMA API");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/sdma/sdma_malloc.c b/arch/arm/plat-mxc/sdma/sdma_malloc.c
new file mode 100644
index 000000000000..2b04ef6c3c08
--- /dev/null
+++ b/arch/arm/plat-mxc/sdma/sdma_malloc.c
@@ -0,0 +1,388 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file plat-mxc/sdma/sdma_malloc.c
+ * @brief This file contains functions for SDMA non-cacheable buffers allocation
+ *
+ * SDMA (Smart DMA) is used for transferring data between MCU and peripherals
+ *
+ * @ingroup SDMA
+ */
+
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <asm/dma.h>
+#include <asm/mach/dma.h>
+#include <mach/hardware.h>
+
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/dmapool.h>
+
+#define DEBUG 0
+
+#if DEBUG
+#define DPRINTK(fmt, args...) printk("%s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+#ifdef CONFIG_SDMA_IRAM
+#define IRAM_VIRT_BASE IRAM_BASE_ADDR_VIRT
+#define IRAM_PHYS_BASE IRAM_BASE_ADDR
+#if (CONFIG_SDMA_IRAM_SIZE&0x3FF)
+#error "IRAM size of SDMA should be multiple of 1Kbytes"
+#else
+#define IRAM_SDMA_SIZE CONFIG_SDMA_IRAM_SIZE /* 4K */
+#endif
+#define IRAM_UNIT_SIZE 512
+#define IRAM_POOL_SIZE (IRAM_SDMA_SIZE/IRAM_UNIT_SIZE)
+
+#define IS_IRAM_VIRT(x) (((x)<IRAM_VIRT_BASE)?0:\
+ (((x) - IRAM_VIRT_BASE)>IRAM_SDMA_SIZE)?0:1)
+
+#define IS_IRAM_PHYS(x) (((x)<IRAM_PHYS_BASE)?0:\
+ (((x) - IRAM_PHYS_BASE)>IRAM_SDMA_SIZE)?0:1)
+#endif /*CONFIG_SDMA_IRAM */
+
+/*!
+ * Defines SDMA non-cacheable buffers pool
+ */
+static struct dma_pool *pool;
+
+#ifdef CONFIG_SDMA_IRAM
+typedef struct iram_head_s {
+ struct list_head list;
+} iram_head_t;
+
+static spinlock_t iram_pool_lock = SPIN_LOCK_UNLOCKED;
+static struct list_head iram_free_list;
+static unsigned char iram_pool_flag[IRAM_POOL_SIZE];
+
+static void sdma_iram_free(void *buf);
+#endif /*CONFIG_SDMA_IRAM */
+
+/*!
+ * SDMA memory conversion hashing structure
+ */
+typedef struct {
+ struct list_head node;
+ int use_count;
+ /*! Virtual address */
+ void *virt;
+ /*! Physical address */
+ unsigned long phys;
+} virt_phys_struct;
+
+static struct list_head buf_map;
+
+/*!
+ * Defines the size of each buffer in SDMA pool.
+ * The size must be at least 512 bytes, because
+ * sdma channel control blocks array size is 512 bytes
+ */
+#define SDMA_POOL_SIZE 1024
+
+/*!
+ * Adds new buffer structure into conversion hash tables
+ *
+ * @param vf SDMA memory conversion hashing structure
+ *
+ * @return 1 on success, 0 on fail
+ */
+static int add_entry(virt_phys_struct * vf)
+{
+ virt_phys_struct *p;
+
+ vf->phys &= PAGE_MASK;
+ vf->virt = (void *)((u32) vf->virt & PAGE_MASK);
+
+ list_for_each_entry(p, &buf_map, node) {
+ if (p->virt == vf->virt) {
+ p->use_count++;
+ return 0;
+ }
+ }
+
+ p = kmalloc(sizeof(virt_phys_struct), GFP_KERNEL);
+ if (p == 0) {
+ return -ENOMEM;
+ }
+
+ *p = *vf;
+ p->use_count = 1;
+ list_add_tail(&p->node, &buf_map);
+
+ DPRINTK("added vaddr 0x%p, paddr 0x%08X to list\n", p->virt, p->phys);
+
+ return 0;
+}
+
+/*!
+ * Deletes buffer stracture from conversion hash tables
+ *
+ * @param buf SDMA memory buffer virtual addr
+ *
+ * @return 0 on success, -1 on fail
+ */
+static int delete_entry(void *buf)
+{
+ virt_phys_struct *p;
+
+ buf = (void *)((u32) buf & PAGE_MASK);
+
+ list_for_each_entry(p, &buf_map, node) {
+ if (p->virt == buf) {
+ p->use_count--;
+ break;
+ }
+ }
+
+ if (p->use_count == 0) {
+ list_del(&p->node);
+ kfree(p);
+ }
+
+ return 0;
+}
+
+/*!
+ * Virtual to physical address conversion functio
+ *
+ * @param buf pointer to virtual address
+ *
+ * @return physical address
+ */
+unsigned long sdma_virt_to_phys(void *buf)
+{
+ u32 offset = (u32) buf & (~PAGE_MASK);
+ virt_phys_struct *p;
+
+ DPRINTK("searching for vaddr 0x%p\n", buf);
+
+#ifdef CONFIG_SDMA_IRAM
+ if (IS_IRAM_VIRT((unsigned long)buf)) {
+ if ((unsigned long)buf & (IRAM_UNIT_SIZE - 1)) {
+ printk(KERN_WARNING "%s buffer offset = %ld\n",
+ __FUNCTION__, (unsigned long)buf);
+ }
+ return (unsigned long)buf + IRAM_PHYS_BASE - IRAM_VIRT_BASE;
+ }
+#endif /*CONFIG_SDMA_IRAM */
+
+ list_for_each_entry(p, &buf_map, node) {
+ if ((u32) p->virt == ((u32) buf & PAGE_MASK)) {
+ return p->phys | offset;
+ }
+ }
+
+ if (virt_addr_valid(buf)) {
+ return virt_to_phys(buf);
+ }
+
+ printk(KERN_WARNING
+ "SDMA malloc: could not translate virt address 0x%p\n", buf);
+ return 0;
+}
+
+/*!
+ * Physical to virtual address conversion functio
+ *
+ * @param buf pointer to physical address
+ *
+ * @return virtual address
+ */
+void *sdma_phys_to_virt(unsigned long buf)
+{
+ u32 offset = buf & (~PAGE_MASK);
+ virt_phys_struct *p;
+
+#ifdef CONFIG_SDMA_IRAM
+ if (IS_IRAM_PHYS((unsigned long)buf)) {
+ if (buf & (IRAM_UNIT_SIZE - 1)) {
+ printk(KERN_WARNING "%s buffer offset = %ld\n",
+ __FUNCTION__, (unsigned long)buf);
+ }
+ return (void *)buf + IRAM_VIRT_BASE - IRAM_PHYS_BASE;
+ }
+#endif /*CONFIG_SDMA_IRAM */
+
+ list_for_each_entry(p, &buf_map, node) {
+ if (p->phys == (buf & PAGE_MASK)) {
+ return (void *)((u32) p->virt | offset);
+ }
+ }
+
+ printk(KERN_WARNING
+ "SDMA malloc: could not translate phys address 0x%lx\n", buf);
+ return 0;
+}
+
+/*!
+ * Allocates uncacheable buffer
+ *
+ * @param size size of allocated buffer
+ * @return pointer to buffer
+ */
+void *sdma_malloc(size_t size)
+{
+ void *buf;
+ dma_addr_t dma_addr;
+ virt_phys_struct vf;
+
+ if (size > SDMA_POOL_SIZE) {
+ printk(KERN_WARNING
+ "size in sdma_malloc is more than %d bytes\n",
+ SDMA_POOL_SIZE);
+ buf = 0;
+ } else {
+ buf = dma_pool_alloc(pool, GFP_KERNEL, &dma_addr);
+ if (buf > 0) {
+ vf.virt = buf;
+ vf.phys = dma_addr;
+
+ if (add_entry(&vf) < 0) {
+ dma_pool_free(pool, buf, dma_addr);
+ buf = 0;
+ }
+ }
+ }
+
+ DPRINTK("allocated vaddr 0x%p\n", buf);
+ return buf;
+}
+
+/*!
+ * Frees uncacheable buffer
+ *
+ * @param buf buffer pointer for deletion
+ */
+void sdma_free(void *buf)
+{
+#ifdef CONFIG_SDMA_IRAM
+ if (IS_IRAM_VIRT((unsigned long)buf)) {
+ sdma_iram_free(buf);
+ return;
+ }
+#endif /*CONFIG_SDMA_IRAM */
+
+ dma_pool_free(pool, buf, sdma_virt_to_phys(buf));
+ delete_entry(buf);
+}
+
+#ifdef CONFIG_SDMA_IRAM
+/*!
+ * Allocates uncacheable buffer from IRAM
+ */
+void *sdma_iram_malloc(size_t size)
+{
+ void *buf = NULL;
+ int index = -1;
+ unsigned long flags;
+ if (size > IRAM_UNIT_SIZE) {
+ printk(KERN_WARNING
+ "size in sdma_iram_malloc is more than %d bytes\n",
+ IRAM_UNIT_SIZE);
+ } else {
+ spin_lock_irqsave(&iram_pool_lock, flags);
+ if (!list_empty(&iram_free_list)) {
+ buf =
+ list_entry(iram_free_list.next, iram_head_t, list);
+ list_del(iram_free_list.next);
+ index =
+ ((unsigned long)buf -
+ IRAM_VIRT_BASE) / IRAM_UNIT_SIZE;
+ if (index < 0 || index >= IRAM_POOL_SIZE) {
+ spin_unlock_irqrestore(&iram_pool_lock, flags);
+ printk(KERN_ERR "The iram pool has crashed\n");
+ return NULL;
+ }
+ if (iram_pool_flag[index]) {
+ spin_unlock_irqrestore(&iram_pool_lock, flags);
+ printk(KERN_WARNING
+ "iram block %d already has been allocated \n",
+ index);
+ }
+ iram_pool_flag[index] = 1;
+ }
+ spin_unlock_irqrestore(&iram_pool_lock, flags);
+ if ((unsigned long)buf & (IRAM_UNIT_SIZE - 1)) {
+ printk(KERN_WARNING
+ "the start address is not align of %d, buffer offset %ld\n",
+ IRAM_UNIT_SIZE, (unsigned long)buf);
+
+ buf = PTR_ALIGN(buf, IRAM_UNIT_SIZE);
+ }
+ }
+ return buf;
+}
+
+/*!
+ * Free uncacheable buffer into IRAM.
+ */
+static void sdma_iram_free(void *buf)
+{
+ iram_head_t *p;
+ int index;
+ unsigned long flags;
+ /* The check of parameter will be done in sdma_free */
+ index = ((unsigned long)buf - IRAM_VIRT_BASE) / IRAM_UNIT_SIZE;
+ spin_lock_irqsave(&iram_pool_lock, flags);
+ p = (iram_head_t *) ((unsigned long)buf & (~(IRAM_UNIT_SIZE - 1)));
+ list_add_tail(&(p->list), &iram_free_list);
+ if (iram_pool_flag[index]) {
+ iram_pool_flag[index] = 0;
+ spin_unlock_irqrestore(&iram_pool_lock, flags);
+ } else {
+ printk(KERN_WARNING
+ "Free %p which IRAM block %d is already freed\n", buf,
+ index);
+ spin_unlock_irqrestore(&iram_pool_lock, flags);
+ }
+}
+
+/*!
+ * Initialized the free list of IRAM.
+ */
+static void iram_pool_init(void)
+{
+ int i;
+ iram_head_t *p;
+ memset(iram_pool_flag, 0, IRAM_POOL_SIZE);
+ INIT_LIST_HEAD(&iram_free_list);
+ for (i = 0; i < IRAM_POOL_SIZE; i++) {
+ p = (iram_head_t *) (IRAM_VIRT_BASE + i * IRAM_UNIT_SIZE);
+ list_add_tail(&(p->list), &iram_free_list);
+ }
+}
+#endif /*CONFIG_SDMA_IRAM */
+
+/*!
+ * SDMA buffers pool initialization function
+ */
+void __init init_sdma_pool(void)
+{
+#ifdef CONFIG_SDMA_IRAM
+ iram_pool_init();
+#endif /*CONFIG_SDMA_IRAM */
+
+ pool = dma_pool_create("SDMA", NULL, SDMA_POOL_SIZE, 0, 0);
+
+ INIT_LIST_HEAD(&buf_map);
+}
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("MXC Linux SDMA API");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/serialxc.c b/arch/arm/plat-mxc/serialxc.c
new file mode 100644
index 000000000000..cf18bfdc8a76
--- /dev/null
+++ b/arch/arm/plat-mxc/serialxc.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/usb/fsl_xcvr.h>
+
+#include <mach/hardware.h>
+#include <mach/arc_otg.h>
+
+static void usb_serial_init(struct fsl_xcvr_ops *this)
+{
+}
+
+static void usb_serial_uninit(struct fsl_xcvr_ops *this)
+{
+}
+
+static struct fsl_xcvr_ops serial_ops = {
+ .name = "serial",
+ .xcvr_type = PORTSC_PTS_SERIAL,
+ .init = usb_serial_init,
+ .uninit = usb_serial_uninit,
+};
+
+extern void fsl_usb_xcvr_register(struct fsl_xcvr_ops *xcvr_ops);
+
+static int __init serialxc_init(void)
+{
+ pr_debug("%s\n", __FUNCTION__);
+
+ fsl_usb_xcvr_register(&serial_ops);
+
+ return 0;
+}
+
+extern void fsl_usb_xcvr_unregister(struct fsl_xcvr_ops *xcvr_ops);
+
+static void __exit serialxc_exit(void)
+{
+ fsl_usb_xcvr_unregister(&serial_ops);
+}
+
+module_init(serialxc_init);
+module_exit(serialxc_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("serial xcvr driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/snoop.c b/arch/arm/plat-mxc/snoop.c
new file mode 100644
index 000000000000..b6e48c7e59d0
--- /dev/null
+++ b/arch/arm/plat-mxc/snoop.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <mach/hardware.h>
+#include <linux/io.h>
+
+#ifdef M4IF_BASE_ADDR
+#define SNOOP_V2
+#define MAX_SNOOP 2
+#define g_snoop_base (IO_ADDRESS(M4IF_BASE_ADDR) + 0x4C)
+#elif defined(M3IF_BASE_ADDR)
+#define MAX_SNOOP 1
+#define g_snoop_base (IO_ADDRESS(M3IF_BASE_ADDR) + 0x28)
+#else
+#define MAX_SNOOP 0
+#define g_snoop_base 0
+#endif
+
+/* M3IF Snooping Configuration Register 0 (M3IFSCFG0) READ/WRITE*/
+#define SBAR(x) (x * 0x14)
+/* M3IF Snooping Configuration Register 1 (M3IFSCFG1) READ/WRITE*/
+#define SERL(x) ((x * 0x14) + 0x4)
+/* M3IF Snooping Configuration Register 2 (M3IFSCFG2) READ/WRITE*/
+#define SERH(x) ((x * 0x14) + 0x8)
+/* M3IF Snooping Status Register 0 (M3IFSSR0) READ/WRITE */
+#define SSRL(x) ((x * 0x14) + 0xC)
+/* M3IF Snooping Status Register 1 (M3IFSSR1) */
+#define SSRH(x) ((x * 0x14) + 0x10)
+
+#if MAX_SNOOP
+
+int mxc_snoop_set_config(u32 num, unsigned long base, int size)
+{
+ u32 reg;
+ uint32_t msb;
+ uint32_t seg_size;
+ uint32_t window_size = 0;
+ int i;
+
+ if (num >= MAX_SNOOP) {
+ return -EINVAL;
+ }
+
+ /* Setup M3IF for snooping */
+ if (size) {
+
+ if (base == 0) {
+ return -EINVAL;
+ }
+
+ msb = fls(size);
+ if (!(size & ((1UL << msb) - 1)))
+ msb--; /* Already aligned to power 2 */
+ if (msb < 11)
+ msb = 11;
+
+ window_size = (1UL << msb);
+ seg_size = window_size / 64;
+
+ msb -= 11;
+
+ reg = base & ~((1UL << msb) - 1);
+ reg |= msb << 1;
+ reg |= 1; /* enable snooping */
+ reg |= 0x80; /* Set pulse width to default (M4IF only) */
+ __raw_writel(reg, g_snoop_base + SBAR(num));
+
+ reg = 0;
+ for (i = 0; i < 32; i++) {
+ if (i * seg_size >= size)
+ break;
+ reg |= 1UL << i;
+ }
+ __raw_writel(reg, g_snoop_base + SERL(num));
+
+ reg = 0;
+ for (i = 32; i < 64; i++) {
+ if (i * seg_size >= size)
+ break;
+ reg |= 1UL << (i - 32);
+ }
+ __raw_writel(reg, g_snoop_base + SERH(num));
+
+ pr_debug
+ ("Snooping unit # %d enabled: window size = 0x%X, M3IFSCFG0=0x%08X, M3IFSCFG1=0x%08X, M3IFSCFG2=0x%08X\n",
+ num, window_size, __raw_readl(g_snoop_base + SBAR(num)),
+ __raw_readl(g_snoop_base + SERL(num)),
+ __raw_readl(g_snoop_base + SERH(num)));
+ } else {
+ __raw_writel(0, g_snoop_base + SBAR(num));
+ }
+
+ return window_size;
+}
+
+EXPORT_SYMBOL(mxc_snoop_set_config);
+
+int mxc_snoop_get_status(u32 num, u32 * statl, u32 * stath)
+{
+ if (num >= MAX_SNOOP) {
+ return -EINVAL;
+ }
+
+ *statl = __raw_readl(g_snoop_base + SSRL(num));
+ *stath = __raw_readl(g_snoop_base + SSRH(num));
+ /* DPRINTK("status = 0x%08X%08X\n", stat[1], stat[0]); */
+
+#ifdef SNOOP_V2
+ __raw_writel(*statl, g_snoop_base + SSRL(num));
+ __raw_writel(*stath, g_snoop_base + SSRH(num));
+#else
+ __raw_writel(0x0, g_snoop_base + SSRL(num));
+ __raw_writel(0x0, g_snoop_base + SSRH(num));
+#endif
+ return 0;
+}
+
+EXPORT_SYMBOL(mxc_snoop_get_status);
+
+#endif /* MAX_SNOOP */
diff --git a/arch/arm/plat-mxc/spba.c b/arch/arm/plat-mxc/spba.c
new file mode 100644
index 000000000000..a7f21a9e36df
--- /dev/null
+++ b/arch/arm/plat-mxc/spba.c
@@ -0,0 +1,133 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/types.h>
+#include <linux/clk.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <mach/hardware.h>
+#include <mach/spba.h>
+
+/*!
+ * @file plat-mxc/spba.c
+ *
+ * @brief This file contains the SPBA API implementation details.
+ *
+ * @ingroup SPBA
+ */
+
+static DEFINE_SPINLOCK(spba_lock);
+
+#define SPBA_MASTER_MIN 1
+#define SPBA_MASTER_MAX 7
+
+/*!
+ * the base addresses for the SPBA modules
+ */
+static unsigned long spba_base = (unsigned long)IO_ADDRESS(SPBA_CTRL_BASE_ADDR);
+
+/*!
+ * SPBA clock
+ */
+static struct clk *spba_clk;
+/*!
+ * This function allows the three masters (A, B, C) to take ownership of a
+ * shared peripheral.
+ *
+ * @param mod specified module as defined in \b enum \b #spba_module
+ * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters
+ *
+ * @return 0 if successful; -1 otherwise.
+ */
+int spba_take_ownership(int mod, int master)
+{
+ unsigned long spba_flags;
+ __u32 rtn_val = -1;
+
+ if (master < SPBA_MASTER_MIN || master > SPBA_MASTER_MAX) {
+ printk("spba_take_ownership() invalide master= %d\n", master);
+ BUG(); /* oops */
+ }
+
+ if (spba_clk == NULL)
+ spba_clk = clk_get(NULL, "spba_clk");
+
+ clk_enable(spba_clk);
+
+ spin_lock_irqsave(&spba_lock, spba_flags);
+ __raw_writel(master, spba_base + mod);
+
+ if ((__raw_readl(spba_base + mod) & MXC_SPBA_RAR_MASK) == master) {
+ rtn_val = 0;
+ }
+
+ spin_unlock_irqrestore(&spba_lock, spba_flags);
+
+ clk_disable(spba_clk);
+ return rtn_val;
+}
+
+/*!
+ * This function releases the ownership for a shared peripheral.
+ *
+ * @param mod specified module as defined in \b enum \b #spba_module
+ * @param master one of more (or-ed together) masters as defined in \b enum \b #spba_masters
+ *
+ * @return 0 if successful; -1 otherwise.
+ */
+int spba_rel_ownership(int mod, int master)
+{
+ unsigned long spba_flags;
+ volatile unsigned long rar;
+
+ if (master < SPBA_MASTER_MIN || master > SPBA_MASTER_MAX) {
+ printk("spba_take_ownership() invalide master= %d\n", master);
+ BUG(); /* oops */
+ }
+
+ if (spba_clk == NULL)
+ spba_clk = clk_get(NULL, "spba_clk");
+
+ clk_enable(spba_clk);
+
+ if ((__raw_readl(spba_base + mod) & master) == 0) {
+ clk_disable(spba_clk);
+ return 0; /* does not own it */
+ }
+
+ spin_lock_irqsave(&spba_lock, spba_flags);
+
+ /* Since only the last 3 bits are writeable, doesn't need to mask off
+ bits 31-3 */
+ rar = __raw_readl(spba_base + mod) & (~master);
+ __raw_writel(rar, spba_base + mod);
+
+ if ((__raw_readl(spba_base + mod) & master) != 0) {
+ spin_unlock_irqrestore(&spba_lock, spba_flags);
+ clk_disable(spba_clk);
+ return -1;
+ }
+
+ spin_unlock_irqrestore(&spba_lock, spba_flags);
+
+ clk_disable(spba_clk);
+
+ return 0;
+}
+
+EXPORT_SYMBOL(spba_take_ownership);
+EXPORT_SYMBOL(spba_rel_ownership);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("SPBA");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
new file mode 100644
index 000000000000..5cfe328fc865
--- /dev/null
+++ b/arch/arm/plat-mxc/tzic.c
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <mach/hardware.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <asm/mach/irq.h>
+
+/*
+ *****************************************
+ * TZIC Registers *
+ *****************************************
+ */
+#define TZIC_BASE IO_ADDRESS(TZIC_BASE_ADDR)
+#define TZIC_INTCNTL (TZIC_BASE + 0x0000) /* control register */
+#define TZIC_INTTYPE (TZIC_BASE + 0x0004) /* Controller type register */
+#define TZIC_IMPID (TZIC_BASE + 0x0008) /* Distributor Implementer Identification Register */
+#define TZIC_PRIOMASK (TZIC_BASE + 0x000C) /* Priority Mask Reg */
+#define TZIC_SYNCCTRL (TZIC_BASE + 0x0010) /* Synchronizer Control register */
+#define TZIC_DSMINT (TZIC_BASE + 0x0014) /* DSM interrupt Holdoffregister */
+#define TZIC_INTSEC0 (TZIC_BASE + 0x0080) /* interrupt security register 0 */
+#define TZIC_ENSET0 (TZIC_BASE + 0x0100) /* Enable Set Register 0 */
+#define TZIC_ENCLEAR0 (TZIC_BASE + 0x0180) /* Enable Clear Register 0 */
+#define TZIC_SRCSET0 (TZIC_BASE + 0x0200) /* Source Set Register 0 */
+#define TZIC_SRCCLAR0 (TZIC_BASE + 0x0280) /* Source Clear Register 0 */
+#define TZIC_PRIORITY0 (TZIC_BASE + 0x0400) /* Priority Register 0 */
+#define TZIC_PND0 (TZIC_BASE + 0x0D00) /* Pending Register 0 */
+#define TZIC_HIPND0 (TZIC_BASE + 0x0D80) /* High Priority Pending Register */
+#define TZIC_WAKEUP0 (TZIC_BASE + 0x0E00) /* Wakeup Config Register */
+#define TZIC_SWINT (TZIC_BASE + 0x0F00) /* Software Interrupt Rigger Register */
+#define TZIC_ID0 (TZIC_BASE + 0x0FD0) /* Indentification Register 0 */
+
+/*!
+ * Disable interrupt number "irq" in the TZIC
+ *
+ * @param irq interrupt source number
+ */
+static void mxc_mask_irq(unsigned int irq)
+{
+ int index, off;
+
+ index = irq >> 5;
+ off = irq & 0x1F;
+ __raw_writel(1 << off, TZIC_ENCLEAR0 + (index << 2));
+}
+
+/*!
+ * Enable interrupt number "irq" in the TZIC
+ *
+ * @param irq interrupt source number
+ */
+static void mxc_unmask_irq(unsigned int irq)
+{
+ int index, off;
+
+ index = irq >> 5;
+ off = irq & 0x1F;
+ __raw_writel(1 << off, TZIC_ENSET0 + (index << 2));
+}
+
+static unsigned int wakeup_intr[4];
+
+/*!
+ * Set interrupt number "irq" in the TZIC as a wake-up source.
+ *
+ * @param irq interrupt source number
+ * @param enable enable as wake-up if equal to non-zero
+ * disble as wake-up if equal to zero
+ *
+ * @return This function returns 0 on success.
+ */
+static int mxc_set_wake_irq(unsigned int irq, unsigned int enable)
+{
+ unsigned int index, off;
+
+ index = irq >> 5;
+ off = irq & 0x1F;
+
+ if (index > 3)
+ return -1;
+
+ if (enable)
+ wakeup_intr[index] |= (1 << off);
+ else
+ wakeup_intr[index] &= ~(1 << off);
+
+ return 0;
+}
+
+static struct irq_chip mxc_tzic_chip = {
+ .name = "MXC_TZIC",
+ .ack = mxc_mask_irq,
+ .mask = mxc_mask_irq,
+ .unmask = mxc_unmask_irq,
+ .set_wake = mxc_set_wake_irq,
+};
+
+/*!
+ * This function initializes the TZIC hardware and disables all the
+ * interrupts. It registers the interrupt enable and disable functions
+ * to the kernel for each interrupt source.
+ */
+void __init mxc_init_irq(void)
+{
+ int i;
+
+ /* put the TZIC into the reset value with
+ * all interrupts disabled
+ */
+ i = __raw_readl(TZIC_INTCNTL);
+
+ __raw_writel(0x80010001, TZIC_INTCNTL);
+ i = __raw_readl(TZIC_INTCNTL);
+ __raw_writel(0x1f, TZIC_PRIOMASK);
+ i = __raw_readl(TZIC_PRIOMASK);
+ __raw_writel(0x02, TZIC_SYNCCTRL);
+ i = __raw_readl(TZIC_SYNCCTRL);
+ for (i = 0; i < 4; i++) {
+ __raw_writel(0xFFFFFFFF, TZIC_INTSEC0 + i * 4);
+ }
+ /* disable all interrupts */
+ for (i = 0; i < 4; i++) {
+ __raw_writel(0xFFFFFFFF, TZIC_ENCLEAR0 + i * 4);
+ }
+
+ /* all IRQ no FIQ Warning :: No selection */
+
+ for (i = 0; i < MXC_MAX_INT_LINES; i++) {
+ set_irq_chip(i, &mxc_tzic_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+
+ printk(KERN_INFO "MXC IRQ initialized\n");
+}
+
+/*!
+ * enable wakeup interrupt
+ *
+ * @param is_idle 1 if called in idle loop (enset registers);
+ * 0 to be used when called from low power entry
+ * @return 0 if successful; non-zero otherwise
+ */
+int tzic_enable_wake(int is_idle)
+{
+ unsigned int i, v;
+
+ __raw_writel(1, TZIC_DSMINT);
+ if (unlikely(__raw_readl(TZIC_DSMINT) == 0))
+ return -EAGAIN;
+
+ if (likely(is_idle)) {
+ for (i = 0; i < 4; i++) {
+ v = __raw_readl(TZIC_ENSET0 + i * 4);
+ __raw_writel(v, TZIC_WAKEUP0 + i * 4);
+ }
+ } else {
+ for (i = 0; i < 4; i++) {
+ v = wakeup_intr[i];
+ __raw_writel(v, TZIC_WAKEUP0 + i * 4);
+ }
+ }
+ return 0;
+}
diff --git a/arch/arm/plat-mxc/usb_common.c b/arch/arm/plat-mxc/usb_common.c
new file mode 100644
index 000000000000..72c4bfe85551
--- /dev/null
+++ b/arch/arm/plat-mxc/usb_common.c
@@ -0,0 +1,772 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * otg_{get,set}_transceiver() are from arm/plat-omap/usb.c.
+ * which is Copyright (C) 2004 Texas Instruments, Inc.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ *@defgroup USB ARC OTG USB Driver
+ */
+
+/*!
+ * @file usb_common.c
+ *
+ * @brief platform related part of usb driver.
+ * @ingroup USB
+ */
+
+/*!
+ *Include files
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/usb/otg.h>
+#include <linux/usb/fsl_xcvr.h>
+#include <linux/regulator/regulator.h>
+#include <mach/arc_otg.h>
+#include <asm/mach-types.h>
+
+#define MXC_NUMBER_USB_TRANSCEIVER 6
+struct fsl_xcvr_ops *g_xc_ops[MXC_NUMBER_USB_TRANSCEIVER] = { NULL };
+
+static struct clk *usb_clk;
+static struct clk *usb_ahb_clk;
+
+extern int gpio_usbotg_hs_active(void);
+extern int gpio_usbotg_hs_inactive(void);
+
+/*
+ * make sure USB_CLK is running at 60 MHz +/- 1000 Hz
+ */
+static int fsl_check_usbclk(void)
+{
+ unsigned long freq;
+
+ usb_ahb_clk = clk_get(NULL, "usb_ahb_clk");
+ if (clk_enable(usb_ahb_clk)) {
+ printk(KERN_ERR "clk_enable(usb_ahb_clk) failed\n");
+ return -EINVAL;
+ }
+ clk_put(usb_ahb_clk);
+
+ usb_clk = clk_get(NULL, "usb_clk");
+ freq = clk_get_rate(usb_clk);
+ clk_put(usb_clk);
+ if ((freq < 59999000) || (freq > 60001000)) {
+ printk(KERN_ERR "USB_CLK=%lu, should be 60MHz\n", freq);
+ return -1;
+ }
+
+ return 0;
+}
+
+void fsl_usb_xcvr_register(struct fsl_xcvr_ops *xcvr_ops)
+{
+ int i;
+
+ pr_debug("%s\n", __func__);
+ for (i = 0; i < MXC_NUMBER_USB_TRANSCEIVER; i++) {
+ if (g_xc_ops[i] == NULL) {
+ g_xc_ops[i] = xcvr_ops;
+ return;
+ }
+ }
+
+ pr_debug("Failed %s\n", __func__);
+}
+EXPORT_SYMBOL(fsl_usb_xcvr_register);
+
+void fsl_platform_set_test_mode (struct fsl_usb2_platform_data *pdata, enum usb_test_mode mode)
+{
+ if (pdata->xcvr_ops && pdata->xcvr_ops->set_test_mode)
+ pdata->xcvr_ops->set_test_mode((u32 *)(pdata->regs + ULPIVW_OFF), mode);
+}
+EXPORT_SYMBOL(fsl_platform_set_test_mode);
+
+void fsl_usb_xcvr_unregister(struct fsl_xcvr_ops *xcvr_ops)
+{
+ int i;
+
+ pr_debug("%s\n", __func__);
+ for (i = 0; i < MXC_NUMBER_USB_TRANSCEIVER; i++) {
+ if (g_xc_ops[i] == xcvr_ops) {
+ g_xc_ops[i] = NULL;
+ return;
+ }
+ }
+
+ pr_debug("Failed %s\n", __func__);
+}
+EXPORT_SYMBOL(fsl_usb_xcvr_unregister);
+
+static struct fsl_xcvr_ops *fsl_usb_get_xcvr(char *name)
+{
+ int i;
+
+ pr_debug("%s\n", __func__);
+ if (name == NULL) {
+ printk(KERN_ERR "get_xcvr(): No tranceiver name\n");
+ return NULL;
+ }
+
+ for (i = 0; i < MXC_NUMBER_USB_TRANSCEIVER; i++) {
+ if (strcmp(g_xc_ops[i]->name, name) == 0) {
+ return g_xc_ops[i];
+ }
+ }
+ pr_debug("Failed %s\n", __func__);
+ return NULL;
+}
+
+/* The dmamask must be set for EHCI to work */
+static u64 ehci_dmamask = ~(u32) 0;
+
+/*!
+ * Register an instance of a USB host platform device.
+ *
+ * @param res: resource pointer
+ * @param n_res: number of resources
+ * @param config: config pointer
+ *
+ * @return newly-registered platform_device
+ *
+ * The USB controller supports 3 host interfaces, and the
+ * kernel can be configured to support some number of them.
+ * Each supported host interface is registered as an instance
+ * of the "fsl-ehci" device. Call this function multiple times
+ * to register each host interface.
+ */
+static int instance_id = 0;
+struct platform_device *host_pdev_register(struct resource *res, int n_res,
+ struct fsl_usb2_platform_data *config)
+{
+ struct platform_device *pdev;
+ int rc;
+
+ pr_debug("register host res=0x%p, size=%d\n", res, n_res);
+
+ pdev = platform_device_register_simple("fsl-ehci",
+ instance_id, res, n_res);
+ if (IS_ERR(pdev)) {
+ pr_debug("can't register %s Host, %ld\n",
+ config->name, PTR_ERR(pdev));
+ return NULL;
+ }
+
+ pdev->dev.coherent_dma_mask = 0xffffffff;
+ pdev->dev.dma_mask = &ehci_dmamask;
+
+ /*
+ * platform_device_add_data() makes a copy of
+ * the platform_data passed in. That makes it
+ * impossible to share the same config struct for
+ * all OTG devices (host,gadget,otg). So, just
+ * set the platorm_data pointer ourselves.
+ */
+ rc = platform_device_add_data(pdev, config,
+ sizeof(struct fsl_usb2_platform_data));
+ if (rc) {
+ platform_device_unregister(pdev);
+ return NULL;
+ }
+
+ printk(KERN_INFO "usb: %s host (%s) registered\n", config->name,
+ config->transceiver);
+ pr_debug("pdev=0x%p dev=0x%p resources=0x%p pdata=0x%p\n",
+ pdev, &pdev->dev, pdev->resource, pdev->dev.platform_data);
+
+ instance_id++;
+
+ return pdev;
+}
+
+/* DDD looks like this is needed by Belcarra code */
+void fsl_platform_set_vbus_power(struct fsl_usb2_platform_data *pdata, int on)
+{
+ if (pdata->xcvr_ops && pdata->xcvr_ops->set_vbus_power)
+ pdata->xcvr_ops->set_vbus_power(pdata->xcvr_ops, pdata, on);
+}
+EXPORT_SYMBOL(fsl_platform_set_vbus_power);
+
+/* DDD looks like this is needed by Belcarra code */
+void fsl_platform_perform_remote_wakeup(struct fsl_usb2_platform_data *pdata)
+{
+ if (pdata->xcvr_ops && pdata->xcvr_ops->set_remote_wakeup)
+ pdata->xcvr_ops->set_remote_wakeup(
+ (u32 *)(pdata->regs + ULPIVW_OFF));
+}
+EXPORT_SYMBOL(fsl_platform_perform_remote_wakeup);
+
+#if defined(CONFIG_USB_OTG)
+static struct otg_transceiver *xceiv;
+
+/**
+ * otg_get_transceiver - find the (single) OTG transceiver driver
+ *
+ * Returns the transceiver driver, after getting a refcount to it; or
+ * null if there is no such transceiver. The caller is responsible for
+ * releasing that count.
+ */
+struct otg_transceiver *otg_get_transceiver(void)
+{
+ pr_debug("%s xceiv=0x%p\n", __func__, xceiv);
+ if (xceiv)
+ get_device(xceiv->dev);
+ return xceiv;
+}
+EXPORT_SYMBOL(otg_get_transceiver);
+
+int otg_set_transceiver(struct otg_transceiver *x)
+{
+ pr_debug("%s xceiv=0x%p x=0x%p\n", __func__, xceiv, x);
+ if (xceiv && x)
+ return -EBUSY;
+ xceiv = x;
+ return 0;
+}
+EXPORT_SYMBOL(otg_set_transceiver);
+
+static struct resource *otg_resources;
+
+struct resource *otg_get_resources(void)
+{
+ return otg_resources;
+}
+EXPORT_SYMBOL(otg_get_resources);
+
+int otg_set_resources(struct resource *resources)
+{
+ otg_resources = resources;
+ return 0;
+}
+EXPORT_SYMBOL(otg_set_resources);
+#endif
+
+static void usbh1_set_serial_xcvr(void)
+{
+ pr_debug("%s: \n", __func__);
+ USBCTRL &= ~(UCTRL_H1SIC_MASK | UCTRL_BPE); /* disable bypass mode */
+ USBCTRL |= UCTRL_H1SIC_SU6 | /* single-ended / unidir. */
+ UCTRL_H1WIE | UCTRL_H1DT | /* disable H1 TLL */
+ UCTRL_H1PM; /* power mask */
+}
+
+static void usbh1_set_ulpi_xcvr(void)
+{
+ pr_debug("%s: \n", __func__);
+
+ /* Stop then Reset */
+ UH1_USBCMD &= ~UCMD_RUN_STOP;
+ while (UH1_USBCMD & UCMD_RUN_STOP) ;
+
+ UH1_USBCMD |= UCMD_RESET;
+ while (UH1_USBCMD & UCMD_RESET) ;
+
+ /* Select the clock from external PHY */
+ USB_CTRL_1 |= USB_CTRL_UH1_EXT_CLK_EN;
+
+ /* select ULPI PHY PTS=2 */
+ UH1_PORTSC1 = (UH1_PORTSC1 & ~PORTSC_PTS_MASK) | PORTSC_PTS_ULPI;
+
+ USBCTRL |= UCTRL_H1WIE; /* HOST1 wakeup intr enable */
+ USBCTRL |= UCTRL_H1UIE; /* Host1 ULPI interrupt enable */
+ USBCTRL &= ~UCTRL_H1PM; /* HOST1 power mask */
+
+ /* Interrupt Threshold Control:Immediate (no threshold) */
+ UH1_USBCMD &= UCMD_ITC_NO_THRESHOLD;
+
+ UH1_USBCMD |= UCMD_RESET; /* reset the controller */
+
+ /* allow controller to reset, and leave time for
+ * the ULPI transceiver to reset too.
+ */
+ msleep(100);
+
+ /* Turn off the usbpll for ulpi tranceivers */
+ clk_disable(usb_clk);
+}
+static void usbh2_set_ulpi_xcvr(void)
+{
+ u32 tmp;
+
+ pr_debug("%s\n", __func__);
+ USBCTRL &= ~(UCTRL_H2SIC_MASK | UCTRL_BPE);
+ USBCTRL |= UCTRL_H2WIE | /* wakeup intr enable */
+ UCTRL_H2UIE | /* ULPI intr enable */
+ UCTRL_H2DT | /* disable H2 TLL */
+ UCTRL_H2PM; /* power mask */
+
+ /* must set ULPI phy before turning off clock */
+ tmp = UH2_PORTSC1 & ~PORTSC_PTS_MASK;
+ tmp |= PORTSC_PTS_ULPI;
+ UH2_PORTSC1 = tmp;
+
+ UH2_USBCMD |= UCMD_RESET; /* reset the controller */
+
+ /* allow controller to reset, and leave time for
+ * the ULPI transceiver to reset too.
+ */
+ msleep(100);
+
+ /* Turn off the usbpll for ulpi tranceivers */
+ clk_disable(usb_clk);
+}
+
+static void usbh2_set_serial_xcvr(void)
+{
+ pr_debug("%s: \n", __func__);
+
+ /* Stop then Reset */
+ UH2_USBCMD &= ~UCMD_RUN_STOP;
+ while (UH2_USBCMD & UCMD_RUN_STOP) ;
+
+ UH2_USBCMD |= UCMD_RESET;
+ while (UH2_USBCMD & UCMD_RESET) ;
+
+ USBCTRL &= ~(UCTRL_H2SIC_MASK); /* Disable bypass mode */
+ USBCTRL &= ~(UCTRL_H2PM); /* Power Mask */
+ USBCTRL &= ~UCTRL_H2OCPOL; /* OverCurrent Polarity is Low Active */
+ USBCTRL |= UCTRL_H2WIE | /* Wakeup intr enable */
+ UCTRL_IP_PUE_DOWN | /* ipp_pue_pulldwn_dpdm */
+ UCTRL_USBTE | /* USBT is enabled */
+ UCTRL_H2DT; /* Disable H2 TLL */
+
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 0) {
+ /* Disable Host2 bus Lock for i.MX35 1.0 */
+ USBCTRL |= UCTRL_H2LOCKD;
+ /* USBOTG_PWR low active */
+ USBCTRL &= ~UCTRL_PP;
+ /* OverCurrent Polarity is Low Active */
+ USBCTRL &= ~UCTRL_OCPOL;
+ } else if (cpu_is_mx35_rev(CHIP_REV_2_0) >= 1) {
+ /* i.MX35 2.0 OTG and Host2 have seperate OC/PWR polarity */
+ USBCTRL &= ~UCTRL_H2PP;
+ USBCTRL &= ~UCTRL_H2OCPOL;
+ } else if (cpu_is_mx25()) {
+ /*
+ * USBH2_PWR and USBH2_OC are active high.
+ * Must force xcvr clock to "internal" so that
+ * we can write to PTS field after it's been
+ * cleared by ehci_turn_off_all_ports().
+ */
+ USBCTRL |= UCTRL_H2PP | UCTRL_H2OCPOL | UCTRL_XCSH2;
+ /* Disable Host2 bus Lock */
+ USBCTRL |= UCTRL_H2LOCKD;
+ }
+
+ USBCTRL &= ~(UCTRL_PP);
+ UH2_PORTSC1 = (UH2_PORTSC1 & (~PORTSC_PTS_MASK)) | PORTSC_PTS_SERIAL;
+
+ if (UH2_HCSPARAMS & HCSPARAMS_PPC)
+ UH2_PORTSC1 |= PORTSC_PORT_POWER;
+
+ /* Reset controller before set host mode */
+ UH2_USBCMD |= UCMD_RESET;
+ while (UH2_USBCMD & UCMD_RESET) ;
+
+ msleep(100);
+}
+
+extern void usbh2_get_xcvr_power(struct device *dev);
+extern void usbh2_put_xcvr_power(struct device *dev);
+extern void gpio_usbh1_setback_stp(void);
+
+int fsl_usb_host_init(struct platform_device *pdev)
+{
+ struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+ struct fsl_xcvr_ops *xops;
+
+ pr_debug("%s: pdev=0x%p pdata=0x%p\n", __func__, pdev, pdata);
+
+ xops = fsl_usb_get_xcvr(pdata->transceiver);
+ if (!xops) {
+ printk(KERN_ERR "%s transceiver ops missing\n", pdata->name);
+ return -EINVAL;
+ }
+ pdata->xcvr_ops = xops;
+ pdata->xcvr_type = xops->xcvr_type;
+ pdata->pdev = pdev;
+
+ if (fsl_check_usbclk() != 0)
+ return -EINVAL;
+
+ /* set host2 usb phy usb3317 power supply for imx31 3 stack */
+ if ((pdata->xcvr_type == PORTSC_PTS_ULPI) && (machine_is_mx31_3ds())) {
+ pdata->xcvr_pwr =
+ kmalloc(sizeof(struct fsl_xcvr_power), GFP_KERNEL);
+ if (!(pdata->xcvr_pwr))
+ return -ENOMEM;
+
+ pdata->xcvr_pwr->usb_pdev = pdev;
+ usbh2_get_xcvr_power(&(pdev->dev));
+ }
+
+ pr_debug("%s: grab pins\n", __func__);
+ if (pdata->gpio_usb_active())
+ return -EINVAL;
+
+ if (clk_enable(usb_clk)) {
+ printk(KERN_ERR "clk_enable(usb_clk) failed\n");
+ return -EINVAL;
+ }
+
+ if (cpu_is_mx51()) {
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_enable(usb_clk);
+ clk_put(usb_clk);
+ }
+
+ if (xops->init)
+ xops->init(xops);
+
+ if (xops->xcvr_type == PORTSC_PTS_SERIAL) {
+ if (cpu_is_mx35()) {
+ usbh2_set_serial_xcvr();
+ /* Close the internal 60Mhz */
+ USBCTRL &= ~UCTRL_XCSH2;
+ } else if (cpu_is_mx25())
+ usbh2_set_serial_xcvr();
+ else
+ usbh1_set_serial_xcvr();
+ } else if (xops->xcvr_type == PORTSC_PTS_ULPI) {
+ if (cpu_is_mx51()) {
+ usbh1_set_ulpi_xcvr();
+ gpio_usbh1_setback_stp();
+ } else
+ usbh2_set_ulpi_xcvr();
+ }
+
+ pr_debug("%s: %s success\n", __func__, pdata->name);
+ return 0;
+}
+EXPORT_SYMBOL(fsl_usb_host_init);
+
+void fsl_usb_host_uninit(struct fsl_usb2_platform_data *pdata)
+{
+ pr_debug("%s\n", __func__);
+
+ if (pdata->xcvr_ops && pdata->xcvr_ops->uninit)
+ pdata->xcvr_ops->uninit(pdata->xcvr_ops);
+
+ pdata->regs = NULL;
+
+ pdata->gpio_usb_inactive();
+ if (pdata->xcvr_type == PORTSC_PTS_SERIAL) {
+ /* Workaround an IC issue for 2.6.26 kernal:
+ * when turn off root hub port power, EHCI set
+ * PORTSC reserved bits to be 0, but PTS with 0
+ * means UTMI interface, so here force the Host2
+ * port use the internal 60Mhz.
+ */
+ if (cpu_is_mx35())
+ USBCTRL |= UCTRL_XCSH2;
+ clk_disable(usb_clk);
+ }
+ else if ((pdata->xcvr_type == PORTSC_PTS_ULPI)
+ && (machine_is_mx31_3ds())) {
+ usbh2_put_xcvr_power(&(pdata->xcvr_pwr->usb_pdev->dev));
+ kfree(pdata->xcvr_pwr);
+ }
+
+ if (cpu_is_mx51()) {
+ usb_clk = clk_get(NULL, "usboh3_clk");
+ clk_disable(usb_clk);
+ clk_put(usb_clk);
+ }
+}
+EXPORT_SYMBOL(fsl_usb_host_uninit);
+
+static void otg_set_serial_xcvr(void)
+{
+ pr_debug("%s\n", __func__);
+}
+
+void otg_set_serial_host(void)
+{
+ pr_debug("%s\n", __func__);
+ /* set USBCTRL for host operation
+ * disable: bypass mode,
+ * set: single-ended/unidir/6 wire, OTG wakeup intr enable,
+ * power mask
+ */
+ USBCTRL &= ~UCTRL_OSIC_MASK;
+#if defined(CONFIG_ARCH_MX27) || defined(CONFIG_ARCH_MX3)
+ USBCTRL &= ~UCTRL_BPE;
+#endif
+
+#if defined(CONFIG_MXC_USB_SB3)
+ USBCTRL |= UCTRL_OSIC_SB3 | UCTRL_OWIE | UCTRL_OPM;
+#elif defined(CONFIG_MXC_USB_SU6)
+ USBCTRL |= UCTRL_OSIC_SU6 | UCTRL_OWIE | UCTRL_OPM;
+#elif defined(CONFIG_MXC_USB_DB4)
+ USBCTRL |= UCTRL_OSIC_DB4 | UCTRL_OWIE | UCTRL_OPM;
+#else
+ USBCTRL |= UCTRL_OSIC_DU6 | UCTRL_OWIE | UCTRL_OPM;
+#endif
+
+ USB_OTG_MIRROR = OTGM_VBUSVAL | OTGM_ASESVLD; /* 0xa */
+}
+EXPORT_SYMBOL(otg_set_serial_host);
+
+void otg_set_serial_peripheral(void)
+{
+ /* set USBCTRL for device operation
+ * disable: bypass mode
+ * set: differential/unidir/6 wire, OTG wakeup intr enable,
+ * power mask
+ */
+ USBCTRL &= ~UCTRL_OSIC_MASK;
+#if defined(CONFIG_ARCH_MX27) || defined(CONFIG_ARCH_MX3)
+ USBCTRL &= ~UCTRL_BPE;
+#endif
+
+#if defined(CONFIG_MXC_USB_SB3)
+ USBCTRL |= UCTRL_OSIC_SB3 | UCTRL_OWIE | UCTRL_OPM;
+#elif defined(CONFIG_MXC_USB_SU6)
+ USBCTRL |= UCTRL_OSIC_SU6 | UCTRL_OWIE | UCTRL_OPM;
+#elif defined(CONFIG_MXC_USB_DB4)
+ USBCTRL |= UCTRL_OSIC_DB4 | UCTRL_OWIE | UCTRL_OPM;
+#else
+ USBCTRL |= UCTRL_OSIC_DU6 | UCTRL_OWIE | UCTRL_OPM;
+#endif
+
+ USB_OTG_MIRROR = OTGM_VBUSVAL | OTGM_BSESVLD | OTGM_IDIDG; /* oxd */
+}
+EXPORT_SYMBOL(otg_set_serial_peripheral);
+
+static void otg_set_ulpi_xcvr(void)
+{
+ u32 tmp;
+
+ pr_debug("%s\n", __func__);
+ USBCTRL &= ~UCTRL_OSIC_MASK;
+#if defined(CONFIG_ARCH_MX27) || defined(CONFIG_ARCH_MX3)
+ USBCTRL &= ~UCTRL_BPE;
+#endif
+ USBCTRL |= UCTRL_OUIE | /* ULPI intr enable */
+ UCTRL_OWIE | /* OTG wakeup intr enable */
+ UCTRL_OPM; /* power mask */
+
+ /* must set ULPI phy before turning off clock */
+ tmp = UOG_PORTSC1 & ~PORTSC_PTS_MASK;
+ tmp |= PORTSC_PTS_ULPI;
+ UOG_PORTSC1 = tmp;
+
+ /* need to reset the controller here so that the ID pin
+ * is correctly detected.
+ */
+ UOG_USBCMD |= UCMD_RESET;
+
+ /* allow controller to reset, and leave time for
+ * the ULPI transceiver to reset too.
+ */
+ msleep(100);
+
+ /* Turn off the usbpll for ulpi tranceivers */
+ clk_disable(usb_clk);
+}
+
+int fsl_usb_xcvr_suspend(struct fsl_xcvr_ops *xcvr_ops)
+{
+ if (!machine_is_mx31_3ds())
+ return -ECANCELED;
+
+ if (xcvr_ops->xcvr_type == PORTSC_PTS_ULPI) {
+ if (fsl_check_usbclk() != 0)
+ return -EINVAL;
+ if (gpio_usbotg_hs_active())
+ return -EINVAL;
+ clk_enable(usb_clk);
+
+ otg_set_ulpi_xcvr();
+
+ if (xcvr_ops->suspend)
+ /* suspend transceiver */
+ xcvr_ops->suspend(xcvr_ops);
+
+ gpio_usbotg_hs_inactive();
+ clk_disable(usb_clk);
+ }
+ return 0;
+}
+EXPORT_SYMBOL(fsl_usb_xcvr_suspend);
+
+static void otg_set_utmi_xcvr(void)
+{
+ u32 tmp;
+
+ /* Stop then Reset */
+ UOG_USBCMD &= ~UCMD_RUN_STOP;
+ while (UOG_USBCMD & UCMD_RUN_STOP) ;
+
+ UOG_USBCMD |= UCMD_RESET;
+ while ((UOG_USBCMD) & (UCMD_RESET)) ;
+
+ if (cpu_is_mx51()) {
+ /* OTG Polarity of Overcurrent is Low active */
+ USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_OC_POL;
+ /* Enable OTG Overcurrent Event */
+ USB_PHY_CTR_FUNC &= ~USB_UTMI_PHYCTRL_OC_DIS;
+ } else if (cpu_is_mx25()) {
+ USBCTRL |= UCTRL_OCPOL;
+ USBCTRL &= ~UCTRL_PP;
+ } else {
+ /* USBOTG_PWR low active */
+ USBCTRL &= ~UCTRL_PP;
+ /* OverCurrent Polarity is Low Active */
+ USBCTRL &= ~UCTRL_OCPOL;
+
+ if (cpu_is_mx35_rev(CHIP_REV_2_0) < 0)
+ /* OTG Lock Disable */
+ USBCTRL |= UCTRL_OLOCKD;
+ }
+
+ USBCTRL &= ~UCTRL_OPM; /* OTG Power Mask */
+ USBCTRL |= UCTRL_OWIE; /* OTG Wakeup Intr Enable */
+
+ /* set UTMI xcvr */
+ tmp = UOG_PORTSC1 & ~PORTSC_PTS_MASK;
+ tmp |= PORTSC_PTS_UTMI;
+ UOG_PORTSC1 = tmp;
+
+ if (cpu_is_mx51()) {
+ /* Set the PHY clock to 19.2MHz */
+ USB_PHY_CTR_FUNC2 &= ~USB_UTMI_PHYCTRL2_PLLDIV_MASK;
+ USB_PHY_CTR_FUNC2 |= 0x01;
+ }
+ if (!cpu_is_mx25()) {
+ /* Workaround an IC issue for 2.6.26 kernal:
+ * when turn off root hub port power, EHCI set
+ * PORTSC reserved bits to be 0, but PTW with 0
+ * means 8 bits tranceiver width, here change
+ * it back to be 16 bits and do PHY diable and
+ * then enable.
+ */
+ UOG_PORTSC1 |= PORTSC_PTW;
+
+ /* Enable UTMI interface in PHY control Reg */
+ USB_PHY_CTR_FUNC &= ~USB_UTMI_PHYCTRL_UTMI_ENABLE;
+ USB_PHY_CTR_FUNC |= USB_UTMI_PHYCTRL_UTMI_ENABLE;
+ }
+
+ if (UOG_HCSPARAMS & HCSPARAMS_PPC)
+ UOG_PORTSC1 |= PORTSC_PORT_POWER;
+
+ /* need to reset the controller here so that the ID pin
+ * is correctly detected.
+ */
+ /* Stop then Reset */
+ UOG_USBCMD &= ~UCMD_RUN_STOP;
+ while (UOG_USBCMD & UCMD_RUN_STOP) ;
+
+ UOG_USBCMD |= UCMD_RESET;
+ while ((UOG_USBCMD) & (UCMD_RESET)) ;
+
+ /* allow controller to reset, and leave time for
+ * the ULPI transceiver to reset too.
+ */
+ msleep(100);
+
+ /* Turn off the usbpll for mx25 UTMI tranceivers */
+ /* DDD: can we do this UTMI xcvrs on all boards? */
+ if (cpu_is_mx25())
+ clk_disable(usb_clk);
+}
+
+static int otg_used = 0;
+
+int usbotg_init(struct platform_device *pdev)
+{
+ struct fsl_usb2_platform_data *pdata = pdev->dev.platform_data;
+ struct fsl_xcvr_ops *xops;
+
+ pr_debug("%s: pdev=0x%p pdata=0x%p\n", __func__, pdev, pdata);
+
+ xops = fsl_usb_get_xcvr(pdata->transceiver);
+ if (!xops) {
+ printk(KERN_ERR "DR transceiver ops missing\n");
+ return -EINVAL;
+ }
+ pdata->xcvr_ops = xops;
+ pdata->xcvr_type = xops->xcvr_type;
+ pdata->pdev = pdev;
+
+ if (!otg_used) {
+ if (fsl_check_usbclk() != 0)
+ return -EINVAL;
+
+ pr_debug("%s: grab pins\n", __func__);
+ if (pdata->gpio_usb_active())
+ return -EINVAL;
+
+ if (clk_enable(usb_clk)) {
+ printk(KERN_ERR "clk_enable(usb_clk) failed\n");
+ return -EINVAL;
+ }
+
+ if (xops->init)
+ xops->init(xops);
+
+ if (xops->xcvr_type == PORTSC_PTS_SERIAL) {
+ if (pdata->operating_mode == FSL_USB2_DR_HOST) {
+ otg_set_serial_host();
+ /* need reset */
+ UOG_USBCMD |= UCMD_RESET;
+ msleep(100);
+ } else if (pdata->operating_mode == FSL_USB2_DR_DEVICE)
+ otg_set_serial_peripheral();
+ otg_set_serial_xcvr();
+ } else if (xops->xcvr_type == PORTSC_PTS_ULPI) {
+ otg_set_ulpi_xcvr();
+ } else if (xops->xcvr_type == PORTSC_PTS_UTMI) {
+ otg_set_utmi_xcvr();
+ }
+ }
+
+ otg_used++;
+ pr_debug("%s: success\n", __func__);
+ return 0;
+}
+EXPORT_SYMBOL(usbotg_init);
+
+void usbotg_uninit(struct fsl_usb2_platform_data *pdata)
+{
+ pr_debug("%s\n", __func__);
+
+ otg_used--;
+ if (!otg_used) {
+ if (pdata->xcvr_ops && pdata->xcvr_ops->uninit)
+ pdata->xcvr_ops->uninit(pdata->xcvr_ops);
+
+ pdata->regs = NULL;
+
+ if (machine_is_mx31_3ds()) {
+ if (pdata->xcvr_ops && pdata->xcvr_ops->suspend)
+ pdata->xcvr_ops->suspend(pdata->xcvr_ops);
+ clk_disable(usb_clk);
+ }
+
+ pdata->gpio_usb_inactive();
+ if (pdata->xcvr_type == PORTSC_PTS_SERIAL)
+ clk_disable(usb_clk);
+ }
+}
+EXPORT_SYMBOL(usbotg_uninit);
diff --git a/arch/arm/plat-mxc/utmixc.c b/arch/arm/plat-mxc/utmixc.c
new file mode 100644
index 000000000000..ab1911794313
--- /dev/null
+++ b/arch/arm/plat-mxc/utmixc.c
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2005-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/fsl_devices.h>
+#include <linux/usb/fsl_xcvr.h>
+
+#include <mach/hardware.h>
+#include <mach/arc_otg.h>
+#include <asm/mach-types.h>
+#include <mach/pmic_external.h>
+
+static void usb_utmi_init(struct fsl_xcvr_ops *this)
+{
+}
+
+static void usb_utmi_uninit(struct fsl_xcvr_ops *this)
+{
+}
+
+/*!
+ * set vbus power
+ *
+ * @param view viewport register
+ * @param on power on or off
+ */
+static void set_power(struct fsl_xcvr_ops *this,
+ struct fsl_usb2_platform_data *pdata, int on)
+{
+ struct device *dev = &pdata->pdev->dev;
+ struct regulator *usbotg_regux;
+
+ pr_debug("real %s(on=%d) pdata=0x%p\n", __func__, on, pdata);
+ if (machine_is_mx37_3ds()) {
+ if (!board_is_mx37(BOARD_REV_2))
+ usbotg_regux = regulator_get(dev, "DCDC2");
+ else
+ usbotg_regux = regulator_get(dev, "SWBST");
+ if (on) {
+ regulator_enable(usbotg_regux);
+ } else {
+ regulator_disable(usbotg_regux);
+ }
+ regulator_put(usbotg_regux, dev);
+#if defined(CONFIG_MXC_PMIC_MC13892_MODULE) || defined(CONFIG_MXC_PMIC_MC13892)
+ } else if (machine_is_mx51_3ds()) {
+ unsigned int value;
+
+ usbotg_regux = regulator_get(dev, "SWBST");
+ if (on)
+ regulator_enable(usbotg_regux);
+ else
+ regulator_disable(usbotg_regux);
+ regulator_put(usbotg_regux, dev);
+
+ /* VUSBIN */
+ pmic_read_reg(REG_USB1, &value, 0xffffff);
+ if (on)
+ value |= 0x1;
+ else
+ value &= ~0x1;
+ pmic_write_reg(REG_USB1, value, 0xffffff);
+
+ /* VUSBEN */
+ usbotg_regux = regulator_get(dev, "USB");
+ if (on)
+ regulator_enable(usbotg_regux);
+ else
+ regulator_disable(usbotg_regux);
+ regulator_put(usbotg_regux, dev);
+#endif
+ }
+}
+
+static struct fsl_xcvr_ops utmi_ops = {
+ .name = "utmi",
+ .xcvr_type = PORTSC_PTS_UTMI,
+ .init = usb_utmi_init,
+ .uninit = usb_utmi_uninit,
+ .set_vbus_power = set_power,
+};
+
+extern void fsl_usb_xcvr_register(struct fsl_xcvr_ops *xcvr_ops);
+
+static int __init utmixc_init(void)
+{
+ fsl_usb_xcvr_register(&utmi_ops);
+ return 0;
+}
+
+extern void fsl_usb_xcvr_unregister(struct fsl_xcvr_ops *xcvr_ops);
+
+static void __exit utmixc_exit(void)
+{
+ fsl_usb_xcvr_unregister(&utmi_ops);
+}
+
+module_init(utmixc_init);
+module_exit(utmixc_exit);
+
+MODULE_AUTHOR("Freescale Semiconductor, Inc.");
+MODULE_DESCRIPTION("utmi xcvr driver");
+MODULE_LICENSE("GPL");
diff --git a/arch/arm/plat-mxc/wdog.c b/arch/arm/plat-mxc/wdog.c
new file mode 100644
index 000000000000..80dd1bd31be9
--- /dev/null
+++ b/arch/arm/plat-mxc/wdog.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2004-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ */
+
+/*
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+/*!
+ * @file plat-mxc/wdog.c
+ * @brief This file contains watchdog timer implementations.
+ *
+ * This file contains watchdog timer implementations for timer tick.
+ *
+ * @ingroup WDOG
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+
+#define WDOG_WT 0x8 /* WDOG WT starting bit inside WCR */
+#define WCR_WOE_BIT (1 << 6)
+#define WCR_WDA_BIT (1 << 5)
+#define WCR_SRS_BIT (1 << 4)
+#define WCR_WRE_BIT (1 << 3)
+#define WCR_WDE_BIT (1 << 2)
+#define WCR_WDBG_BIT (1 << 1)
+#define WCR_WDZST_BIT (1 << 0)
+
+/*
+ * WatchDog
+ */
+#define WDOG_WCR 0 /* 16bit watchdog control reg */
+#define WDOG_WSR 2 /* 16bit watchdog service reg */
+#define WDOG_WRSR 4 /* 16bit watchdog reset status reg */
+
+/*!
+ * The base addresses for the WDOG modules
+ */
+static unsigned long wdog_base[2] = {
+ IO_ADDRESS(WDOG1_BASE_ADDR),
+#ifdef WDOG2_BASE_ADDR
+ IO_ADDRESS(WDOG2_BASE_ADDR),
+#endif
+};
+
+void mxc_wd_reset(void)
+{
+ u16 reg;
+ struct clk *clk;
+
+ clk = clk_get(NULL, "wdog_clk");
+ clk_enable(clk);
+
+ reg = __raw_readw(wdog_base[0] + WDOG_WCR) & ~WCR_SRS_BIT;
+ reg |= WCR_WDE_BIT;
+ __raw_writew(reg, wdog_base[0] + WDOG_WCR);
+}